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
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). 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).
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
ordmasculinein 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
python3 -m ttx_diff 'https://github.com/NaN-xyz/Rubik-Filtered?1126980434#glitchpop/sources/RubikGlitchPop.glyphs'Only the
glyftable differs:ordmasculinehas 423 points (fontc) vs 424 points (fontmake).The source curve
The cubic in question has four nearly-identical control points:
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 withabs() < 1e-15to zero (cu2qu.py:58-59). 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
ZeroDivisionErrorin 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).