diff --git a/README.md b/README.md index aae7258..8c4158a 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ var svg = ctx.getSvg(); Updates ========== +- v1.0.5 fixes for #5 and #6 (with contributions from KoKuToru) - v1.0.4 generate ids that start with a letter - v1.0.3 fixed #4 where largeArcFlag was set incorrectly in some cases - v1.0.2 Split up rgba values set in fill/stroke to allow illustrator import support. diff --git a/canvas2svg.js b/canvas2svg.js index 898a3f8..34b974a 100644 --- a/canvas2svg.js +++ b/canvas2svg.js @@ -1,5 +1,5 @@ /*!! - * Canvas 2 Svg v1.0.4 + * Canvas 2 Svg v1.0.5 * A low level canvas to SVG converter. Uses a mock canvas context to build an SVG document. * * Licensed under the MIT license: @@ -57,6 +57,13 @@ lookup["\\xa0"] = ' '; return lookup; } + + //helper function to map canvas-textAlign to svg-textAnchor + function getTextAnchor(textAlign) { + //TODO: support rtl languages + var mapping = {"left":"start", "right":"end", "center":"middle", "start":"start", "end":"end"}; + return mapping[textAlign] || mapping.start; + } // Unpack entities lookup where the numbers are in radix 32 to reduce the size // entity mapping courtesy of tinymce @@ -507,6 +514,9 @@ * if the currentPathElement is not empty create a new path element */ ctx.prototype.moveTo = function(x,y){ + if(this.__currentElement.nodeName !== "path") { + this.beginPath(); + } this.__addPathCommand(format("M {x} {y}", {x:x, y:y})); }; @@ -746,7 +756,8 @@ "font-weight" : font.weight, "text-decoration" : font.decoration, "x" : x, - "y" : y + "y" : y, + "text-anchor": getTextAnchor(this.textAlign) }, true); textElement.appendChild(document.createTextNode(text)); @@ -781,6 +792,7 @@ * @return {TextMetrics} */ ctx.prototype.measureText = function(text){ + this.__ctx.font = this.font; return this.__ctx.measureText(text); }; diff --git a/jasmine-tests/spec/canvas2svgspec.js b/jasmine-tests/spec/canvas2svgspec.js index b4b3cdf..00674c9 100755 --- a/jasmine-tests/spec/canvas2svgspec.js +++ b/jasmine-tests/spec/canvas2svgspec.js @@ -38,11 +38,11 @@ describe("canvas2svg", function() { expect(ctx2.height).toEqual(400); expect(ctx2.enableMirroring).toEqual(false); - var ctx = C2S(); - expect(ctx instanceof C2S).toBe(true); - expect(ctx.width).toEqual(500); - expect(ctx.height).toEqual(500); - expect(ctx.enableMirroring).toEqual(false); + var ctx3 = C2S(); + expect(ctx3 instanceof C2S).toBe(true); + expect(ctx3.width).toEqual(500); + expect(ctx3.height).toEqual(500); + expect(ctx3.enableMirroring).toEqual(false); }); @@ -155,4 +155,77 @@ describe("canvas2svg", function() { }); }); + describe("supports path commands", function() { + + it("and moveTo may be called without beginPath, but is not recommended", function() { + var ctx = new C2S(); + ctx.moveTo(0,0); + ctx.lineTo(100,100); + ctx.stroke(); + }); + }); + + describe("supports text align", function() { + + it("not specifying a value defaults to 'start'", function() { + + var ctx = new C2S(); + ctx.font = "normal 36px Times"; + ctx.fillStyle = "#000000"; + ctx.fillText("A Text Example", 0, 50); + var svg = ctx.getSvg(); + expect(svg.querySelector("text").getAttribute("text-anchor")).toBe("start"); + + }); + + it("assuming ltr, left maps to 'start'", function() { + + var ctx = new C2S(); + ctx.textAlign = "left"; + ctx.font = "normal 36px Times"; + ctx.fillStyle = "#000000"; + ctx.fillText("A Text Example", 0, 50); + var svg = ctx.getSvg(); + expect(svg.querySelector("text").getAttribute("text-anchor")).toBe("start"); + + }); + + it("assuming ltr, right maps to 'end'", function() { + + var ctx = new C2S(); + ctx.textAlign = "right"; + ctx.font = "normal 36px Times"; + ctx.fillStyle = "#000000"; + ctx.fillText("A Text Example", 0, 50); + var svg = ctx.getSvg(); + expect(svg.querySelector("text").getAttribute("text-anchor")).toBe("end"); + + }); + + it("center maps to 'middle'", function() { + + var ctx = new C2S(); + ctx.textAlign = "center"; + ctx.font = "normal 36px Times"; + ctx.fillStyle = "#000000"; + ctx.fillText("A Text Example", 0, 50); + var svg = ctx.getSvg(); + expect(svg.querySelector("text").getAttribute("text-anchor")).toBe("middle"); + + }); + + it("stores the proper values on save and restore", function() { + var ctx = new C2S(); + ctx.textAlign = "center"; + expect(ctx.textAlign).toBe("center"); + ctx.save(); + expect(ctx.textAlign).toBe("center"); + ctx.textAlign = "right"; + expect(ctx.textAlign).toBe("right"); + ctx.restore(); + expect(ctx.textAlign).toBe("center"); + }); + + }); + });