mirror of
https://github.com/exyte/Macaw.git
synced 2024-09-11 05:05:23 +03:00
Parse transform values using a scanner
This commit is contained in:
parent
b0196e217d
commit
974b2d012c
@ -557,52 +557,51 @@ open class SVGParser {
|
|||||||
|
|
||||||
switch attributeName {
|
switch attributeName {
|
||||||
case "translate":
|
case "translate":
|
||||||
if let x = Double(values[0]) {
|
let x = values[0]
|
||||||
var y: Double = 0
|
var y: Double = 0
|
||||||
if values.indices.contains(1) {
|
if values.indices ~= 1 {
|
||||||
y = Double(values[1]) ?? 0
|
y = values[1]
|
||||||
}
|
}
|
||||||
transform = transform.move(dx: x, dy: y)
|
transform = transform.move(dx: x, dy: y)
|
||||||
}
|
|
||||||
case "scale":
|
case "scale":
|
||||||
if let x = Double(values[0]) {
|
let x = values[0]
|
||||||
var y: Double = x
|
var y: Double = x
|
||||||
if values.indices.contains(1) {
|
if values.indices ~= 1 {
|
||||||
y = Double(values[1]) ?? x
|
y = values[1]
|
||||||
}
|
}
|
||||||
transform = transform.scale(sx: x, sy: y)
|
transform = transform.scale(sx: x, sy: y)
|
||||||
}
|
|
||||||
case "rotate":
|
case "rotate":
|
||||||
if let angle = Double(values[0]) {
|
let angle = values[0]
|
||||||
if values.count == 1 {
|
if values.count == 1 {
|
||||||
transform = transform.rotate(angle: degreesToRadians(angle))
|
transform = transform.rotate(angle: degreesToRadians(angle))
|
||||||
} else if values.count == 3 {
|
} else if values.count == 3 {
|
||||||
if let x = Double(values[1]), let y = Double(values[2]) {
|
let x = values[1]
|
||||||
transform = transform.move(dx: x, dy: y).rotate(angle: degreesToRadians(angle)).move(dx: -x, dy: -y)
|
let y = values[2]
|
||||||
}
|
transform = transform
|
||||||
}
|
.move(dx: x, dy: y)
|
||||||
}
|
.rotate(angle: degreesToRadians(angle))
|
||||||
|
.move(dx: -x, dy: -y)
|
||||||
|
}
|
||||||
case "skewX":
|
case "skewX":
|
||||||
if let x = Double(values[0]) {
|
let x = values[0]
|
||||||
let v = tan((x * Double.pi) / 180.0)
|
let v = tan((x * Double.pi) / 180.0)
|
||||||
transform = transform.shear(shx: v, shy: 0)
|
transform = transform.shear(shx: v, shy: 0)
|
||||||
}
|
|
||||||
case "skewY":
|
case "skewY":
|
||||||
if let y = Double(values[0]) {
|
let y = values[0]
|
||||||
let y = tan((y * Double.pi) / 180.0)
|
let v = tan((y * Double.pi) / 180.0)
|
||||||
transform = transform.shear(shx: 0, shy: y)
|
transform = transform.shear(shx: 0, shy: v)
|
||||||
}
|
|
||||||
case "matrix":
|
case "matrix":
|
||||||
if values.count != 6 {
|
if values.count != 6 {
|
||||||
return transform
|
return transform
|
||||||
}
|
}
|
||||||
if let m11 = Double(values[0]), let m12 = Double(values[1]),
|
let m11 = values[0]
|
||||||
let m21 = Double(values[2]), let m22 = Double(values[3]),
|
let m12 = values[1]
|
||||||
let dx = Double(values[4]), let dy = Double(values[5]) {
|
let m21 = values[2]
|
||||||
|
let m22 = values[3]
|
||||||
let transformMatrix = Transform(m11: m11, m12: m12, m21: m21, m22: m22, dx: dx, dy: dy)
|
let dx = values[4]
|
||||||
transform = transform.concat(with: transformMatrix)
|
let dy = values[5]
|
||||||
}
|
let transformMatrix = Transform(m11: m11, m12: m12, m21: m21, m22: m22, dx: dx, dy: dy)
|
||||||
|
transform = transform.concat(with: transformMatrix)
|
||||||
default:
|
default:
|
||||||
break stopParse
|
break stopParse
|
||||||
}
|
}
|
||||||
@ -641,20 +640,21 @@ open class SVGParser {
|
|||||||
b: Int(blue.rounded(.up)))
|
b: Int(blue.rounded(.up)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func parseTransformValues(_ values: String, collectedValues: [String] = []) -> [String] {
|
fileprivate func parseTransformValues(_ values: String) -> [Double] {
|
||||||
guard let matcher = SVGParserRegexHelper.getTransformMatcher() else {
|
// Parse comma-separated list of numbers.
|
||||||
return collectedValues
|
var collectedValues: [Double] = []
|
||||||
}
|
let scanner = Scanner(string: values)
|
||||||
var updatedValues: [String] = collectedValues
|
|
||||||
let fullRange = NSRange(location: 0, length: values.count)
|
while !scanner.isAtEnd {
|
||||||
if let matchedValue = matcher.firstMatch(in: values, options: .reportCompletion, range: fullRange) {
|
if let value = scanner.scannedDouble() {
|
||||||
let value = (values as NSString).substring(with: matchedValue.range)
|
collectedValues.append(value)
|
||||||
updatedValues.append(value)
|
} else {
|
||||||
let rangeToRemove = NSRange(location: 0, length: matchedValue.range.location + matchedValue.range.length)
|
break
|
||||||
let newValues = (values as NSString).replacingCharacters(in: rangeToRemove, with: "")
|
}
|
||||||
return parseTransformValues(newValues, collectedValues: updatedValues)
|
_ = scanner.scanString(",", into: nil)
|
||||||
}
|
}
|
||||||
return updatedValues
|
|
||||||
|
return collectedValues
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func getStyleAttributes(_ groupAttributes: [String: String],
|
fileprivate func getStyleAttributes(_ groupAttributes: [String: String],
|
||||||
|
@ -2,23 +2,9 @@ import Foundation
|
|||||||
|
|
||||||
class SVGParserRegexHelper {
|
class SVGParserRegexHelper {
|
||||||
|
|
||||||
fileprivate static let transformPattern = "\\-?\\d+\\.?\\d*e?\\-?\\d*"
|
|
||||||
fileprivate static let textElementPattern = "<text.*?>((?s:.*))<\\/text>"
|
fileprivate static let textElementPattern = "<text.*?>((?s:.*))<\\/text>"
|
||||||
|
|
||||||
fileprivate static var transformMatcher: NSRegularExpression?
|
|
||||||
fileprivate static var textElementMatcher: NSRegularExpression?
|
fileprivate static var textElementMatcher: NSRegularExpression?
|
||||||
|
|
||||||
class func getTransformMatcher() -> NSRegularExpression? {
|
|
||||||
if self.transformMatcher == nil {
|
|
||||||
do {
|
|
||||||
self.transformMatcher = try NSRegularExpression(pattern: transformPattern, options: .caseInsensitive)
|
|
||||||
} catch {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return self.transformMatcher
|
|
||||||
}
|
|
||||||
|
|
||||||
class func getTextElementMatcher() -> NSRegularExpression? {
|
class func getTextElementMatcher() -> NSRegularExpression? {
|
||||||
if self.textElementMatcher == nil {
|
if self.textElementMatcher == nil {
|
||||||
do {
|
do {
|
||||||
|
Loading…
Reference in New Issue
Block a user