1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-11 05:05:23 +03:00

Use spaces instead of tabs

This commit is contained in:
Petrov Anatoly 2020-06-06 19:26:36 +07:00
parent 22233257ed
commit e53ca25b11

View File

@ -534,21 +534,21 @@ open class SVGParser {
fileprivate func parseTransformationAttribute(_ attributes: String, fileprivate func parseTransformationAttribute(_ attributes: String,
transform: Transform = Transform()) -> Transform { transform: Transform = Transform()) -> Transform {
// Transform attribute regular grammar (whitespace characters are ignored): // Transform attribute regular grammar (whitespace characters are ignored):
// ([a-zA-Z]+)\(((-?\d+\.?\d*e?-?\d*,?)+)\) // ([a-zA-Z]+)\(((-?\d+\.?\d*e?-?\d*,?)+)\)
// Group (1) is an attribute name. // Group (1) is an attribute name.
// Group (2) is comma-separated numbers. // Group (2) is comma-separated numbers.
var transform = transform var transform = transform
let scanner = Scanner(string: attributes) let scanner = Scanner(string: attributes)
stopParse: while !scanner.isAtEnd { stopParse: while !scanner.isAtEnd {
guard let attributeName = scanner.scannedCharacters(from: .transformationAttributeCharacters), guard let attributeName = scanner.scannedCharacters(from: .transformationAttributeCharacters),
scanner.scanString("(", into: nil), scanner.scanString("(", into: nil),
let valuesString = scanner.scannedUpToString(")"), let valuesString = scanner.scannedUpToString(")"),
scanner.scanString(")", into: nil) else { scanner.scanString(")", into: nil) else {
break stopParse break stopParse
} }
let values = parseTransformValues(valuesString) let values = parseTransformValues(valuesString)
if values.isEmpty { if values.isEmpty {
@ -558,50 +558,50 @@ open class SVGParser {
switch attributeName { switch attributeName {
case "translate": case "translate":
let x = values[0] let x = values[0]
var y: Double = 0 var y: Double = 0
if values.indices ~= 1 { if values.indices ~= 1 {
y = values[1] y = values[1]
} }
transform = transform.move(dx: x, dy: y) transform = transform.move(dx: x, dy: y)
case "scale": case "scale":
let x = values[0] let x = values[0]
var y: Double = x var y: Double = x
if values.indices ~= 1 { if values.indices ~= 1 {
y = values[1] y = values[1]
} }
transform = transform.scale(sx: x, sy: y) transform = transform.scale(sx: x, sy: y)
case "rotate": case "rotate":
let angle = 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 {
let x = values[1] let x = values[1]
let y = values[2] let y = values[2]
transform = transform transform = transform
.move(dx: x, dy: y) .move(dx: x, dy: y)
.rotate(angle: degreesToRadians(angle)) .rotate(angle: degreesToRadians(angle))
.move(dx: -x, dy: -y) .move(dx: -x, dy: -y)
} }
case "skewX": case "skewX":
let x = 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":
let y = values[0] let y = values[0]
let v = tan((y * Double.pi) / 180.0) let v = tan((y * Double.pi) / 180.0)
transform = transform.shear(shx: 0, shy: v) transform = transform.shear(shx: 0, shy: v)
case "matrix": case "matrix":
if values.count != 6 { if values.count != 6 {
return transform return transform
} }
let m11 = values[0] let m11 = values[0]
let m12 = values[1] let m12 = values[1]
let m21 = values[2] let m21 = values[2]
let m22 = values[3] let m22 = values[3]
let dx = values[4] let dx = values[4]
let dy = values[5] let dy = values[5]
let transformMatrix = Transform(m11: m11, m12: m12, m21: m21, m22: m22, dx: dx, dy: dy) let transformMatrix = Transform(m11: m11, m12: m12, m21: m21, m22: m22, dx: dx, dy: dy)
transform = transform.concat(with: transformMatrix) transform = transform.concat(with: transformMatrix)
default: default:
break stopParse break stopParse
} }
@ -641,20 +641,20 @@ open class SVGParser {
} }
fileprivate func parseTransformValues(_ values: String) -> [Double] { fileprivate func parseTransformValues(_ values: String) -> [Double] {
// Parse comma-separated list of numbers. // Parse comma-separated list of numbers.
var collectedValues: [Double] = [] var collectedValues: [Double] = []
let scanner = Scanner(string: values) let scanner = Scanner(string: values)
while !scanner.isAtEnd { while !scanner.isAtEnd {
if let value = scanner.scannedDouble() { if let value = scanner.scannedDouble() {
collectedValues.append(value) collectedValues.append(value)
} else { } else {
break break
} }
_ = scanner.scanString(",", into: nil) _ = scanner.scanString(",", into: nil)
} }
return collectedValues return collectedValues
} }
fileprivate func getStyleAttributes(_ groupAttributes: [String: String], fileprivate func getStyleAttributes(_ groupAttributes: [String: String],
@ -1044,18 +1044,18 @@ open class SVGParser {
fontWeight: fontWeight, fontWeight: fontWeight,
pos: pos) pos: pos)
} else { } else {
let rect = Rect(x: getDoubleValue(element, attribute: "x") ?? 0, let rect = Rect(x: getDoubleValue(element, attribute: "x") ?? 0,
y: getDoubleValue(element, attribute: "y") ?? 0) y: getDoubleValue(element, attribute: "y") ?? 0)
let collectedTspans = collectTspans(element.children, let collectedTspans = collectTspans(element.children,
textAnchor: textAnchor, textAnchor: textAnchor,
fill: fill, fill: fill,
stroke: stroke, stroke: stroke,
opacity: opacity, opacity: opacity,
fontName: fontName, fontName: fontName,
fontSize: fontSize, fontSize: fontSize,
fontWeight: fontWeight, fontWeight: fontWeight,
bounds: rect) bounds: rect)
return Group(contents: collectedTspans, place: pos, tag: getTag(element)) return Group(contents: collectedTspans, place: pos, tag: getTag(element))
} }
} }
@ -1105,72 +1105,72 @@ open class SVGParser {
fontSize: Int?, fontSize: Int?,
fontWeight: String?, fontWeight: String?,
bounds: Rect) -> [Node] { bounds: Rect) -> [Node] {
var collection: [Node] = [] var collection: [Node] = []
var bounds = bounds var bounds = bounds
// Whether to add a space before the next non-whitespace-only text. // Whether to add a space before the next non-whitespace-only text.
var addWhitespace = false var addWhitespace = false
// Whether to preserve leading whitespaces before the next text // Whether to preserve leading whitespaces before the next text
// by adding a single space prefix. // by adding a single space prefix.
var preserveWhitespace = false var preserveWhitespace = false
for element in contents { for element in contents {
let text: Text? let text: Text?
if let textElement = element as? TextElement { if let textElement = element as? TextElement {
// parse as regular text element // parse as regular text element
let textString = textElement.text let textString = textElement.text
let hasLeadingWhitespace = textString.first?.isWhitespace == true let hasLeadingWhitespace = textString.first?.isWhitespace == true
let hasTrailingWhitespace = textString.last?.isWhitespace == true let hasTrailingWhitespace = textString.last?.isWhitespace == true
var trimmedString = textString.trimmingCharacters(in: .whitespacesAndNewlines) var trimmedString = textString.trimmingCharacters(in: .whitespacesAndNewlines)
let isWhitespaceOnly = trimmedString.isEmpty let isWhitespaceOnly = trimmedString.isEmpty
if hasLeadingWhitespace && preserveWhitespace && !isWhitespaceOnly { if hasLeadingWhitespace && preserveWhitespace && !isWhitespaceOnly {
trimmedString = " " + trimmedString trimmedString = " " + trimmedString
} }
addWhitespace = preserveWhitespace && hasTrailingWhitespace addWhitespace = preserveWhitespace && hasTrailingWhitespace
preserveWhitespace = false preserveWhitespace = false
if trimmedString.isEmpty { if trimmedString.isEmpty {
continue continue
} }
let place = Transform().move(dx: bounds.x + bounds.w, dy: bounds.y) let place = Transform().move(dx: bounds.x + bounds.w, dy: bounds.y)
text = Text(text: trimmedString, text = Text(text: trimmedString,
font: getFont(fontName: fontName, fontWeight: fontWeight, fontSize: fontSize), font: getFont(fontName: fontName, fontWeight: fontWeight, fontSize: fontSize),
fill: fill, fill: fill,
stroke: stroke, stroke: stroke,
align: anchorToAlign(textAnchor), align: anchorToAlign(textAnchor),
baseline: .alphabetic, baseline: .alphabetic,
place: place, place: place,
opacity: opacity) opacity: opacity)
} else if let tspanElement = element as? XMLElement, } else if let tspanElement = element as? XMLElement,
tspanElement.name == "tspan" { tspanElement.name == "tspan" {
// parse as <tspan> element // parse as <tspan> element
// ultimately skip it if it cannot be parsed // ultimately skip it if it cannot be parsed
text = parseTspan(tspanElement, text = parseTspan(tspanElement,
withWhitespace: addWhitespace, withWhitespace: addWhitespace,
textAnchor: textAnchor, textAnchor: textAnchor,
fill: fill, fill: fill,
stroke: stroke, stroke: stroke,
opacity: opacity, opacity: opacity,
fontName: fontName, fontName: fontName,
fontSize: fontSize, fontSize: fontSize,
fontWeight: fontWeight, fontWeight: fontWeight,
bounds: bounds, bounds: bounds,
previousCollectedTspan: collection.last) previousCollectedTspan: collection.last)
preserveWhitespace = true preserveWhitespace = true
addWhitespace = false addWhitespace = false
} else { } else {
print("Skipped an unexpected element type: \(type(of: element)).") print("Skipped an unexpected element type: \(type(of: element)).")
text = nil text = nil
} }
if let text = text { if let text = text {
collection.append(text) collection.append(text)
bounds = Rect(x: bounds.x, y: bounds.y, w: bounds.w + text.bounds.w, h: bounds.h) bounds = Rect(x: bounds.x, y: bounds.y, w: bounds.w + text.bounds.w, h: bounds.h)
} }
} }
return collection return collection
@ -1629,23 +1629,23 @@ open class SVGParser {
return 0 return 0
} }
let scanner = Scanner(string: string) let scanner = Scanner(string: string)
let value = scanner.scannedDouble() let value = scanner.scannedDouble()
let unit = scanner.scannedCharacters(from: .unitCharacters) let unit = scanner.scannedCharacters(from: .unitCharacters)
if !scanner.isAtEnd { if !scanner.isAtEnd {
let junk = scanner.scannedUpToCharacters(from: []) ?? "" let junk = scanner.scannedUpToCharacters(from: []) ?? ""
print("Found trailing junk \"\(junk)\" in string \"\(string)\".") print("Found trailing junk \"\(junk)\" in string \"\(string)\".")
return .none return .none
} }
switch unit { switch unit {
case nil, "px": case nil, "px":
return value return value
default: default:
print("SVG parsing error. Unit \"\(unit ?? "")\" is not supported") print("SVG parsing error. Unit \"\(unit ?? "")\" is not supported")
return value return value
} }
} }
fileprivate func getDoubleValueFromPercentage(_ element: SWXMLHash.XMLElement, attribute: String) -> Double? { fileprivate func getDoubleValueFromPercentage(_ element: SWXMLHash.XMLElement, attribute: String) -> Double? {
@ -2154,53 +2154,53 @@ fileprivate enum SVGKeys {
} }
fileprivate extension Scanner { fileprivate extension Scanner {
/// A version of `scanDouble()`, available for an earlier OS. /// A version of `scanDouble()`, available for an earlier OS.
func scannedDouble() -> Double? { func scannedDouble() -> Double? {
if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) {
return scanDouble() return scanDouble()
} else { } else {
var double: Double = 0 var double: Double = 0
return scanDouble(&double) ? double : nil return scanDouble(&double) ? double : nil
} }
} }
/// A version of `scanCharacters(from:)`, available for an earlier OS. /// A version of `scanCharacters(from:)`, available for an earlier OS.
func scannedCharacters(from set: CharacterSet) -> String? { func scannedCharacters(from set: CharacterSet) -> String? {
if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) {
return scanCharacters(from: set) return scanCharacters(from: set)
} else { } else {
var string: NSString? = nil var string: NSString? = nil
return scanCharacters(from: set, into: &string) ? string as String? : nil return scanCharacters(from: set, into: &string) ? string as String? : nil
} }
} }
/// A version of `scanUpToCharacters(from:)`, available for an earlier OS. /// A version of `scanUpToCharacters(from:)`, available for an earlier OS.
func scannedUpToCharacters(from set: CharacterSet) -> String? { func scannedUpToCharacters(from set: CharacterSet) -> String? {
if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) {
return scanUpToCharacters(from: set) return scanUpToCharacters(from: set)
} else { } else {
var string: NSString? = nil var string: NSString? = nil
return scanUpToCharacters(from: set, into: &string) ? string as String? : nil return scanUpToCharacters(from: set, into: &string) ? string as String? : nil
} }
} }
/// A version of `scanUpToString(_:)`, available for an earlier OS. /// A version of `scanUpToString(_:)`, available for an earlier OS.
func scannedUpToString(_ substring: String) -> String? { func scannedUpToString(_ substring: String) -> String? {
if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { if #available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) {
return scanUpToString(substring) return scanUpToString(substring)
} else { } else {
var string: NSString? = nil var string: NSString? = nil
return scanUpTo(substring, into: &string) ? string as String? : nil return scanUpTo(substring, into: &string) ? string as String? : nil
} }
} }
} }
fileprivate extension CharacterSet { fileprivate extension CharacterSet {
/// Latin alphabet characters. /// Latin alphabet characters.
static let latinAlphabet = CharacterSet(charactersIn: "a"..."z") static let latinAlphabet = CharacterSet(charactersIn: "a"..."z")
.union(CharacterSet(charactersIn: "A"..."Z")) .union(CharacterSet(charactersIn: "A"..."Z"))
static let unitCharacters = CharacterSet.latinAlphabet static let unitCharacters = CharacterSet.latinAlphabet
static let transformationAttributeCharacters = CharacterSet.latinAlphabet static let transformationAttributeCharacters = CharacterSet.latinAlphabet
} }