@@ -365,12 +365,20 @@ open class SVGParser {
365
365
parentPattern = defPatterns [ id]
366
366
}
367
367
368
+ var viewBox : Rect = . zero( )
369
+ if let viewBoxString = element. allAttributes [ " viewBox " ] ? . text {
370
+ let nums = viewBoxString. components ( separatedBy: . whitespaces) . map { Double ( $0) }
371
+ if nums. count == 4 , let x = nums [ 0 ] , let y = nums [ 1 ] , let w = nums [ 2 ] , let h = nums [ 3 ] {
372
+ viewBox = Rect ( x: x, y: y, w: w, h: h)
373
+ }
374
+ }
375
+
368
376
let x = getDoubleValue ( element, attribute: " x " ) ?? parentPattern? . bounds. x ?? 0
369
377
let y = getDoubleValue ( element, attribute: " y " ) ?? parentPattern? . bounds. y ?? 0
370
378
let w = getDoubleValue ( element, attribute: " width " ) ?? parentPattern? . bounds. w ?? 0
371
379
let h = getDoubleValue ( element, attribute: " height " ) ?? parentPattern? . bounds. h ?? 0
372
380
let bounds = Rect ( x: x, y: y, w: w, h: h)
373
-
381
+
374
382
guard bounds. w > 0 && bounds. h > 0 else {
375
383
return . none
376
384
}
@@ -384,6 +392,8 @@ open class SVGParser {
384
392
contentUserSpace = false
385
393
}
386
394
395
+ let position = getPatternPosition ( element)
396
+
387
397
var contentNode : Node ?
388
398
if pattern. children. isEmpty {
389
399
if let parentPattern = parentPattern {
@@ -402,11 +412,10 @@ open class SVGParser {
402
412
}
403
413
contentNode = Group ( contents: shapes)
404
414
}
405
-
415
+
406
416
if let contentNode = contentNode {
407
- return UserSpacePattern ( content: contentNode, bounds: bounds, userSpace: userSpace, contentUserSpace: contentUserSpace)
417
+ return UserSpacePattern ( content: contentNode, bounds: bounds, viewBox : viewBox , userSpace: userSpace, contentUserSpace: contentUserSpace, position : position )
408
418
}
409
-
410
419
return . none
411
420
}
412
421
@@ -425,7 +434,14 @@ open class SVGParser {
425
434
426
435
fileprivate func getPosition( _ element: SWXMLHash . XMLElement ) -> Transform {
427
436
guard let transformAttribute = element. allAttributes [ " transform " ] ? . text else {
428
- return Transform . identity
437
+ return . identity
438
+ }
439
+ return parseTransformationAttribute ( transformAttribute)
440
+ }
441
+
442
+ fileprivate func getPatternPosition( _ element: SWXMLHash . XMLElement ) -> Transform {
443
+ guard let transformAttribute = element. allAttributes [ " patternTransform " ] ? . text else {
444
+ return . identity
429
445
}
430
446
return parseTransformationAttribute ( transformAttribute)
431
447
}
@@ -665,7 +681,7 @@ open class SVGParser {
665
681
fillColor = String ( fallbackColor)
666
682
}
667
683
}
668
-
684
+
669
685
if fillColor == SVGKeys . currentColor, let currentColor = groupStyle [ SVGKeys . color] {
670
686
fillColor = currentColor
671
687
}
@@ -676,14 +692,14 @@ open class SVGParser {
676
692
fileprivate func getPatternFill( pattern: UserSpacePattern , locus: Locus ? ) -> Pattern {
677
693
if pattern. userSpace == false && pattern. contentUserSpace == true {
678
694
let tranform = BoundsUtils . transformForLocusInRespectiveCoords ( respectiveLocus: pattern. bounds, absoluteLocus: locus!)
679
- return Pattern ( content: pattern. content, bounds: pattern. bounds. applying ( tranform) , userSpace: true )
695
+ return Pattern ( content: pattern. content, bounds: pattern. bounds. applying ( tranform) , viewBox : pattern . viewBox , userSpace: true , position : pattern . position )
680
696
}
681
697
if pattern. userSpace == true && pattern. contentUserSpace == false {
682
698
if let patternNode = BoundsUtils . createNodeFromRespectiveCoords ( respectiveNode: pattern. content, absoluteLocus: locus!) {
683
- return Pattern ( content: patternNode, bounds: pattern. bounds, userSpace: pattern. userSpace)
699
+ return Pattern ( content: patternNode, bounds: pattern. bounds, viewBox : pattern . viewBox , userSpace: pattern. userSpace, position : pattern . position )
684
700
}
685
701
}
686
- return Pattern ( content: pattern. content, bounds: pattern. bounds, userSpace: true )
702
+ return Pattern ( content: pattern. content, bounds: pattern. bounds, viewBox : pattern . viewBox , userSpace: true , position : pattern . position )
687
703
}
688
704
689
705
fileprivate func getStroke( _ styleParts: [ String : String ] , groupStyle: [ String : String ] = [ : ] ) -> Stroke ? {
@@ -1893,7 +1909,7 @@ fileprivate extension String {
1893
1909
let end = index ( endIndex, offsetBy: - fromEnd)
1894
1910
return String ( self [ start..< end] )
1895
1911
}
1896
-
1912
+
1897
1913
func slice( from: String , to: String ) -> String ? {
1898
1914
return ( range ( of: from) ? . upperBound) . flatMap { substringFrom in
1899
1915
( range ( of: to, range: substringFrom..< endIndex) ? . lowerBound) . map { substringTo in
@@ -1924,16 +1940,20 @@ fileprivate class UserSpaceNode {
1924
1940
}
1925
1941
1926
1942
fileprivate class UserSpacePattern {
1943
+ let viewBox : Rect
1927
1944
let content : Node
1928
1945
let bounds : Rect
1929
1946
let userSpace : Bool
1930
1947
let contentUserSpace : Bool
1948
+ let position : Transform
1931
1949
1932
- init ( content: Node , bounds: Rect , userSpace: Bool = false , contentUserSpace: Bool = true ) {
1950
+ init ( content: Node , bounds: Rect , viewBox: Rect = Rect ( x: 0 , y: 0 , w: 0 , h: 0 ) , userSpace: Bool = false , contentUserSpace: Bool = true , position: Transform = . identity) {
1951
+ self . viewBox = viewBox
1933
1952
self . content = content
1934
1953
self . bounds = bounds
1935
1954
self . userSpace = userSpace
1936
1955
self . contentUserSpace = contentUserSpace
1956
+ self . position = position
1937
1957
}
1938
1958
}
1939
1959
0 commit comments