Skip to content

Commit 4db58aa

Browse files
committed
Text Anchor
1 parent 0982af6 commit 4db58aa

12 files changed

+100
-93
lines changed

Samples/key/key-symbol.svg

Lines changed: 12 additions & 12 deletions
Loading

SwiftDraw/DOM.PresentationAttributes.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ extension DOM {
5454

5555
var fontFamily: String?
5656
var fontSize: Float?
57-
57+
var textAnchor: TextAnchor?
58+
5859
var transform: [DOM.Transform]?
5960
var clipPath: DOM.URL?
6061
var clipRule: DOM.FillRule?
@@ -131,6 +132,7 @@ extension DOM.PresentationAttributes {
131132

132133
merged.fontFamily = att.fontFamily ?? fontFamily
133134
merged.fontSize = att.fontSize ?? fontSize
135+
merged.textAnchor = att.textAnchor ?? textAnchor
134136

135137
merged.transform = att.transform ?? transform
136138
merged.clipPath = att.clipPath ?? clipPath

SwiftDraw/DOM.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@ extension DOM {
8888
case round
8989
case bevel
9090
}
91-
91+
92+
enum TextAnchor: String {
93+
case start
94+
case middle
95+
case end
96+
}
97+
9298
enum Transform: Equatable {
9399
case matrix(a: Float, b: Float, c: Float, d: Float, e: Float, f: Float)
94100
case translate(tx: Float, ty: Float)

SwiftDraw/LayerTree.Builder.Layer.swift

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -32,48 +32,48 @@
3232
import Foundation
3333

3434
extension LayerTree.Builder {
35-
36-
func makeShapeContents(from shape: LayerTree.Shape, with state: State) -> LayerTree.Layer.Contents {
37-
let stroke = makeStrokeAttributes(with: state)
38-
let fill = makeFillAttributes(with: state)
39-
return .shape(shape, stroke, fill)
40-
}
41-
42-
func makeUseLayerContents(from use: DOM.Use, with state: State) throws -> LayerTree.Layer.Contents {
43-
guard
44-
let id = use.href.fragment,
45-
let element = svg.defs.elements[id] else {
46-
throw LayerTree.Error.invalid("missing referenced element: \(use.href)")
35+
36+
func makeShapeContents(from shape: LayerTree.Shape, with state: State) -> LayerTree.Layer.Contents {
37+
let stroke = makeStrokeAttributes(with: state)
38+
let fill = makeFillAttributes(with: state)
39+
return .shape(shape, stroke, fill)
4740
}
48-
49-
let l = makeLayer(from: element, inheriting: state)
50-
let x = use.x ?? 0.0
51-
let y = use.y ?? 0.0
52-
53-
if x != 0 || y != 0 {
54-
l.transform.insert(.translate(tx: x, ty: y), at: 0)
41+
42+
func makeUseLayerContents(from use: DOM.Use, with state: State) throws -> LayerTree.Layer.Contents {
43+
guard
44+
let id = use.href.fragment,
45+
let element = svg.defs.elements[id] else {
46+
throw LayerTree.Error.invalid("missing referenced element: \(use.href)")
47+
}
48+
49+
let l = makeLayer(from: element, inheriting: state)
50+
let x = use.x ?? 0.0
51+
let y = use.y ?? 0.0
52+
53+
if x != 0 || y != 0 {
54+
l.transform.insert(.translate(tx: x, ty: y), at: 0)
55+
}
56+
57+
return .layer(l)
58+
59+
}
60+
61+
static func makeTextContents(from text: DOM.Text, with state: State) -> LayerTree.Layer.Contents {
62+
var point = Point(text.x ?? 0, text.y ?? 0)
63+
var att = makeTextAttributes(with: state)
64+
att.fontName = text.attributes.fontFamily ?? att.fontName
65+
att.size = text.attributes.fontSize ?? att.size
66+
att.anchor = text.attributes.textAnchor ?? att.anchor
67+
point.x += makeXOffset(for: text.value, with: att)
68+
return .text(text.value, point, att)
5569
}
56-
57-
return .layer(l)
58-
59-
}
60-
61-
static func makeTextContents(from text: DOM.Text, with state: State) -> LayerTree.Layer.Contents {
62-
let point = Point(text.x ?? 0, text.y ?? 0)
63-
var att = makeTextAttributes(with: state)
64-
att.fontName = text.attributes.fontFamily ?? att.fontName
65-
att.size = text.attributes.fontSize ?? att.size
66-
return .text(text.value, point, att)
67-
}
68-
69-
static func makeImageContents(from image: DOM.Image) throws -> LayerTree.Layer.Contents {
70-
guard
71-
let decoded = image.href.decodedData,
72-
let im = LayerTree.Image(mimeType: decoded.mimeType, data: decoded.data) else {
73-
throw LayerTree.Error.invalid("Cannot decode image")
70+
71+
static func makeImageContents(from image: DOM.Image) throws -> LayerTree.Layer.Contents {
72+
guard
73+
let decoded = image.href.decodedData,
74+
let im = LayerTree.Image(mimeType: decoded.mimeType, data: decoded.data) else {
75+
throw LayerTree.Error.invalid("Cannot decode image")
76+
}
77+
return .image(im)
7478
}
75-
return .image(im)
76-
}
77-
78-
7979
}

SwiftDraw/LayerTree.Builder.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ extension LayerTree.Builder {
230230
return LayerTree.TextAttributes(
231231
color: fill,
232232
fontName: state.fontFamily,
233-
size: state.fontSize
233+
size: state.fontSize,
234+
anchor: state.textAnchor
234235
)
235236
}
236237

@@ -333,6 +334,7 @@ extension LayerTree.Builder {
333334

334335
var fontFamily: String
335336
var fontSize: DOM.Float
337+
var textAnchor: DOM.TextAnchor
336338

337339
init() {
338340
//default root SVG element state
@@ -351,6 +353,7 @@ extension LayerTree.Builder {
351353
fill = .color(.keyword(.black))
352354
fillOpacity = 1.0
353355
fillRule = .nonzero
356+
textAnchor = .start
354357

355358
fontFamily = "Helvetica"
356359
fontSize = 12.0
@@ -384,6 +387,7 @@ extension LayerTree.Builder {
384387

385388
state.fontFamily = attributes.fontFamily ?? existing.fontFamily
386389
state.fontSize = attributes.fontSize ?? existing.fontSize
390+
state.textAnchor = attributes.textAnchor ?? existing.textAnchor
387391

388392
return state
389393
}

SwiftDraw/LayerTree.Layer.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@ extension LayerTree {
139139
var color: Color
140140
var fontName: String
141141
var size: Float
142+
var anchor: DOM.TextAnchor
142143
}
143144
}

SwiftDraw/Parser.XML.Element.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ extension XMLParser {
258258

259259
el.fontFamily = (try att.parseString("font-family"))?.trimmingCharacters(in: .whitespacesAndNewlines)
260260
el.fontSize = try att.parseFloat("font-size")
261+
el.textAnchor = try att.parseRaw("text-anchor")
261262

262263
if let val = try? att.parseString("transform") {
263264
el.transform = try parseTransform(val)

SwiftDraw/Parser.XML.Text.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ extension XMLParser {
5454
let element = DOM.Text(value: value)
5555
element.x = try att.parseCoordinate("x")
5656
element.y = try att.parseCoordinate("y")
57-
element.attributes.fontFamily = (try att.parseString("font-family"))?.trimmingCharacters(in: .whitespacesAndNewlines)
58-
element.attributes.fontSize = try att.parseFloat("font-size")
5957
return element
6058
}
6159
}

SwiftDraw/Renderer.SFSymbol.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,9 @@ extension SFSymbolTemplate {
400400
<text x="250px" y="30px">Ultralight</text>
401401
<text x="450px" y="30px">Regular</text>
402402
<text x="650px" y="30px">Black</text>
403-
<text id="template-version" fill="#505050" x="730.0" y="575.0">Template v.3.0</text>
403+
<text id="template-version" fill="#505050" x="790.0" y="575.0" text-anchor="end">Template v.3.0</text>
404404
<a href="https://github.com/swhitty/SwiftDraw">
405-
<text fill="#505050" x="627.0" y="590.0">https://github.com/swhitty/SwiftDraw</text>
405+
<text fill="#505050" x="790.0" y="590.0" text-anchor="end">https://github.com/swhitty/SwiftDraw</text>
406406
</a>
407407
</g>
408408
</g>

SwiftDraw/XML.Formatter.SVG.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ extension XML.Formatter {
116116

117117
attributes["font-family"] = graphic.fontFamily
118118
attributes["font-size"] = formatter.format(graphic.fontSize)
119+
attributes["text-anchor"] = graphic.textAnchor?.rawValue
119120

120121
attributes["clip-path"] = graphic.clipPath.map(encodeURL)
121122
attributes["mask"] = graphic.mask.map(encodeURL)

0 commit comments

Comments
 (0)