Fix glyph cache poisoning across renders; add CLAUDE.md and handoff.md

fontkit caches glyphs per font for the whole process and pdfkit embeds composite
components with no code points, so setting ':' before '.' in Poppins corrupted every
later render in the same process (text layer showed '1,200;00', line breaks shifted).
primeFontGlyphs() now creates the component glyphs with their cmap code point at font
registration, awaited by renderCore and browser init. Regression test and Quirk 13 added;
the warm-up workarounds in the template tests are removed.
This commit is contained in:
2026-10-04 13:11:40 +05:30
parent 579508742f
commit 8a6b1ee32a
9 changed files with 308 additions and 25 deletions
@@ -1,17 +1,8 @@
import { beforeAll, expect, it } from "vitest";
import { prefsFor, renderFixture } from "./harness";
import { expect, it } from "vitest";
import { describeSweep, STANDALONE_SWEEP } from "./harness.sweep";
import { TEMPLATES } from "./registry";
// Monolith, Cobalt Stripe, Marble and Highlighter: the same sweep as the other templates, in a second file so the two run side by side.
//
// Poppins Regular is warmed with a document that has amounts first. fontkit caches glyph objects per font for the process and
// pdfkit creates a composite's components (the period inside Poppins' colon) at embed time with no code points: Monolith, which
// sets ':' in Poppins Regular but amounts in Medium, would leave the period unextractable for Highlighter's amounts
// (src/pdf/quirks.test.tsx, quirk 13).
beforeAll(async () => {
await renderFixture({ name: "warm-up", items: 3 }, prefsFor("A4", { templateId: "highlighter" }));
});
describeSweep((id) => STANDALONE_SWEEP.includes(id));