Font.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * @author zz85 / http://www.lab4games.net/zz85/blog
  3. * @author mrdoob / http://mrdoob.com/
  4. */
  5. import { ShapePath } from './ShapePath.js';
  6. function Font( data ) {
  7. this.type = 'Font';
  8. this.data = data;
  9. }
  10. Object.assign( Font.prototype, {
  11. isFont: true,
  12. generateShapes: function ( text, size, divisions ) {
  13. if ( size === undefined ) size = 100;
  14. if ( divisions === undefined ) divisions = 4;
  15. var shapes = [];
  16. var paths = createPaths( text, size, divisions, this.data );
  17. for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
  18. Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
  19. }
  20. return shapes;
  21. }
  22. } );
  23. function createPaths( text, size, divisions, data ) {
  24. var chars = String( text ).split( '' );
  25. var scale = size / data.resolution;
  26. var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
  27. var paths = [];
  28. var offsetX = 0, offsetY = 0;
  29. for ( var i = 0; i < chars.length; i ++ ) {
  30. var char = chars[ i ];
  31. if ( char === '\n' ) {
  32. offsetX = 0;
  33. offsetY -= line_height;
  34. } else {
  35. var ret = createPath( char, divisions, scale, offsetX, offsetY, data );
  36. offsetX += ret.offsetX;
  37. paths.push( ret.path );
  38. }
  39. }
  40. return paths;
  41. }
  42. function createPath( char, divisions, scale, offsetX, offsetY, data ) {
  43. var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
  44. if ( ! glyph ) return;
  45. var path = new ShapePath();
  46. var x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
  47. if ( glyph.o ) {
  48. var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
  49. for ( var i = 0, l = outline.length; i < l; ) {
  50. var action = outline[ i ++ ];
  51. switch ( action ) {
  52. case 'm': // moveTo
  53. x = outline[ i ++ ] * scale + offsetX;
  54. y = outline[ i ++ ] * scale + offsetY;
  55. path.moveTo( x, y );
  56. break;
  57. case 'l': // lineTo
  58. x = outline[ i ++ ] * scale + offsetX;
  59. y = outline[ i ++ ] * scale + offsetY;
  60. path.lineTo( x, y );
  61. break;
  62. case 'q': // quadraticCurveTo
  63. cpx = outline[ i ++ ] * scale + offsetX;
  64. cpy = outline[ i ++ ] * scale + offsetY;
  65. cpx1 = outline[ i ++ ] * scale + offsetX;
  66. cpy1 = outline[ i ++ ] * scale + offsetY;
  67. path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
  68. break;
  69. case 'b': // bezierCurveTo
  70. cpx = outline[ i ++ ] * scale + offsetX;
  71. cpy = outline[ i ++ ] * scale + offsetY;
  72. cpx1 = outline[ i ++ ] * scale + offsetX;
  73. cpy1 = outline[ i ++ ] * scale + offsetY;
  74. cpx2 = outline[ i ++ ] * scale + offsetX;
  75. cpy2 = outline[ i ++ ] * scale + offsetY;
  76. path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
  77. break;
  78. }
  79. }
  80. }
  81. return { offsetX: glyph.ha * scale, path: path };
  82. }
  83. export { Font };