{"version":3,"file":"BitmapFontManager.mjs","sources":["../../../src/scene/text-bitmap/BitmapFontManager.ts"],"sourcesContent":["import { lru } from 'tiny-lru';\nimport { Cache } from '../../assets/cache/Cache';\nimport { type TextureStyle, type TextureStyleOptions } from '../../rendering/renderers/shared/texture/TextureStyle';\nimport { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\nimport { warn } from '../../utils/logging/warn';\nimport { CanvasTextMetrics } from '../text/canvas/CanvasTextMetrics';\nimport { TextStyle } from '../text/TextStyle';\nimport { DynamicBitmapFont } from './DynamicBitmapFont';\nimport { getBitmapTextLayout } from './utils/getBitmapTextLayout';\nimport { resolveCharacters } from './utils/resolveCharacters';\n\nimport type { TextStyleOptions } from '../text/TextStyle';\nimport type { BitmapFont } from './BitmapFont';\nimport type { BitmapTextLayoutData } from './utils/getBitmapTextLayout';\n\nlet fontCount = 0;\n\n/**\n * The options for installing a new BitmapFont. Once installed, the font will be available\n * for use in BitmapText objects through the fontFamily property of TextStyle.\n * @example\n * ```ts\n * import { BitmapFont, BitmapText } from 'pixi.js';\n *\n * // Basic font installation\n * BitmapFont.install({\n *     name: 'BasicFont',\n *     style: {\n *         fontFamily: 'Arial',\n *         fontSize: 24,\n *         fill: '#ffffff'\n *     }\n * });\n *\n * // Advanced font installation\n * BitmapFont.install({\n *     name: 'AdvancedFont',\n *     style: {\n *         fontFamily: 'Arial',\n *         fontSize: 32,\n *         fill: '#ff0000',\n *         stroke: { color: '#000000', width: 2 }\n *     },\n *     // Include specific character ranges\n *     chars: [\n *         ['a', 'z'],           // lowercase letters\n *         ['A', 'Z'],           // uppercase letters\n *         ['0', '9'],           // numbers\n *         '!@#$%^&*()_+-=[]{}' // symbols\n *     ],\n *     resolution: 2,            // High-DPI support\n *     padding: 4,              // Glyph padding\n *     skipKerning: false,      // Enable kerning\n *     textureStyle: {\n *         scaleMode: 'linear',\n *     }\n * });\n *\n * // Using the installed font\n * const text = new BitmapText({\n *     text: 'Hello World',\n *     style: {\n *         fontFamily: 'AdvancedFont',\n *         fontSize: 48\n *     }\n * });\n * ```\n * @category text\n * @standard\n */\nexport interface BitmapFontInstallOptions\n{\n    /**\n     * The name of the font. This will be used as the fontFamily in text styles to access this font.\n     * Must be unique across all installed bitmap fonts.\n     * @example\n     * ```ts\n     * BitmapFont.install({\n     *     name: 'MyCustomFont',\n     *     style: { fontFamily: 'Arial' }\n     * });\n     * ```\n     */\n    name?: string;\n\n    /**\n     * Characters included in the font set. You can specify individual characters or ranges.\n     * Don't forget to include spaces ' ' in your character set!\n     * @default BitmapFont.ALPHANUMERIC\n     * @example\n     * ```ts\n     * // Different ways to specify characters\n     * BitmapFont.install({\n     *     name: 'RangeFont',\n     *     chars: [\n     *         ['a', 'z'],              // Range of characters\n     *         '0123456789',            // String of characters\n     *         [['0', '9'], ['A', 'Z']] // Multiple ranges\n     *     ]\n     * });\n     * ```\n     */\n    chars?: string | (string | string[])[];\n\n    /**\n     * Render resolution for glyphs. Higher values create sharper text at the cost of memory.\n     * Useful for supporting high-DPI displays.\n     * @default 1\n     * @example\n     * ```ts\n     * BitmapFont.install({\n     *     name: 'HiDPIFont',\n     *     resolution: window.devicePixelRatio || 2\n     * });\n     * ```\n     */\n    resolution?: number;\n\n    /**\n     * Padding between glyphs on texture atlas. Balances visual quality with texture space.\n     * - Lower values: More compact, but may have visual artifacts\n     * - Higher values: Better quality, but uses more texture space\n     * @default 4\n     * @example\n     * ```ts\n     * BitmapFont.install({\n     *     name: 'PaddedFont',\n     *     padding: 8 // More padding for better quality\n     * });\n     * ```\n     */\n    padding?: number;\n\n    /**\n     * Skip generation of kerning information for the BitmapFont.\n     * - true: Faster generation, but text may have inconsistent spacing\n     * - false: Better text appearance, but slower generation\n     * @default false\n     * @example\n     * ```ts\n     * BitmapFont.install({\n     *     name: 'FastFont',\n     *     skipKerning: true // Prioritize performance\n     * });\n     * ```\n     */\n    skipKerning?: boolean;\n\n    /**\n     * Style options to render the BitmapFont with.\n     * Supports all TextStyle properties including fill, stroke, and shadow effects.\n     * @example\n     * ```ts\n     * BitmapFont.install({\n     *     name: 'StyledFont',\n     *     style: {\n     *         fontFamily: 'Arial',\n     *         fontSize: 32,\n     *         fill: 'white',\n     *         stroke: { color: '#000000', width: 2 },\n     *         dropShadow: {\n     *             color: '#000000',\n     *             blur: 2,\n     *             distance: 3\n     *         }\n     *     }\n     * });\n     * ```\n     */\n    style?: TextStyle | TextStyleOptions;\n\n    /**\n     * Optional texture style to use when creating the font textures.\n     * Controls how the font textures are rendered and filtered.\n     * @example\n     * ```ts\n     * BitmapFont.install({\n     *     name: 'CrispFont',\n     *     textureStyle: {\n     *         scaleMode: 'nearest',\n     *     }\n     * });\n     * ```\n     */\n    textureStyle?: TextureStyle | TextureStyleOptions;\n\n    /**\n     * Whether to allow overriding the fill color with a tint at runtime.\n     *\n     * When enabled, the font can be dynamically tinted using the `tint` property of BitmapText,\n     * allowing a single font to display multiple colors without creating separate font textures.\n     * This is memory efficient but requires the font to be rendered with white fill color.\n     *\n     * When disabled, the fill color is permanently baked into the font texture. This allows\n     * any fill color but prevents runtime tinting - each color variation requires a separate font.\n     * @default false (automatically determined based on style)\n     *\n     * **Requirements for tinting:**\n     * - Fill color must be white (`0xFFFFFF` or `'#ffffff'`)\n     * - No stroke effects\n     * - No drop shadows (or only black shadows)\n     * - No gradient or pattern fills\n     *\n     * **Performance considerations:**\n     * - ✅ Enabled: One font texture, multiple colors via tinting (memory efficient)\n     * - ❌ Disabled: Separate font texture per color (higher memory usage)\n     * @example\n     * ```ts\n     * // Correct usage - white fill with tinting enabled\n     * BitmapFont.install({\n     *     name: 'TintableFont',\n     *     style: {\n     *         fontFamily: 'Arial',\n     *         fontSize: 24,\n     *         fill: 0xFFFFFF  // Must be white for tinting\n     *     },\n     *     dynamicFill: true\n     * });\n     *\n     * // Use the font with different colors via tinting\n     * const redText = new BitmapText({\n     *     text: 'Red Text',\n     *     style: { fontFamily: 'TintableFont', fill: 'red }, // Red tint\n     * });\n     *\n     * const blueText = new BitmapText({\n     *     text: 'Blue Text',\n     *     style: { fontFamily: 'TintableFont', fill: 'blue' }, // Blue tint\n     * });\n     * ```\n     * @example\n     * ```ts\n     * // Incorrect usage - colored fill with tinting enabled\n     * BitmapFont.install({\n     *     name: 'BadTintFont',\n     *     style: {\n     *         fontFamily: 'Arial',\n     *         fontSize: 24,\n     *         fill: 0xFF0000  // ❌ Red fill won't tint properly\n     *     },\n     *     dynamicFill: true  // ❌ Will not work as expected\n     * });\n     * ```\n     * @example\n     * ```ts\n     * // Alternative - baked colors (no tinting)\n     * BitmapFont.install({\n     *     name: 'BakedColorFont',\n     *     style: {\n     *         fontFamily: 'Arial',\n     *         fontSize: 24,\n     *         fill: 0xFF0000,  // Any color works\n     *         stroke: { color: 0x000000, width: 2 }  // Strokes allowed\n     *     },\n     *     dynamicFill: false  // Color is baked in\n     * });\n     * ```\n     */\n    dynamicFill?: boolean;\n}\n\n/** @advanced */\nclass BitmapFontManagerClass\n{\n    /**\n     * This character set includes all the letters in the alphabet (both lower- and upper- case).\n     * @type {string[][]}\n     * @example\n     * BitmapFont.from('ExampleFont', style, { chars: BitmapFont.ALPHA })\n     */\n    public readonly ALPHA = [['a', 'z'], ['A', 'Z'], ' '];\n\n    /**\n     * This character set includes all decimal digits (from 0 to 9).\n     * @type {string[][]}\n     * @example\n     * BitmapFont.from('ExampleFont', style, { chars: BitmapFont.NUMERIC })\n     */\n    public readonly NUMERIC = [['0', '9']];\n\n    /**\n     * This character set is the union of `BitmapFont.ALPHA` and `BitmapFont.NUMERIC`.\n     * @type {string[][]}\n     */\n    public readonly ALPHANUMERIC = [['a', 'z'], ['A', 'Z'], ['0', '9'], ' '];\n\n    /**\n     * This character set consists of all the ASCII table.\n     * @type {string[][]}\n     * @see http://www.asciitable.com/\n     */\n    public readonly ASCII = [[' ', '~']];\n\n    /** Default options for installing a new BitmapFont. */\n    public defaultOptions: Omit<BitmapFontInstallOptions, 'style'> = {\n        chars: this.ALPHANUMERIC,\n        resolution: 1,\n        padding: 4,\n        skipKerning: false,\n        textureStyle: null,\n    };\n\n    /** Cache for measured text layouts to avoid recalculating them multiple times. */\n    public readonly measureCache = lru<BitmapTextLayoutData>(1000);\n\n    /**\n     * Get a font for the specified text and style.\n     * @param text - The text to get the font for\n     * @param style - The style to use\n     */\n    public getFont(text: string, style: TextStyle): BitmapFont\n    {\n        let fontFamilyKey = `${style.fontFamily as string}-bitmap`;\n        let overrideFill = true;\n\n        // check if the font is already installed\n        if (Cache.has(fontFamilyKey))\n        {\n            const dynamicFont = Cache.get<DynamicBitmapFont>(fontFamilyKey);\n\n            (dynamicFont as DynamicBitmapFont).ensureCharacters?.(text);\n\n            return dynamicFont;\n        }\n\n        // assuming there is no texture we can use a tint!\n        if (style._fill.fill && !style._stroke)\n        {\n            fontFamilyKey += style._fill.fill.styleKey;\n            overrideFill = false;\n        }\n        else if (style._stroke || style.dropShadow)\n        {\n            // if there is a stoke, we need to use the style key as this the font generated cannot be tinted\n            // due to the fact the font has at least two colors.\n            fontFamilyKey = `${style.styleKey}-bitmap`;\n            overrideFill = false;\n        }\n\n        fontFamilyKey += `-${style.fontStyle}`;\n        fontFamilyKey += `-${style.fontVariant}`;\n        fontFamilyKey += `-${style.fontWeight}`;\n\n        // first get us the the right font...\n        if (!Cache.has(fontFamilyKey))\n        {\n            const styleCopy = Object.create(style);\n\n            // Override the lineHeight, let the BitmapFont calculate the lineHeight\n            // from the fontMetrics instead using a custom lineHeight from BitmapText parameter\n            // eslint-disable-next-line dot-notation\n            styleCopy['_lineHeight'] = 0;\n\n            const fnt = new DynamicBitmapFont({\n                style: styleCopy,\n                overrideFill,\n                overrideSize: true,\n                ...this.defaultOptions,\n            });\n\n            fontCount++;\n\n            // warn users if they have created too many dynamic fonts\n            if (fontCount > 50)\n            {\n                // eslint-disable-next-line max-len\n                warn('BitmapText', `You have dynamically created ${fontCount} bitmap fonts, this can be inefficient. Try pre installing your font styles using \\`BitmapFont.install({name:\"style1\", style})\\``);\n            }\n\n            fnt.once('destroy', () =>\n            {\n                fontCount--;\n                Cache.remove(fontFamilyKey);\n            });\n\n            Cache.set(\n                fontFamilyKey as string,\n                fnt\n            );\n        }\n\n        const dynamicFont = Cache.get(fontFamilyKey);\n\n        (dynamicFont as DynamicBitmapFont).ensureCharacters?.(text);\n\n        return dynamicFont;\n    }\n\n    /**\n     * Get the layout of a text for the specified style.\n     * @param text - The text to get the layout for\n     * @param style - The style to use\n     * @param trimEnd - Whether to ignore whitespaces at the end of each line\n     */\n    public getLayout(text: string, style: TextStyle, trimEnd: boolean = true): BitmapTextLayoutData\n    {\n        const bitmapFont = this.getFont(text, style);\n\n        const id = `${text}-${style.styleKey}-${trimEnd}`;\n\n        // Check if we have a cached layout\n        if (this.measureCache.has(id))\n        {\n            return this.measureCache.get(id);\n        }\n\n        const segments = CanvasTextMetrics.graphemeSegmenter(text);\n\n        // Generate the layout data\n        const layoutData = getBitmapTextLayout(segments, style, bitmapFont, trimEnd);\n\n        this.measureCache.set(id, layoutData);\n\n        return layoutData;\n    }\n\n    /**\n     * Measure the text using the specified style.\n     * @param text - The text to measure\n     * @param style - The style to use\n     * @param trimEnd - Whether to ignore whitespaces at the end of each line\n     */\n    public measureText(\n        text: string,\n        style: TextStyle,\n        trimEnd: boolean = true\n    ): { width: number; height: number; scale: number; offsetY: number }\n    {\n        return this.getLayout(text, style, trimEnd);\n    }\n\n    /**\n     * Generates a bitmap-font for the given style and character set\n     * @param options - Setup options for font generation.\n     * @returns Font generated by style options.\n     * @example\n     * import { BitmapFontManager, BitmapText } from 'pixi.js';\n     *\n     * BitmapFontManager.install('TitleFont', {\n     *     fontFamily: 'Arial',\n     *     fontSize: 12,\n     *     strokeThickness: 2,\n     *     fill: 'purple',\n     * });\n     *\n     * const title = new BitmapText({ text: 'This is the title', fontFamily: 'TitleFont' });\n     */\n    public install(options: BitmapFontInstallOptions): BitmapFont;\n    /** @deprecated since 7.0.0 */\n    public install(name: string, style?: TextStyle | TextStyleOptions, options?: BitmapFontInstallOptions): BitmapFont;\n    // eslint-disable-next-line max-len\n    public install(...args: [string | BitmapFontInstallOptions, (TextStyle | TextStyleOptions)?, BitmapFontInstallOptions?]): BitmapFont\n    {\n        let options = args[0] as BitmapFontInstallOptions;\n\n        if (typeof options === 'string')\n        {\n            options = {\n                name: options,\n                style: args[1],\n                chars: args[2]?.chars,\n                resolution: args[2]?.resolution,\n                padding: args[2]?.padding,\n                skipKerning: args[2]?.skipKerning,\n            } as BitmapFontInstallOptions;\n\n            // #if _DEBUG\n            // eslint-disable-next-line max-len\n            deprecation(v8_0_0, 'BitmapFontManager.install(name, style, options) is deprecated, use BitmapFontManager.install({name, style, ...options})');\n            // #endif\n        }\n\n        const name = options?.name;\n\n        if (!name)\n        {\n            throw new Error('[BitmapFontManager] Property `name` is required.');\n        }\n\n        options = { ...this.defaultOptions, ...options };\n\n        const textStyle = options.style;\n\n        const style = textStyle instanceof TextStyle ? textStyle : new TextStyle(textStyle);\n        const overrideFill = options.dynamicFill ?? this._canUseTintForStyle(style);\n        const font = new DynamicBitmapFont({\n            style,\n            overrideFill,\n            skipKerning: options.skipKerning,\n            padding: options.padding,\n            resolution: options.resolution,\n            overrideSize: false,\n            textureStyle: options.textureStyle,\n        });\n\n        const flatChars = resolveCharacters(options.chars);\n\n        font.ensureCharacters(flatChars.join(''));\n\n        Cache.set(`${name}-bitmap`, font);\n\n        font.once('destroy', () => Cache.remove(`${name}-bitmap`));\n\n        return font;\n    }\n\n    /**\n     * Uninstalls a bitmap font from the cache.\n     * @param {string} name - The name of the bitmap font to uninstall.\n     */\n    public uninstall(name: string)\n    {\n        const cacheKey = `${name}-bitmap`;\n        const font = Cache.get<BitmapFont>(cacheKey);\n\n        if (font)\n        {\n            font.destroy();\n        }\n    }\n\n    /**\n     * Determines if a style can use tinting instead of baking colors into the bitmap.\n     * Tinting is more efficient as it allows reusing the same bitmap with different colors.\n     * @param style - The text style to evaluate\n     * @returns true if the style can use tinting, false if colors must be baked in\n     * @private\n     */\n    private _canUseTintForStyle(style: TextStyle): boolean\n    {\n        // Exclude strokes, non black shadows and ensure\n        // we have a non gradient or pattern fill,\n        // and the fill color is white\n        return !style._stroke\n            && (!style.dropShadow || style.dropShadow.color === 0x000000)\n            && !style._fill.fill\n            && style._fill.color === 0xFFFFFF;\n    }\n}\n\n/**\n * The BitmapFontManager is a helper that exists to install and uninstall fonts\n * into the cache for BitmapText objects.\n * @category text\n * @advanced\n * @class\n * @example\n * import { BitmapFontManager, BitmapText } from 'pixi.js';\n *\n * BitmapFontManager.install({\n *   name: 'TitleFont',\n *   style: {}\n * });\n *\n * const title = new BitmapText({ text: 'This is the title', style: { fontFamily: 'TitleFont' }});\n */\nexport const BitmapFontManager = new BitmapFontManagerClass();\n"],"names":["dynamicFont"],"mappings":"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"}