Skip to content

Commit 9d4804c

Browse files
committed
support small, medium and large SFSymbols
1 parent a535740 commit 9d4804c

File tree

6 files changed

+128
-15
lines changed

6 files changed

+128
-15
lines changed

CommandLine/CommandLine.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Available keys for --format swift:
9090
9191
Available keys for --format sfsymbol:
9292
--insets alignment of regular variant: top,left,bottom,right | auto
93+
--size size category to generate: small, medium large. (default is small)
9394
--ultralight svg file of ultralight variant
9495
--ultralight-insets alignment of ultralight variant: top,left,bottom,right | auto
9596
--black svg file of black variant

SwiftDraw/Sources/CommandLine/CommandLine+Process.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public extension CommandLine {
5252
return code.data(using: .utf8)!
5353
case .sfsymbol:
5454
let renderer = SFSymbolRenderer(
55+
size: config.symbolSize ?? .small,
5556
options: config.options,
5657
insets: config.insets,
5758
insetsUltralight: config.insetsUltralight ?? config.insets,

SwiftDraw/Sources/CommandLine/CommandLine.Configuration.swift

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extension CommandLine {
4848
public var scale: Scale
4949
public var options: SVG.Options
5050
public var precision: Int?
51+
public var symbolSize: SFSymbolRenderer.SizeCategory?
5152
public var isLegacyInsetsEnabled: Bool
5253
}
5354

@@ -107,7 +108,7 @@ extension CommandLine {
107108
throw Error.invalid
108109
}
109110

110-
let size = try parseSize(from: modifiers[.size])
111+
let size = try parseSize(from: modifiers[.size], format: format)
111112
let scale = try parseScale(from: modifiers[.scale])
112113
let precision = try parsePrecision(from: modifiers[.precision])
113114
let insets = try parseInsets(from: modifiers[.insets]) ?? Insets()
@@ -117,6 +118,7 @@ extension CommandLine {
117118
let black = try parseFileURL(file: modifiers[.black], within: baseDirectory)
118119
let blackInsets = try parseInsets(from: modifiers[.blackInsets])
119120
let output = try parseFileURL(file: modifiers[.output], within: baseDirectory)
121+
let symbolSize = try parseSymbolSize(from: modifiers[.size], format: format)
120122

121123
let options = try parseOptions(from: modifiers)
122124
let result = source.newURL(for: format, scale: scale)
@@ -134,6 +136,7 @@ extension CommandLine {
134136
scale: scale,
135137
options: options,
136138
precision: precision,
139+
symbolSize: symbolSize,
137140
isLegacyInsetsEnabled: modifiers.keys.contains(.legacy)
138141
)
139142
}
@@ -178,8 +181,9 @@ extension CommandLine {
178181
return precision
179182
}
180183

181-
static func parseSize(from value: String??) throws -> Size {
182-
guard let value = value,
184+
static func parseSize(from value: String??, format: Format) throws -> Size {
185+
guard format != .sfsymbol,
186+
let value = value,
183187
let value = value else {
184188
return .default
185189
}
@@ -196,6 +200,26 @@ extension CommandLine {
196200
return .custom(width: Int(width), height: Int(height))
197201
}
198202

203+
static func parseSymbolSize(from value: String??, format: Format) throws -> SFSymbolRenderer.SizeCategory? {
204+
guard format == .sfsymbol,
205+
let value = value,
206+
let value = value else {
207+
return nil
208+
}
209+
210+
switch value {
211+
case "small":
212+
return .small
213+
case "medium":
214+
return .medium
215+
case "large":
216+
return .large
217+
default:
218+
throw Error.invalid
219+
220+
}
221+
}
222+
199223
static func parseAPI(from value: String??) throws -> API? {
200224
guard let value = value,
201225
let value = value else {

SwiftDraw/Sources/Formatter/XML.Formatter.SVG.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,17 +328,17 @@ extension XML.Formatter {
328328
case let .matrix(a: a, b: b, c: c, d: d, e: e, f: f):
329329
return "matrix(\(formatter.format(a,b,c,d,e,f)))"
330330
case let .translate(tx: tx, ty: ty):
331-
return "translate(\(formatter.format(tx, ty))"
331+
return "translate(\(formatter.format(tx, ty)))"
332332
case let .scale(sx: sx, sy: sy):
333-
return "scale(\(formatter.format(sx, sy))"
333+
return "scale(\(formatter.format(sx, sy)))"
334334
case let .rotate(angle: angle):
335-
return "rotate(\(formatter.format(angle))"
335+
return "rotate(\(formatter.format(angle)))"
336336
case let .rotatePoint(angle: angle, cx: cx, cy: cy):
337-
return "rotate(\(formatter.format(angle, cx, cy))"
337+
return "rotate(\(formatter.format(angle, cx, cy)))"
338338
case let .skewX(angle: angle):
339-
return "skewX(\(formatter.format(angle))"
339+
return "skewX(\(formatter.format(angle)))"
340340
case let .skewY(angle: angle):
341-
return "skewY(\(formatter.format(angle))"
341+
return "skewY(\(formatter.format(angle)))"
342342
}
343343
}
344344

SwiftDraw/Sources/Renderer/Renderer.SFSymbol.swift

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,30 @@ import Foundation
3434

3535
public struct SFSymbolRenderer {
3636

37+
private let size: SizeCategory
3738
private let options: SVG.Options
3839
private let insets: CommandLine.Insets
3940
private let insetsUltralight: CommandLine.Insets
4041
private let insetsBlack: CommandLine.Insets
4142
private let formatter: CoordinateFormatter
4243
private let isLegacyInsets: Bool
4344

44-
public init(options: SVG.Options,
45-
insets: CommandLine.Insets,
46-
insetsUltralight: CommandLine.Insets,
47-
insetsBlack: CommandLine.Insets,
48-
precision: Int,
49-
isLegacyInsets: Bool) {
45+
public enum SizeCategory {
46+
case small
47+
case medium
48+
case large
49+
}
50+
51+
public init(
52+
size: SizeCategory,
53+
options: SVG.Options,
54+
insets: CommandLine.Insets,
55+
insetsUltralight: CommandLine.Insets,
56+
insetsBlack: CommandLine.Insets,
57+
precision: Int,
58+
isLegacyInsets: Bool
59+
) {
60+
self.size = size
5061
self.options = options
5162
self.insets = insets
5263
self.insetsUltralight = insetsUltralight
@@ -94,6 +105,8 @@ public struct SFSymbolRenderer {
94105
template.black.appendPaths(pathsRegular, from: bounds, isLegacy: isLegacyInsets)
95106
}
96107

108+
template.setSize(size)
109+
97110
let element = try XML.Formatter.SVG(formatter: formatter).makeElement(from: template.svg)
98111
let formatter = XML.Formatter(spaces: 4)
99112
let result = formatter.encodeRootElement(element)
@@ -356,25 +369,36 @@ struct SFSymbolTemplate {
356369

357370
let svg: DOM.SVG
358371

372+
var typeReference: DOM.Path
359373
var ultralight: Variant
360374
var regular: Variant
361375
var black: Variant
362376

363377
init(svg: DOM.SVG) throws {
364378
self.svg = svg
379+
self.typeReference = try svg.group(id: "Guides").path(id: "H-reference")
365380
self.ultralight = try Variant(svg: svg, kind: "Ultralight")
366381
self.regular = try Variant(svg: svg, kind: "Regular")
367382
self.black = try Variant(svg: svg, kind: "Black")
368383
}
369384

385+
mutating func setSize(_ size: SFSymbolRenderer.SizeCategory) {
386+
typeReference.attributes.transform = [.translate(tx: 0, ty: size.yOffset)]
387+
ultralight.setSize(size)
388+
regular.setSize(size)
389+
black.setSize(size)
390+
}
391+
370392
struct Variant {
371393
var left: Guide
372394
var contents: Contents
373395
var right: Guide
396+
private var kind: String
374397

375398
init(svg: DOM.SVG, kind: String) throws {
376399
let guides = try svg.group(id: "Guides")
377400
let symbols = try svg.group(id: "Symbols")
401+
self.kind = kind
378402
self.left = try Guide(guides.path(id: "left-margin-\(kind)-S"))
379403
self.contents = try Contents(symbols.group(id: "\(kind)-S"))
380404
self.right = try Guide(guides.path(id: "right-margin-\(kind)-S"))
@@ -385,6 +409,15 @@ struct SFSymbolTemplate {
385409
let maxX = right.x
386410
return .init(x: minX, y: 76, width: maxX - minX, height: 70)
387411
}
412+
413+
mutating func setSize(_ size: SFSymbolRenderer.SizeCategory) {
414+
left.setID("left-margin-\(kind)-\(size.name)")
415+
left.y += size.yOffset
416+
contents.setID("\(kind)-\(size.name)")
417+
contents.setTransform(.translate(tx: 0, ty: size.yOffset))
418+
right.setID("right-margin-\(kind)-\(size.name)")
419+
right.y += size.yOffset
420+
}
388421
}
389422

390423
struct Guide {
@@ -394,6 +427,10 @@ struct SFSymbolTemplate {
394427
self.path = path
395428
}
396429

430+
func setID(_ id: String) {
431+
path.id = id
432+
}
433+
397434
var x: DOM.Float {
398435
get {
399436
guard case let .move(x, _, _) = path.segments[0] else {
@@ -408,6 +445,21 @@ struct SFSymbolTemplate {
408445
path.segments[0] = .move(x: newValue, y: y, space: space)
409446
}
410447
}
448+
449+
var y: DOM.Float {
450+
get {
451+
guard case let .move(_, y, _) = path.segments[0] else {
452+
fatalError()
453+
}
454+
return y
455+
}
456+
set {
457+
guard case let .move(x, _, space) = path.segments[0] else {
458+
fatalError()
459+
}
460+
path.segments[0] = .move(x: x, y: newValue, space: space)
461+
}
462+
}
411463
}
412464

413465
struct Contents {
@@ -417,6 +469,10 @@ struct SFSymbolTemplate {
417469
self.group = group
418470
}
419471

472+
func setID(_ id: String) {
473+
group.id = id
474+
}
475+
420476
var paths: [DOM.Path] {
421477
get {
422478
group.childElements as! [DOM.Path]
@@ -425,6 +481,35 @@ struct SFSymbolTemplate {
425481
group.childElements = newValue
426482
}
427483
}
484+
485+
func setTransform(_ transform: DOM.Transform) {
486+
group.attributes.transform = [transform]
487+
}
488+
}
489+
}
490+
491+
extension SFSymbolRenderer.SizeCategory {
492+
493+
var name: String {
494+
switch self {
495+
case .small:
496+
return "S"
497+
case .medium:
498+
return "M"
499+
case .large:
500+
return "L"
501+
}
502+
}
503+
504+
var yOffset: Float {
505+
switch self {
506+
case .small:
507+
return 0
508+
case .medium:
509+
return 200
510+
case .large:
511+
return 400
512+
}
428513
}
429514
}
430515

SwiftDraw/Tests/Renderer/Renderer.SFSymbolTests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ private extension SFSymbolRenderer {
188188

189189
static func render(fileURL: URL) throws -> String {
190190
let renderer = SFSymbolRenderer(
191+
size: .small,
191192
options: [],
192193
insets: .init(),
193194
insetsUltralight: .init(),
@@ -200,6 +201,7 @@ private extension SFSymbolRenderer {
200201

201202
static func render(svg: DOM.SVG) throws -> String {
202203
let renderer = SFSymbolRenderer(
204+
size: .small,
203205
options: [],
204206
insets: .init(),
205207
insetsUltralight: .init(),

0 commit comments

Comments
 (0)