Export template source from 488f7e229afed8f03fc3bfa4abe707da0c613460:examples/local-first/packages/language-reader-presentation
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
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;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user