UNPKG

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 11.5 kB
{"version":3,"file":"loadWebFont.mjs","sources":["../../../../src/assets/loader/parsers/loadWebFont.ts"],"sourcesContent":["import { DOMAdapter } from '../../../environment/adapter';\nimport { ExtensionType } from '../../../extensions/Extensions';\nimport { warn } from '../../../utils/logging/warn';\nimport { path } from '../../../utils/path';\nimport { Cache } from '../../cache/Cache';\nimport { checkDataUrl } from '../../utils/checkDataUrl';\nimport { checkExtension } from '../../utils/checkExtension';\nimport { LoaderParserPriority } from './LoaderParser';\n\nimport type { ResolvedAsset } from '../../types';\nimport type { LoaderParser } from './LoaderParser';\n\nconst validWeights = [\n 'normal', 'bold',\n '100', '200', '300', '400', '500', '600', '700', '800', '900',\n];\nconst validFontExtensions = ['.ttf', '.otf', '.woff', '.woff2'];\nconst validFontMIMEs = [\n 'font/ttf',\n 'font/otf',\n 'font/woff',\n 'font/woff2',\n];\n\n/**\n * Cache for font faces\n * @internal\n */\nexport interface FontFaceCache\n{\n entries: {url: string, faces: FontFace[]}[]\n}\n\n/**\n * Data for loading a font\n * @category assets\n * @advanced\n */\nexport type LoadFontData = {\n /** Font family name */\n family: string;\n /** A set of optional descriptors passed as an object. It can contain any of the descriptors available for @font-face: */\n display: string;\n /**\n * The featureSettings property of the FontFace interface retrieves or sets infrequently used\n * font features that are not available from a font's variant properties.\n */\n featureSettings: string;\n /** The stretch property of the FontFace interface retrieves or sets how the font stretches. */\n stretch: string;\n /** The style property of the FontFace interface retrieves or sets the font's style. */\n style: string;\n /**\n * The unicodeRange property of the FontFace interface retrieves or sets the range of\n * unicode code points encompassing the font.\n */\n unicodeRange: string;\n /** The variant property of the FontFace interface programmatically retrieves or sets font variant values. */\n variant: string;\n /** The weight property of the FontFace interface retrieves or sets the weight of the font. */\n weights: string[];\n};\n\n/**\n * RegExp for matching CSS <ident-token>. It doesn't consider escape and non-ASCII characters, but enough for us.\n * @see {@link https://www.w3.org/TR/css-syntax-3/#ident-token-diagram}\n */\nconst CSS_IDENT_TOKEN_REGEX = /^(--|-?[A-Z_])[0-9A-Z_-]*$/i;\n\n/**\n * Return font face name from a file name\n * Ex.: 'fonts/titan-one.woff' turns into 'Titan One'\n * @param url - File url\n * @category assets\n * @internal\n */\nexport function getFontFamilyName(url: string): string\n{\n const ext = path.extname(url);\n const name = path.basename(url, ext);\n\n // Replace dashes by white spaces\n const nameWithSpaces = name.replace(/(-|_)/g, ' ');\n\n // Upper case first character of each word\n const nameTokens = nameWithSpaces.toLowerCase()\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1));\n\n let valid = nameTokens.length > 0;\n\n for (const token of nameTokens)\n {\n if (!token.match(CSS_IDENT_TOKEN_REGEX))\n {\n valid = false;\n break;\n }\n }\n\n let fontFamilyName = nameTokens.join(' ');\n\n if (!valid)\n {\n fontFamilyName = `\"${fontFamilyName.replace(/[\\\\\"]/g, '\\\\$&')}\"`;\n }\n\n return fontFamilyName;\n}\n\n// See RFC 3986 Chapter 2. Characters\nconst validURICharactersRegex = /^[0-9A-Za-z%:/?#\\[\\]@!\\$&'()\\*\\+,;=\\-._~]*$/;\n\n/**\n * Encode URI only when it contains invalid characters.\n * @param uri - URI to encode.\n */\nfunction encodeURIWhenNeeded(uri: string)\n{\n if (validURICharactersRegex.test(uri))\n {\n return uri;\n }\n\n return encodeURI(uri);\n}\n\n/**\n * A loader plugin for handling web fonts\n * @example\n * import { Assets } from 'pixi.js';\n *\n * Assets.load({\n * alias: 'font',\n * src: 'fonts/titan-one.woff',\n * data: {\n * family: 'Titan One',\n * weights: ['normal', 'bold'],\n * }\n * })\n * @category assets\n * @advanced\n */\nexport const loadWebFont = {\n extension: {\n type: ExtensionType.LoadParser,\n priority: LoaderParserPriority.Low,\n },\n\n /** used for deprecation purposes */\n name: 'loadWebFont',\n id: 'web-font',\n\n test(url: string): boolean\n {\n return checkDataUrl(url, validFontMIMEs) || checkExtension(url, validFontExtensions);\n },\n\n async load(url: string, options?: ResolvedAsset<LoadFontData>): Promise<FontFace | FontFace[]>\n {\n const fonts = DOMAdapter.get().getFontFaceSet();\n\n if (fonts)\n {\n const fontFaces: FontFace[] = [];\n const name = options.data?.family ?? getFontFamilyName(url);\n const weights = options.data?.weights?.filter((weight) => validWeights.includes(weight)) ?? ['normal'];\n const data = options.data ?? {};\n\n for (let i = 0; i < weights.length; i++)\n {\n const weight = weights[i];\n\n const font = new FontFace(name, `url('${encodeURIWhenNeeded(url)}')`, {\n ...data,\n weight,\n });\n\n await font.load();\n\n fonts.add(font);\n\n fontFaces.push(font);\n }\n\n if (Cache.has(`${name}-and-url`))\n {\n const cached = Cache.get<FontFaceCache>(`${name}-and-url`);\n\n // If the URL is already cached, we just add the new font faces to the existing cache\n cached.entries.push({ url, faces: fontFaces });\n }\n else\n {\n Cache.set<FontFaceCache>(`${name}-and-url`, {\n entries: [{ url, faces: fontFaces }],\n });\n }\n\n return fontFaces.length === 1 ? fontFaces[0] : fontFaces;\n }\n\n // #if _DEBUG\n warn('[loadWebFont] FontFace API is not supported. Skipping loading font');\n // #endif\n\n return null;\n },\n\n unload(font: FontFace | FontFace[]): void\n {\n const fonts = Array.isArray(font) ? font : [font];\n\n // you can only load 1 family at a time, so we can use the first one\n const fontFamily = fonts[0].family;\n const cached = Cache.get<FontFaceCache>(`${fontFamily}-and-url`);\n\n // find the entry that contains the font faces we want to remove\n const entry = cached.entries.find((f) => f.faces.some((t) => fonts.indexOf(t) !== -1));\n\n // remove the font faces from the cache\n entry.faces = entry.faces.filter((f) => fonts.indexOf(f) === -1);\n\n // if faces are empty, remove the entry\n if (entry.faces.length === 0)\n {\n cached.entries = cached.entries.filter((f) => f !== entry);\n }\n\n // finally remove the font faces from the FontFaceSet\n fonts.forEach((t) =>\n {\n DOMAdapter.get().getFontFaceSet().delete(t);\n });\n\n // Clean up cache if no entries remain\n if (cached.entries.length === 0)\n {\n Cache.remove(`${fontFamily}-and-url`);\n }\n }\n} satisfies LoaderParser<FontFace | FontFace[]>;\n"],"names":[],"mappings":"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"}