import type { PdfAnnotationSpec } from './types.js'; /** RGBA image used for one rasterized emoji run in a FreeText appearance. */ export interface PdfEmojiImage { readonly width: number; readonly height: number; readonly scale: number; readonly pixels: Uint8Array; /** Logical advance in PDF points. Defaults to `width / scale`. */ readonly advance?: number; } /** Loads an encoded emoji asset for one complete grapheme cluster. */ export interface PdfEmojiAssetSource { /** * Loads the encoded image bytes for a grapheme. * * @param grapheme - The complete Unicode grapheme cluster to load. * @param signal - An optional abort signal for cancelling the load. * @returns The encoded image bytes, or `null` when no asset is available. */ load(grapheme: string, signal?: AbortSignal): Promise; } /** Cache shared by downloadable text-appearance assets. */ export interface PdfTextAssetCache { /** * Reads an asset without exposing the cache's mutable backing storage. * * @param key - The stable asset key. * @returns A copy of the cached bytes, or `null` on a cache miss. */ get(key: string): Promise; /** * Stores a copy of an asset. * * @param key - The stable asset key. * @param data - The bytes to cache. * @returns A promise that resolves after the write completes. */ put(key: string, data: Uint8Array): Promise; } /** Rasterizes one complete emoji grapheme for a FreeText appearance. */ export type PdfEmojiRenderer = (grapheme: string, fontSize: number, signal?: AbortSignal) => Promise | PdfEmojiImage | null; /** Measures a text run in PDF points. */ export type PdfTextMeasureProvider = (text: string, fontSize: number, fontFace: string | null) => number; /** Registers or resolves the font used for one PDFium Windows charset. */ export type PdfFreeTextFontResolver = (charset: number) => Promise | string | null; /** Services used by {@link prepareFreeTextAppearance}. */ export interface PdfTextAppearanceServices { /** Text measurement. The default is a deterministic approximation suitable for headless runtimes. */ measureText?: PdfTextMeasureProvider; /** Script-specific font registration. Omit it to let PDFium use its default font. */ resolveFont?: PdfFreeTextFontResolver; /** Emoji rasterization. The default uses native browser emoji, then a downloadable Noto PNG. */ renderEmoji?: PdfEmojiRenderer | null; } /** Options for {@link prepareFreeTextAppearance}. */ export interface PdfFreeTextAppearanceOptions { /** * BCP-47 language hint(s), used mainly to disambiguate Han-only text. * * Kana and Hangul already identify Japanese and Korean, so a hint is * normally unnecessary for them. In a browser, `navigator.languages` and * `navigator.language` are consulted automatically after explicit hints. * Server integrations should pass the document language, the signed-in * user's locale, or a parsed `Accept-Language` preference. The first * applicable `ja`, `ko`, or `zh` hint wins. * */ language?: string | readonly string[]; services?: PdfTextAppearanceServices; signal?: AbortSignal; } /** Options for {@link createNotoEmojiPngSource}. */ export interface PdfNotoEmojiSourceOptions { /** * Directory containing Noto's `emoji_u.png` files. * Defaults to a version-pinned jsDelivr URL; point this at a local mirror for * offline or restricted environments. * */ baseUrl?: string; cache?: PdfTextAssetCache; } /** Options for {@link createDefaultEmojiRenderer}. */ export interface PdfDefaultEmojiRendererOptions extends PdfNotoEmojiSourceOptions { source?: PdfEmojiAssetSource; /** Raster scale for native browser emoji. Default `3`. */ scale?: number; } export declare const defaultNotoEmojiPngBaseUrl = "https://cdn.jsdelivr.net/gh/googlefonts/noto-emoji@8998f5dd683424a73e2314a8c1f1e359c19e8742/png/128/"; /** Simple process-local byte cache. */ export declare class PdfMemoryTextAssetCache implements PdfTextAssetCache { #private; /** @inheritdoc */ get(key: string): Promise; /** @inheritdoc */ put(key: string, data: Uint8Array): Promise; } /** Browser IndexedDB cache for downloaded text-appearance assets. */ export declare class PdfIndexedDbTextAssetCache implements PdfTextAssetCache { #private; /** * Creates a cache backed by a browser IndexedDB database. * * @param databaseName - The IndexedDB database name. Defaults to `pdfrx.text-assets`. */ constructor(databaseName?: string); /** @inheritdoc */ get(key: string): Promise; /** @inheritdoc */ put(key: string, data: Uint8Array): Promise; } /** * Creates the default downloadable Noto Emoji PNG source. * * Assets are requested lazily, one grapheme at a time, and are not distributed * with `@pdfrx/engine`. The URL is pinned to one Noto Emoji revision. * @param options - Options that customize the operation. * @returns The resulting PdfEmojiAssetSource. * */ export declare function createNotoEmojiPngSource(options?: PdfNotoEmojiSourceOptions): PdfEmojiAssetSource; /** * Creates the cross-runtime default emoji renderer. * * Browsers first use an explicitly available native color-emoji family. * Otherwise (including headless server runtimes), a version-pinned Noto Emoji * PNG is downloaded and decoded without a DOM or native image dependency. * @param options - Options that customize the operation. * @returns The resulting PdfEmojiRenderer. * */ export declare function createDefaultEmojiRenderer(options?: PdfDefaultEmojiRendererOptions): PdfEmojiRenderer; /** * Creates a Canvas-backed text measurer when a DOM is available. * * @param fontFamily - The fontFamily value (string). * @returns The resulting PdfTextMeasureProvider. * */ export declare function createCanvasTextMeasureProvider(fontFamily?: string): PdfTextMeasureProvider; /** * Builds a language-aware, wrapped FreeText appearance without requiring a * {@link PdfDocument} instance. * * Most callers that already have an open document should use * {@link PdfDocument.prepareFreeTextAppearance}. This standalone form is useful * for preparing specs in an adapter or service layer. It performs the same * operation and mutates `spec.fontFace`, `spec.appearanceLines`, and * `spec.appearanceRuns`. * * `options.language` is a hint, not a required field. Kana and Hangul identify * Japanese and Korean directly; in browsers, `navigator.languages` and * `navigator.language` are used automatically. Pass an explicit language for * ambiguous Han-only content, to override the browser preference, or in a * server runtime where no browser locale exists. A server commonly gets it * from document metadata, the authenticated user's locale, or a parsed * `Accept-Language` preference. * * @example * ```ts * const spec: PdfAnnotationSpec = { * subtype: 'freeText', * rect: { left: 40, bottom: 700, right: 260, top: 750 }, * contents: '繁體中文 👋', * }; * * // Explicit because this Han-only text is prepared outside a browser. * await prepareFreeTextAppearance(spec, { language: 'zh-Hant' }); * await page.addAnnotation(spec); * ``` * * The defaults use deterministic approximate text measurement outside the * browser, PDFium's default font when no `resolveFont` service is supplied, * and native-browser or downloadable Noto PNG emoji rendering. Pass * `options.services` when the runtime requires exact measurement, registered * script fonts, offline emoji assets, or a custom renderer. * * For provider and deployment examples, read the * [Text, language, and emoji appearance guide](https://github.com/espresso3389/pdfrx_web/blob/master/docs/TEXT-APPEARANCE.md). * To reuse the analyzed runs as ordinary PDF page text and images rather than * an annotation, see the * [practical multilingual Unicode page-content pipeline](https://github.com/espresso3389/pdfrx_web/blob/master/docs/PAGE-CONTENTS.md#practical-multilingual-unicode-pipeline). * @param spec - The spec value (PdfAnnotationSpec). * @param options - Options that customize the operation. * @returns The resulting Promise. * */ export declare function prepareFreeTextAppearance(spec: PdfAnnotationSpec, options?: PdfFreeTextAppearanceOptions): Promise; /** * Decodes the 8-bit, non-interlaced RGB/RGBA PNGs used by Noto Emoji. * * @param data - The input data. * @returns The resulting Promise. * */ export declare function decodeRgbaPng(data: Uint8Array): Promise<{ width: number; height: number; pixels: Uint8Array; }>; //# sourceMappingURL=text-appearance.d.ts.map