{"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 * Data for loading a font\n * @memberof assets\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 * @memberof assets\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 * @memberof assets\n */\nexport const loadWebFont = {\n    extension: {\n        type: ExtensionType.LoadParser,\n        priority: LoaderParserPriority.Low,\n    },\n\n    name: 'loadWebFont',\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            Cache.set(`${name}-and-url`, {\n                url,\n                fontFaces,\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        (Array.isArray(font) ? font : [font])\n            .forEach((t) =>\n            {\n                Cache.remove(t.family);\n                DOMAdapter.get().getFontFaceSet().delete(t);\n            });\n    }\n} satisfies LoaderParser<FontFace | FontFace[]>;\n"],"names":[],"mappings":"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"}