pixi.js
Version:
<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">
1 lines • 23.7 kB
Source Map (JSON)
{"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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"}