Fonts: a text is as tall as its font says

- New paragraph Height: the line height comes from the font, not
  from Pixi's sample string, so descenders are no longer cut.
- Known limits no longer says the frame of a text is estimated.
- Development counts 2067 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-13 15:19:01 +02:00
1 parent be766dcb3b
commit 43968b2708
2 files changed
+15 -5

No files matched your search

+1 -1
@@ -21,7 +21,7 @@ php tests/php/releases.test.php # the release stor
php tests/php/files.test.php # uploaded files in a folder per account (#344), the same way
php tests/php/videos.test.php # the video store, its queue and the worker (#402), with the
# real ffmpeg: the CI image and feuerwerk-video have it
node tools/seed-e2e.mjs && node tools/e2e.mjs # 2066 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 2067 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result
+14 -4
@@ -43,6 +43,14 @@ so a text of ten characters grows by nine times the value. Negative draws them c
how a design's tracking in em carries over: -0.03em at a font size of 216 is -6.5. The spacing
counts into the text's footprint, so selecting, picking and "Add collider" follow it.
**Height.** A text has no height row: it is as tall as the line box its face declares (the
browser's `fontBoundingBoxAscent` + `fontBoundingBoxDescent`, which is where the face says a
line begins and ends), each further line one Pixi line lower. Pixi on its own makes a line only
as tall as `|ÉqÅM` reaches and cuts off whatever reaches further: the tail of Manrope's "g" is
0.015em deeper than its "q" and was cut flat. Where Pixi's box is the taller one, it is kept. So
the height does not change with what is typed, and a glyph only loses ink if it reaches beyond
the face's own metrics. By Manrope's font file, a line is 1.366em instead of 1.25em.
**Filter.** A font asset has one row, **Filter**, the same as a texture's: **Linear** (the default)
draws the glyphs smooth and renders them again, sharper, as the view zooms in. **Nearest** is for
pixel fonts: the glyphs end up at one texel per world unit and are magnified without smoothing,
@@ -66,8 +74,10 @@ of "Regular" cannot then fight over one family, and the same bytes always resolv
face. The name *inside* the file is not read at all — the asset's name comes from the uploaded
file name and is yours to change.
**Known limits.** The selection box and the click area of a text are still estimated from the
character count (`bounds.ts`, `CHAR_WIDTH`), not measured, so a very wide or very narrow face
sits inside a box that does not quite fit it. Only text objects wear fonts; a sprite has no use
for one. There is no bold/italic pair: a font asset is one file, so a bold face is a second
**The frame is what is drawn.** The selection box, the click area in a running game and the
camera's framing take the size of the text's picture (`setTextMeasure` in `bounds.ts`, set by
`textPicture.ts`). Where nothing can measure — the unit tests in node — they fall back to an
estimate from the character count (`CHAR_WIDTH`, `LINE_HEIGHT`).
**Known limits.** Only text objects wear fonts; a sprite has no use for one. There is no bold/italic pair: a font asset is one file, so a bold face is a second
asset.