FontLoader.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. ( function () {
  2. class FontLoader extends THREE.Loader {
  3. constructor( manager ) {
  4. super( manager );
  5. }
  6. load( url, onLoad, onProgress, onError ) {
  7. const scope = this;
  8. const loader = new THREE.FileLoader( this.manager );
  9. loader.setPath( this.path );
  10. loader.setRequestHeader( this.requestHeader );
  11. loader.setWithCredentials( scope.withCredentials );
  12. loader.load( url, function ( text ) {
  13. let json;
  14. try {
  15. json = JSON.parse( text );
  16. } catch ( e ) {
  17. console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );
  18. json = JSON.parse( text.substring( 65, text.length - 2 ) );
  19. }
  20. const font = scope.parse( json );
  21. if ( onLoad ) onLoad( font );
  22. }, onProgress, onError );
  23. }
  24. parse( json ) {
  25. return new Font( json );
  26. }
  27. } //
  28. class Font {
  29. constructor( data ) {
  30. this.isFont = true;
  31. this.type = 'Font';
  32. this.data = data;
  33. }
  34. generateShapes( text, size = 100 ) {
  35. const shapes = [];
  36. const paths = createPaths( text, size, this.data );
  37. for ( let p = 0, pl = paths.length; p < pl; p ++ ) {
  38. shapes.push( ...paths[ p ].toShapes() );
  39. }
  40. return shapes;
  41. }
  42. }
  43. function createPaths( text, size, data ) {
  44. const chars = Array.from( text );
  45. const scale = size / data.resolution;
  46. const line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
  47. const paths = [];
  48. let offsetX = 0,
  49. offsetY = 0;
  50. for ( let i = 0; i < chars.length; i ++ ) {
  51. const char = chars[ i ];
  52. if ( char === '\n' ) {
  53. offsetX = 0;
  54. offsetY -= line_height;
  55. } else {
  56. const ret = createPath( char, scale, offsetX, offsetY, data );
  57. offsetX += ret.offsetX;
  58. paths.push( ret.path );
  59. }
  60. }
  61. return paths;
  62. }
  63. function createPath( char, scale, offsetX, offsetY, data ) {
  64. const glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
  65. if ( ! glyph ) {
  66. console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
  67. return;
  68. }
  69. const path = new THREE.ShapePath();
  70. let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
  71. if ( glyph.o ) {
  72. const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
  73. for ( let i = 0, l = outline.length; i < l; ) {
  74. const action = outline[ i ++ ];
  75. switch ( action ) {
  76. case 'm':
  77. // moveTo
  78. x = outline[ i ++ ] * scale + offsetX;
  79. y = outline[ i ++ ] * scale + offsetY;
  80. path.moveTo( x, y );
  81. break;
  82. case 'l':
  83. // lineTo
  84. x = outline[ i ++ ] * scale + offsetX;
  85. y = outline[ i ++ ] * scale + offsetY;
  86. path.lineTo( x, y );
  87. break;
  88. case 'q':
  89. // quadraticCurveTo
  90. cpx = outline[ i ++ ] * scale + offsetX;
  91. cpy = outline[ i ++ ] * scale + offsetY;
  92. cpx1 = outline[ i ++ ] * scale + offsetX;
  93. cpy1 = outline[ i ++ ] * scale + offsetY;
  94. path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
  95. break;
  96. case 'b':
  97. // bezierCurveTo
  98. cpx = outline[ i ++ ] * scale + offsetX;
  99. cpy = outline[ i ++ ] * scale + offsetY;
  100. cpx1 = outline[ i ++ ] * scale + offsetX;
  101. cpy1 = outline[ i ++ ] * scale + offsetY;
  102. cpx2 = outline[ i ++ ] * scale + offsetX;
  103. cpy2 = outline[ i ++ ] * scale + offsetY;
  104. path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
  105. break;
  106. }
  107. }
  108. }
  109. return {
  110. offsetX: glyph.ha * scale,
  111. path: path
  112. };
  113. }
  114. THREE.Font = Font;
  115. THREE.FontLoader = FontLoader;
  116. } )();