175 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
			Vendored
		
	
	
	
| var Glyph = {
 | |
|   glyphs: [],
 | |
|   ratio: null, 
 | |
|   head:  null, 
 | |
|   os2:   null, 
 | |
|   hmtx:  null,
 | |
|   width: null,
 | |
|   height: null,
 | |
|   scale: 1.0,
 | |
|   
 | |
|   splitPath: function(path) {
 | |
|   	return path.match(/([a-z])|(-?\d+(?:\.\d+)?)/ig);
 | |
|   },
 | |
| 
 | |
|   drawPath: function(ctx, path) {
 | |
|     var p = Glyph.splitPath(path);
 | |
| 
 | |
|     if (!p) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     var l = p.length;
 | |
|     var i = 0;
 | |
| 
 | |
|     ctx.beginPath();
 | |
| 
 | |
|     while(i < l) {
 | |
|       var v = p[i];
 | |
| 
 | |
|       switch(v) {
 | |
|         case "M":
 | |
|           ctx.moveTo(p[++i], p[++i]);
 | |
|           break;
 | |
| 
 | |
|         case "L":
 | |
|           ctx.lineTo(p[++i], p[++i]);
 | |
|           break;
 | |
| 
 | |
|         case "Q":
 | |
|           ctx.quadraticCurveTo(p[++i], p[++i], p[++i], p[++i]);
 | |
|           break;
 | |
| 
 | |
|         case "z":
 | |
|           i++;
 | |
|           break;
 | |
| 
 | |
|         default:
 | |
|           i++;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     ctx.fill();
 | |
|     ctx.closePath();
 | |
|   },
 | |
|   
 | |
|   drawSVGContours: function(ctx, contours) {
 | |
|     // Is the path
 | |
|     if (!$.isArray(contours)) {
 | |
|       Glyph.drawPath(ctx, contours);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     var contour, path, transform;
 | |
| 
 | |
|     for (var ci = 0, cl = contours.length; ci < cl; ci++) {
 | |
|       contour = contours[ci];
 | |
|       path = contour.contours;
 | |
|       transform = contour.transform;
 | |
| 
 | |
|       ctx.save();
 | |
|       ctx.transform(transform[0], transform[1], transform[2], transform[3], transform[4], transform[5]);
 | |
|       Glyph.drawSVGContours(ctx, path);
 | |
|       ctx.restore();
 | |
|     }
 | |
|   },
 | |
|   
 | |
|   drawHorizLine: function(ctx, y, color) {
 | |
|     ctx.beginPath();
 | |
|     ctx.strokeStyle = color;
 | |
|     ctx.moveTo(0, y);
 | |
|     ctx.lineTo(Glyph.width * Glyph.ratio, y);
 | |
|     ctx.closePath();
 | |
|     ctx.stroke();
 | |
|   },
 | |
|   
 | |
|   draw: function (canvas, shape, gid) {
 | |
|     var element  = canvas[0];
 | |
|     var ctx      = element.getContext("2d");
 | |
|     var ratio    = Glyph.ratio;
 | |
|     var width    = Glyph.width  * Glyph.scale;
 | |
|     var height   = Glyph.height * Glyph.scale;
 | |
|     ctx.clearRect(0, 0, width, height);
 | |
| 
 | |
|     ctx.lineWidth = ratio / Glyph.scale;
 | |
|     
 | |
|     // Invert axis
 | |
|     ctx.translate(0, height);
 | |
|     ctx.scale(1/ratio, -(1/ratio));
 | |
|     ctx.scale(Glyph.scale, Glyph.scale);
 | |
|     
 | |
|     ctx.translate(0, -Glyph.head.yMin);
 | |
|     
 | |
|     // baseline
 | |
|     Glyph.drawHorizLine(ctx, 0, "rgba(0,255,0,0.2)");
 | |
|     
 | |
|     // ascender
 | |
|     Glyph.drawHorizLine(ctx, Glyph.os2.typoAscender, "rgba(255,0,0,0.2)");
 | |
|     
 | |
|     // descender
 | |
|     Glyph.drawHorizLine(ctx, -Math.abs(Glyph.os2.typoDescender), "rgba(255,0,0,0.2)");
 | |
|     
 | |
|     ctx.translate(-Glyph.head.xMin, 0);
 | |
|     
 | |
|     ctx.save();
 | |
|       var s = ratio*3;
 | |
|       
 | |
|       ctx.strokeStyle = "rgba(0,0,0,0.5)";
 | |
|       ctx.lineWidth = (ratio * 1.5) / Glyph.scale;
 | |
|       
 | |
|       // origin
 | |
|       ctx.beginPath();
 | |
|       ctx.moveTo(-s, -s);
 | |
|       ctx.lineTo(+s, +s);
 | |
|       ctx.moveTo(+s, -s);
 | |
|       ctx.lineTo(-s, +s);
 | |
|       ctx.closePath();
 | |
|       ctx.stroke();
 | |
|       
 | |
|       // horizontal advance
 | |
|       var advance = Glyph.hmtx[gid][0];
 | |
|       ctx.beginPath();
 | |
|       ctx.moveTo(-s+advance, -s);
 | |
|       ctx.lineTo(+s+advance, +s);
 | |
|       ctx.moveTo(+s+advance, -s);
 | |
|       ctx.lineTo(-s+advance, +s);
 | |
|       ctx.closePath();
 | |
|       ctx.stroke();
 | |
|     ctx.restore();
 | |
|     
 | |
|     if (!shape) {
 | |
|       return;
 | |
|     }
 | |
|     
 | |
|     // glyph bounding box
 | |
|     ctx.beginPath();
 | |
|     ctx.strokeStyle = "rgba(0,0,0,0.3)";
 | |
|     ctx.rect(0, 0, shape.xMin + shape.xMax, shape.yMin + shape.yMax);
 | |
|     ctx.closePath();
 | |
|     ctx.stroke();
 | |
|     
 | |
|     ctx.strokeStyle = "black";
 | |
|     //ctx.globalCompositeOperation = "xor";
 | |
|     
 | |
|     Glyph.drawSVGContours(ctx, shape.SVGContours);
 | |
|   },
 | |
|   drawAll: function(){
 | |
|     $.each(Glyph.glyphs, function(i, g){
 | |
|       Glyph.draw($('#glyph-canvas-'+g[0]), g[1], g[0]);
 | |
|     });
 | |
|   },
 | |
|   resize: function(value){
 | |
|     Glyph.scale = value / 100;
 | |
| 
 | |
|     $.each(document.getElementsByTagName('canvas'), function(i, canvas){
 | |
|       canvas.height = Glyph.height * Glyph.scale;
 | |
|       canvas.width  = Glyph.width  * Glyph.scale;
 | |
|     });
 | |
| 
 | |
|     Glyph.drawAll();
 | |
|   }
 | |
| };
 | |
| 
 | |
| $(function(){
 | |
|   Glyph.drawAll();
 | |
| }); | 
