Facetype.js: A typeface.js generator

A simple way to convert ttf files to typeface.json font files, can be found at facetype.js.

Those json files can then be used like Three.js example.

3 Likes

This is indeed a great resource. Thanks @gero3! Now, if there was some solution to importing Text Geometry through THREE.ObjectLoader.

EDIT: Also would be great to have a means to play with this in the three.js editor. As I understand it, this is not possible as there is no clean workflow. I suppose there could be an entry to ‘add text’ with a default text (‘three.js’), and the properties panel could expose a text field and other parameters to modify the text. The editor could ship with a few pre-defined fonts.

This used to be something you could do in previous versions, but, admittedly, it was not so clean. What I do now is pretty hacky, I modify the r84 ObjectLoader to accept TextGeometry as was the old case, and add a basic typeface.json file. In my plugin, I export text to json in the following manner:

My geometries is as such:

...
"geometries" : [{
    	"uuid" : "d03772e6-7c7e-49e9-aa86-1a6d09aa1ed1",
    	"type" : "TextGeometry",
    	"text" : "hello",
    	"data" : {
    		"size" : 10.0,
    		"height" : 0.0
    	}
   }
 ]...

and as a child of the scene:

...    
"children" : [{
    	"uuid" : "99ca2a23-cd72-452e-976d-5c5210ce5482",
    	"type" : "Mesh",
    	"name" : "",
    	"geometry" : "d03772e6-7c7e-49e9-aa86-1a6d09aa1ed1",
    	"material" : "fb7ae420-05d4-45ea-b77c-556a040b03e5",
    	"userData" : {}
    	},
    	"matrix" : [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
    	} ...

Then I make the following changes to ObjectLoader:

...
parseGeometries: function ( json ) {

        var geometries = {};

	if ( json !== undefined ) {

	    var geometryLoader = new JSONLoader();
	    var bufferGeometryLoader = new BufferGeometryLoader();
                
            //HACK To make Exported JSON format compatible with latest ThreeJS versions
            var fontBase = { "glyphs": ... some font.json from Facetype.js... };
            var font = new Font(fontBase);

	    for ( var i = 0, l = json.length; i < l; i ++ ) { 
...

and:

case 'Geometry':

       geometry = geometryLoader.parse( data.data, this.texturePath ).geometry;

        break;

//HACK
case 'TextGeometry':
                            
      geometry = new Geometries[ data.type ](
                                data.text, {
                                    font: font,
                                    size: data.data.size,
                                    height: data.data.height
                                });
                            
        break;

default:

	console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );

	continue;

That could really work. But we may need a bit more than a hack :wink:

Everything save for the embedding of the font glyphs was part of threejs up to the late r70s. Then people noticed that the old font system was not really kept up, and then @gero3 came along and fixed that, subsequently changing the way that text geometry works, and requiring the removal of the last code snipped to be removed from the source.

Essentially the issue lies in where to get the font from:

geometry = new Geometries[ data.type ](
                                data.text, {
                                    font: font,
                                    size: data.data.size,
                                    height: data.data.height
                                });
                            
        break; 

I suppose there would need to be a sort of ‘fontSource’ and the code could be like:

case ‘TextGeometry’:

  geometry = new Geometries[ data.type ](
                            data.text, {
                                font: new FontLoader.load( data.fontSource ), // or new Font(data.fontSource);
                                size: data.data.size,
                                height: data.data.height
                            });
                        
    break;

Actually, we could make it so, that we add a new resourcetype ‘fonts’ to the object json and let textgeometry reference to the font object.

2 Likes

right, and it could be a path or a dataUrl.

That’s great! 3D Text is back! :smirk:

PR of a first (non hacky) draft: https://github.com/mrdoob/three.js/pull/11026

1 Like

If anyone can give me a few hints on how to enable loading fonts stored in .json files in the context of ObjectLoader, I’d appreciate it. This is more a js issue rather than three.js. FontLoader.parse() works just fine when a file has the glyphs embedded (this is what the PR above does, and suits my use case perfectly), but I think I will need to change FontLoader.load() to be able to use it within ObjectLoader. Can anyone get some eyes on that and give me some suggestions?
Thanks!