Skip to content

Commit 7c34280

Browse files
committed
Clipping Mask layers to the contents they are clipping
1 parent ad8b68f commit 7c34280

File tree

4 files changed

+33
-25
lines changed

4 files changed

+33
-25
lines changed

Samples/thats-no-moon.svg

Lines changed: 8 additions & 11 deletions
Loading

SwiftDraw/LayerTree.AB.Builder.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,33 @@ extension LayerTree {
8282
l.clip = createClipShapes(for: element)
8383
l.mask = createMaskLayer(for: element)
8484
l.opacity = state.opacity
85-
85+
l.contents = makeAllContents(from: element, with: state)
86+
87+
// clips the mask to the content
88+
l.mask?.clip = l.contents.compactMap { (contents: Layer.Contents) -> LayerTree.Shape? in
89+
switch(contents) {
90+
case .shape(let s, _, _): return s
91+
default: return nil
92+
}
93+
}
94+
95+
return l
96+
}
97+
98+
func makeAllContents(from element: DOM.GraphicsElement, with state: State) -> [Layer.Contents] {
99+
var all = [Layer.Contents]()
86100
if let contents = makeContents(from: element, with: state) {
87-
l.appendContents(contents)
101+
all.append(contents)
88102
}
89103
else if let container = element as? ContainerElement {
90104
container.childElements.forEach{
91105
let contents = Layer.Contents.layer(makeLayer(from: $0, inheriting: state))
92-
l.appendContents(contents)
106+
all.append(contents)
93107
}
94108
}
95-
96-
return l
109+
return all
97110
}
98-
111+
99112
func makeContents(from element: DOM.GraphicsElement, with state: State) -> Layer.Contents? {
100113
if let shape = Builder.makeShape(from: element) {
101114
return makeShapeContents(from: shape, with: state)

SwiftDraw/LayerTree.CommandGenerator.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,14 @@ extension LayerTree {
4444

4545
func renderCommands(for layer: Layer) -> [RendererCommand<P.Types>] {
4646
guard layer.opacity > 0.0 else { return [] }
47-
47+
4848
let opacityCommands = renderCommands(forOpacity: layer.opacity)
4949
let transformCommands = renderCommands(forTransforms: layer.transform)
5050
let clipCommands = renderCommands(forClip: layer.clip)
5151
let maskCommands = renderCommands(forMask: layer.mask)
52-
53-
//TODO: handle layer.mask
54-
// render to transparanency layer then composite contents on top.
55-
52+
5653
var commands = [RendererCommand<P.Types>]()
57-
54+
5855
if !opacityCommands.isEmpty ||
5956
!transformCommands.isEmpty ||
6057
!clipCommands.isEmpty ||
@@ -218,7 +215,7 @@ extension LayerTree {
218215
func renderCommands(forClip shapes: [Shape]) -> [RendererCommand<P.Types>] {
219216
guard !shapes.isEmpty else { return [] }
220217

221-
let paths = shapes.map{ provider.createPath(from: $0) }
218+
let paths = shapes.map { provider.createPath(from: $0) }
222219
let clipPath = provider.createPath(from: paths)
223220

224221
return [.setClip(path: clipPath)]
@@ -233,6 +230,7 @@ extension LayerTree {
233230
var commands = [RendererCommand<P.Types>]()
234231
commands.append(.pushTransparencyLayer)
235232
commands.append(.setBlend(mode: modeCopy))
233+
commands.append(contentsOf: renderCommands(forClip: layer.clip))
236234

237235
let drawMask = layer.contents.flatMap{
238236
renderCommands(for: $0, colorConverter: LuminanceColorConverter())

SwiftDraw/LayerTree.Layer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ extension LayerTree {
4040
case text(String, Point, TextAttributes)
4141
case layer(Layer)
4242
}
43-
43+
4444
func appendContents(_ contents: Contents) {
4545
switch contents {
4646
case .layer(let l):

0 commit comments

Comments
 (0)