Skip to content

fix(font): skip the glyphs the shaper marks invisible - #170

Merged
tannevaled merged 1 commit into
mainfrom
feat/honour-invisible-glyphs
Aug 8, 2026
Merged

fix(font): skip the glyphs the shaper marks invisible#170
tannevaled merged 1 commit into
mainfrom
feat/honour-invisible-glyphs

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

The bug

Measure and Draw disagreed about default-ignorable characters. Measure summed every shaped advance; Draw skipped only .notdef.

A word joiner therefore reserved a full advance of empty space in the middle of a word, and a soft hyphen — which Go Regular maps to a real hyphen glyph — drew a visible dash mid-word.

The fix

go-opentype/shape v0.4.0 now zeroes and flags those leftovers (Glyph.Invisible), which fixes the width. This PR honours the flag when painting.

That second half matters: without it a mapped ignorable would still stamp its glyph, now at zero advance, straight on top of the following letter — strictly worse than before the shape fix.

invisible(g) names the rule (.notdef or shaper-hidden) so Draw and any future back-end apply the same one.

Verification

  • go test -race100.0% of statements, race-clean.
  • Asserted on pixels: six ignorables (U+00AD, U+2060, U+200B, U+200D, U+FEFF, U+FE0F) placed inside a word leave the measured width and every byte of the surface identical.

🤖 Generated with Claude Code

Measure and Draw disagreed about default-ignorable characters. Measure summed
every shaped advance; Draw skipped only .notdef. A word joiner therefore
reserved a full advance of empty space in the middle of a word, and a soft
hyphen — which Go Regular maps to a real hyphen glyph — drew a visible dash
mid-word.

go-opentype/shape v0.4.0 now zeroes and flags those leftovers (Glyph.Invisible),
which fixes the width. This honours the flag when painting: without it a mapped
ignorable would still stamp its glyph, now at zero advance, straight on top of
the following letter — strictly worse than before.

invisible(g) names the rule (.notdef or shaper-hidden) so Draw and any future
back-end apply the same one.

100% coverage held; race-clean. Asserted on pixels: six ignorables inside a word
leave the measured width and every byte of the surface identical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit d5176d1 into main Aug 8, 2026
1 check passed
@tannevaled
tannevaled deleted the feat/honour-invisible-glyphs branch August 8, 2026 20:27
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