Skip to content

[fontdrasil] Fix many-to-one axis map handling#1995

Merged
anthrotype merged 3 commits intomainfrom
fix-many-to-one-axis-map
May 1, 2026
Merged

[fontdrasil] Fix many-to-one axis map handling#1995
anthrotype merged 3 commits intomainfrom
fix-many-to-one-axis-map

Conversation

@anthrotype
Copy link
Copy Markdown
Member

@anthrotype anthrotype commented May 1, 2026

This is the companion to fonttools/fonttools#4085.

Fixes the remaining ttx_diff discrepancy on SUSE-Italic at 7159afb255 reported in googlefonts/ufo2ft#978

"output is identical" in ttx-diff after updated fonttools is installed in the fontc .venv.


PiecewiseLinearMap::map() uses binary_search, which returns an arbitrary/unspecified index when there are multiple matches:

https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search

When a many-to-one forward map (e.g. user=900 -> design=1000 and user=1000 -> design=1000) is reversed, the value returned from binary_search can differ from fontmake's (which takes the first match).

I changed it to use partition_point to always find the first occurrence.

After fixing this I found a second related issue: to_ir_axis derived fvar axis min/default/max by round-tripping design coords through design_to_user, which is lossy for many-to-one maps.

Changed it to take min/max directly from the user-space values in the mapping, matching glyphsLib's approach.

(I will release a patched fonttools soon and bump fontc requirements after)

anthrotype added 3 commits May 1, 2026 16:43
When the map is reversed (e.g. design-to-user), a many-to-one forward
map produces duplicate keys. binary_search may return any matching
index for duplicates, so use partition_point to always find the first
occurrence.

googlefonts/ufo2ft#978
Instead of round-tripping design coords through design_to_user (which
is lossy for many-to-one axis maps), read the user-space values
directly from the mapping entries. This matches glyphsLib's approach.

googlefonts/ufo2ft#978
@anthrotype anthrotype force-pushed the fix-many-to-one-axis-map branch from ab4e47e to e76d106 Compare May 1, 2026 15:44
@anthrotype
Copy link
Copy Markdown
Member Author

https://github.com/googlefonts/fontc/actions/runs/25220991765/job/73952882058?pr=1995#step:4:195

thread 'piecewise_linear_map::tests::many_to_one_reverse' (3210) panicked at fontdrasil/src/piecewise_linear_map.rs:151:9:
assertion `left == right` failed
  left: 1000.0
 right: 900.0

Copy link
Copy Markdown
Member

@cmyr cmyr left a comment

Choose a reason for hiding this comment

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

nice!

@anthrotype anthrotype added this pull request to the merge queue May 1, 2026
Merged via the queue into main with commit 911eb9e May 1, 2026
13 checks passed
@anthrotype anthrotype deleted the fix-many-to-one-axis-map branch May 1, 2026 16:14
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.

2 participants