Skip to content

Commit 580fe04

Browse files
committed
Shapes
1 parent e618eee commit 580fe04

File tree

4 files changed

+190
-143
lines changed

4 files changed

+190
-143
lines changed

Examples/Basic/Sources/ViewController.swift

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -117,59 +117,24 @@ extension UIImage {
117117
let rgb = CGColorSpaceCreateDeviceRGB()
118118
let color1 = CGColor(colorSpace: rgb, components: [1.0, 0.98039216, 0.98039216, 1.0])!
119119
ctx.setFillColor(color1)
120-
let path = CGPath(
121-
roundedRect: CGRect(x: 0.0, y: 0.0, width: 256.0, height: 256.0),
122-
cornerWidth: 0.0,
123-
cornerHeight: 0.0,
124-
transform: nil
125-
)
126-
ctx.addPath(path)
127-
ctx.fillPath(using: .evenOdd)
120+
ctx.fill(CGRect(x: 0.0, y: 0.0, width: 256.0, height: 256.0))
128121
ctx.saveGState()
129122
ctx.translateBy(x: 128.0, y: 128.0)
130123
ctx.rotate(by: 0.7853981)
131124
let patternDraw: CGPatternDrawPatternCallback = { _, ctx in
132125
let rgb = CGColorSpaceCreateDeviceRGB()
133126
let color1 = CGColor(colorSpace: rgb, components: [0.0, 0.5019608, 0.0, 1.0])!
134127
ctx.setFillColor(color1)
135-
let path = CGPath(
136-
roundedRect: CGRect(x: 0.0, y: 0.0, width: 32.0, height: 32.0),
137-
cornerWidth: 0.0,
138-
cornerHeight: 0.0,
139-
transform: nil
140-
)
141-
ctx.addPath(path)
142-
ctx.fillPath(using: .evenOdd)
128+
ctx.fill(CGRect(x: 0.0, y: 0.0, width: 32.0, height: 32.0))
143129
let color2 = CGColor(colorSpace: rgb, components: [1.0, 0.0, 0.0, 1.0])!
144130
ctx.setFillColor(color2)
145-
let path1 = CGPath(
146-
roundedRect: CGRect(x: 32.0, y: 0.0, width: 32.0, height: 32.0),
147-
cornerWidth: 0.0,
148-
cornerHeight: 0.0,
149-
transform: nil
150-
)
151-
ctx.addPath(path1)
152-
ctx.fillPath(using: .evenOdd)
131+
ctx.fill(CGRect(x: 32.0, y: 0.0, width: 32.0, height: 32.0))
153132
let color3 = CGColor(colorSpace: rgb, components: [0.0, 0.0, 1.0, 1.0])!
154133
ctx.setFillColor(color3)
155-
let path2 = CGPath(
156-
roundedRect: CGRect(x: 0.0, y: 32.0, width: 32.0, height: 32.0),
157-
cornerWidth: 0.0,
158-
cornerHeight: 0.0,
159-
transform: nil
160-
)
161-
ctx.addPath(path2)
162-
ctx.fillPath(using: .evenOdd)
134+
ctx.fill(CGRect(x: 0.0, y: 32.0, width: 32.0, height: 32.0))
163135
let color4 = CGColor(colorSpace: rgb, components: [1.0, 0.7529412, 0.79607844, 1.0])!
164136
ctx.setFillColor(color4)
165-
let path3 = CGPath(
166-
roundedRect: CGRect(x: 32.0, y: 32.0, width: 32.0, height: 32.0),
167-
cornerWidth: 0.0,
168-
cornerHeight: 0.0,
169-
transform: nil
170-
)
171-
ctx.addPath(path3)
172-
ctx.fillPath(using: .evenOdd)
137+
ctx.fill(CGRect(x: 32.0, y: 32.0, width: 32.0, height: 32.0))
173138
}
174139
var patternCallback = CGPatternCallbacks(version: 0, drawPattern: patternDraw, releaseInfo: nil)
175140
let pattern = CGPattern(
@@ -185,14 +150,7 @@ extension UIImage {
185150
ctx.setFillColorSpace(CGColorSpace(patternBaseSpace: nil)!)
186151
var patternAlpha : CGFloat = 1.0
187152
ctx.setFillPattern(pattern, colorComponents: &patternAlpha)
188-
let path1 = CGPath(
189-
roundedRect: CGRect(x: -64.0, y: -64.0, width: 128.0, height: 128.0),
190-
cornerWidth: 0.0,
191-
cornerHeight: 0.0,
192-
transform: nil
193-
)
194-
ctx.addPath(path1)
195-
ctx.fillPath(using: .evenOdd)
153+
ctx.fill(CGRect(x: -64.0, y: -64.0, width: 128.0, height: 128.0))
196154
ctx.restoreGState()
197155
}
198156
}

SwiftDraw.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
01BA4DAA2689F91E001FF7B5 /* Renderer.CGText+Path.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01BA4DA92689F91E001FF7B5 /* Renderer.CGText+Path.swift */; };
11+
01BA4DB02689F923001FF7B5 /* Renderer.CGText+Path.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01BA4DA92689F91E001FF7B5 /* Renderer.CGText+Path.swift */; };
1012
01FAD0512678CFA9003B6875 /* Renderer.CGText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FAD0502678CFA9003B6875 /* Renderer.CGText.swift */; };
1113
01FAD0582678D652003B6875 /* CGTextRenderer+Code.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FAD0572678D652003B6875 /* CGTextRenderer+Code.swift */; };
1214
01FAD070267A0DA6003B6875 /* LayerTree.CommandOptimizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FAD06F267A0DA6003B6875 /* LayerTree.CommandOptimizer.swift */; };
@@ -270,6 +272,7 @@
270272
/* End PBXCopyFilesBuildPhase section */
271273

