From 8192cf6cbdddd4e02b3504c4b1dccf8c23b13f40 Mon Sep 17 00:00:00 2001 From: Radu Ursache Date: Wed, 22 Apr 2026 21:19:28 +0300 Subject: [PATCH] Auto-generate SF Symbol weight variants from stroke-width scaling Adds --ultralight-stroke-width and --black-stroke-width flags to the sfsymbol format. When set without an explicit variant SVG, SwiftDraw clones the regular DOM, multiplies every stroke-width value by the scale (decimal or percent syntax), then runs that mutated DOM through the existing variant pipeline. Explicit --ultralight or --black always wins, with a warning when both are supplied. Fixes #38 --- CommandLine/CommandLine.swift | 16 +- README.md | 27 +- .../CommandLine/CommandLine+Process.swift | 4 +- .../CommandLine/CommandLine.Arguments.swift | 6 + .../CommandLine.Configuration.swift | 19 +- .../Renderer.SFSymbol+StrokeScale.swift | 129 ++++++++++ .../Sources/Renderer/Renderer.SFSymbol.swift | 42 ++- .../CommandLine.ConfigurationTests.swift | 33 +++ .../Renderer.SFSymbolStrokeScaleTests.swift | 241 ++++++++++++++++++ .../Tests/Test.bundle/stroke-attribute.svg | 4 + .../Tests/Test.bundle/stroke-inline-style.svg | 4 + SwiftDraw/Tests/Test.bundle/stroke-mixed.svg | 11 + SwiftDraw/Tests/Test.bundle/stroke-none.svg | 4 + .../Tests/Test.bundle/stroke-stylesheet.svg | 7 + 14 files changed, 530 insertions(+), 17 deletions(-) create mode 100644 SwiftDraw/Sources/Renderer/Renderer.SFSymbol+StrokeScale.swift create mode 100644 SwiftDraw/Tests/Renderer/Renderer.SFSymbolStrokeScaleTests.swift create mode 100644 SwiftDraw/Tests/Test.bundle/stroke-attribute.svg create mode 100644 SwiftDraw/Tests/Test.bundle/stroke-inline-style.svg create mode 100644 SwiftDraw/Tests/Test.bundle/stroke-mixed.svg create mode 100644 SwiftDraw/Tests/Test.bundle/stroke-none.svg create mode 100644 SwiftDraw/Tests/Test.bundle/stroke-stylesheet.svg diff --git a/CommandLine/CommandLine.swift b/CommandLine/CommandLine.swift index 07ccc54..89e8cc0 100644 --- a/CommandLine/CommandLine.swift +++ b/CommandLine/CommandLine.swift @@ -92,11 +92,17 @@ 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 - --black-insets alignment of black variant: top,left,bottom,right | auto - --legacy use the original, less precise alignment logic from earlier swiftdraw versions. + --ultralight svg file of ultralight variant + --ultralight-insets alignment of ultralight variant: top,left,bottom,right | auto + --ultralight-stroke-width auto-generate ultralight variant by scaling regular stroke-width: 0.5 | 50% + --black svg file of black variant + --black-insets alignment of black variant: top,left,bottom,right | auto + --black-stroke-width auto-generate black variant by scaling regular stroke-width: 2.0 | 200% + --legacy use the original, less precise alignment logic from earlier swiftdraw versions. + +Notes: + An explicit --ultralight or --black file always wins over the matching stroke-width flag. + Stroke-width scaling has no effect on shapes that lack a stroke (a warning is printed). """) diff --git a/README.md b/README.md index fd1a5ca..975d2cb 100644 --- a/README.md +++ b/README.md @@ -114,11 +114,13 @@ 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 - --black-insets alignment of black variant: top,left,bottom,right | auto - --legacy use the original, less precise alignment logic from earlier swiftdraw versions. + --ultralight svg file of ultralight variant + --ultralight-insets alignment of ultralight variant: top,left,bottom,right | auto + --ultralight-stroke-width auto-generate ultralight variant by scaling regular stroke-width: 0.5 | 50% + --black svg file of black variant + --black-insets alignment of black variant: top,left,bottom,right | auto + --black-stroke-width auto-generate black variant by scaling regular stroke-width: 2.0 | 200% + --legacy use the original, less precise alignment logic from earlier swiftdraw versions. ``` ```bash @@ -179,6 +181,21 @@ Alignment: --insets 40,30,40,30 Variants can also be aligned using `--ultralightInsets` and `--blackInsets`. +#### Auto-generated weight variants + +When matching ultralight or black SVGs are not available, SwiftDraw can synthesize them from the regular SVG by scaling every `stroke-width` value before strokes are expanded. Both decimal and percent forms are accepted: + +```bash +$ swiftdraw key.svg --format sfsymbol \ + --ultralight-stroke-width 50% \ + --black-stroke-width 2.0 +``` + +Notes: + - An explicit `--ultralight` or `--black` SVG always wins over the matching `--*-stroke-width` flag. A warning is printed if both are supplied. + - The scaler walks element attributes, inline styles, and ` + + + + + + diff --git a/SwiftDraw/Tests/Test.bundle/stroke-none.svg b/SwiftDraw/Tests/Test.bundle/stroke-none.svg new file mode 100644 index 0000000..24c363c --- /dev/null +++ b/SwiftDraw/Tests/Test.bundle/stroke-none.svg @@ -0,0 +1,4 @@ + + + + diff --git a/SwiftDraw/Tests/Test.bundle/stroke-stylesheet.svg b/SwiftDraw/Tests/Test.bundle/stroke-stylesheet.svg new file mode 100644 index 0000000..911a7d4 --- /dev/null +++ b/SwiftDraw/Tests/Test.bundle/stroke-stylesheet.svg @@ -0,0 +1,7 @@ + + + + +