{"version":3,"file":"loadWebFont.mjs","sources":["../../../src/loader/parsers/loadWebFont.ts"],"sourcesContent":["import { extensions, ExtensionType, settings, utils } from '@pixi/core';\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 * Loader plugin for handling web fonts\n * @memberof PIXI\n */\nexport type LoadFontData = {\n    family: string;\n    display: string;\n    featureSettings: string;\n    stretch: string;\n    style: string;\n    unicodeRange: string;\n    variant: string;\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/tital-one.woff' turns into 'Titan One'\n * @param url - File url\n */\nexport function getFontFamilyName(url: string): string\n{\n    const ext = utils.path.extname(url);\n    const name = utils.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/** Web font loader plugin */\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 = settings.ADAPTER.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            return fontFaces.length === 1 ? fontFaces[0] : fontFaces;\n        }\n\n        if (process.env.DEBUG)\n        {\n            console.warn('[loadWebFont] FontFace API is not supported. Skipping loading font');\n        }\n\n        return null;\n    },\n\n    unload(font: FontFace | FontFace[]): void\n    {\n        (Array.isArray(font) ? font : [font])\n            .forEach((t) => settings.ADAPTER.getFontFaceSet().delete(t));\n    }\n} as LoaderParser<FontFace | FontFace[]>;\n\nextensions.add(loadWebFont);\n"],"names":[],"mappings":";;;;AAQA,MAAM,eAAe;AAAA,EACjB;AAAA,EAAU;AAAA,EACV;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAC5D,GACM,sBAAsB,CAAC,QAAQ,QAAQ,SAAS,QAAQ,GACxD,iBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,GAqBM,wBAAwB;AAOvB,SAAS,kBAAkB,KAClC;AACI,QAAM,MAAM,MAAM,KAAK,QAAQ,GAAG,GAO5B,aANO,MAAM,KAAK,SAAS,KAAK,GAAG,EAGb,QAAQ,UAAU,GAAG,EAGf,YAAY,EACzC,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC;AAE3D,MAAA,QAAQ,WAAW,SAAS;AAEhC,aAAW,SAAS;AAEhB,QAAI,CAAC,MAAM,MAAM,qBAAqB,GACtC;AACY,cAAA;AACR;AAAA,IACJ;AAGA,MAAA,iBAAiB,WAAW,KAAK,GAAG;AAEnC,SAAA,UAED,iBAAiB,IAAI,eAAe,QAAQ,UAAU,MAAM,CAAC,MAG1D;AACX;AAGA,MAAM,0BAA0B;AAMhC,SAAS,oBAAoB,KAC7B;AACI,SAAI,wBAAwB,KAAK,GAAG,IAEzB,MAGJ,UAAU,GAAG;AACxB;AAGO,MAAM,cAAc;AAAA,EACvB,WAAW;AAAA,IACP,MAAM,cAAc;AAAA,IACpB,UAAU,qBAAqB;AAAA,EACnC;AAAA,EAEA,MAAM;AAAA,EAEN,KAAK,KACL;AACI,WAAO,aAAa,KAAK,cAAc,KAAK,eAAe,KAAK,mBAAmB;AAAA,EACvF;AAAA,EAEA,MAAM,KAAK,KAAa,SACxB;AACU,UAAA,QAAQ,SAAS,QAAQ,eAAe;AAE9C,QAAI,OACJ;AACI,YAAM,YAAwB,CAAA,GACxB,OAAO,QAAQ,MAAM,UAAU,kBAAkB,GAAG,GACpD,UAAU,QAAQ,MAAM,SAAS,OAAO,CAAC,WAAW,aAAa,SAAS,MAAM,CAAC,KAAK,CAAC,QAAQ,GAC/F,OAAO,QAAQ,QAAQ,CAAA;AAE7B,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KACpC;AACI,cAAM,SAAS,QAAQ,CAAC,GAElB,OAAO,IAAI,SAAS,MAAM,OAAO,oBAAoB,GAAG,CAAC,KAAK;AAAA,UAChE,GAAG;AAAA,UACH;AAAA,QAAA,CACH;AAEK,cAAA,KAAK,KAEX,GAAA,MAAM,IAAI,IAAI,GAEd,UAAU,KAAK,IAAI;AAAA,MACvB;AAEA,aAAO,UAAU,WAAW,IAAI,UAAU,CAAC,IAAI;AAAA,IACnD;AAIY,WAAA,QAAA,KAAK,oEAAoE,GAG9E;AAAA,EACX;AAAA,EAEA,OAAO,MACP;AACI,KAAC,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI,GAC9B,QAAQ,CAAC,MAAM,SAAS,QAAQ,eAAiB,EAAA,OAAO,CAAC,CAAC;AAAA,EACnE;AACJ;AAEA,WAAW,IAAI,WAAW;"}