glyph.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. var Glyph = {
  2. ratio: null,
  3. head: null,
  4. os2: null,
  5. hmtx: null,
  6. midValue: function (a, b){
  7. return a + (b - a)/2;
  8. },
  9. splitPath: function(path) {
  10. return path.match(/([a-z])|(-?\d+(?:\.\d+)?)/ig);
  11. },
  12. drawSVGContours: function(ctx, path) {
  13. var p = Glyph.splitPath(path);
  14. if (!p) {
  15. return;
  16. }
  17. var l = p.length;
  18. var i = 0;
  19. while(i < l) {
  20. var v = p[i];
  21. switch(v) {
  22. case "M":
  23. ctx.beginPath();
  24. ctx.moveTo(p[++i], p[++i]);
  25. break;
  26. case "L":
  27. ctx.lineTo(p[++i], p[++i]);
  28. break;
  29. case "Q":
  30. ctx.quadraticCurveTo(p[++i], p[++i], p[++i], p[++i]);
  31. break;
  32. case "z":
  33. ctx.closePath();
  34. ctx.fill();
  35. i++;
  36. break;
  37. default:
  38. i++;
  39. }
  40. }
  41. },
  42. drawHorizLine: function(ctx, y, color) {
  43. ctx.beginPath();
  44. ctx.strokeStyle = color;
  45. ctx.moveTo(0, y);
  46. ctx.lineTo(Glyph.width * Glyph.ratio, y);
  47. ctx.closePath();
  48. ctx.stroke();
  49. },
  50. draw: function (canvas, shape, gid) {
  51. var element = canvas[0];
  52. var ctx = element.getContext("2d");
  53. var ratio = Glyph.ratio;
  54. Glyph.width = element.width;
  55. Glyph.height = element.height;
  56. ctx.lineWidth = ratio;
  57. // Invert axis
  58. ctx.translate(0, Glyph.height);
  59. ctx.scale(1/ratio, -(1/ratio));
  60. ctx.translate(0, -Glyph.head.yMin);
  61. // baseline
  62. Glyph.drawHorizLine(ctx, 0, "rgba(0,255,0,0.2)");
  63. // ascender
  64. Glyph.drawHorizLine(ctx, Glyph.os2.typoAscender, "rgba(255,0,0,0.2)");
  65. // descender
  66. Glyph.drawHorizLine(ctx, -Math.abs(Glyph.os2.typoDescender), "rgba(255,0,0,0.2)");
  67. ctx.translate(-Glyph.head.xMin, 0);
  68. ctx.save();
  69. var s = ratio*3;
  70. ctx.strokeStyle = "rgba(0,0,0,0.5)";
  71. ctx.lineWidth = ratio * 1.5;
  72. // origin
  73. ctx.beginPath();
  74. ctx.moveTo(-s, -s);
  75. ctx.lineTo(+s, +s);
  76. ctx.moveTo(+s, -s);
  77. ctx.lineTo(-s, +s);
  78. ctx.closePath();
  79. ctx.stroke();
  80. // horizontal advance
  81. var advance = Glyph.hmtx[gid][0];
  82. ctx.beginPath();
  83. ctx.moveTo(-s+advance, -s);
  84. ctx.lineTo(+s+advance, +s);
  85. ctx.moveTo(+s+advance, -s);
  86. ctx.lineTo(-s+advance, +s);
  87. ctx.closePath();
  88. ctx.stroke();
  89. ctx.restore();
  90. if (!shape) {
  91. return;
  92. }
  93. // glyph bounding box
  94. ctx.beginPath();
  95. ctx.strokeStyle = "rgba(0,0,0,0.3)";
  96. ctx.rect(0, 0, shape.xMin + shape.xMax, shape.yMin + shape.yMax);
  97. ctx.closePath();
  98. ctx.stroke();
  99. ctx.strokeStyle = "black";
  100. ctx.globalCompositeOperation = "xor";
  101. Glyph.drawSVGContours(ctx, shape.SVGContours);
  102. }
  103. };