-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 40a0e6d
Showing
18 changed files
with
1,448 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.DS_Store | ||
/.build | ||
/Packages | ||
xcuserdata/ | ||
DerivedData/ | ||
.swiftpm/configuration/registries.json | ||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata | ||
.netrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.DS_Store | ||
/.build | ||
/Packages | ||
xcuserdata/ | ||
DerivedData/ | ||
.swiftpm/configuration/registries.json | ||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata | ||
.netrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// swift-tools-version: 5.10 | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "Example", | ||
platforms: [ | ||
.macOS(.v13) | ||
], | ||
dependencies: [ | ||
.package( | ||
name: "PDFViewKit", | ||
path: ".." | ||
) | ||
], | ||
targets: [ | ||
.executableTarget( | ||
name: "Example", | ||
dependencies: ["PDFViewKit"] | ||
) | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import SwiftUI | ||
import PDFViewKit | ||
|
||
struct MyPDFContent: View { | ||
|
||
var body: some View { | ||
Text("Hello, World") | ||
} | ||
|
||
} | ||
|
||
let destination = FileManager.default.temporaryDirectory.appending(path: "MyPDF.pdf") | ||
|
||
let document = PDFDocument { | ||
MyPDFContent() | ||
} | ||
|
||
do { | ||
try PDFRenderer.render( | ||
document: document, | ||
to: destination, | ||
atPageSize: .a4 | ||
) | ||
|
||
print("PDF written to \(destination.absoluteString).") | ||
} catch { | ||
print("Failed to render PDF: \(error)") | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// swift-tools-version: 5.10 | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "PDFViewKit", | ||
platforms: [ | ||
.macOS(.v13) | ||
], | ||
products: [ | ||
.library( | ||
name: "PDFViewKit", | ||
targets: ["PDFViewKit"] | ||
) | ||
], | ||
targets: [ | ||
.target(name: "PDFViewKit") | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# PDFViewKit | ||
|
||
Create PDF files using SwiftUI views. | ||
|
||
## Usage | ||
|
||
First, define the views that make up the content of your PDF. Since PDF pages are fixed size, you need to make sure | ||
that your content fits your page size. | ||
|
||
```swift | ||
import SwiftUI | ||
|
||
struct MyPDFContent: View { | ||
|
||
var body: some View { | ||
Text("Hello, World") | ||
} | ||
|
||
} | ||
``` | ||
|
||
Then, use the `render(document:to:atPageSize:)` function on `PDFRenderer`. | ||
This function expects a `PDFDocument` which can be created by passing it a set of views that each make up a single page. | ||
|
||
```swift | ||
let document = PDFDocument { | ||
MyPDFContent() | ||
} | ||
|
||
do { | ||
try PDFRenderer.render( | ||
document: document, | ||
at: destination, | ||
atPageSize: .a4 | ||
) | ||
} catch { | ||
... | ||
} | ||
``` | ||
|
||
That's it! Your PDF file will be generated into the given `destination` URL. | ||
|
||
## Important notes | ||
|
||
SwiftUI is a framework for creating dynamic user interfaces. PDFs are not dynamic and their pages have a fixed size. | ||
Therefore, no interactivity is possible in your views, and using certain property wrappers will generate runtime | ||
warnings since the views are not part of any view hierarchy in a scene. | ||
|
||
Interactive views are not rendered with their default look. Instead, they will appear as a red crossed out area. | ||
For these views, you will need to provide a non-interactive view that mimics the original view's appearance. | ||
|
||
The following alternative views are already provided: | ||
|
||
- [`Link`](https://developer.apple.com/documentation/swiftui/link): `PDFLink` | ||
|
||
### Implementing your own PDF-compatible views | ||
|
||
To create views that react to being rendered into a PDF file, you can use the `@Environment(\.renderingEnvironment)` to | ||
determine if the view is currently being rendered into a PDF. This allows you to switch out the implementation of your | ||
view, and make it interactive if used inside of an actual application window hierarchy. | ||
|
||
Similarly, you can get the PDF rendering DPI using `@Environment(\.pdfRenderingDPI)`. | ||
The PDF's page size is provided using `@Environment(\.pdfPageSize)`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
// | ||
// DIN.swift | ||
// PDFViewKit | ||
// | ||
// Copyright (C) 2024 Sören Gade | ||
// See LICENSE for full license. | ||
// | ||
|
||
import Foundation | ||
|
||
// Source: https://de.wikipedia.org/wiki/Papierformat#Internationale_Papierformate_(ISO/DIN) | ||
public enum DIN { | ||
|
||
case a0 | ||
case a1 | ||
case a2 | ||
case a3 | ||
case a4 | ||
case a5 | ||
case a6 | ||
case a7 | ||
case a8 | ||
case a9 | ||
case a10 | ||
|
||
} | ||
|
||
// MARK: Physical page sizes | ||
|
||
public extension DIN { | ||
|
||
var width: Measurement<UnitLength> { | ||
switch self { | ||
case .a0: | ||
Measurement( | ||
value: 841, | ||
unit: .millimeters | ||
) | ||
|
||
case .a1: | ||
Measurement( | ||
value: 594, | ||
unit: .millimeters | ||
) | ||
|
||
case .a2: | ||
Measurement( | ||
value: 420, | ||
unit: .millimeters | ||
) | ||
|
||
case .a3: | ||
Measurement( | ||
value: 297, | ||
unit: .millimeters | ||
) | ||
|
||
case .a4: | ||
Measurement( | ||
value: 210, | ||
unit: .millimeters | ||
) | ||
|
||
case .a5: | ||
Measurement( | ||
value: 148, | ||
unit: .millimeters | ||
) | ||
|
||
case .a6: | ||
Measurement( | ||
value: 105, | ||
unit: .millimeters | ||
) | ||
|
||
case .a7: | ||
Measurement( | ||
value: 74, | ||
unit: .millimeters | ||
) | ||
|
||
case .a8: | ||
Measurement( | ||
value: 52, | ||
unit: .millimeters | ||
) | ||
|
||
case .a9: | ||
Measurement( | ||
value: 37, | ||
unit: .millimeters | ||
) | ||
|
||
case .a10: | ||
Measurement( | ||
value: 26, | ||
unit: .millimeters | ||
) | ||
} | ||
} | ||
|
||
var height: Measurement<UnitLength> { | ||
switch self { | ||
case .a0: | ||
Measurement( | ||
value: 1189, | ||
unit: .millimeters | ||
) | ||
|
||
case .a1: | ||
Measurement( | ||
value: 841, | ||
unit: .millimeters | ||
) | ||
|
||
case .a2: | ||
Measurement( | ||
value: 594, | ||
unit: .millimeters | ||
) | ||
|
||
case .a3: | ||
Measurement( | ||
value: 420, | ||
unit: .millimeters | ||
) | ||
case .a4: | ||
Measurement( | ||
value: 297, | ||
unit: .millimeters | ||
) | ||
|
||
case .a5: | ||
Measurement( | ||
value: 210, | ||
unit: .millimeters | ||
) | ||
|
||
case .a6: | ||
Measurement( | ||
value: 148, | ||
unit: .millimeters | ||
) | ||
|
||
case .a7: | ||
Measurement( | ||
value: 105, | ||
unit: .millimeters | ||
) | ||
|
||
case .a8: | ||
Measurement( | ||
value: 74, | ||
unit: .millimeters | ||
) | ||
|
||
case .a9: | ||
Measurement( | ||
value: 52, | ||
unit: .millimeters | ||
) | ||
|
||
case .a10: | ||
Measurement( | ||
value: 37, | ||
unit: .millimeters | ||
) | ||
} | ||
} | ||
|
||
} | ||
|
||
// MARK: Calculated properties based on physical sizes | ||
|
||
public extension DIN { | ||
|
||
var aspectRatio: CGFloat { | ||
width.converted(to: .millimeters).value / height.converted(to: .millimeters).value | ||
} | ||
|
||
func size(atDPI dpi: DPI) -> CGSize { | ||
CGSize( | ||
width: width.converted(to: .inches).value * dpi.rawValue, | ||
height: height.converted(to: .inches).value * dpi.rawValue | ||
) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// | ||
// DPI.swift | ||
// PDFViewKit | ||
// | ||
// Copyright (C) 2024 Sören Gade | ||
// See LICENSE for full license. | ||
// | ||
|
||
import Foundation | ||
|
||
public enum DPI: CGFloat { | ||
|
||
// based on https://www.adobe.com/uk/creativecloud/photography/discover/dots-per-inch-dpi-resolution.html | ||
case display = 96 | ||
case displayHigh = 144 // 150% | ||
|
||
case print = 300 | ||
case printArtwork = 600 | ||
|
||
} |
Oops, something went wrong.