1
1
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:
Petrov Anatoly 2020-06-06 02:04:15 +07:00
parent b0196e217d
commit 974b2d012c
2 changed files with 52 additions and 66 deletions

View File

@ -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],

View File

@ -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 {