Skip to content

Commit 4f701b6

Browse files
committed
Refactor Gradients
1 parent 12357c0 commit 4f701b6

File tree

8 files changed

+84
-100
lines changed

8 files changed

+84
-100
lines changed

Examples/Sources/ViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ViewController: UIViewController {
6565

6666
override func loadView() {
6767
let imageView = UIImageView(frame: UIScreen.main.bounds)
68-
imageView.image = Image(named: "spider.svg", in: .samples)?.rasterize()
68+
imageView.image = Image(named: "star-struck.svg", in: .samples)?.rasterize()
6969
imageView.contentMode = .scaleAspectFit
7070
imageView.backgroundColor = .white
7171
self.view = imageView

SwiftDraw/DOM.RadialGradient.swift

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
extension DOM {
3333

3434
final class RadialGradient: Element {
35+
typealias Units = LinearGradient.Units
3536

3637
var id: String
3738
var r: Coordinate?
@@ -73,11 +74,3 @@ extension DOM.RadialGradient: Equatable {
7374
return lhs.id == rhs.id && lhs.stops == rhs.stops
7475
}
7576
}
76-
77-
extension DOM.RadialGradient {
78-
79-
enum Units: String {
80-
case userSpaceOnUse
81-
case objectBoundingBox
82-
}
83-
}

SwiftDraw/LayerTree.Builder.swift

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ extension LayerTree.Builder {
215215
}
216216
}
217217

218-
func makeLinearGradient(for gradientId: URL) -> LayerTree.Gradient? {
218+
func makeLinearGradient(for gradientId: URL) -> LayerTree.LinearGradient? {
219219
guard let element = svg.defs.linearGradients.first(where: { $0.id == gradientId.fragment }),
220220
let gradient = makeGradient(for: element) else {
221221
return nil
@@ -249,7 +249,7 @@ extension LayerTree.Builder {
249249
return pattern
250250
}
251251

252-
func makeGradient(for element: DOM.LinearGradient) -> LayerTree.Gradient? {
252+
func makeGradient(for element: DOM.LinearGradient) -> LayerTree.LinearGradient? {
253253
guard
254254
let x1 = element.x1,
255255
let y1 = element.y1,
@@ -258,56 +258,52 @@ extension LayerTree.Builder {
258258
return nil
259259
}
260260

261-
var gradient = LayerTree.Gradient(start: Point(x1, y1), end: Point(x2, y2))
261+
var stops = [LayerTree.Gradient.Stop]()
262262
if let id = element.href?.fragment,
263263
let reference = svg.defs.linearGradients.first(where: { $0.id == id }) {
264-
gradient.stops = makeGradientStops(for: reference)
264+
stops = makeGradientStops(for: reference)
265265
} else {
266-
gradient.stops = makeGradientStops(for: element)
266+
stops = makeGradientStops(for: element)
267267
}
268-
269-
if element.gradientUnits == .userSpaceOnUse {
270-
gradient.units = .userSpaceOnUse
271-
}
272-
273-
gradient.transform = Self.createTransforms(from: element.gradientTransform)
274-
275-
guard gradient.stops.count > 1 else {
268+
guard stops.count > 1 else {
276269
return nil
277270
}
278271

272+
var gradient = LayerTree.LinearGradient(
273+
gradient: .init(stops: stops),
274+
start: Point(x1, y1),
275+
end: Point(x2, y2)
276+
)
277+
278+
gradient.units = Self.createUnits(from: element.gradientUnits)
279+
gradient.transform = Self.createTransforms(from: element.gradientTransform)
279280
return gradient
280281
}
281282

282283
func makeGradient(for element: DOM.RadialGradient) -> LayerTree.RadialGradient? {
283-
var gradient = LayerTree.Gradient(start: Point(0, 0), end: Point(1, 1))
284+
var stops = [LayerTree.Gradient.Stop]()
284285
if let id = element.href?.fragment,
285-
let reference = svg.defs.linearGradients.first(where: { $0.id == id }) {
286-
gradient.stops = makeGradientStops(for: reference)
286+
let reference = svg.defs.radialGradients.first(where: { $0.id == id }) {
287+
stops = makeGradientStops(for: reference)
287288
} else {
288-
gradient.stops = makeGradientStops(for: element)
289-
}
290-
291-
if element.gradientUnits == .userSpaceOnUse {
292-
gradient.units = .userSpaceOnUse
289+
stops = makeGradientStops(for: element)
293290
}
294-
295-
gradient.transform = Self.createTransforms(from: element.gradientTransform)
296-
297-
guard gradient.stops.count > 1 else {
291+
guard stops.count > 1 else {
298292
return nil
299293
}
300294

301295
let cx = element.cx ?? 0.5
302296
let cy = element.cy ?? 0.5
303-
304-
return LayerTree.RadialGradient(
305-
gradient: gradient,
297+
var gradient = LayerTree.RadialGradient(
298+
gradient: .init(stops: stops),
306299
center: LayerTree.Point(element.fx ?? cx, element.fy ?? cy),
307300
radius: LayerTree.Float(element.fr ?? 0),
308301
endCenter: LayerTree.Point(cx, cy),
309302
endRadius: LayerTree.Float(element.r ?? 0.5)
310303
)
304+
gradient.units = Self.createUnits(from: element.gradientUnits)
305+
gradient.transform = Self.createTransforms(from: element.gradientTransform)
306+
return gradient
311307
}
312308

313309
func makeGradientStops(for element: DOM.LinearGradient) -> [LayerTree.Gradient.Stop] {
@@ -437,6 +433,18 @@ extension LayerTree.Builder {
437433
}
438434
}
439435

436+
static func createUnits(from units: DOM.LinearGradient.Units?) -> LayerTree.Gradient.Units {
437+
guard let units = units else {
438+
return .objectBoundingBox
439+
}
440+
switch units {
441+
case .objectBoundingBox:
442+
return .objectBoundingBox
443+
case .userSpaceOnUse:
444+
return .userSpaceOnUse
445+
}
446+
}
447+
440448
static func createTransforms(from transforms: [DOM.Transform]) -> [LayerTree.Transform] {
441449
return transforms.flatMap{ createTransform(for: $0) }
442450
}

SwiftDraw/LayerTree.CommandGenerator.swift

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ extension LayerTree {
366366
}
367367

368368

369-
func renderCommands(forLinear gradient: LayerTree.Gradient,
369+
func renderCommands(forLinear gradient: LayerTree.LinearGradient,
370370
endpoints: (start: LayerTree.Point, end: LayerTree.Point),
371371
opacity: LayerTree.Float,
372372
colorConverter: ColorConverter) -> [RendererCommand<P.Types>] {
@@ -390,7 +390,7 @@ extension LayerTree {
390390
commands.append(contentsOf: renderCommands(forTransforms: gradient.transform))
391391
}
392392

393-
let converted = apply(colorConverter: colorConverter, to: gradient)
393+
let converted = apply(colorConverter: colorConverter, to: gradient.gradient)
394394
let gradient = provider.createGradient(from: converted)
395395
let start = provider.createPoint(from: pathStart)
396396
let end = provider.createPoint(from: pathEnd)
@@ -409,7 +409,7 @@ extension LayerTree {
409409
let endCenter: LayerTree.Point
410410
let endRadius: LayerTree.Float
411411

412-
switch gradient.gradient.units {
412+
switch gradient.units {
413413
case .objectBoundingBox:
414414
let h = sqrt((bounds.width*bounds.width) + (bounds.height*bounds.height)) / 2
415415
startCenter = LayerTree.Point(
@@ -430,8 +430,8 @@ extension LayerTree {
430430
}
431431

432432
var commands = [RendererCommand<P.Types>]()
433-
if !gradient.gradient.transform.isEmpty {
434-
commands.append(contentsOf: renderCommands(forTransforms: gradient.gradient.transform))
433+
if !gradient.transform.isEmpty {
434+
commands.append(contentsOf: renderCommands(forTransforms: gradient.transform))
435435
}
436436

437437
let converted = apply(colorConverter: colorConverter, to: gradient.gradient)
@@ -465,9 +465,8 @@ private extension LayerTree.Rect {
465465
}
466466

467467
private func apply(colorConverter: ColorConverter, to gradient: LayerTree.Gradient) -> LayerTree.Gradient {
468-
var converted = LayerTree.Gradient(start: gradient.start, end: gradient.end)
469-
converted.stops = gradient.stops.map { apply(colorConverter: colorConverter, to: $0) }
470-
return converted
468+
let stops = gradient.stops.map { apply(colorConverter: colorConverter, to: $0) }
469+
return LayerTree.Gradient(stops: stops)
471470
}
472471

473472
private func apply(colorConverter: ColorConverter, to stop: LayerTree.Gradient.Stop) -> LayerTree.Gradient.Stop {

SwiftDraw/LayerTree.Gradient.swift

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,16 @@
3232
extension LayerTree {
3333

3434
struct Gradient: Hashable {
35-
var start: Point
36-
var end: Point
3735
var stops: [Stop]
38-
var units: Units = .objectBoundingBox
39-
var transform: [Transform]
40-
4136
var colorSpace: ColorSpace {
4237
if stops.contains(where: { $0.color.isP3 }) {
4338
return .p3
4439
}
4540
return .srgb
4641
}
4742

48-
init(start: Point, end: Point) {
49-
self.start = start
50-
self.end = end
51-
self.stops = []
52-
self.transform = []
43+
init(stops: [Stop]) {
44+
self.stops = stops
5345
}
5446

5547
struct Stop: Hashable {
@@ -70,12 +62,22 @@ extension LayerTree {
7062
}
7163
}
7264

65+
struct LinearGradient: Hashable {
66+
var gradient: Gradient
67+
var start: Point
68+
var end: Point
69+
var units: Gradient.Units = .objectBoundingBox
70+
var transform: [Transform] = []
71+
}
72+
7373
struct RadialGradient: Hashable {
7474
var gradient: Gradient
7575
var center: Point
7676
var radius: Float
7777
var endCenter: Point
7878
var endRadius: Float
79+
var units: Gradient.Units = .objectBoundingBox
80+
var transform: [Transform] = []
7981
}
8082
}
8183

SwiftDraw/LayerTree.Layer.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ extension LayerTree {
9090

9191
enum Stroke: Equatable {
9292
case color(Color)
93-
case linearGradient(Gradient)
93+
case linearGradient(LinearGradient)
9494
case radialGradient(RadialGradient)
9595

9696
static let none = Stroke.color(.none)
@@ -113,7 +113,7 @@ extension LayerTree {
113113
self.opacity = opacity
114114
}
115115

116-
init(linear gradient: Gradient, rule: FillRule, opacity: Float) {
116+
init(linear gradient: LinearGradient, rule: FillRule, opacity: Float) {
117117
self.fill = .linearGradient(gradient)
118118
self.rule = rule
119119
self.opacity = opacity
@@ -128,7 +128,7 @@ extension LayerTree {
128128
enum Fill: Equatable {
129129
case color(Color)
130130
case pattern(Pattern)
131-
case linearGradient(Gradient)
131+
case linearGradient(LinearGradient)
132132
case radialGradient(RadialGradient)
133133
}
134134
}

0 commit comments

Comments
 (0)