/** * Browser-portable font substitution policy shared by production export and * the visual-parity harness. Keep filesystem and fontconfig probes out of this * module so `docxodus/export-browser` remains safe to bundle for browsers. */ export declare const FONT_SUBSTITUTION_CONTRACT_VERSION: 1; export declare const FONT_RESOLVER_SCHEMA_VERSION: 1; export declare const FONT_RESOLVER_CONTRACT_ID: "https://docxodus.dev/contracts/font-resolver/v1"; export interface FontSubstitutionEntry { /** Family declared by the source document. */ family: string; /** License-safe configured family selected when an exact family is absent. */ substitute: string; /** Whether the substitute is designed to preserve the source family's metrics. */ metricCompatible: boolean; } /** NFC and whitespace normalization used before deterministic family matching. */ export declare function normalizeFontFamilyName(value: string): string; /** Locale-independent case-insensitive lookup key for a normalized family. */ export declare function fontFamilyKey(value: string): string; export declare const FONT_SUBSTITUTION_CONTRACT: ReadonlyArray>; /** Canonical path-free material both resolver sides hash for contract drift detection. */ export declare const FONT_SUBSTITUTION_CONTRACT_MATERIAL: Readonly<{ schemaVersion: 1; entries: readonly Readonly[]; }>; export type FontFaceStyle = "normal" | "italic" | "oblique"; export type FontFamilyKind = "named" | "generic"; export type FontFileFormat = "ttf" | "otf" | "woff" | "woff2"; export type FontMediaType = "font/ttf" | "font/otf" | "font/woff" | "font/woff2"; export type FontResolutionStatus = "resolved" | "substituted" | "missing" | "load_failed" | "unverified"; export type FontResolutionSource = "browser" | "configured" | "attested"; export type FontFaceMatch = "exact" | "synthesized"; export type FontGlyphCoverage = "complete" | "partial" | "unverified"; export type FontEmbeddingKind = "installable" | "previewPrint" | "editable" | "attested"; /** A deterministic, text-free description of one computed CSS face request. */ export interface FontRequest { id: string; familyStack: readonly string[]; /** One syntax classification per family; quoted generic words remain named families. */ familyKinds: readonly FontFamilyKind[]; style: FontFaceStyle; weight: number; /** CSS font-stretch as a percentage, where 100 is normal width. */ stretch: number; /** Sorted, distinct Unicode scalar values sampled from nodes using this face. */ sampleCodePoints: readonly number[]; } export interface FontResolverRequest { schemaVersion: typeof FONT_RESOLVER_SCHEMA_VERSION; requests: readonly FontRequest[]; } export interface FontLicenseEvidence { kind: FontEmbeddingKind; /** Canonical digest of path-free OS/2 or caller-attested evidence. */ identity: string; noSubsetting: boolean; } /** Immutable configured bytes and metadata returned to the browser coordinator. */ export interface FontResolverFace { id: string; resolvedFamily: string; postscriptName?: string; version: string; style: FontFaceStyle; weight: number; stretch: number; format: FontFileFormat; mediaType: FontMediaType; byteLength: number; sha256: string; /** Canonical RFC 4648 padded base64. The browser constructs the data URL. */ bytesBase64: string; licenseEvidence: FontLicenseEvidence; } export interface FontResolverOutcome { requestId: string; status: Exclude; faceId?: string; requestedFamily?: string; resolvedFamily?: string; metricCompatible?: boolean; faceMatch?: FontFaceMatch; glyphCoverage?: FontGlyphCoverage; missingCodePoints?: readonly number[]; } export interface FontResolverResponse { schemaVersion: typeof FONT_RESOLVER_SCHEMA_VERSION; resolverContract: typeof FONT_RESOLVER_CONTRACT_ID; substitutionContractVersion: typeof FONT_SUBSTITUTION_CONTRACT_VERSION; substitutionContractDigest: string; outcomes: readonly FontResolverOutcome[]; faces: readonly FontResolverFace[]; } /** * Trusted caller policy authority for face selection, license evidence, and * declared glyph coverage. Docxodus validates its schema, byte digest, and * browser loadability, but cannot independently prove those policy claims. */ export type FontResolver = (request: FontResolverRequest, signal: AbortSignal) => Promise; /** Path- and byte-free evidence retained in render reports and fingerprints. */ export interface FontResolution { requestId: string; requestedFamily: string; requestedFamilies: readonly string[]; requestedFamilyKinds: readonly FontFamilyKind[]; requestedStyle: FontFaceStyle; requestedWeight: number; requestedStretch: number; sampleCodePointCount: number; sampleDigest: string; resolvedFamily?: string; resolvedFace?: string; status: FontResolutionStatus; source: FontResolutionSource; format?: FontFileFormat; fileSha256?: string; version?: string; faceMatch?: FontFaceMatch; metricCompatible?: boolean; glyphCoverage?: FontGlyphCoverage; missingCodePointCount?: number; /** Whether Chromium can paint some fallback despite an authoritative resolver miss. */ browserFallbackAvailable?: boolean; licenseEvidence?: FontLicenseEvidence; /** The Font Loading API's own reason, present only when `status` is `load_failed`. */ loadFailureDetail?: string; /** * An exact, digest-identified, license-evidenced face with complete glyph coverage that * actually loaded — the single question `strictFonts` gates on. Computed once at the source * that has every raw signal in scope, so a direct reader of the render report never has to * separately remember that `fileSha256`/`faceMatch`/`glyphCoverage` describe the *selected* * face and say nothing on their own about whether it loaded (see `status`). */ verified: boolean; } export interface FontConfigurationIdentity { resolverContract: typeof FONT_RESOLVER_CONTRACT_ID; substitutionContractVersion: typeof FONT_SUBSTITUTION_CONTRACT_VERSION; substitutionContractDigest: string; resolutionDigest: string; /** * Present only when a resolver was configured: a digest of the resolver's own response, * excluding browser-observed load outcomes. Lets the cross-attempt drift check compare what * the resolver actually answered, rather than `resolutionDigest`, which also reflects * whether each face happened to decode in the browser this particular attempt. */ resolverDigest?: string; } //# sourceMappingURL=font-contract.d.ts.map