From b059da2d4e52ad40a9cb54f8de6e65d08308f737 Mon Sep 17 00:00:00 2001 From: Martin Ball Date: Fri, 23 Oct 2026 11:09:43 +0100 Subject: [PATCH] =?UTF-8?q?#3692:=20review=20=E2=80=94=20docs:=20why=20the?= =?UTF-8?q?=20hinting=20breaker=20is=20timed,=20and=20what=20brotli-decomp?= =?UTF-8?q?ressor=20brings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hinting breaker stays wall-clock: skrifa's interpreter budget is fixed, counts instructions rather than the points each one moves, and reports no work count, so there is nothing deterministic to bound. The comment now says the result can depend on the machine by design, and that only faces needing the interpreter for their contours are hinted at all. Cargo.toml notes that brotli-decompressor is the crate and version wuff already uses: pure Rust, forbid(unsafe_code) by default, wasm-ready, BSD-3-Clause/MIT. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01CX1hMKX28764Lrx5moxs1o --- Cargo.toml | 2 ++ crates/fonts/src/fontdb.rs | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6bdbf2ef9..ee319c50a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,8 @@ harfrust = "0.13" # (brotli-decompressor, flate2) are already in the tree. wuff = "0.2.9" # WOFF2's brotli stream, decoded ahead of wuff so its glyph point counts are checked first (#3703). +# The same crate and version wuff already decodes it with (no new code in the build): pure Rust, +# `forbid(unsafe_code)` in its default build, no_std-capable (builds for wasm), BSD-3-Clause/MIT. brotli-decompressor = "5" vello_cpu = "0.2" image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp", "gif", "bmp", "tiff"] } diff --git a/crates/fonts/src/fontdb.rs b/crates/fonts/src/fontdb.rs index 931655903..7da5d927c 100644 --- a/crates/fonts/src/fontdb.rs +++ b/crates/fonts/src/fontdb.rs @@ -110,8 +110,15 @@ const MAX_HINT_GLYPH_BYTES: usize = 256 * 1024; /// still take seconds for one glyph, so [`MIN_HINT_STRIKES`] strikes that are also at least one /// in [`HINT_SLOW_RATIO`] of its hinted draws turn hinting off: a face that is slow throughout /// stops after a few glyphs, while the odd draw slowed by a busy machine leaves a face hinted. -/// ponytail: wall-clock, not interpreter work (skrifa has no work bound yet, #3827). Native only -/// (no clock on wasm). +/// +/// Wall-clock, not interpreter work: skrifa's own budget (a million instructions a program, not +/// settable) counts instructions, not the points each one moves, and it exposes no count of the +/// work done, so time is the only measure there is (#3827). Whether such a face stays hinted can +/// therefore depend on the machine, by design: only faces that need the interpreter to assemble +/// their contours (legacy CJK fonts such as DFKai-SB) are hinted at all, and those typically hint +/// a glyph in microseconds, so 50 ms is far above an honest face on a loaded machine; a face +/// that trips it is drawn unhinted (its outlines possibly misassembled) rather than freezing the +/// app. Native only (no clock on wasm). #[cfg(not(target_arch = "wasm32"))] const HINT_STRIKE: std::time::Duration = std::time::Duration::from_millis(50); #[cfg(not(target_arch = "wasm32"))]