Skip to content

Commit 1474c46

Browse files
committed
support capInsets
1 parent 445af85 commit 1474c46

File tree

1 file changed

+100
-2
lines changed

1 file changed

+100
-2
lines changed

SwiftDraw/Sources/SVG+CoreGraphics.swift

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,72 @@ public extension CGContext {
6464
for r in 0..<rows {
6565
for c in 0..<cols {
6666
let tile = CGRect(
67-
x: rect.minX + CGFloat(r) * svg.size.width,
68-
y: rect.minY + CGFloat(c) * svg.size.height,
67+
x: rect.minX + CGFloat(c) * svg.size.width,
68+
y: rect.minY + CGFloat(r) * svg.size.height,
6969
width: svg.size.width,
7070
height: svg.size.height
7171
)
7272
draw(svg, in: tile)
7373
}
7474
}
7575
}
76+
77+
func draw(
78+
_ svg: SVG,
79+
in rect: CGRect,
80+
capInsets: (top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat),
81+
byTiling: Bool
82+
) {
83+
guard capInsets != (0, 0, 0, 0) else {
84+
draw(svg, in: rect, byTiling: byTiling)
85+
return
86+
}
87+
88+
let source = Slice9(source: CGRect(origin: .zero, size: svg.size), capInsets: capInsets)
89+
let dest = Slice9(source: rect, capInsets: capInsets)
90+
91+
draw(svg, from: source.topLeft, in: dest.topLeft, byTiling: false)
92+
draw(svg, from: source.topMid, in: dest.topMid, byTiling: byTiling)
93+
draw(svg, from: source.topRight, in: dest.topRight, byTiling: false)
94+
draw(svg, from: source.midLeft, in: dest.midLeft, byTiling: byTiling)
95+
draw(svg, from: source.center, in: dest.center, byTiling: byTiling)
96+
draw(svg, from: source.midRight, in: dest.midRight, byTiling: byTiling)
97+
draw(svg, from: source.bottomLeft, in: dest.bottomLeft, byTiling: false)
98+
draw(svg, from: source.bottomMid, in: dest.bottomMid, byTiling: byTiling)
99+
draw(svg, from: source.bottomRight, in: dest.bottomRight, byTiling: false)
100+
}
101+
102+
private func draw(_ svg: SVG, from source: CGRect, in rect: CGRect, byTiling: Bool = false) {
103+
saveGState()
104+
clip(to: [rect])
105+
106+
if byTiling {
107+
let cols = Int(ceil(rect.width / source.width))
108+
let rows = Int(ceil(rect.height / source.height))
109+
for r in 0..<rows {
110+
for c in 0..<cols {
111+
let tile = CGRect(
112+
x: rect.minX + source.width * CGFloat(c),
113+
y: rect.minY + source.height * CGFloat(r),
114+
width: source.width,
115+
height: source.height
116+
)
117+
draw(svg, from: source, in: tile)
118+
}
119+
}
120+
} else {
121+
// stretch
122+
translateBy(x: rect.origin.x, y: rect.origin.y)
123+
scaleBy(
124+
x: rect.width / source.width,
125+
y: rect.height / source.height
126+
)
127+
translateBy(x: -source.minX, y: -source.minY)
128+
CGRenderer(context: self).perform(svg.commands)
129+
}
130+
131+
restoreGState()
132+
}
76133
}
77134

78135
public extension SVG {
@@ -142,4 +199,45 @@ private extension LayerTree.Size {
142199
}
143200
}
144201

202+
struct Slice9 {
203+
var source: CGRect
204+
var capInsets: (top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat)
205+
206+
var topLeft: CGRect {
207+
CGRect(x: source.minX, y: source.minY, width: capInsets.left, height: capInsets.top)
208+
}
209+
210+
var bottomLeft: CGRect {
211+
CGRect(x: source.minX, y: source.height - capInsets.bottom, width: capInsets.left, height: capInsets.bottom)
212+
}
213+
214+
var topRight: CGRect {
215+
CGRect(x: source.maxX - capInsets.right, y: source.minY, width: capInsets.right, height: capInsets.top)
216+
}
217+
218+
var bottomRight: CGRect {
219+
CGRect(x: source.maxX - capInsets.right, y: source.maxY - capInsets.bottom, width: capInsets.right, height: capInsets.bottom)
220+
}
221+
222+
var midLeft: CGRect {
223+
CGRect(x: source.minX, y: capInsets.top, width: capInsets.left, height: source.maxY - capInsets.top - capInsets.bottom)
224+
}
225+
226+
var midRight: CGRect {
227+
CGRect(x: source.maxX - capInsets.right, y: capInsets.top, width: capInsets.right, height: source.maxY - capInsets.top - capInsets.bottom)
228+
}
229+
230+
var topMid: CGRect {
231+
CGRect(x: capInsets.left, y: source.minY, width: source.maxX - capInsets.left - capInsets.right, height: capInsets.top)
232+
}
233+
234+
var bottomMid: CGRect {
235+
CGRect(x: capInsets.left, y: source.maxY - capInsets.bottom, width: source.maxX - capInsets.left - capInsets.right, height: capInsets.bottom)
236+
}
237+
238+
var center: CGRect {
239+
CGRect(x: capInsets.left, y: capInsets.top, width: source.maxX - capInsets.left - capInsets.right, height: source.maxY - capInsets.top - capInsets.bottom)
240+
}
241+
}
242+
145243
#endif

0 commit comments

Comments
 (0)