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 @@ -94,6 +94,7 @@ Available keys for --format sfsymbol:
--ultralightInsets alignment of ultralight variant: top,left,bottom,right | auto
--black svg file of black variant
--blackInsets alignment of black variant: top,left,bottom,right | auto
--legacy use the original, less precise alignment logic from earlier swiftdraw versions.


""")
Expand Down
4 changes: 2 additions & 2 deletions DOM/Sources/Parser.XML.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ package struct XMLParser {
self.rawValue = rawValue
}

package static let skipInvalidAttributes = Options(rawValue: 1)
package static let skipInvalidElements = Options(rawValue: 2)
package static let skipInvalidAttributes = Options(rawValue: 1 << 0)
package static let skipInvalidElements = Options(rawValue: 1 << 1)
}

package init(options: Options = [], filename: String? = nil) {
Expand Down
21 changes: 13 additions & 8 deletions SwiftDraw/Sources/CommandLine/CommandLine+Process.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,19 @@ public extension CommandLine {
precision: config.precision ?? 2)
return code.data(using: .utf8)!
case .sfsymbol:
let renderer = SFSymbolRenderer(options: config.options,
insets: config.insets,
insetsUltralight: config.insetsUltralight ?? config.insets,
insetsBlack: config.insetsBlack ?? config.insets,
precision: config.precision ?? 3)
let svg = try renderer.render(regular: config.input,
ultralight: config.inputUltralight,
black: config.inputBlack)
let renderer = SFSymbolRenderer(
options: config.options,
insets: config.insets,
insetsUltralight: config.insetsUltralight ?? config.insets,
insetsBlack: config.insetsBlack ?? config.insets,
precision: config.precision ?? 3,
isLegacyInsets: config.isLegacyInsetsEnabled
)
let svg = try renderer.render(
regular: config.input,
ultralight: config.inputUltralight,
black: config.inputBlack
)
return svg.data(using: .utf8)!
case .jpeg, .pdf, .png:
#if canImport(CoreGraphics)
Expand Down
8 changes: 7 additions & 1 deletion SwiftDraw/Sources/CommandLine/CommandLine.Arguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,15 @@ extension CommandLine {
case black
case blackInsets
case hideUnsupportedFilters
case legacy

var hasValue: Bool {
self != .hideUnsupportedFilters
switch self {
case .hideUnsupportedFilters, .legacy:
return false
default:
return true
}
}
}

Expand Down
30 changes: 17 additions & 13 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 isLegacyInsetsEnabled: Bool
}

public enum Format: String {
Expand Down Expand Up @@ -119,19 +120,22 @@ extension CommandLine {

let options = try parseOptions(from: modifiers)
let result = source.newURL(for: format, scale: scale)
return Configuration(input: source,
inputUltralight: ultralight,
inputBlack: black,
output: output ?? result,
format: format,
size: size,
api: api,
insets: insets,
insetsUltralight: ultralightInsets,
insetsBlack: blackInsets,
scale: scale,
options: options,
precision: precision)
return Configuration(
input: source,
inputUltralight: ultralight,
inputBlack: black,
output: output ?? result,
format: format,
size: size,
api: api,
insets: insets,
insetsUltralight: ultralightInsets,
insetsBlack: blackInsets,
scale: scale,
options: options,
precision: precision,
isLegacyInsetsEnabled: modifiers.keys.contains(.legacy)
)
}

static func parseFileURL(file: String, within directory: URL) throws -> URL {
Expand Down
4 changes: 2 additions & 2 deletions SwiftDraw/Sources/LayerTree/LayerTree.CommandOptimizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ struct OptimizerOptions: OptionSet {
self.rawValue = rawValue
}

static let skipRedundantState = OptimizerOptions(rawValue: 1)
static let skipInitialSaveState = OptimizerOptions(rawValue: 2)
static let skipRedundantState = OptimizerOptions(rawValue: 1 << 0)
static let skipInitialSaveState = OptimizerOptions(rawValue: 1 << 1)
}

extension RendererCommand {
Expand Down
54 changes: 34 additions & 20 deletions SwiftDraw/Sources/Renderer/Renderer.SFSymbol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,23 @@ public struct SFSymbolRenderer {
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) {
precision: Int,
isLegacyInsets: Bool) {
self.options = options
self.insets = insets
self.insetsUltralight = insetsUltralight
self.insetsBlack = insetsBlack
self.formatter = CoordinateFormatter(delimeter: .comma,
precision: .capped(max: precision))
self.formatter = CoordinateFormatter(
delimeter: .comma,
precision: .capped(max: precision)
)
self.isLegacyInsets = isLegacyInsets
}

public func render(regular: URL, ultralight: URL?, black: URL?) throws -> String {
Expand All @@ -68,25 +73,25 @@ public struct SFSymbolRenderer {

template.svg.styles = image.styles.map(makeSymbolStyleSheet)

let boundsRegular = try makeBounds(svg: image, auto: Self.makeAutoBounds(for: pathsRegular), for: .regular)
template.regular.appendPaths(pathsRegular, from: boundsRegular)
let boundsRegular = try makeBounds(svg: image, auto: Self.makeAutoBounds(for: pathsRegular, isLegacy: isLegacyInsets), for: .regular)
template.regular.appendPaths(pathsRegular, from: boundsRegular, isLegacy: isLegacyInsets)

if let ultralight = ultralight,
let paths = Self.getPaths(for: ultralight) {
let bounds = try makeBounds(svg: ultralight, isRegularSVG: false, auto: Self.makeAutoBounds(for: paths), for: .ultralight)
template.ultralight.appendPaths(paths, from: bounds)
let bounds = try makeBounds(svg: ultralight, isRegularSVG: false, auto: Self.makeAutoBounds(for: paths, isLegacy: isLegacyInsets), for: .ultralight)
template.ultralight.appendPaths(paths, from: bounds, isLegacy: isLegacyInsets)
} else {
let bounds = try makeBounds(svg: image, auto: Self.makeAutoBounds(for: pathsRegular), for: .ultralight)
template.ultralight.appendPaths(pathsRegular, from: bounds)
let bounds = try makeBounds(svg: image, auto: Self.makeAutoBounds(for: pathsRegular, isLegacy: isLegacyInsets), for: .ultralight)
template.ultralight.appendPaths(pathsRegular, from: bounds, isLegacy: isLegacyInsets)
}

if let black = black,
let paths = Self.getPaths(for: black) {
let bounds = try makeBounds(svg: black, isRegularSVG: false, auto: Self.makeAutoBounds(for: paths), for: .black)
template.black.appendPaths(paths, from: bounds)
let bounds = try makeBounds(svg: black, isRegularSVG: false, auto: Self.makeAutoBounds(for: paths, isLegacy: isLegacyInsets), for: .black)
template.black.appendPaths(paths, from: bounds, isLegacy: isLegacyInsets)
} else {
let bounds = try makeBounds(svg: image, auto: Self.makeAutoBounds(for: pathsRegular), for: .black)
template.black.appendPaths(pathsRegular, from: bounds)
let bounds = try makeBounds(svg: image, auto: Self.makeAutoBounds(for: pathsRegular, isLegacy: isLegacyInsets), for: .black)
template.black.appendPaths(pathsRegular, from: bounds, isLegacy: isLegacyInsets)
}

let element = try XML.Formatter.SVG(formatter: formatter).makeElement(from: template.svg)
Expand Down Expand Up @@ -257,7 +262,7 @@ extension SFSymbolRenderer {
#endif
}

static func makeAutoBounds(for paths: [SymbolPath]) -> LayerTree.Rect {
static func makeAutoBounds(for paths: [SymbolPath], isLegacy: Bool = false) -> LayerTree.Rect {
var min = LayerTree.Point.maximum
var max = LayerTree.Point.minimum
for p in paths {
Expand All @@ -266,8 +271,10 @@ extension SFSymbolRenderer {
max = max.maximum(combining: .init(bounds.maxX, bounds.maxY))
}

min.x -= 10
max.x += 10
if !isLegacy {
min.x -= 10
max.x += 10
}

return LayerTree.Rect(
x: min.x,
Expand Down Expand Up @@ -516,7 +523,7 @@ private extension ContainerElement {

private extension SFSymbolTemplate.Variant {

mutating func appendPaths(_ paths: [SFSymbolRenderer.SymbolPath], from source: LayerTree.Rect) {
mutating func appendPaths(_ paths: [SFSymbolRenderer.SymbolPath], from source: LayerTree.Rect, isLegacy: Bool = false) {
let matrix = SFSymbolRenderer.makeTransformation(from: source, to: bounds)
contents.paths = paths
.map {
Expand All @@ -527,9 +534,16 @@ private extension SFSymbolTemplate.Variant {
}

let midX = bounds.midX
let newWidth = ((source.width * matrix.a) / 2)
left.x = midX - newWidth
right.x = midX + newWidth
if isLegacy {
// preserve behaviour from earlier SwiftDraw versions with --legacy option
let newWidth = ((source.width * matrix.a) / 2) + 10
left.x = min(left.x, midX - newWidth)
right.x = max(right.x, midX + newWidth)
} else {
let newWidth = ((source.width * matrix.a) / 2)
left.x = midX - newWidth
right.x = midX + newWidth
}
}
}

Expand Down
24 changes: 16 additions & 8 deletions SwiftDraw/Tests/Renderer/Renderer.SFSymbolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,26 @@ private extension DOM.SVG {
private extension SFSymbolRenderer {

static func render(fileURL: URL) throws -> String {
let renderer = SFSymbolRenderer(options: [], insets: .init(),
insetsUltralight: .init(),
insetsBlack: .init(),
precision: 3)
let renderer = SFSymbolRenderer(
options: [],
insets: .init(),
insetsUltralight: .init(),
insetsBlack: .init(),
precision: 3,
isLegacyInsets: false
)
return try renderer.render(regular: fileURL, ultralight: nil, black: nil)
}

static func render(svg: DOM.SVG) throws -> String {
let renderer = SFSymbolRenderer(options: [], insets: .init(),
insetsUltralight: .init(),
insetsBlack: .init(),
precision: 3)
let renderer = SFSymbolRenderer(
options: [],
insets: .init(),
insetsUltralight: .init(),
insetsBlack: .init(),
precision: 3,
isLegacyInsets: false
)
return try renderer.render(default: svg, ultralight: nil, black: nil)
}
}