Font.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /**
  2. * @author zz85 / http://www.lab4games.net/zz85/blog
  3. * @author mrdoob / http://mrdoob.com/
  4. */
  5. THREE.Font = function ( data ) {
  6. this.data = data;
  7. };
  8. THREE.Font.prototype = {
  9. constructor: THREE.Font,
  10. generateShapes: function ( text, size, curveSegments ) {
  11. function createPaths( text ) {
  12. var chars = String( text ).split( '' );
  13. var scale = size / data.resolution;
  14. var offset = 0;
  15. var paths = [];
  16. for ( var i = 0; i < chars.length; i ++ ) {
  17. var path = new THREE.Path();
  18. var ret = extractGlyphPoints( chars[ i ], scale, offset, path );
  19. offset += ret.offset;
  20. paths.push( ret.path );
  21. }
  22. return paths;
  23. }
  24. function extractGlyphPoints( c, scale, offset, path ) {
  25. var pts = [];
  26. var b2 = THREE.ShapeUtils.b2;
  27. var b3 = THREE.ShapeUtils.b3;
  28. var i, i2, divisions,
  29. outline, action, length,
  30. scaleX, scaleY,
  31. x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2,
  32. laste,
  33. glyph = data.glyphs[ c ] || data.glyphs[ '?' ];
  34. if ( ! glyph ) return;
  35. if ( glyph.o ) {
  36. outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
  37. length = outline.length;
  38. scaleX = scale;
  39. scaleY = scale;
  40. for ( i = 0; i < length; ) {
  41. action = outline[ i ++ ];
  42. //console.log( action );
  43. switch ( action ) {
  44. case 'm':
  45. // Move To
  46. x = outline[ i ++ ] * scaleX + offset;
  47. y = outline[ i ++ ] * scaleY;
  48. path.moveTo( x, y );
  49. break;
  50. case 'l':
  51. // Line To
  52. x = outline[ i ++ ] * scaleX + offset;
  53. y = outline[ i ++ ] * scaleY;
  54. path.lineTo( x, y );
  55. break;
  56. case 'q':
  57. // QuadraticCurveTo
  58. cpx = outline[ i ++ ] * scaleX + offset;
  59. cpy = outline[ i ++ ] * scaleY;
  60. cpx1 = outline[ i ++ ] * scaleX + offset;
  61. cpy1 = outline[ i ++ ] * scaleY;
  62. path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
  63. laste = pts[ pts.length - 1 ];
  64. if ( laste ) {
  65. cpx0 = laste.x;
  66. cpy0 = laste.y;
  67. for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
  68. var t = i2 / divisions;
  69. b2( t, cpx0, cpx1, cpx );
  70. b2( t, cpy0, cpy1, cpy );
  71. }
  72. }
  73. break;
  74. case 'b':
  75. // Cubic Bezier Curve
  76. cpx = outline[ i ++ ] * scaleX + offset;
  77. cpy = outline[ i ++ ] * scaleY;
  78. cpx1 = outline[ i ++ ] * scaleX + offset;
  79. cpy1 = outline[ i ++ ] * scaleY;
  80. cpx2 = outline[ i ++ ] * scaleX + offset;
  81. cpy2 = outline[ i ++ ] * scaleY;
  82. path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
  83. laste = pts[ pts.length - 1 ];
  84. if ( laste ) {
  85. cpx0 = laste.x;
  86. cpy0 = laste.y;
  87. for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
  88. var t = i2 / divisions;
  89. b3( t, cpx0, cpx1, cpx2, cpx );
  90. b3( t, cpy0, cpy1, cpy2, cpy );
  91. }
  92. }
  93. break;
  94. }
  95. }
  96. }
  97. return { offset: glyph.ha * scale, path: path };
  98. }
  99. //
  100. if ( size === undefined ) size = 100;
  101. if ( curveSegments === undefined ) curveSegments = 4;
  102. var data = this.data;
  103. var paths = createPaths( text );
  104. var shapes = [];
  105. for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
  106. Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
  107. }
  108. return shapes;
  109. }
  110. };