Download raw (2.1 KB)
var parser = new DOMParser(), doc = parser.parseFromString('<TTGlyph name="A" xMin="0" yMin="0" xMax="500" yMax="750"><contour><pt x="100" y="100" on="1"/><pt x="300" y="100" on="1"/><pt x="300" y="300" on="1"/><pt x="100" y="300" on="1"/></contour><instructions/></TTGlyph>', 'text/xml'), deltas = parser.parseFromString('<glyphVariations glyph="A"><tuple><coord axis="wght" value="1.0"/><delta pt="0" x="-100" y="-100"/><delta pt="1" x="100" y="-100"/><delta pt="2" x="100" y="100"/><delta pt="3" x="-100" y="100"/></tuple></glyphVariations>', 'text/xml'), canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d'), points = []; doc.childNodes.forEach((glyph) => { if (glyph.nodeName.toLowerCase() == 'ttglyph') { glyph.childNodes.forEach((contour) => { if (contour.nodeName.toLowerCase() == 'contour') { ctx.save(); ctx.transform(1, 0, 0, -1, 200, 800); ctx.beginPath(); contour.childNodes.forEach((pt, k) => { if (pt.nodeName.toLowerCase() == 'pt') { var x = parseInt(pt.attributes.x.value), y = parseInt(pt.attributes.y.value); if (k > 0) { ctx.lineTo(x, y); } else { ctx.moveTo(x, y); } points.push([x, y]); } }); ctx.closePath(); ctx.stroke(); ctx.restore(); } }); } }); console.log(deltas) deltas.querySelectorAll('glyphVariations').forEach((glyphVariations) => { glyphVariations.querySelectorAll('tuple').forEach((tuple) => { tuple.querySelectorAll('delta').forEach((delta) => { var pt = delta.attributes.pt.value, x = parseInt(delta.attributes.x.value), y = parseInt(delta.attributes.y.value); ctx.save(); ctx.transform(1, 0, 0, -1, 200, 800); ctx.beginPath(); ctx.moveTo(points[pt][0], points[pt][1]); ctx.lineTo(points[pt][0] + x, points[pt][1] + y); ctx.stroke(); ctx.beginPath(); ctx.arc(points[pt][0] + x, points[pt][1] + y, 2, 0, 2 * Math.PI, false); ctx.fill(); ctx.restore(); }); }); });