From 43968b27082aa84566f87e4bc2872a10763f3a44 Mon Sep 17 00:00:00 2001 From: MelekTaus Date: Tue, 13 Oct 2026 15:19:01 +0200 Subject: [PATCH] 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 --- Development.md | 2 +- Fonts.md | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Development.md b/Development.md index be98607..9b022fe 100644 --- a/Development.md +++ b/Development.md @@ -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 diff --git a/Fonts.md b/Fonts.md index 5d14670..54943d3 100644 --- a/Fonts.md +++ b/Fonts.md @@ -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.