Visitar URL original
Fix axis mapping edge cases and glyph-swap component references by black7375 · Pull Request #1164 · googlefonts/glyphsLib · GitHub
Skip to content

Fix axis mapping edge cases and glyph-swap component references - #1164

Open
black7375 wants to merge 1 commit into
googlefonts:mainfrom
black7375:fix/glyphs-conversion-edge-cases
Open

black7375 wants to merge 1 commit into
googlefonts:mainfrom
black7375:fix/glyphs-conversion-edge-cases

Conversation

@black7375

@black7375 black7375 commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fix axis-mapping and glyph-swap edge cases encountered when converting Glyphs sources through glyphsLib and fontmake.

This PR now builds on the instance-mapping fixes in #1197. It retains upstream's mapping selection, endpoint extrapolation, trimming, and 16.16 rounding instead of adding a second implementation.

Changes

  • Preserve an interpolated default master as an explicit knot in the Axis Mappings custom parameter, without extending the declared mapping bounds.
  • Use AxisDescriptor.map_backward() for axis-default lookup and upstream's new interpolation helper, preserving both endpoints of flat segments.
  • Reject decreasing design-coordinate mappings before trimming or fallback can hide them.
  • Require fontTools 4.63.0 for its flat-segment-aware reverse mapping.
  • Update component references when swapping glyph contents, retaining the existing Unicode assignments and upstream's missing-glyph handling.
  • Update variable-feature expectations for numerically equivalent float output.
  • Remove the obsolete Lexend-Arabic expected-output override; compare against upstream output directly while retaining default-source assertions.

Design rationale

Preserve explicit defaults without reinterpreting the source

Designspace axis defaults use user coordinates, while source locations use design coordinates. The mapped default must therefore match the default source's location. See the Designspace axis documentation and fontTools default-source lookup.

An interpolated user-space default can be rounded during XML serialization and then map back to a slightly different design coordinate. Adding an explicit knot preserves its correspondence to the master through serialization. fontTools also requires mapping knots for the axis minimum, maximum, and default when building avar; this is a fontTools build requirement, not a UFO constraint.

Upstream already inserts inferred default knots. The additional handling here covers explicit Axis Mappings and only inserts a missing default strictly inside the existing user-coordinate range. Existing knots and bounds remain unchanged. In particular, it does not flip mappings, infer their direction from the Glyphs file version, or extend explicit bounds to conceal the out-of-range sources discussed in #993.

Preserve flat segments throughout upstream's new mapping pipeline

The OpenType avar specification permits equal consecutive output coordinates: flat segments are valid. Its output coordinates must not decrease. This PR applies nondecreasing validation as a conversion policy before trimming or fallback; it does not claim that UFO defines axis-mapping constraints.

Inverting a mapping into a dictionary loses one endpoint when multiple user coordinates share a design coordinate. This also affects upstream's new helper used for default interpolation and trimming. For example, with 100→100, 300→400, 400→400, 900→900, design coordinate 350 corresponds to user coordinate approximately 266.666667, not 350.

fontTools 4.63.0 includes fonttools/fonttools#4085, which preserves both endpoints during reverse mapping. The dependency bump makes that corrected implementation available everywhere this PR uses it, while retaining upstream's 16.16 rounding. Output such as 400.0 instead of 400 is numerically equivalent and is not a new formatting requirement.

Preserve component relationships during glyph swaps

UFO GLIF components reference base glyphs by name within the same layer and must not create circular references. Swapping only glyph contents can turn an existing reference into a self-reference: for example, when a.alt contains a component referencing a.

Swapping the corresponding component references along with the contents preserves the existing component relationships. Unicode assignments remain attached to the original names. This is the rationale for the component-reference update, not a claim that the UFO specification defines Glyphs.app's complete Rename Glyphs semantics.

@black7375
black7375 force-pushed the fix/glyphs-conversion-edge-cases branch 2 times, most recently from 0686366 to 1ade42d Compare September 8, 2026 16:12
@black7375
black7375 force-pushed the fix/glyphs-conversion-edge-cases branch from 1ade42d to c325c84 Compare October 10, 2026 15:42
@black7375 black7375 changed the title Fix Glyphs conversion edge cases Fix axis mapping edge cases and glyph-swap component references Oct 10, 2026

This branch has not been deployed

No deployments
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.

1 participant