Up-in-the-Air – blob

You can use Git to clone the repository via the web URL. Download snapshot (zip)
93caeb5bbaad29f01a5d8e4aa2a7c3f0090b9ed4
[Up-in-the-Air] / addons
1 import {
2         FileLoader,
3         Loader,
4         ShapePath
5 } from 'three';
7 class FontLoader extends Loader {
9         constructor( manager ) {
11                 super( manager );
13         }
15         load( url, onLoad, onProgress, onError ) {
17                 const scope = this;
19                 const loader = new FileLoader( this.manager );
20                 loader.setPath( this.path );
21                 loader.setRequestHeader( this.requestHeader );
22                 loader.setWithCredentials( this.withCredentials );
23                 loader.load( url, function ( text ) {
25                         const font = scope.parse( JSON.parse( text ) );
27                         if ( onLoad ) onLoad( font );
29                 }, onProgress, onError );
31         }
33         parse( json ) {
35                 return new Font( json );
37         }
39 }
41 //
43 class Font {
45         constructor( data ) {
47                 this.isFont = true;
49                 this.type = 'Font';
51                 this.data = data;
53         }
55         generateShapes( text, size = 100 ) {
57                 const shapes = [];
58                 const paths = createPaths( text, size, this.data );
60                 for ( let p = 0, pl = paths.length; p < pl; p ++ ) {
62                         shapes.push( ...paths[ p ].toShapes() );
64                 }
66                 return shapes;
68         }
70 }
72 function createPaths( text, size, data ) {
74         const chars = Array.from( text );
75         const scale = size / data.resolution;
76         const line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
78         const paths = [];
80         let offsetX = 0, offsetY = 0;
82         for ( let i = 0; i < chars.length; i ++ ) {
84                 const char = chars[ i ];
86                 if ( char === '\n' ) {
88                         offsetX = 0;
89                         offsetY -= line_height;
91                 } else {
93                         const ret = createPath( char, scale, offsetX, offsetY, data );
94                         offsetX += ret.offsetX;
95                         paths.push( ret.path );
97                 }
99         }
101         return paths;
105 function createPath( char, scale, offsetX, offsetY, data ) {
107         const glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
109         if ( ! glyph ) {
111                 console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
113                 return;
115         }
117         const path = new ShapePath();
119         let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
121         if ( glyph.o ) {
123                 const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
125                 for ( let i = 0, l = outline.length; i < l; ) {
127                         const action = outline[ i ++ ];
129                         switch ( action ) {
131                                 case 'm': // moveTo
133                                         x = outline[ i ++ ] * scale + offsetX;
134                                         y = outline[ i ++ ] * scale + offsetY;
136                                         path.moveTo( x, y );
138                                         break;
140                                 case 'l': // lineTo
142                                         x = outline[ i ++ ] * scale + offsetX;
143                                         y = outline[ i ++ ] * scale + offsetY;
145                                         path.lineTo( x, y );
147                                         break;
149                                 case 'q': // quadraticCurveTo
151                                         cpx = outline[ i ++ ] * scale + offsetX;
152                                         cpy = outline[ i ++ ] * scale + offsetY;
153                                         cpx1 = outline[ i ++ ] * scale + offsetX;
154                                         cpy1 = outline[ i ++ ] * scale + offsetY;
156                                         path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
158                                         break;
160                                 case 'b': // bezierCurveTo
162                                         cpx = outline[ i ++ ] * scale + offsetX;
163                                         cpy = outline[ i ++ ] * scale + offsetY;
164                                         cpx1 = outline[ i ++ ] * scale + offsetX;
165                                         cpy1 = outline[ i ++ ] * scale + offsetY;
166                                         cpx2 = outline[ i ++ ] * scale + offsetX;
167                                         cpy2 = outline[ i ++ ] * scale + offsetY;
169                                         path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
171                                         break;
173                         }
175                 }
177         }
179         return { offsetX: glyph.ha * scale, path: path };
183 export { FontLoader, Font };