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:
parent
22233257ed
commit
e53ca25b11
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user