{"version":3,"file":"TTFLoader.cjs","sources":["../../src/loaders/TTFLoader.js"],"sourcesContent":["import { FileLoader, Loader } from 'three'\nimport { parse } from '../libs/opentype.js'\n\n/**\n * Requires opentype.js to be included in the project.\n * Loads TTF files and converts them into typeface JSON that can be used directly\n * to create THREE.Font objects.\n */\n\nclass TTFLoader extends Loader {\n  constructor(manager) {\n    super(manager)\n\n    this.reversed = false\n  }\n\n  load(url, onLoad, onProgress, onError) {\n    const scope = this\n\n    const loader = new FileLoader(this.manager)\n    loader.setPath(this.path)\n    loader.setResponseType('arraybuffer')\n    loader.setRequestHeader(this.requestHeader)\n    loader.setWithCredentials(this.withCredentials)\n    loader.load(\n      url,\n      function (buffer) {\n        try {\n          onLoad(parse(buffer))\n        } catch (e) {\n          if (onError) {\n            onError(e)\n          } else {\n            console.error(e)\n          }\n\n          scope.manager.itemError(url)\n        }\n      },\n      onProgress,\n      onError,\n    )\n  }\n\n  parse(arraybuffer) {\n    function convert(font, reversed) {\n      const round = Math.round\n\n      const glyphs = {}\n      const scale = 100000 / ((font.unitsPerEm || 2048) * 72)\n\n      const glyphIndexMap = font.encoding.cmap.glyphIndexMap\n      const unicodes = Object.keys(glyphIndexMap)\n\n      for (let i = 0; i < unicodes.length; i++) {\n        const unicode = unicodes[i]\n        const glyph = font.glyphs.glyphs[glyphIndexMap[unicode]]\n\n        if (unicode !== undefined) {\n          const token = {\n            ha: round(glyph.advanceWidth * scale),\n            x_min: round(glyph.xMin * scale),\n            x_max: round(glyph.xMax * scale),\n            o: '',\n          }\n\n          if (reversed) {\n            glyph.path.commands = reverseCommands(glyph.path.commands)\n          }\n\n          glyph.path.commands.forEach(function (command) {\n            if (command.type.toLowerCase() === 'c') {\n              command.type = 'b'\n            }\n\n            token.o += command.type.toLowerCase() + ' '\n\n            if (command.x !== undefined && command.y !== undefined) {\n              token.o += round(command.x * scale) + ' ' + round(command.y * scale) + ' '\n            }\n\n            if (command.x1 !== undefined && command.y1 !== undefined) {\n              token.o += round(command.x1 * scale) + ' ' + round(command.y1 * scale) + ' '\n            }\n\n            if (command.x2 !== undefined && command.y2 !== undefined) {\n              token.o += round(command.x2 * scale) + ' ' + round(command.y2 * scale) + ' '\n            }\n          })\n\n          glyphs[String.fromCodePoint(glyph.unicode)] = token\n        }\n      }\n\n      return {\n        glyphs: glyphs,\n        familyName: font.getEnglishName('fullName'),\n        ascender: round(font.ascender * scale),\n        descender: round(font.descender * scale),\n        underlinePosition: font.tables.post.underlinePosition,\n        underlineThickness: font.tables.post.underlineThickness,\n        boundingBox: {\n          xMin: font.tables.head.xMin,\n          xMax: font.tables.head.xMax,\n          yMin: font.tables.head.yMin,\n          yMax: font.tables.head.yMax,\n        },\n        resolution: 1000,\n        original_font_information: font.tables.name,\n      }\n    }\n\n    function reverseCommands(commands) {\n      const paths = []\n      let path\n\n      commands.forEach(function (c) {\n        if (c.type.toLowerCase() === 'm') {\n          path = [c]\n          paths.push(path)\n        } else if (c.type.toLowerCase() !== 'z') {\n          path.push(c)\n        }\n      })\n\n      const reversed = []\n\n      paths.forEach(function (p) {\n        const result = {\n          type: 'm',\n          x: p[p.length - 1].x,\n          y: p[p.length - 1].y,\n        }\n\n        reversed.push(result)\n\n        for (let i = p.length - 1; i > 0; i--) {\n          const command = p[i]\n          const result = { type: command.type }\n\n          if (command.x2 !== undefined && command.y2 !== undefined) {\n            result.x1 = command.x2\n            result.y1 = command.y2\n            result.x2 = command.x1\n            result.y2 = command.y1\n          } else if (command.x1 !== undefined && command.y1 !== undefined) {\n            result.x1 = command.x1\n            result.y1 = command.y1\n          }\n\n          result.x = p[i - 1].x\n          result.y = p[i - 1].y\n          reversed.push(result)\n        }\n      })\n\n      return reversed\n    }\n\n    return convert(parse(arraybuffer), this.reversed)\n  }\n}\n\nexport { TTFLoader }\n"],"names":["Loader","FileLoader","parse","result"],"mappings":"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"}