googlefonts / googlefonts/fontc
subtle cu2qu rounding issue
- Dominant language
- Rust
- Stars
- 193
- Forks
- 21
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 60
Description
this is ultimately meaningless, but wanted to open an issue to at least track.
## cu2qu epsilon causes extra point for near-degenerate cubics
### Summary
fontc produces 1 fewer point than fontmake for the glyph `ordmasculine` in RubikGlitchPop. The difference comes from cubic-to-quadratic conversion of a nearly degenerate cubic where all four control points are within ~0.05 design units and round to the same integer coordinate.
### Reproduction
```bash
python3 -m ttx_diff 'https://github.com/NaN-xyz/Rubik-Filtered?1126980434#glitchpop/sources/RubikGlitchPop.glyphs'
```
Only the `glyf` table differs: `ordmasculine` has 423 points (fontc) vs 424 points (fontmake).
### The source curve
The cubic in question has four nearly-identical control points:
```
p0 = (234.740, 471.556)
p1 = (234.742, 471.574)
p2 = (234.744, 471.592)
p3 = (234.746, 471.610)
```
All round to `(235, 472)`. The lines p0-p1 and p2-p3 are nearly parallel, producing a cross product of ~5e-16.
### What happens
cu2qu's `dot()` function clamps values with `abs() < 1e-15` to zero ([cu2qu.py:58-59](https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/cu2qu/cu2qu.py#L58-L59)). This was added to ensure consistent results between pure Python and Cython runtimes, where IEEE-754 rounding can differ slightly for perpendicular vectors.
For this curve, the ~5e-16 cross product gets clamped to zero, causing a `ZeroDivisionError` in the crossing-point calculation. The n=1 quadratic approximation fails and falls through to n=2, producing 2 quadratic segments (an extra off-curve point) instead of 1.
kurbo (used by fontc) has no such epsilon — the ~5e-16 cross product is treated as non-zero, a valid crossing point is found, and 1 quadratic segment is produced.
### Impact
The difference is purely cosmetic. Both outputs render identically — all points are at the same integer coordinate `(235, 472)`. fontc's output is marginally better (1 fewer point).
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.