Add typography roles, text primitives, fontkit measurer and layout lint
Txt always sets an absolute line height; RenderTxt never does. Row pins every cell and stacks when the fill column would be too narrow. IdText and FitText shrink then chunk or truncate. The fontkit measurer matches react-pdf text widths exactly. A TypeScript-AST lint test enforces the layout rules (no lineHeight outside Txt, no non-literal fixed/wrap/minPresenceAhead, flexGrow needs flexBasis, no stray absolute positioning).
This commit is contained in:
@@ -1,17 +1,8 @@
|
||||
import { Font } from "@react-pdf/renderer";
|
||||
import { FONT_MANIFEST } from "./manifest";
|
||||
import { familySources } from "./stack";
|
||||
|
||||
/** Every stack ends here: Latin and the rupee sign from Plex, then the Indic scripts. */
|
||||
export const FONT_STACK: readonly string[] = [
|
||||
"IBM Plex Sans",
|
||||
"Noto Sans Devanagari",
|
||||
"Noto Sans Kannada",
|
||||
];
|
||||
|
||||
/** `[primary, ...tail]` without duplicates, for a style's fontFamily. */
|
||||
export function stack(primary: string): string[] {
|
||||
return [primary, ...FONT_STACK.filter((f) => f !== primary)];
|
||||
}
|
||||
export { FONT_STACK, familySources, stack, type FamilySource } from "./stack";
|
||||
|
||||
let registered = false;
|
||||
|
||||
@@ -28,23 +19,11 @@ export function registerBundledFonts(base: string): void {
|
||||
registered = true;
|
||||
|
||||
for (const fam of FONT_MANIFEST.families) {
|
||||
const sources: { src: string; fontWeight: number; fontStyle: "normal" | "italic" }[] = [];
|
||||
const weights = new Set<number>();
|
||||
for (const font of fam.fonts) {
|
||||
weights.add(font.weight);
|
||||
sources.push({
|
||||
src: `${base}/${fam.folder}/${font.file}`,
|
||||
fontWeight: font.weight,
|
||||
fontStyle: font.style,
|
||||
});
|
||||
}
|
||||
// react-pdf resolves every family in a fallback stack with the node's own style and throws for
|
||||
// a family that has no italic, so any weight without a real italic reuses its upright file.
|
||||
for (const weight of weights) {
|
||||
if (sources.some((s) => s.fontWeight === weight && s.fontStyle === "italic")) continue;
|
||||
const upright = sources.find((s) => s.fontWeight === weight && s.fontStyle === "normal");
|
||||
if (upright) sources.push({ ...upright, fontStyle: "italic" });
|
||||
}
|
||||
const sources = familySources(fam).map((s) => ({
|
||||
src: `${base}/${fam.folder}/${s.file}`,
|
||||
fontWeight: s.fontWeight,
|
||||
fontStyle: s.fontStyle,
|
||||
}));
|
||||
Font.register({ family: fam.family, fonts: sources });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user