Files
package-language-reader-pre…/src/canvas/measure.ts
T

26 lines
1.0 KiB
TypeScript

import type { Font, Measure } from "./types.js";
export const fontString = (font: Font) =>
`${font.italic ? "italic " : ""}${font.weight === "bold" ? "bold " : ""}${font.size}px ${font.family}`;
// A bounded per-surface cache replaces the original global memoizee cache.
// Font loading creates a new measure/layout so fallback metrics cannot persist.
export function canvasMeasure(context: CanvasRenderingContext2D, maximum = 12000): Measure {
const cache = new Map<string, ReturnType<Measure>>();
return (text, font) => {
const key = `${fontString(font)}/${text}`;
const cached = cache.get(key);
if (cached) return cached;
context.font = fontString(font);
const metrics = context.measureText(text);
const value = {
width: Math.max(0, metrics.width),
ascent: Math.max(metrics.actualBoundingBoxAscent || 0, font.size * 0.85),
descent: Math.max(metrics.actualBoundingBoxDescent || 0, font.size * 0.22),
};
if (cache.size >= maximum) cache.clear();
cache.set(key, value);
return value;
};
}