UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

96 lines (95 loc) 3.01 kB
"use strict"; import { ShapePath } from "three"; export class Font { constructor(data) { this.data = data; this.isFont = true; this.type = "font"; } generateShapes(text, options = {}) { if (options.size == null) { options.size = 100; } if (options.isCCW == null) { options.isCCW = false; } const allShapes = []; const allPaths = createPaths(text, options.size, this.data); for (const pathsForChar of allPaths) { const shapesForChar = []; for (const path of pathsForChar) { const shapes = path.toShapes(options.isCCW); shapesForChar.push(...shapes); } allShapes.push(shapesForChar); } return allShapes; } } function createPaths(text, size, data) { const chars = Array.from(text); const scale = size / data.resolution; const lineHeight = (data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness) * scale; const allPaths = []; let offsetX = 0, offsetY = 0; for (let i = 0; i < chars.length; i++) { const char = chars[i]; const pathsForChar = []; if (char === "\n") { offsetX = 0; offsetY -= lineHeight; } else { const ret = createPath(char, scale, offsetX, offsetY, data); if (ret) { offsetX += ret.offsetX; pathsForChar.push(ret.path); } } allPaths.push(pathsForChar); } return allPaths; } function createPath(char, scale, offsetX, offsetY, data) { const glyph = data.glyphs[char] || data.glyphs["?"]; if (!glyph) { console.error('THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + "."); return; } const path = new ShapePath(); let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2; if (glyph.o) { const outline = glyph._cachedOutline || (glyph._cachedOutline = glyph.o.split(" ")); for (let i = 0, l = outline.length; i < l; ) { const action = outline[i++]; switch (action) { case "m": x = outline[i++] * scale + offsetX; y = outline[i++] * scale + offsetY; path.moveTo(x, y); break; case "l": x = outline[i++] * scale + offsetX; y = outline[i++] * scale + offsetY; path.lineTo(x, y); break; case "q": cpx = outline[i++] * scale + offsetX; cpy = outline[i++] * scale + offsetY; cpx1 = outline[i++] * scale + offsetX; cpy1 = outline[i++] * scale + offsetY; path.quadraticCurveTo(cpx1, cpy1, cpx, cpy); break; case "b": cpx = outline[i++] * scale + offsetX; cpy = outline[i++] * scale + offsetY; cpx1 = outline[i++] * scale + offsetX; cpy1 = outline[i++] * scale + offsetY; cpx2 = outline[i++] * scale + offsetX; cpy2 = outline[i++] * scale + offsetY; path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, cpx, cpy); break; } } } return { offsetX: glyph.ha * scale, path }; }