Skip to content

Load each glyph-fallback face once per font system - #558

Merged
Velli20 merged 1 commit into
mainfrom
cache-glyph-fallback-faces
Oct 11, 2026
Merged

Velli20 merged 1 commit into
mainfrom
cache-glyph-fallback-faces

Conversation

@Velli20

@Velli20 Velli20 commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Summary

A character missing from a run's font loaded every fallback candidate anew, and the only cache (FallbackCache) lived for a single text run. Each load built a fresh face with a new FontFaceId, so the canvas glyph outline cache missed too. With the Foxit CFF substitutes, whose loading parses every private dictionary and builds a charmap from the whole charset, pages whose text falls back took over 10× longer to interpret, on every redraw in the Skia viewer.

FontSystem now keeps the faces it loads for in-memory fallback programs, keyed by buffer address, length, format and face index. It holds each source so its buffer cannot be freed and its address reused.

Measurements

Page interpretation (record_ms, conformance worker, regression profile) for a text-heavy document whose embedded TrueType subsets fall back:

page A page B
before 97 ms 116 ms
after 5 ms 6 ms

Bisecting merges showed 7–9 ms up to #555, rising to ~125 ms at #556. Rendered output is byte-identical before and after.

Test plan

  • cargo fmt --check, cargo clippy --all --workspace
  • cargo test -p pdf-text-engine -p pdf-font -p pdf-canvas -p pdf-renderer
  • Rendered pages compared byte for byte before and after

🤖 Generated with Claude Code

A character missing from a run's font loaded every fallback candidate
anew, and the only cache lived for a single text run. Each load built a
fresh face with a new id, so the canvas glyph cache missed as well. With
the Foxit CFF substitutes, whose loading parses every private dictionary
and builds a charmap from the whole charset, text-heavy pages that fall
back took over ten times longer to interpret, on every redraw.

FontSystem now keeps the faces it loads for in-memory fallback programs,
keyed by buffer address, length, format and face index, and holds each
source so its buffer cannot be freed and its address reused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Velli20
Velli20 merged commit 6ecb89e into main Oct 11, 2026
10 checks passed
@Velli20
Velli20 deleted the cache-glyph-fallback-faces branch October 11, 2026 11:33
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