1 line
7.7 KiB
Plaintext
1 line
7.7 KiB
Plaintext
|
|
{"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 = {
|