/** * Google Fonts `css2` discovery: URL construction, `@font-face` parsing, and * the variant "closeness ladder". This is the single source of truth for logic * previously duplicated across pdf-export (node + browser), psd-import, and * svg-import. */ import { type UnicodeRange } from './unicode-range.js'; /** * One `@font-face` block: the file, and the `unicode-range` that gates it. * `ranges` is empty when the block named none, which means it covers every * codepoint — that is what css2 returns to a client it cannot subset for. */ export interface GoogleFontFace { url: string; ranges: ReadonlyArray; /** Variable font axis range, when the stylesheet declares one. */ weightRange?: readonly [number, number]; } /** * Map keyed by `","` (e.g. `"0,400"`) → the faces css2 * served for it, in stylesheet order. * * One weight maps to MANY faces, not one. css2 answers a browser with a file * per subset — 6 for Noto Sans Symbols 2, 32 for Noto Sans — and answers a * client whose `User-Agent` it does not know with a single unsubsetted file. * Keeping only one of them silently picked the last, which css2 orders `latin` * last: in the browser every non-Latin family resolved to its Latin subset, so * the export fetched a face and still drew the missing-glyph box. */ export type GoogleFontFaces = Map; export declare function googleFontUrl(family: string): string; /** The css2 URL without the axis spec (fallback for families that reject it). */ export declare function bareGoogleFontUrl(family: string): string; /** * The css2 URL for a single specific variant (e.g. weight 300 italic). * css2 responds 4xx when the family doesn't ship the variant — callers * treat that as "fall back to the family-level stylesheet". */ export declare function googleFontVariantUrl(family: string, italic: boolean, weight: number): string; /** * Parse a Google Fonts css2 stylesheet into a variant → faces map. One entry * per `@font-face` block that carries a resolvable `font-style`, `font-weight` * and `url(...)`, grouped by variant and kept in stylesheet order. */ export declare function parseGoogleFontFaces(css: string): GoogleFontFaces; /** * Pick the closest available variant URL for a requested (bold, italic) pair, * walking a closeness ladder over what Google actually shipped: * 1. exact (italic, weight) * 2. drop italic, keep weight * 3. keep italic, fall back to weight 400 * 4. plain 0,400 * 5. anything in the map * Returns `undefined` when the map is empty. */ export declare function pickVariant(faces: GoogleFontFaces, bold: boolean | number, italic: boolean, codePoints?: Iterable): string | undefined; /** CSS font matching: prefer the requested weight, then search in CSS order. */ export declare function pickFontWeight(weights: readonly number[], wanted: number): number | undefined;