Skip to content

Commit 43a0ffa

Browse files
committed
PDF output from command line tool now uses image masks instead of transparency layers.
1 parent af9b3f6 commit 43a0ffa

File tree

3 files changed

+50
-12
lines changed

3 files changed

+50
-12
lines changed

CommandLine/CommandLine.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ extension SwiftDraw.CommandLine {
7575
case .jpeg:
7676
return image.jpegData()
7777
case .pdf:
78-
return image.pdfData()
78+
return try? Image.pdfData(fileURL: config.input)
7979
case .png:
8080
return image.pngData()
8181
}
@@ -84,8 +84,8 @@ extension SwiftDraw.CommandLine {
8484
static func printHelp() {
8585
print("")
8686
print("""
87-
swiftdraw, version 0.3
88-
copyright (c) 2018 Simon Whitty
87+
swiftdraw, version 0.6
88+
copyright (c) 2019 Simon Whitty
8989
9090
usage: swiftdraw <file.svg> [--format png | pdf | jpeg]
9191

SwiftDraw/Image+CoreGraphics.swift

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,18 @@ public extension CGContext {
4242
renderer.perform(image.commands)
4343
return
4444
}
45-
46-
let sx = rect.width / image.size.width
47-
let sy = rect.height / image.size.height
45+
46+
let scale = CGSize(width: rect.width / image.size.width,
47+
height: rect.height / image.size.height)
48+
draw(image.commands, in: rect, scale: scale)
49+
}
50+
51+
fileprivate func draw(_ commands: [RendererCommand<CGTypes>], in rect: CGRect, scale: CGSize = CGSize(width: 1.0, height: 1.0)) {
52+
let renderer = CGRenderer(context: self)
4853
saveGState()
4954
translateBy(x: rect.origin.x, y: rect.origin.y)
50-
scaleBy(x: sx, y: sy)
51-
renderer.perform(image.commands)
55+
scaleBy(x: scale.width, y: scale.height)
56+
renderer.perform(commands)
5257
restoreGState()
5358
}
5459
}
@@ -73,4 +78,30 @@ public extension Image {
7378

7479
return data as Data
7580
}
81+
82+
static func pdfData(fileURL url: URL) throws -> Data {
83+
let svg = try DOM.SVG.parse(fileURL: url)
84+
let layer = LayerTree.Builder(svg: svg).makeLayer()
85+
var mediaBox = CGRect(x: 0, y: 0, width: CGFloat(svg.width), height: CGFloat(svg.height))
86+
let generator = LayerTree.CommandGenerator(provider: CGProvider(supportsTransparencyLayers: false),
87+
size: LayerTree.Size(svg.width, svg.height))
88+
let commands = generator.renderCommands(for: layer)
89+
let data = NSMutableData()
90+
guard let consumer = CGDataConsumer(data: data as CFMutableData) else { throw Error.unknown }
91+
92+
guard let ctx = CGContext(consumer: consumer, mediaBox: &mediaBox, nil) else { throw Error.unknown }
93+
94+
ctx.beginPage(mediaBox: &mediaBox)
95+
let flip = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: mediaBox.size.height)
96+
ctx.concatenate(flip)
97+
ctx.draw(commands, in: mediaBox)
98+
ctx.endPage()
99+
ctx.closePDF()
100+
101+
return data as Data
102+
}
103+
104+
private enum Error: Swift.Error {
105+
case unknown
106+
}
76107
}

SwiftDraw/Image.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,20 @@ public final class Image: NSObject {
7878
}
7979
#endif
8080

81+
extension DOM.SVG {
82+
83+
static func parse(fileURL url: URL) throws -> DOM.SVG {
84+
let parser = XMLParser(options: [.skipInvalidElements])
85+
let element = try XML.SAXParser.parse(contentsOf: url)
86+
return try parser.parseSVG(element)
87+
}
88+
}
89+
8190
public extension Image {
8291

8392
convenience init?(fileURL url: URL) {
84-
let parser = XMLParser(options: [.skipInvalidElements])
85-
guard let element = try? XML.SAXParser.parse(contentsOf: url),
86-
let svg = try? parser.parseSVG(element) else {
87-
return nil
93+
guard let svg = try? DOM.SVG.parse(fileURL: url) else {
94+
return nil
8895
}
8996

9097
self.init(svg: svg)

0 commit comments

Comments
 (0)