diff --git a/Samples.bundle/checkmark.svg b/Samples.bundle/checkmark.svg
new file mode 100644
index 0000000..22a4a4f
--- /dev/null
+++ b/Samples.bundle/checkmark.svg
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/SwiftDraw/Parser.XML.Color.swift b/SwiftDraw/Parser.XML.Color.swift
index eeb283f..cbc1e39 100644
--- a/SwiftDraw/Parser.XML.Color.swift
+++ b/SwiftDraw/Parser.XML.Color.swift
@@ -55,7 +55,8 @@ extension XMLParser {
}
private func parseColorNone(data: String) -> DOM.Color? {
- if data.trimmingCharacters(in: .whitespaces) == "none" {
+ let trimmed = data.trimmingCharacters(in: .whitespaces)
+ if trimmed == "none" || trimmed == "transparent" {
return DOM.Color.none // .none resolves to Optional.none
}
return nil
diff --git a/SwiftDraw/Renderer.SFSymbol.swift b/SwiftDraw/Renderer.SFSymbol.swift
index f669c20..b05d9c6 100644
--- a/SwiftDraw/Renderer.SFSymbol.swift
+++ b/SwiftDraw/Renderer.SFSymbol.swift
@@ -126,7 +126,6 @@ extension SFSymbolRenderer {
case black
}
-
func getInsets(for variant: Variant) -> CommandLine.Insets {
switch variant {
case .regular:
@@ -177,7 +176,8 @@ extension SFSymbolRenderer {
static func getSymbolPaths(for layer: LayerTree.Layer,
ctm: LayerTree.Transform.Matrix = .identity) -> [SymbolPath] {
- guard layer.opacity > 0 else { return [] }
+ let isSFSymbolLayer = containsAcceptedName(layer.class)
+ guard isSFSymbolLayer || layer.opacity > 0 else { return [] }
guard layer.clip.isEmpty else {
print("Warning:", "clip-path unsupported in SF Symbols.", to: &.standardError)
return []
@@ -190,12 +190,15 @@ extension SFSymbolRenderer {
let ctm = ctm.concatenated(layer.transform.toMatrix())
var paths = [SymbolPath]()
- let symbolClass = containsAcceptedName(layer.class) ? layer.class : nil
+ let symbolClass = isSFSymbolLayer ? layer.class : nil
for c in layer.contents {
switch c {
case let .shape(shape, stroke, fill):
- if let path = makePath(for: shape, stoke: stroke, fill: fill)?.applying(matrix: ctm) {
+ if let path = makePath(for: shape,
+ stoke: stroke,
+ fill: fill,
+ preserve: isSFSymbolLayer)?.applying(matrix: ctm) {
if fill.rule == .evenodd {
paths.append(SymbolPath(class: symbolClass, path: path.makeNonZero()))
} else {
@@ -218,13 +221,14 @@ extension SFSymbolRenderer {
static func makePath(for shape: LayerTree.Shape,
stoke: LayerTree.StrokeAttributes,
- fill: LayerTree.FillAttributes) -> LayerTree.Path? {
+ fill: LayerTree.FillAttributes,
+ preserve: Bool) -> LayerTree.Path? {
- if fill.fill != .none && fill.opacity > 0 {
+ if preserve || (fill.fill != .none && fill.opacity > 0) {
return shape.path
}
- if stoke.color != .none && stoke.width > 0 {
+ if preserve || (stoke.color != .none && stoke.width > 0) {
#if canImport(CoreGraphics)
return expandOutlines(for: shape.path, stroke: stoke)
#else
diff --git a/SwiftDrawTests/Parser.XML.ColorTests.swift b/SwiftDrawTests/Parser.XML.ColorTests.swift
index da2006c..f258e7f 100644
--- a/SwiftDrawTests/Parser.XML.ColorTests.swift
+++ b/SwiftDrawTests/Parser.XML.ColorTests.swift
@@ -40,6 +40,12 @@ final class ParserColorTests: XCTestCase {
XCTAssertEqual(try XMLParser().parseColor("\t none \t"), .none)
}
+ func testColorTransparent() {
+ XCTAssertEqual(try XMLParser().parseColor("transparent"), .none)
+ XCTAssertEqual(try XMLParser().parseColor(" transparent"), .none)
+ XCTAssertEqual(try XMLParser().parseColor("\t transparent \t"), .none)
+ }
+
func testColorCurrent() {
XCTAssertEqual(try XMLParser().parseColor("currentColor"), .currentColor)
XCTAssertEqual(try XMLParser().parseColor(" currentColor"), .currentColor)
diff --git a/SwiftDrawTests/Renderer.SFSymbolTests.swift b/SwiftDrawTests/Renderer.SFSymbolTests.swift
index df50d09..7ee254f 100644
--- a/SwiftDrawTests/Renderer.SFSymbolTests.swift
+++ b/SwiftDrawTests/Renderer.SFSymbolTests.swift
@@ -72,6 +72,62 @@ final class RendererSFSymbolTests: XCTestCase {
}
+ func testTransparentLayers_Are_Removed() throws {
+ let source = try DOM.SVG.parse(#"""
+
+
+ """#)
+
+ let template = try SFSymbolTemplate.parse(
+ SFSymbolRenderer.render(svg: source)
+ )
+
+ XCTAssertEqual(
+ template.ultralight.contents.paths.count,
+ 1
+ )
+ XCTAssertEqual(
+ template.regular.contents.paths.count,
+ 1
+ )
+ XCTAssertEqual(
+ template.black.contents.paths.count,
+ 1
+ )
+ }
+
+ func testTransparentSFSymboleLayers_AreNot_Removed() throws {
+ let source = try DOM.SVG.parse(#"""
+
+
+ """#)
+
+ let template = try SFSymbolTemplate.parse(
+ SFSymbolRenderer.render(svg: source)
+ )
+
+ XCTAssertEqual(
+ template.ultralight.contents.paths.count,
+ 3
+ )
+ XCTAssertEqual(
+ template.regular.contents.paths.count,
+ 3
+ )
+ XCTAssertEqual(
+ template.black.contents.paths.count,
+ 3
+ )
+ }
+
#if canImport(CoreGraphics)
func testStrokeSymbol() throws {
let url = try Bundle.test.url(forResource: "key.svg")