Skip to content

Normalize SF Symbol variant paths for interpolation compatibility#123

Merged
swhitty merged 1 commit into
swhitty:mainfrom
rursache:fix/57-sfsymbol-interpolation
Apr 22, 2026
Merged

Normalize SF Symbol variant paths for interpolation compatibility#123
swhitty merged 1 commit into
swhitty:mainfrom
rursache:fix/57-sfsymbol-interpolation

Conversation

@rursache
Copy link
Copy Markdown
Contributor

Summary

  • Fixes "the provided variants are not interpolatable" error when generating SF Symbols with separate weight variant SVGs
  • Root cause: source SVGs (e.g. from Apple's CoreSVG) can have incompatible path structures between weights - one variant may have a cubic curve (rounded corner) where another has a line (sharp corner), producing different segment counts
  • Adds two-phase path normalization after variant generation:
    1. Segment count alignment: inserts degenerate zero-length cubics in shorter variants to match the longest
    2. Type promotion: promotes L (line) to degenerate C (cubic) where types differ at the same position

Example (from the reported issue):

Before fix:

  • Ultralight Path 1: 27 segments (14 cubics)
  • Regular Path 1: 26 segments (13 cubics)
  • Black Path 1: 26 segments (13 cubics)

After fix:

  • All variants: 27 segments (14 cubics) with matching command sequences

Test plan

  • Added testNormalizeSegments_PromotesLineToCubic - verifies L→C promotion
  • Added testNormalizeSegments_InsertsDegenerate - verifies alignment with extra segments
  • Added testNormalizeSegments_AlreadyMatching - verifies no-op when paths match
  • Added testCommandType and testPromoteToCubic unit tests for helpers
  • Verified with reporter's photo.error SVGs - all 3 variants produce matching segment sequences
  • All 193+ tests pass, existing key.svg symbol test unaffected

Closes #57

When generating SF Symbols with separate weight variants (ultralight,
regular, black), the source SVGs can have incompatible path structures -
different segment counts or types (e.g. a cubic curve in one weight
where another has a straight line). SF Symbols requires identical
path structures across all variants for interpolation.

This fix adds a two-phase normalization after variant paths are generated:

1. Segment count alignment: When one variant has an extra segment
   (e.g. a rounded corner as cubic where others have a sharp corner),
   degenerate zero-length cubic segments are inserted in the shorter
   variants to match the longest.

2. Type promotion: When variants have the same number of segments but
   different types at a position (line vs cubic), lines are promoted
   to degenerate cubic curves with control points along the line.

Closes #57
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 22, 2026

Codecov Report

❌ Patch coverage is 93.88646% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.46%. Comparing base (6238058) to head (280336c).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
SwiftDraw/Sources/Renderer/Renderer.SFSymbol.swift 90.62% 12 Missing ⚠️
...ftDraw/Tests/Renderer/Renderer.SFSymbolTests.swift 98.01% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #123      +/-   ##
==========================================
+ Coverage   89.02%   89.46%   +0.44%     
==========================================
  Files         159      159              
  Lines       11959    15618    +3659     
==========================================
+ Hits        10646    13973    +3327     
- Misses       1313     1645     +332     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Owner

@swhitty swhitty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow thank you for this

@swhitty swhitty merged commit 8f03233 into swhitty:main Apr 22, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

the provided variants are not interpolatable

2 participants