@@ -64,15 +64,72 @@ public extension CGContext {
64
64
for r in 0 ..< rows {
65
65
for c in 0 ..< cols {
66
66
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,
69
69
width: svg. size. width,
70
70
height: svg. size. height
71
71
)
72
72
draw ( svg, in: tile)
73
73
}
74
74
}
75
75
}
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
+ }
76
133
}
77
134
78
135
public extension SVG {
@@ -142,4 +199,45 @@ private extension LayerTree.Size {
142
199
}
143
200
}
144
201
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
+
145
243
#endif
0 commit comments