diff --git a/Source/Model/Nodes/SVGText.swift b/Source/Model/Nodes/SVGText.swift index 098cb99..d82b42f 100644 --- a/Source/Model/Nodes/SVGText.swift +++ b/Source/Model/Nodes/SVGText.swift @@ -6,6 +6,13 @@ import Combine #endif public class SVGText: SVGNode { + public struct Shift: Codable { + public let dx: String? + public let dy: String? + + public static let empty = Shift(dx: nil, dy: nil) + } + public enum Anchor: String, SerializableEnum { case leading case center @@ -18,12 +25,18 @@ public class SVGText: SVGNode { public var fill: SVGPaint? public var stroke: SVGStroke? public var textAnchor: Anchor = .leading + public var textAnchorString: String? = nil + public var contents: [SVGNode] = [] // Store tspan and text without tspan + public var shift: Shift? = nil #else @Published public var text: String @Published public var font: SVGFont? @Published public var fill: SVGPaint? @Published public var stroke: SVGStroke? @Published public var textAnchor: Anchor = .leading + @Published public var textAnchorString: String? = nil + @Published public var contents: [SVGNode] = [] + @Published public var shift: Shift? = nil #endif public init( @@ -33,16 +46,22 @@ public class SVGText: SVGNode { stroke: SVGStroke? = nil, textAnchor: Anchor = .leading, transform: CGAffineTransform = .identity, + contents: [SVGNode] = [], opaque: Bool = true, opacity: Double = 1, clip: SVGUserSpaceNode? = nil, - mask: SVGNode? = nil + mask: SVGNode? = nil, + shift: SVGText.Shift = .empty, + textAnchorString: String? = nil ) { self.text = text self.font = font self.fill = fill self.stroke = stroke self.textAnchor = textAnchor + self.contents = contents + self.shift = shift + self.textAnchorString = textAnchorString super.init(transform: transform, opaque: opaque, opacity: opacity, clip: clip, mask: mask) } diff --git a/Source/Parser/SVG/Elements/SVGTextParser.swift b/Source/Parser/SVG/Elements/SVGTextParser.swift index 5cbbe6f..8d7cae8 100644 --- a/Source/Parser/SVG/Elements/SVGTextParser.swift +++ b/Source/Parser/SVG/Elements/SVGTextParser.swift @@ -23,11 +23,21 @@ class SVGTextParser: SVGBaseElementParser { let y = SVGHelper.parseCGFloat(context.properties, "y") let transform = CGAffineTransform(translationX: x, y: y) + let shift = SVGText.Shift(dx: context.properties["dx"], dy: context.properties["dy"]) + if let textNode = context.element.contents.first as? XMLText { let trimmed = textNode.text.trimmingCharacters(in: .whitespacesAndNewlines).processingWhitespaces() - return SVGText(text: trimmed, font: font, fill: SVGHelper.parseFill(context.styles, context.index), stroke: SVGHelper.parseStroke(context.styles, index: context.index), textAnchor: textAnchor, transform: transform) + + return SVGText(text: trimmed, font: font, fill: SVGHelper.parseFill(context.styles, context.index), stroke: SVGHelper.parseStroke(context.styles, index: context.index), textAnchor: textAnchor, transform: transform, shift: shift, textAnchorString: context.style("text-anchor")) } - return .none + return SVGGroup(contents: parseContents(context: context, delegate: delegate)) + //return .none + } + + func parseContents(context: SVGNodeContext, delegate: (XMLElement) -> SVGNode?) -> [SVGNode] { + return context.element.contents + .compactMap { $0 as? XMLElement } + .compactMap { delegate($0) } } private func parseTextAnchor(_ string: String?) -> SVGText.Anchor { diff --git a/Source/Parser/SVG/SVGParser.swift b/Source/Parser/SVG/SVGParser.swift index 1c11de2..1656994 100644 --- a/Source/Parser/SVG/SVGParser.swift +++ b/Source/Parser/SVG/SVGParser.swift @@ -55,6 +55,7 @@ public struct SVGParser { "g": SVGGroupParser(), "use": SVGUseParser(), "text": SVGTextParser(), + "tspan": SVGTextParser(), "image": SVGImageParser(), "rect": SVGRectParser(), "circle": SVGCircleParser(), @@ -68,6 +69,9 @@ public struct SVGParser { ] private static func parse(context: SVGNodeContext) -> SVGNode? { + if context.element.name == "tspan" { + // TODO: handle differently + } return parsers[context.element.name]?.parse(context: context) { parse(element: $0, parentContext: context) }