Skip to content

The bitmap font counts runes, and the ellipsis has a glyph - #461

Merged
tannevaled merged 1 commit into
mainfrom
bitmap-counts-runes
Sep 7, 2026
Merged

The bitmap font counts runes, and the ellipsis has a glyph#461
tannevaled merged 1 commit into
mainfrom
bitmap-counts-runes

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Measure did len(text), and its own doc line has always said "every rune (known or unknown) consumes exactly one Advance slot". Draw walked bytes too, indexing the glyph table by byte. So everything outside ASCII was measured two or three times too wide, and drawn as two or three blanks in a row — pushing the rest of the line along by that much.

Measured at Advance 6, before:

"e" 6 "é" 12 "€" 18 "…" 18
"abc" 18 "àbc" 24

⭐ And it explains a rule in another repository

go-xrkit/desk forbids apostrophes in its settings window because "the glasses' own menu bar" came out with a hole in it. The hole was three cells wide: a curly apostrophe is three bytes, so Draw walked three of them and found no glyph for any.

⛔ And the ellipsis could not have a glyph at all

font5x7 was keyed by byte, so no key above 127 could exist — including U+2026, which ellipsize() appends. Ellipsis=true therefore shortened the text and drew nothing in its place: on screen, indistinguishable from text clipped by its bounds.

The table is keyed by rune now (its literals were rune constants already, so the table itself did not change) and carries three dots on the baseline.

The ellipsis test was passing for the wrong reason

Its own comment said so:

"With the bitmap font the ellipsis is 3 bytes (18px) … so the widest prefix p with (len(p)+3)*6 <= 60 is 7 bytes"

The byte count was written into the test as though it were the rule. It now expects nine runes, and asserts that the last cell is inked — which is what distinguishes an ellipsis from a clip.

Its "narrower than the full render" check is gone: the full render is clipped by the bounds, so its width is wherever its last surviving glyph stops, and an ellipsised line can legitimately paint further right.

Proved by sabotage

Restoring len(text) fails both new tests and the ellipsis test, naming the byte counts:

Measure("é") = 12, want 6 (1 cell(s) of 6): 2 bytes were counted instead of 1 runes
the truncated render stops at 47 in a 60-wide box: nothing was painted in the
last cell, so the ellipsis was appended but never drawn

🤖 Generated with Claude Code

Measure did len(text), and its own doc line has always said "every rune
(known or unknown) consumes exactly one Advance slot". Draw walked bytes
too, indexing the glyph table by byte. So everything outside ASCII was
measured two or three times too wide and drawn as two or three blanks in a
row, pushing the rest of the line along by that much.

Measured at Advance 6, before:

  "e"   6      "é"   12     "€"   18     "…"   18
  "abc" 18     "àbc" 24

⭐ AND IT EXPLAINS A RULE IN ANOTHER REPOSITORY. go-xrkit/desk forbids
apostrophes in its settings window because "the glasses' own menu bar" came
out with a hole in it. The hole was THREE cells wide: a curly apostrophe is
three bytes, so Draw walked three of them and found no glyph for any.

⛔ AND THE ELLIPSIS COULD NOT HAVE A GLYPH AT ALL. font5x7 was keyed by
BYTE, so no key above 127 could exist -- including U+2026, which ellipsize()
appends. Ellipsis=true therefore shortened the text and drew NOTHING in its
place: on screen, indistinguishable from text clipped by its bounds. The
table is keyed by rune now (its literals were rune constants already, so it
did not change) and carries three dots on the baseline.

TestLabelEllipsis was passing for the wrong reason, and its own comment said
so: "the ellipsis is 3 bytes (18px) ... the widest prefix is 7 bytes". The
byte count was written into the test as though it were the rule. It now
expects nine runes, and asserts that the last cell is INKED -- which is what
distinguishes an ellipsis from a clip. Its "narrower than the full render"
check is gone: the full render is clipped by the bounds, so its width is
wherever its last surviving glyph stops, and an ellipsised line can
legitimately paint further right.

Proved by sabotage: restoring len(text) fails both new tests and the
ellipsis test, naming the byte counts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 08baca5 into main Sep 7, 2026
1 check passed
@tannevaled
tannevaled deleted the bitmap-counts-runes branch September 7, 2026 16:45
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