Skip to content

sfnt: read the format 4 glyph id array from its real start - #54

Merged
timzifer merged 1 commit into
mainfrom
fix/sfnt-cmap4-range-offset
Sep 22, 2026
Merged

timzifer merged 1 commit into
mainfrom
fix/sfnt-cmap4-range-offset

Conversation

@timzifer

Copy link
Copy Markdown
Owner

The glyph id array of a format 4 cmap begins after the idRangeOffset array (16+4*segCountX2). read4 sliced it at 16+3*segCountX2 — the start of the offset array — while lookup measured from its end, so every code point in a range-offset segment read the id segCountX2 bytes early: a neighbour's glyph, or none. Delta segments were unaffected, and the test font only had those.

Impact with Noto Sans (the Fyne UI font): • drew as , in every embedded PDF, and 753 BMP code points (Romanian Ș/ț, much of Cyrillic Extended, combining marks) had no glyph. ToUnicode is built from the rune, so copied text still read correctly and hid it.

  • c.glyphIDs = t[16+4*c.segX2:]
  • sfnttest.Cmap4Ranged: a format 4 map with two range-offset segments, so the offset arithmetic is checked at two segment indices; TestTheCmapFormats/format 4 with range offsets is red before, green after.
  • Checked out of tree against golang.org/x/image/font/sfnt: every BMP code point of Noto Sans Regular, Bold and Italic now maps identically (was 753 mismatches).

🤖 Generated with Claude Code

The glyph id array of a format 4 cmap begins after the idRangeOffset
array, at 16+4*segCountX2. The reader sliced it at 16+3*segCountX2 - the
start of the offset array - while lookup measured from its end, so every
code point in a range-offset segment read the id segCountX2 bytes early,
a neighbour's glyph or none. Delta segments were unaffected, which is all
the test font had.

In Noto Sans that drew "•" as "," in every embedded PDF and left 753 BMP
code points (Romanian Ș/ț, much of Cyrillic Extended, the combining marks)
without a glyph. The PDF's ToUnicode map came from the rune, so copied
text still read correctly and hid it. Against x/image/font/sfnt the
lookup now agrees on every BMP code point of Noto Sans Regular, Bold and
Italic.

sfnttest.Cmap4Ranged is a format 4 map with two range-offset segments, so
the offset arithmetic is checked at two different segment indices.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@timzifer
timzifer merged commit 2796a67 into main Sep 22, 2026
18 checks passed
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