272274
/* Begin PBXFileReference section */
275+
01BA4DA92689F91E001FF7B5 /* Renderer.CGText+Path.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Renderer.CGText+Path.swift"; sourceTree = "<group>"; };
273276
01FAD0502678CFA9003B6875 /* Renderer.CGText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Renderer.CGText.swift; sourceTree = "<group>"; };
274277
01FAD0572678D652003B6875 /* CGTextRenderer+Code.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGTextRenderer+Code.swift"; sourceTree = "<group>"; };
275278
01FAD06F267A0DA6003B6875 /* LayerTree.CommandOptimizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayerTree.CommandOptimizer.swift; sourceTree = "<group>"; };
@@ -461,6 +464,7 @@
461464
isa = PBXGroup;
462465
children = (
463466
01FAD0502678CFA9003B6875 /* Renderer.CGText.swift */,
467+
01BA4DA92689F91E001FF7B5 /* Renderer.CGText+Path.swift */,
464468
D90DB39D219CCBBD00D374D2 /* Renderer.CoreGraphics.swift */,
465469
D90DB39F219CCBBD00D374D2 /* Renderer.LayerTree.swift */,
466470
D90DB39E219CCBBD00D374D2 /* Renderer.swift */,
@@ -1053,6 +1057,7 @@
10531057
D923F11E21FBC09500FEA273 /* Image+CoreGraphics.swift in Sources */,
10541058
D90DB434219CD1C600D374D2 /* DOM.Path.swift in Sources */,
10551059
D90DB405219CD06800D374D2 /* XML.SAXParser.swift in Sources */,
1060+
01BA4DB02689F923001FF7B5 /* Renderer.CGText+Path.swift in Sources */,
10561061
D9D9EB30224A3DEA006CF83C /* Parser.XML.Pattern.swift in Sources */,
10571062
D9BA810721BA577B005159E7 /* CommandLine.Configuration.swift in Sources */,
10581063
D90DB43A219CD1C600D374D2 /* DOM.Color.swift in Sources */,
@@ -1193,6 +1198,7 @@
11931198
D90DB406219CD06800D374D2 /* XML.swift in Sources */,
11941199
D90DB454219CD27800D374D2 /* Parser.XML.Gradient.swift in Sources */,
11951200
D90DB3A0219CCBBD00D374D2 /* Renderer.CoreGraphics.swift in Sources */,
1201+
01BA4DAA2689F91E001FF7B5 /* Renderer.CGText+Path.swift in Sources */,
11961202
D90DB450219CD27800D374D2 /* Parser.XML.Color.swift in Sources */,
11971203
D90DB3EF219CCEDE00D374D2 /* URL+Data.swift in Sources */,
11981204
D90DB460219CD27800D374D2 /* Parser.XML.Image.swift in Sources */,
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
//
2+
// Renderer.CGText+Path.swift
3+
// SwiftDraw
4+
//
5+
// Created by swhitty1 on 28/6/21.
6+
// Copyright © 2021 WhileLoop Pty Ltd. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
extension CGTextRenderer {
12+
13+
func createOrGetPath(_ path: [LayerTree.Shape]) -> String {
14+
guard path.count == 1 else {
15+
fatalError("not yet supported")
16+
}
17+
let code = renderPath(from: path[0])
18+
return createOrGetPath(code)
19+
}
20+
21+
func getSimpleRect(from path: [LayerTree.Shape]) -> String? {
22+
guard
23+
path.count == 1,
24+
case let .rect(rect, radii) = path[0],
25+
radii == .zero else {
26+
return nil
27+
}
28+
29+
return renderRect(from: rect)
30+
}
31+
32+
func getSimpleEllipse(from path: [LayerTree.Shape]) -> String? {
33+
guard
34+
path.count == 1,
35+
case let .ellipse(rect) = path[0] else {
36+
return nil
37+
}
38+
39+
return renderRect(from: rect)
40+
}
41+
42+
func getSimpleLine(from path: [LayerTree.Shape]) -> [LayerTree.Point]? {
43+
guard
44+
path.count == 1,
45+
case let .line(points) = path[0] else {
46+
return nil
47+
}
48+
49+
return points
50+
}
51+
52+
func renderPath(from shape: LayerTree.Shape) -> String {
53+
switch shape {
54+
case .line(let points):
55+
return renderLinePath(between: points)
56+
57+
case .rect(let frame, let radii):
58+
return renderRectPath(frame: frame, radii: radii)
59+
60+
case .ellipse(let frame):
61+
return renderEllipsePath(frame: frame)
62+
63+
case .path(let path):
64+
return renderPath(from: path)
65+
66+
case .polygon(let points):
67+
return renderPolygonPath(between: points)
68+
}
69+
}
70+
71+
func renderFloat(from float: LayerTree.Float) -> LayerTree.Float {
72+
return float
73+
}
74+
75+
private func renderPoint(from point: LayerTree.Point) -> String {
76+
return "CGPoint(x: \(point.x), y: \(point.y))"
77+
}
78+
79+
private func renderSize(from size: LayerTree.Size) -> String {
80+
return "CGSize(width: \(size.width), height: \(size.height))"
81+
}
82+
83+
private func renderRect(from rect: LayerTree.Rect) -> String {
84+
return "CGRect(x: \(rect.x), y: \(rect.y), width: \(rect.width), height: \(rect.height))"
85+
}
86+
87+
func renderLinePath(between points: [LayerTree.Point]) -> String {
88+
"""
89+
let path1 = CGMutablePath()
90+
path1.addLines(between: [
91+
\(points, indent: 2)
92+
])
93+
"""
94+
}
95+
96+
func renderRectPath(frame: LayerTree.Rect, radii: LayerTree.Size) -> String {
97+
"""
98+
let path1 = CGPath(
99+
roundedRect: \(renderRect(from: frame)),
100+
cornerWidth: \(renderFloat(from: radii.width)),
101+
cornerHeight: \(renderFloat(from: radii.height)),
102+
transform: nil
103+
)
104+
"""
105+
}
106+
107+
func renderPolygonPath(between points: [LayerTree.Point]) -> String {
108+
var lines: [String] = ["let path1 = CGMutablePath()"]
109+
lines.append("path1.addLines(between: [")
110+
for p in points {
111+
lines.append(" \(renderPoint(from: p)),")
112+
}
113+
lines.append("])")
114+
lines.append("path1.closeSubpath()")
115+
return lines.joined(separator: "\n")
116+
}
117+
118+
func renderEllipsePath(frame: LayerTree.Rect) -> String {
119+
"""
120+
let path1 = CGPath(
121+
ellipseIn: \(renderRect(from: frame)),
122+
transform: nil
123+
)
124+
"""
125+
}
126+
127+
func renderPath(from path: LayerTree.Path) -> String {
128+
var lines: [String] = ["let path1 = CGMutablePath()"]
129+
for s in path.segments {
130+
switch s {
131+
case .move(let p):
132+
lines.append("path1.move(to: \(renderPoint(from: p)))")
133+
case .line(let p):
134+
lines.append("path1.addLine(to: \(renderPoint(from: p)))")
135+
case .cubic(let p, let cp1, let cp2):
136+
lines.append("""
137+
path1.addCurve(to: \(renderPoint(from: p)),
138+
control1: \(renderPoint(from: cp1)),
139+
control2: \(renderPoint(from: cp2)))
140+
""")
141+
case .close:
142+
lines.append("path1.closeSubpath()")
143+
}
144+
}
145+
return lines.joined(separator: "\n")
146+
}
147+
}

0 commit comments

Comments
 (0)