Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CommandLine/CommandLine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Available keys for --format swift:

Available keys for --format sfsymbol:
--insets alignment of regular variant: top,left,bottom,right | auto
--size size category to generate: small, medium large. (default is small)
--ultralight svg file of ultralight variant
--ultralight-insets alignment of ultralight variant: top,left,bottom,right | auto
--black svg file of black variant
Expand Down
1 change: 1 addition & 0 deletions SwiftDraw/Sources/CommandLine/CommandLine+Process.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public extension CommandLine {
return code.data(using: .utf8)!
case .sfsymbol:
let renderer = SFSymbolRenderer(
size: config.symbolSize ?? .small,
options: config.options,
insets: config.insets,
insetsUltralight: config.insetsUltralight ?? config.insets,
Expand Down
30 changes: 27 additions & 3 deletions SwiftDraw/Sources/CommandLine/CommandLine.Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ extension CommandLine {
public var scale: Scale
public var options: SVG.Options
public var precision: Int?
public var symbolSize: SFSymbolRenderer.SizeCategory?
public var isLegacyInsetsEnabled: Bool
}

Expand Down Expand Up @@ -107,7 +108,7 @@ extension CommandLine {
throw Error.invalid
}

let size = try parseSize(from: modifiers[.size])
let size = try parseSize(from: modifiers[.size], format: format)
let scale = try parseScale(from: modifiers[.scale])
let precision = try parsePrecision(from: modifiers[.precision])
let insets = try parseInsets(from: modifiers[.insets]) ?? Insets()
Expand All @@ -117,6 +118,7 @@ extension CommandLine {
let black = try parseFileURL(file: modifiers[.black], within: baseDirectory)
let blackInsets = try parseInsets(from: modifiers[.blackInsets])
let output = try parseFileURL(file: modifiers[.output], within: baseDirectory)
let symbolSize = try parseSymbolSize(from: modifiers[.size], format: format)

let options = try parseOptions(from: modifiers)
let result = source.newURL(for: format, scale: scale)
Expand All @@ -134,6 +136,7 @@ extension CommandLine {
scale: scale,
options: options,
precision: precision,
symbolSize: symbolSize,
isLegacyInsetsEnabled: modifiers.keys.contains(.legacy)
)
}
Expand Down Expand Up @@ -178,8 +181,9 @@ extension CommandLine {
return precision
}

static func parseSize(from value: String??) throws -> Size {
guard let value = value,
static func parseSize(from value: String??, format: Format) throws -> Size {
guard format != .sfsymbol,
let value = value,
let value = value else {
return .default
}
Expand All @@ -196,6 +200,26 @@ extension CommandLine {
return .custom(width: Int(width), height: Int(height))
}

static func parseSymbolSize(from value: String??, format: Format) throws -> SFSymbolRenderer.SizeCategory? {
guard format == .sfsymbol,
let value = value,
let value = value else {
return nil
}

switch value {
case "small":
return .small
case "medium":
return .medium
case "large":
return .large
default:
throw Error.invalid

}
}

static func parseAPI(from value: String??) throws -> API? {
guard let value = value,
let value = value else {
Expand Down
12 changes: 6 additions & 6 deletions SwiftDraw/Sources/Formatter/XML.Formatter.SVG.swift
Original file line number Diff line number Diff line change
Expand Up @@ -328,17 +328,17 @@ extension XML.Formatter {
case let .matrix(a: a, b: b, c: c, d: d, e: e, f: f):
return "matrix(\(formatter.format(a,b,c,d,e,f)))"
case let .translate(tx: tx, ty: ty):
return "translate(\(formatter.format(tx, ty))"
return "translate(\(formatter.format(tx, ty)))"
case let .scale(sx: sx, sy: sy):
return "scale(\(formatter.format(sx, sy))"
return "scale(\(formatter.format(sx, sy)))"
case let .rotate(angle: angle):
return "rotate(\(formatter.format(angle))"
return "rotate(\(formatter.format(angle)))"
case let .rotatePoint(angle: angle, cx: cx, cy: cy):
return "rotate(\(formatter.format(angle, cx, cy))"
return "rotate(\(formatter.format(angle, cx, cy)))"
case let .skewX(angle: angle):
return "skewX(\(formatter.format(angle))"
return "skewX(\(formatter.format(angle)))"
case let .skewY(angle: angle):
return "skewY(\(formatter.format(angle))"
return "skewY(\(formatter.format(angle)))"
}
}

Expand Down
97 changes: 91 additions & 6 deletions SwiftDraw/Sources/Renderer/Renderer.SFSymbol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,30 @@ import Foundation

public struct SFSymbolRenderer {

private let size: SizeCategory
private let options: SVG.Options
private let insets: CommandLine.Insets
private let insetsUltralight: CommandLine.Insets
private let insetsBlack: CommandLine.Insets
private let formatter: CoordinateFormatter
private let isLegacyInsets: Bool

public init(options: SVG.Options,
insets: CommandLine.Insets,
insetsUltralight: CommandLine.Insets,
insetsBlack: CommandLine.Insets,
precision: Int,
isLegacyInsets: Bool) {
public enum SizeCategory {
case small
case medium
case large
}

public init(
size: SizeCategory,
options: SVG.Options,
insets: CommandLine.Insets,
insetsUltralight: CommandLine.Insets,
insetsBlack: CommandLine.Insets,
precision: Int,
isLegacyInsets: Bool
) {
self.size = size
self.options = options
self.insets = insets
self.insetsUltralight = insetsUltralight
Expand Down Expand Up @@ -94,6 +105,8 @@ public struct SFSymbolRenderer {
template.black.appendPaths(pathsRegular, from: bounds, isLegacy: isLegacyInsets)
}

template.setSize(size)

let element = try XML.Formatter.SVG(formatter: formatter).makeElement(from: template.svg)
let formatter = XML.Formatter(spaces: 4)
let result = formatter.encodeRootElement(element)
Expand Down Expand Up @@ -356,25 +369,36 @@ struct SFSymbolTemplate {

let svg: DOM.SVG

var typeReference: DOM.Path
var ultralight: Variant
var regular: Variant
var black: Variant

init(svg: DOM.SVG) throws {
self.svg = svg
self.typeReference = try svg.group(id: "Guides").path(id: "H-reference")
self.ultralight = try Variant(svg: svg, kind: "Ultralight")
self.regular = try Variant(svg: svg, kind: "Regular")
self.black = try Variant(svg: svg, kind: "Black")
}

mutating func setSize(_ size: SFSymbolRenderer.SizeCategory) {
typeReference.attributes.transform = [.translate(tx: 0, ty: size.yOffset)]
ultralight.setSize(size)
regular.setSize(size)
black.setSize(size)
}

struct Variant {
var left: Guide
var contents: Contents
var right: Guide
private var kind: String

init(svg: DOM.SVG, kind: String) throws {
let guides = try svg.group(id: "Guides")
let symbols = try svg.group(id: "Symbols")
self.kind = kind
self.left = try Guide(guides.path(id: "left-margin-\(kind)-S"))
self.contents = try Contents(symbols.group(id: "\(kind)-S"))
self.right = try Guide(guides.path(id: "right-margin-\(kind)-S"))
Expand All @@ -385,6 +409,15 @@ struct SFSymbolTemplate {
let maxX = right.x
return .init(x: minX, y: 76, width: maxX - minX, height: 70)
}

mutating func setSize(_ size: SFSymbolRenderer.SizeCategory) {
left.setID("left-margin-\(kind)-\(size.name)")
left.y += size.yOffset
contents.setID("\(kind)-\(size.name)")
contents.setTransform(.translate(tx: 0, ty: size.yOffset))
right.setID("right-margin-\(kind)-\(size.name)")
right.y += size.yOffset
}
}

struct Guide {
Expand All @@ -394,6 +427,10 @@ struct SFSymbolTemplate {
self.path = path
}

func setID(_ id: String) {
path.id = id
}

var x: DOM.Float {
get {
guard case let .move(x, _, _) = path.segments[0] else {
Expand All @@ -408,6 +445,21 @@ struct SFSymbolTemplate {
path.segments[0] = .move(x: newValue, y: y, space: space)
}
}

var y: DOM.Float {
get {
guard case let .move(_, y, _) = path.segments[0] else {
fatalError()
}
return y
}
set {
guard case let .move(x, _, space) = path.segments[0] else {
fatalError()
}
path.segments[0] = .move(x: x, y: newValue, space: space)
}
}
}

struct Contents {
Expand All @@ -417,6 +469,10 @@ struct SFSymbolTemplate {
self.group = group
}

func setID(_ id: String) {
group.id = id
}

var paths: [DOM.Path] {
get {
group.childElements as! [DOM.Path]
Expand All @@ -425,6 +481,35 @@ struct SFSymbolTemplate {
group.childElements = newValue
}
}

func setTransform(_ transform: DOM.Transform) {
group.attributes.transform = [transform]
}
}
}

extension SFSymbolRenderer.SizeCategory {

var name: String {
switch self {
case .small:
return "S"
case .medium:
return "M"
case .large:
return "L"
}
}

var yOffset: Float {
switch self {
case .small:
return 0
case .medium:
return 200
case .large:
return 400
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions SwiftDraw/Tests/Renderer/Renderer.SFSymbolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ private extension SFSymbolRenderer {

static func render(fileURL: URL) throws -> String {
let renderer = SFSymbolRenderer(
size: .small,
options: [],
insets: .init(),
insetsUltralight: .init(),
Expand All @@ -200,6 +201,7 @@ private extension SFSymbolRenderer {

static func render(svg: DOM.SVG) throws -> String {
let renderer = SFSymbolRenderer(
size: .small,
options: [],
insets: .init(),
insetsUltralight: .init(),
Expand Down