Skip to content

Commit

Permalink
copy TextGeometry from super-three
Browse files Browse the repository at this point in the history
  • Loading branch information
digama0 authored and dmarcos committed Mar 5, 2024
1 parent a6fe6df commit d8b53ba
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/components/text-geometry.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
/**
* TextGeometry component for A-Frame.
*/
import { TextGeometry } from '../lib/TextGeometry.js';
import { FontLoader } from '../lib/FontLoader.js';

var debug = AFRAME.utils.debug;

var error = debug('aframe-text-component:error');

var fontLoader = new THREE.FontLoader();
var fontLoader = new FontLoader();

AFRAME.registerComponent('text-geometry', {
schema: {
Expand Down Expand Up @@ -42,12 +45,12 @@ AFRAME.registerComponent('text-geometry', {
fontLoader.load(data.font, function (response) {
const textData = AFRAME.utils.clone(data);
textData.font = response;
mesh.geometry = new THREE.TextGeometry(data.value, textData);
mesh.geometry = new TextGeometry(data.value, textData);
mesh.geometry.translate(-0.18, 0, -0.07);
});
} else if (data.font.constructor === Object) {
// Set font if already have a typeface.json through setAttribute.
mesh.geometry = new THREE.TextGeometry(data.value, data);
mesh.geometry = new TextGeometry(data.value, data);
mesh.geometry.translate(-0.18, 0, -0.07);
} else {
error('Must provide `font` (typeface.json) or `fontPath` (string) to text component.');
Expand Down
196 changes: 196 additions & 0 deletions src/lib/FontLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import {
FileLoader,
Loader,
ShapePath
} from 'three';

class FontLoader extends Loader {

constructor(manager) {

super(manager);

}

load(url, onLoad, onProgress, onError) {

const scope = this;

const loader = new FileLoader(this.manager);
loader.setPath(this.path);
loader.setRequestHeader(this.requestHeader);
loader.setWithCredentials(scope.withCredentials);
loader.load(url, function (text) {

let json;

try {

json = JSON.parse(text);

} catch (e) {

console.warn('THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.');
json = JSON.parse(text.substring(65, text.length - 2));

}

const font = scope.parse(json);

if (onLoad) onLoad(font);

}, onProgress, onError);

}

parse(json) {

return new Font(json);

}

}

//

class Font {

constructor(data) {

this.type = 'Font';

this.data = data;

}

generateShapes(text, size = 100) {

const shapes = [];
const paths = createPaths(text, size, this.data);

for (let p = 0, pl = paths.length; p < pl; p++) {

Array.prototype.push.apply(shapes, paths[p].toShapes());

}

return shapes;

}

}

function createPaths(text, size, data) {

const chars = Array.from(text);
const scale = size / data.resolution;
const line_height = (data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness) * scale;

const paths = [];

let offsetX = 0, offsetY = 0;

for (let i = 0; i < chars.length; i++) {

const char = chars[i];

if (char === '\n') {

offsetX = 0;
offsetY -= line_height;

} else {

const ret = createPath(char, scale, offsetX, offsetY, data);
offsetX += ret.offsetX;
paths.push(ret.path);

}

}

return paths;

}

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': // moveTo

x = outline[i++] * scale + offsetX;
y = outline[i++] * scale + offsetY;

path.moveTo(x, y);

break;

case 'l': // lineTo

x = outline[i++] * scale + offsetX;
y = outline[i++] * scale + offsetY;

path.lineTo(x, y);

break;

case 'q': // quadraticCurveTo

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': // bezierCurveTo

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: path };

}

Font.prototype.isFont = true;

export { FontLoader, Font };
55 changes: 55 additions & 0 deletions src/lib/TextGeometry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Text = 3D Text
*
* parameters = {
* font: <THREE.Font>, // font
*
* size: <float>, // size of the text
* height: <float>, // thickness to extrude text
* curveSegments: <int>, // number of points on the curves
*
* bevelEnabled: <bool>, // turn on bevel
* bevelThickness: <float>, // how deep into text bevel goes
* bevelSize: <float>, // how far from text outline (including bevelOffset) is bevel
* bevelOffset: <float> // how far from text outline does bevel start
* }
*/

var ExtrudeGeometry = THREE.ExtrudeGeometry;

class TextGeometry extends ExtrudeGeometry {

constructor(text, parameters = {}) {

const font = parameters.font;

if (font === undefined) {

super(); // generate default extrude geometry

} else {

const shapes = font.generateShapes(text, parameters.size);

// translate parameters to ExtrudeGeometry API

parameters.depth = parameters.height !== undefined ? parameters.height : 50;

// defaults

if (parameters.bevelThickness === undefined) parameters.bevelThickness = 10;
if (parameters.bevelSize === undefined) parameters.bevelSize = 8;
if (parameters.bevelEnabled === undefined) parameters.bevelEnabled = false;

super(shapes, parameters);

}

this.type = 'TextGeometry';

}

}


export { TextGeometry };

0 comments on commit d8b53ba

Please sign in to comment.