diff --git a/AUTHORS.md b/AUTHORS.md index 23eae2a7..3feb569e 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -2,3 +2,12 @@ - Juerg Lehni - Jonathan Puckey + +## Contributors + +- Jt Whissel +- Andrew Roles +- Jacob Lites +- Justin Ridgewell +- Andrew Wagenheim +- Scott Kieronski diff --git a/examples/ExportSVGTests/Circle Testing.html b/examples/ExportSVGTests/Circle Testing.html new file mode 100644 index 00000000..ee665747 --- /dev/null +++ b/examples/ExportSVGTests/Circle Testing.html @@ -0,0 +1,47 @@ + + + + + Circle Testing + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ExportSVGTests/Empty Path Testing.html b/examples/ExportSVGTests/Empty Path Testing.html new file mode 100644 index 00000000..36a71de5 --- /dev/null +++ b/examples/ExportSVGTests/Empty Path Testing.html @@ -0,0 +1,41 @@ + + + + + Empty Path Testing + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ExportSVGTests/Line Testing.html b/examples/ExportSVGTests/Line Testing.html new file mode 100644 index 00000000..0a249da2 --- /dev/null +++ b/examples/ExportSVGTests/Line Testing.html @@ -0,0 +1,60 @@ + + + + + Line Testing + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ExportSVGTests/Random Path Testing.html b/examples/ExportSVGTests/Random Path Testing.html new file mode 100644 index 00000000..6a38bb85 --- /dev/null +++ b/examples/ExportSVGTests/Random Path Testing.html @@ -0,0 +1,54 @@ + + + + + Random Path Testing + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ExportSVGTests/Rect and Attribute Testing.html b/examples/ExportSVGTests/Rect and Attribute Testing.html new file mode 100644 index 00000000..10610cdd --- /dev/null +++ b/examples/ExportSVGTests/Rect and Attribute Testing.html @@ -0,0 +1,70 @@ + + + + + Rectangle Testing + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ExportSVGTests/Text Testing.html b/examples/ExportSVGTests/Text Testing.html new file mode 100644 index 00000000..565eaf1f --- /dev/null +++ b/examples/ExportSVGTests/Text Testing.html @@ -0,0 +1,55 @@ + + + + + Text Testing + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ExportSVGTests/Transform Test 1.html b/examples/ExportSVGTests/Transform Test 1.html new file mode 100644 index 00000000..028b2597 --- /dev/null +++ b/examples/ExportSVGTests/Transform Test 1.html @@ -0,0 +1,45 @@ + + + + + Transform Testing + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ExportSVGTests/Transform Test 2.html b/examples/ExportSVGTests/Transform Test 2.html new file mode 100644 index 00000000..527e2b33 --- /dev/null +++ b/examples/ExportSVGTests/Transform Test 2.html @@ -0,0 +1,39 @@ + + + + + Rectangle Testing + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Circle and Oval Testing.html b/examples/ImportSVGTests/Circle and Oval Testing.html new file mode 100644 index 00000000..3491aa02 --- /dev/null +++ b/examples/ImportSVGTests/Circle and Oval Testing.html @@ -0,0 +1,33 @@ + + + + + Circle and Oval Testing + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Line Testing.html b/examples/ImportSVGTests/Line Testing.html new file mode 100644 index 00000000..8a1987ef --- /dev/null +++ b/examples/ImportSVGTests/Line Testing.html @@ -0,0 +1,32 @@ + + + + + Line Testing + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Multiple Paths Test 1.html b/examples/ImportSVGTests/Multiple Paths Test 1.html new file mode 100644 index 00000000..e8093601 --- /dev/null +++ b/examples/ImportSVGTests/Multiple Paths Test 1.html @@ -0,0 +1,49 @@ + + + + + Multiple Paths Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + I love SVG + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Multiple Paths Test 2.html b/examples/ImportSVGTests/Multiple Paths Test 2.html new file mode 100644 index 00000000..76074cd0 --- /dev/null +++ b/examples/ImportSVGTests/Multiple Paths Test 2.html @@ -0,0 +1,45 @@ + + + + + Stroke Bounds + + + + + + + + + + + + + + + + + + + A + B + C + + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Nested Groups Test.html b/examples/ImportSVGTests/Nested Groups Test.html new file mode 100644 index 00000000..555e2d5c --- /dev/null +++ b/examples/ImportSVGTests/Nested Groups Test.html @@ -0,0 +1,85 @@ + + + + + + Nested Groups Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Rect Testing.html b/examples/ImportSVGTests/Rect Testing.html new file mode 100644 index 00000000..dea89180 --- /dev/null +++ b/examples/ImportSVGTests/Rect Testing.html @@ -0,0 +1,30 @@ + + + + + Rect Testing + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Testing.html b/examples/ImportSVGTests/Testing.html new file mode 100644 index 00000000..434107ee --- /dev/null +++ b/examples/ImportSVGTests/Testing.html @@ -0,0 +1,47 @@ + + + + + Stroke Bounds + + + + + + + + + + + + + + + + + + + + + + + + + + + + + I love SVG + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Text Testing.html b/examples/ImportSVGTests/Text Testing.html new file mode 100644 index 00000000..63a5b21a --- /dev/null +++ b/examples/ImportSVGTests/Text Testing.html @@ -0,0 +1,27 @@ + + + + + Text Testing + + + + + + + Plain SVG Text + + Rotated SVG Text + + + + + \ No newline at end of file diff --git a/examples/ImportSVGTests/Transform Testing.html b/examples/ImportSVGTests/Transform Testing.html new file mode 100644 index 00000000..5576486f --- /dev/null +++ b/examples/ImportSVGTests/Transform Testing.html @@ -0,0 +1,29 @@ + + + + + Circle and Oval Testing + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/paper.js b/src/paper.js index 3052ee61..757274f8 100644 --- a/src/paper.js +++ b/src/paper.js @@ -93,6 +93,9 @@ var paper = new function() { /*#*/ include('text/TextItem.js'); /*#*/ include('text/PointText.js'); +/*#*/ include('svg/ExportSVG.js'); +/*#*/ include('svg/ImportSVG.js'); + /*#*/ include('style/Style.js'); /*#*/ include('style/PathStyle.js'); /*#*/ include('style/ParagraphStyle.js'); diff --git a/src/svg/ExportSVG.js b/src/svg/ExportSVG.js new file mode 100644 index 00000000..26bc5464 --- /dev/null +++ b/src/svg/ExportSVG.js @@ -0,0 +1,477 @@ + /* + * Paper.js + * + * This file is part of Paper.js, a JavaScript Vector Graphics Library, + * based on Scriptographer.org and designed to be largely API compatible. + * http://paperjs.org/ + * http://scriptographer.org/ + * + * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey + * http://lehni.org/ & http://jonathanpuckey.com/ + * + * Distributed under the MIT license. See LICENSE file for details. + * + * All rights reserved. + * + * This class and all methods therein programmed by Stetson-Team-Alpha + * @author Stetson-Team-Alpha + */ + + + /** + * @name ExportSVG + * + * @class The ExportSVG object represents a Paper.js object that will be + * converted into an SVG canvas design. + * The Paper.js object is converted by changing its items into groups + * + */ + +var ExportSVG = this.ExportSVG = Base.extend(/** @Lends ExportSVG# */{ + //initialize the svgObj + initialize: function() { + this.NS = 'http://www.w3.org/2000/svg'; + this.svgObj = document.createElementNS(this.NS, 'svg'); + }, + + /** + * Takes the selected Paper.js project and parses all of its layers and + * groups to be placed into SVG groups, converting the project into one + * SVG group. + * + * @function + * @param {Paper.js Project} project A Paper.js project + * @return {SVG DOM} this.svgObj The imported project converted to an + * SVG project + */ + //TODO: Implement symbols and Gradients + exportProject: function(project) { + var layerArray = project.layers; + var layer; + for (var i = 0; i < layerArray.length; ++i) { + layer = layerArray[i]; + this.svgObj.appendChild(this.exportLayer(layer)); + } + return this.svgObj; + }, + + /** + * + * Takes the selected Paper.js layer and parses all groups + * and items on the layer into one SVG + * + * @name ExportSVG#exportLayer + * @function + * @param {Paper.js Layer} layer A Paper.js layer + * @return {SVG DOM} this.exportGroup(layer) The layer converted into an + * SVG group + */ + exportLayer: function(layer) { + return this.exportGroup(layer); + }, + + /** + * + * Takes a Paper.js group and puts its items in a SVG file. + * + * @name ExportSVG#exportGroup + * @function + * @param {Paper.js Group} group A Paper.js group + * @return {SVG DOM} svgG An SVG object + */ + exportGroup: function(group) { + var svgG = document.createElementNS(this.NS, 'g'); + var curChild; + + for (var i in group.children) { + curChild = group.children[i]; + if (curChild.children) { + svgG.appendChild(this.exportGroup(curChild)); + } else { + svgG.appendChild(this.exportPath(curChild)); + } + } + return svgG; + }, + + /** + * + * Takes the path and puts it in + * a svg file. + * + * @name ExportSVG#exportPath + * @function + * @param {Paper.js Path} path A Paper.js path object + * @return {SVG DOM} svgPath An SVG object of the imported path + */ + exportPath: function(path) { + var svgEle; + //Getting all of the segments(a point, a HandleIn and a HandleOut) in the path + var segArray; + var pointArray; + var handleInArray; + var handleOutArray; + //finding the type of path to export + if(path.content) { + type = 'text'; + } else { + //Values are only defined if the path is not text because + // text does not have these values + segArray = path.getSegments(); + pointArray = new Array(); + handleInArray = new Array(); + handleOutArray = new Array(); + for (i = 0; i < segArray.length; i++) { + pointArray[i] = segArray[i].getPoint(); + handleInArray[i] = segArray[i].getHandleIn(); + handleOutArray[i] = segArray[i].getHandleOut(); + } + var exp = this; + var type = exp._determineType(path, segArray, pointArray, handleInArray, handleOutArray); + } + //switch statement that determines what type of SVG element to add to the SVG Object + switch (type) { + case 'rect': + var width = pointArray[0].getDistance(pointArray[3], false); + var height = pointArray[0].getDistance(pointArray[1], false); + svgEle = document.createElementNS(this.NS, 'rect'); + svgEle.setAttribute('x', path.bounds.topLeft.getX()); + svgEle.setAttribute('y', path.bounds.topLeft.getY()); + svgEle.setAttribute('width', width); + svgEle.setAttribute('height', height); + break; + case 'roundRect': + //d variables and point are used to determine the rounded corners for the rounded rectangle + var dx1 = pointArray[1].getDistance(pointArray[6], false); + var dx2 = pointArray[0].getDistance(pointArray[7], false); + var dx3 = (dx1 - dx2) / 2; + var dy1 = pointArray[0].getDistance(pointArray[3], false); + var dy2 = pointArray[1].getDistance(pointArray[2], false); + var dy3 = (dy1 - dy2) / 2; + var point = new Point((pointArray[3].getX() - dx3), (pointArray[2].getY() - dy3)); + var width = Math.round(dx1); + var height = Math.round(dy1); + var rx = pointArray[3].getX() - point.x; + var ry = pointArray[2].getY() - point.y; + svgEle = document.createElementNS(this.NS, 'rect'); + svgEle.setAttribute('x', path.bounds.topLeft.getX()); + svgEle.setAttribute('y', path.bounds.topLeft.getY()); + svgEle.setAttribute('rx', rx); + svgEle.setAttribute('ry', ry); + svgEle.setAttribute('width', width); + svgEle.setAttribute('height', height); + break; + case'line': + svgEle = document.createElementNS(this.NS, 'line'); + svgEle.setAttribute('x1', pointArray[0].getX()); + svgEle.setAttribute('y1', pointArray[0].getY()); + svgEle.setAttribute('x2', pointArray[pointArray.length - 1].getX()); + svgEle.setAttribute('y2', pointArray[pointArray.length - 1].getY()); + break; + case 'circle': + svgEle = document.createElementNS(this.NS, 'circle'); + var radius = (pointArray[0].getDistance(pointArray[2], false)) /2; + svgEle.setAttribute('cx', path.bounds.center.x); + svgEle.setAttribute('cy', path.bounds.center.y); + svgEle.setAttribute('r', radius); + break; + case 'ellipse': + svgEle = document.createElementNS(this.NS, 'ellipse'); + var radiusX = (pointArray[2].getDistance(pointArray[0], false)) / 2; + var radiusY = (pointArray[3].getDistance(pointArray[1], false)) /2; + svgEle.setAttribute('cx', path.bounds.center.x); + svgEle.setAttribute('cy', path.bounds.center.y); + svgEle.setAttribute('rx', radiusX); + svgEle.setAttribute('ry', radiusY); + break; + case 'polyline': + svgEle = document.createElementNS(this.NS, 'polyline'); + var pointString = ''; + for(i = 0; i < pointArray.length; ++i) { + pointString += pointArray[i].getX() + ',' + pointArray[i].getY() + ' '; + } + svgEle.setAttribute('points', pointString); + break; + case 'polygon': + svgEle = document.createElementNS(this.NS, 'polygon'); + var pointString = ''; + for(i = 0; i < pointArray.length; ++i) { + pointString += pointArray[i].getX() + ',' + pointArray[i].getY() + ' '; + } + svgEle.setAttribute('points', pointString); + break; + case 'text': + svgEle = document.createElementNS(this.NS, 'text'); + svgEle.setAttribute('x', path.getPoint().getX()); + svgEle.setAttribute('y', path.getPoint().getY()); + if(path.style.font != undefined) { + svgEle.setAttribute('font', path.style.font); + } + if(path.characterStyle.font != undefined) { + svgEle.setAttribute('font-family', path.characterStyle.font); + } + if(path.characterStyle.fontSize != undefined) { + svgEle.setAttribute('font-size',path.characterStyle.fontSize); + } + svgEle.textContent = path.getContent(); + break; + default: + svgEle = document.createElementNS(this.NS, 'path'); + svgEle = this.pathSetup(path, pointArray, handleInArray, handleOutArray); + break; + } + //If the object is a circle, ellipse, rectangle, or rounded rectangle, it will find the angle + //found by the determineIfTransformed method and make a path that accommodates for the transformed object + if(type != 'text' && type != undefined && type != 'polygon' && type != 'polyline' && type != 'line') { + //TODO: Need to implement exported transforms for circle, ellipse, and rectangles instead of + //making them paths + var angle = this._determineIfTransformed(path, pointArray, type) + 90; + if(angle != 0) { + if(type == 'rect' || type == 'roundRect') { + svgEle = document.createElementNS(this.NS, 'path'); + svgEle = this.pathSetup(path, pointArray, handleInArray, handleOutArray); + } else { + svgEle = document.createElementNS(this.NS, 'path'); + svgEle = this.pathSetup(path, pointArray, handleInArray, handleOutArray); + } + } + } + if(type == 'text') { + svgEle.setAttribute('transform','rotate(' + path.matrix.getRotation() + ',' + path.getPoint().getX() + ',' +path.getPoint().getY() +')'); + } + if(path.id != undefined) { + svgEle.setAttribute('id', path.id); + } + //checks if there is a stroke color in the passed in path + //adds an SVG element attribute with the defined stroke color + if (path.strokeColor != undefined) { + svgEle.setAttribute('stroke', path.strokeColor.toCssString()); + } + //same thing as above except checking for a fill color + if (path.fillColor != undefined) { + svgEle.setAttribute('fill', path.fillColor.toCssString()); + } else { + svgEle.setAttribute('fill', 'rgba(0,0,0,0)'); + } + //same thing as stroke color except with stroke width + if(path.strokeWidth != undefined){ + svgEle.setAttribute('stroke-width', path.strokeWidth); + } + //same thing as stroke color except with the path name + if(path.name != undefined) { + svgEle.setAttribute('name', path.name); + } + //same thing as stroke color except with the strokeCap + if(path.strokeCap != undefined) { + svgEle.setAttribute('stroke-linecap', path.strokeCap); + } + //same thing as stroke color except with the strokeJoin + if(path.strokeJoin != undefined) { + svgEle.setAttribute('stroke-linejoin', path.strokeJoin); + } + //same thing as stroke color except with the opacity + if(path.opacity != undefined) { + svgEle.setAttribute('opacity', path.opacity); + } + //checks to see if there the dashArray is set, then adds the attribute if there is. + if(path.dashArray[0] != undefined) { + var dashVals = ''; + for (var i in path.dashArray) { + if(i != path.dashArray.length -1) { + dashVals += path.dashArray[i] + ", "; + } else { + dashVals += path.dashArray[i]; + } + } + svgEle.setAttribute('stroke-dasharray', dashVals); + } + //same thing as stroke color except with the dash offset + if(path.dashOffset != undefined) { + svgEle.setAttribute('stroke-dashoffset', path.dashOffset); + } + //same thing as stroke color except with the miter limit + if(path.miterLimit != undefined) { + svgEle.setAttribute('stroke-miterlimit', path.miterLimit); + } + //same thing as stroke color except with the visibility + if(path.visibility != undefined) { + var visString = ''; + if(path.visibility) { + visString = 'visible'; + } else { + visString = 'hidden'; + } + svgEle.setAttribute('visibility', visString); + } + return svgEle; + }, + + //Determines whether the object has been transformed or not through finding the angle + _determineIfTransformed: function(path, pointArray, type) { + var topMidBoundx = (path.bounds.topRight.getX() + path.bounds.topLeft.getX() )/2; + var topMidBoundy = (path.bounds.topRight.getY() + path.bounds.topLeft.getY() )/2; + var topMidBound = new Point(topMidBoundx, topMidBoundy); + var centerPoint = path.getPosition(); + var topMidPathx; + var topMidPathy; + var topMidPath; + switch (type) { + case 'rect': + topMidPathx = (pointArray[1].getX() + pointArray[2].getX() )/2; + topMidPathy = (pointArray[1].getY() + pointArray[2].getY() )/2; + topMidPath = new Point(topMidPathx, topMidPathy); + break; + case 'ellipse': + topMidPath = new Point(pointArray[1].getX(), pointArray[1].getY()); + break; + case 'circle': + topMidPath = new Point(pointArray[1].getX(), pointArray[1].getY()); + break; + case 'roundRect': + topMidPathx = (pointArray[3].getX() + pointArray[4].getX())/2; + topMidPathy = (pointArray[3].getY() + pointArray[4].getY())/2; + topMidPath = new Point(topMidPathx, topMidPathy); + break; + default: + //Nothing happens here + break; + } + var deltaY = topMidPath.y - centerPoint.getY(); + var deltaX = topMidPath.x - centerPoint.getX(); + var angleInDegrees = Math.atan2(deltaY, deltaX) * 180 / Math.PI; + return angleInDegrees; + }, + + //pointstring is formatted in the way the SVG XML will be reading + //Namely, a point and the way to traverse to that point + pathSetup: function(path, pointArray, hIArray, hOArray) { + var svgPath = document.createElementNS(this.NS, 'path'); + var pointString = ''; + var x1; + var x2; + var y1; + var y2; + var handleOut1; + var handleIn2; + pointString += 'M' + pointArray[0].getX() + ',' + pointArray[0].getY() + ' '; + //Checks 2 points and the angles in between the 2 points + for (i = 0; i < pointArray.length-1; i++) { + x1 = pointArray[i].getX(); + y1 = pointArray[i].getY(); + x2 = pointArray[i + 1].getX(); + y2 = pointArray[i + 1].getY(); + handleOut1 = hOArray[i]; + handleIn2 = hIArray[i+1]; + if(handleOut1.getX() == 0 && handleOut1.getY() == 0 && handleIn2.getX() == 0 && handleIn2.getY() ==0) { + //L is lineto, moving to a point with drawing + pointString+= 'L' + x2 + ',' + y2 + ' '; + } else { + //c is curveto, relative: handleOut, handleIn - endpoint, endpoint - startpoint + pointString+= 'c' + (handleOut1.getX()) + ',' + (handleOut1.getY()) + ' '; + pointString+= (x2 - x1 + handleIn2.getX()) + ',' + (y2 - y1 + handleIn2.getY()) + ' '; + pointString+= (x2 - x1) + ',' + (y2-y1) + ' '; + } + } + if (!hOArray[hOArray.length - 1].equals([0,0]) && !hIArray[0].equals([0,0])) { + handleOut1 = hOArray[hOArray.length - 1]; + handleIn2 = hIArray[0]; + // Bezier curve from last point to first + x1 = pointArray[pointArray.length - 1].getX(); + y1 = pointArray[pointArray.length - 1].getY(); + x2 = pointArray[0].getX(); + y2 = pointArray[0].getY(); + pointString+= 'c' + (handleOut1.getX()) + ',' + (handleOut1.getY()) + ' '; + pointString+= (x2 - x1 + handleIn2.getX()) + ',' + (y2 - y1 + handleIn2.getY()) + ' '; + pointString+= (x2 - x1) + ',' + (y2-y1) + ' '; + } + if (path.getClosed()) + { + //Z implies a closed path, connecting the first and last points + pointString += 'z'; + } + svgPath.setAttribute('d',pointString); + return svgPath; + }, + + /** + * Checks the type SVG object created by converting from Paper.js + * + * @name ExportSVG#checkType + * @function + * @param {SVG Object Array} segArray An array of objects for the newly + * converted SVG object + * @return {String} type A string labeling which type of object the + * passed in object is + */ + _determineType: function(path, segArray, pointArray, handleInArray, handleOutArray) { + var type; + var dPoint12; + var dPoint34; + var curves = false; + var segHandleIn; + var segHandleOut; + for( var i in segArray){ + //Checks for any curves (if the handles have values). Differentiates between straight objects(line, polyline, rect, and polygon) and + //and objects with curves(circle, ellipse, roundedRectangle). + segHandleIn = segArray[i].getHandleIn(); + segHandleOut = segArray[i].getHandleOut(); + curves = segHandleIn.getX() != 0 || segHandleIn.getY() != 0 ? true : curves; + curves = segHandleOut.getX() != 0 || segHandleOut.getY() != 0 ? true : curves; + } + //Checks for curves in the passed in segments + //Checks if the type of the passed in path is a rounded rectangle, an ellipse, a circle, or if it's simply a path + //If there aren't any curves (if curves = false), then it checks if the type is a rectangle, a polygon, a polyline, or simply a line. + if(curves){ + if(segArray.length == 8) { + //if the distance between (point0 and point3) and (point7 and point4) are equal then it is a roundedRectangle + dPoint12 = Math.round(pointArray[0].getDistance(pointArray[3], false)); + dPoint34 = Math.round(pointArray[7].getDistance(pointArray[4], false)); + if(dPoint12 == dPoint34) { + type = 'roundRect'; + } + } else if(segArray.length == 4) { + //checks if the values of the point have values similar to circles and ellipses + var checkPointValues = true; + for(i = 0; i < pointArray.length && checkPointValues == true; i++) { + if(handleInArray[i].getX() != 0 || handleInArray[i].getY() != 0 && Math.round(Math.abs(handleInArray[i].getX())) === Math.round(Math.abs(handleOutArray[i].getX())) && Math.round(Math.abs(handleInArray[i].getY())) === Math.round(Math.abs(handleOutArray[i].getY()))) { + checkPointValues = true; + } else { + checkPointValues = false; + } + } + if(checkPointValues == true) { + //if the distance between (point0 and point2) and (point1 and point3) are equal, then it is a circle + var d1 = Math.round(pointArray[0].getDistance(pointArray[2], false)); + var d2 = Math.round(pointArray[1].getDistance(pointArray[3], false)); + if(d1 == d2) { + type = 'circle'; + } else { + type = 'ellipse'; + } + } + } + } else if(!curves) { + if(segArray.length == 4) { + //if the distance between (point0 and point1) and (point2 and point3) are equal, then it is a rectangle + dPoint12 = Math.round(pointArray[0].getDistance(pointArray[1], false)); + dPoint34 = Math.round(pointArray[3].getDistance(pointArray[2], false)); + if(dPoint12 == dPoint34) { + type = 'rect'; + } + } else if(segArray.length >= 3) { + //If it is an object with more than 3 segments and the path is closed, it is a polygon + if(path.getClosed()) { + type = 'polygon'; + } else { + type = 'polyline'; + } + } else { + //if all of the handle values are == 0 and there are only 2 segments, it is a line + type = 'line'; + } + } else { + type = null; + } + return type; + } +}); diff --git a/src/svg/ImportSVG.js b/src/svg/ImportSVG.js new file mode 100644 index 00000000..30277395 --- /dev/null +++ b/src/svg/ImportSVG.js @@ -0,0 +1,581 @@ +/* +* Paper.js +* +* This file is part of Paper.js, a JavaScript Vector Graphics Library, +* based on Scriptographer.org and designed to be largely API compatible. +* http://paperjs.org/ +* http://scriptographer.org/ +* +* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey +* http://lehni.org/ & http://jonathanpuckey.com/ +* +* Distributed under the MIT license. See LICENSE file for details. +* +* All rights reserved. +* +* +* +* This class and all methods therein designed by Stetson-Team-Alpha +* @author Stetson-Team-Alpha +*/ + +/** +* @name ImportSVG +* @class The ImportSVG object represents an object created using the SVG +* Canvas that will be converted into a Paper.js object. +* The SVG object is imported into Paper.js by converting it into items +* within groups. +* +*/ + +var ImportSVG = this.ImportSVG = Base.extend(/** @Lends ImportSVG# */{ + /** + * Creates a Paper.js object using data parsed from the selected + * SVG Document Object Model (DOM). The SVG object is imported, + * than a layer is created (with groups for the items if needed). + * + * Supports nested groups + * + * @param {SVG DOM} svg An SVG DOM object with parameters + * @return {item} A Paper.js layer + */ + importSVG: function(svg) { + var item; + var symbol; + switch (svg.nodeName.toLowerCase()) { + case 'line': + item = this._importLine(svg); + break; + case 'rect': + item = this._importRectangle(svg); + break; + case 'circle': + item = this._importCircle(svg); + break; + case 'ellipse': + item = this._importOval(svg); + break; + case 'g': + case 'svg': + item = this._importGroup(svg); + break; + case 'text': + item = this._importText(svg); + break; + case 'path': + item = this._importPath(svg); + break; + case 'polygon': + case 'polyline': + item = this._importPoly(svg); + break; + case 'symbol': + item = this._importGroup(svg); + this._importAttributesAndStyles(svg, item); + symbol = new Symbol(item); + item = null; + default: + //Not supported yet. + } + + if (item) { + this._importAttributesAndStyles(svg, item); + } + + return item; + }, + + /** + * Creates a Paper.js group by parsing a specific GNode of the + * imported SVG DOM + * + * @name ImportSVG#importGroup + * @function + * @param {XML DOM} svg A node passed in by the imported SVG + * @return {Group} group A Paper.js group + * + * + */ + _importGroup: function(svg) { + var group = new Group(); + var child; + for (var i in svg.childNodes) { + child = svg.childNodes[i]; + if (child.nodeType != 1) { + continue; + } + item = this.importSVG(child); + if (item) { + group.addChild(item); + } + } + + return group; + }, + + /** + * Creates a Path.Circle item in Paper.js using an imported + * Circle from SVG + * + * @name ImportSVG#importCircle + * @function + * @param {XML DOM} svgCircle An SVG circle node + * @return {Path.Circle} circle A Path.Circle item for Paper.js + */ + _importCircle: function(svgCircle) { + var cx = svgCircle.cx.baseVal.value || 0; + var cy = svgCircle.cy.baseVal.value || 0; + var r = svgCircle.r.baseVal.value || 0; + var center = new Point(cx, cy); + var circle = new Path.Circle(center, r); + + return circle; + }, + + + /** + * Creates a Path.Oval item in Paper.js using an imported Oval from SVG + * + * @name ImportSVG#importOval + * @function + * @param {XML DOM} svgOval An SVG ellipse node + * @return {Path.Oval} oval A Path.Oval item for Paper.js + */ + _importOval: function(svgOval) { + var cx = svgOval.cx.baseVal.value || 0; + var cy = svgOval.cy.baseVal.value || 0; + var rx = svgOval.rx.baseVal.value || 0; + var ry = svgOval.ry.baseVal.value || 0; + + var center = new Point(cx, cy); + var offset = new Point(rx, ry); + var topLeft = center.subtract(offset); + var bottomRight = center.add(offset); + + var rect = new Rectangle(topLeft, bottomRight); + var oval = new Path.Oval(rect); + + return oval; + }, + + /** + * Creates a Path.Rectangle item from an imported SVG rectangle + * + * @name ImportSVG#importRectangle + * @function + * @param {XML DOM} svgRectangle An SVG rectangle node + * @return {Path.Rectangle} rectangle A Path.Rectangle item for + * Paper.js + */ + /** + * Creates a Path.RoundRectangle item from an imported SVG + * rectangle with rounded corners + * + * @name ImportSVG#importRectangle + * @function + * @param {XML DOM} svgRectangle An SVG rectangle node with + * rounded corners + * @return {Path.RoundRectangle} rectangle A Path.Rectangle item + * for Paper.js + */ + _importRectangle: function(svgRectangle) { + var x = svgRectangle.x.baseVal.value || 0; + var y = svgRectangle.y.baseVal.value || 0; + var rx = svgRectangle.rx.baseVal.value || 0; + var ry = svgRectangle.ry.baseVal.value || 0; + var width = svgRectangle.width.baseVal.value || 0; + var height = svgRectangle.height.baseVal.value || 0; + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var rectangle = new Rectangle(topLeft, size); + + if (rx && ry) { + var cornerSize = new Size(rx, ry); + rectangle = new Path.RoundRectangle(rectangle, cornerSize); + } else { + rectangle = new Path.Rectangle(rectangle); + } + + return rectangle; + }, + + /** + * Creates a Path.Line item in Paper.js from an imported SVG line + * + * @name ImportSVG#importLine + * @function + * @param {XML DOM} svgLine An SVG line node + * @return {Path.Line} line A Path.Line item for Paper.js + */ + _importLine: function(svgLine) { + var x1 = svgLine.x1.baseVal.value || 0; + var y1 = svgLine.y1.baseVal.value || 0; + var x2 = svgLine.x2.baseVal.value || 0; + var y2 = svgLine.y2.baseVal.value || 0; + + var from = new Point(x1, y1); + var to = new Point(x2, y2); + var line = new Path.Line(from, to); + + return line; + }, + + /** + * Creates a PointText item in Paper.js from an imported SVG text node + * + * @name ImportSVG#importText + * @function + * @param {XML DOM} svgText An SVG text node + * @return {Path.Text} text A PointText item for Paper.js + */ + _importText: function(svgText) { + var x = svgText.x.baseVal.getItem(0).value || 0; + var y = svgText.y.baseVal.getItem(0).value || 0; + + var dx = 0; + var dy = 0; + if (svgText.dx.baseVal.numberOfItems) { + dx = svgText.dx.baseVal.getItem(0).value || 0; + } + if (svgText.dy.baseVal.numberOfItems) { + dy = svgText.dy.baseVal.getItem(0).value || 0; + } + + var textLength = svgText.textLength.baseVal.value || 0; + + /* Not supported by Paper.js + x; //multiple values for x + y; //multiple values for y + dx; //multiple values for x + dy; //multiple values for y + var rotate; //character rotation + var lengthAdjust; + */ + var textContent = svgText.textContent || ""; + var bottomLeft = new Point(x, y); + + bottomLeft = bottomLeft.add([dx, dy]); + bottomLeft = bottomLeft.subtract([textLength / 2, 0]); + var text = new PointText(bottomLeft); + text.content = textContent; + + return text; + }, + + /** + * Creates a Paper.js Path by parsing + * a specific SVG node (rectangle, path, circle, polygon, etc.) + * and creating the right Path object based on the SVG type. + * + * @name ImportSVG#importPath + * @function + * @param {XML DOM} svg An SVG object + * @return {Item} item A Paper.js item + */ + _importPath: function(svgPath) { + var path = new Path(); + var segments = svgPath.pathSegList; + var segment; + var j; + var relativeToPoint; + var controlPoint; + var prevCommand; + var segmentTo; + for (var i = 0; i < segments.numberOfItems; ++i){ + segment = segments.getItem(i); + if (segment.pathSegType == SVGPathSeg.PATHSEG_UNKNOWN) { + continue; + } + if (segment.pathSegType % 2 == 1 && path.segments.length > 0) { + relativeToPoint = path.lastSegment.point; + } else { + relativeToPoint = new Point(0, 0); + } + segmentTo = new Point(segment.x, segment.y); + segmentTo = segmentTo.add(relativeToPoint); + switch (segment.pathSegType) { + case SVGPathSeg.PATHSEG_CLOSEPATH: + path.closePath(); + break; + case SVGPathSeg.PATHSEG_MOVETO_ABS: + case SVGPathSeg.PATHSEG_MOVETO_REL: + path.moveTo(segmentTo); + break; + case SVGPathSeg.PATHSEG_LINETO_ABS: + case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: + case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: + case SVGPathSeg.PATHSEG_LINETO_REL: + case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: + case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: + path.lineTo(segmentTo); + break; + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: + path.cubicCurveTo( + relativeToPoint.add([segment.x1, segment.y1]), + relativeToPoint.add([segment.x2, segment.y2]), + segmentTo + ); + break; + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: + path.quadraticCurveTo( + relativeToPoint.add([segment.x1, segment.y1]), + segmentTo + ); + break; + case SVGPathSeg.PATHSEG_ARC_ABS: + case SVGPathSeg.PATHSEG_ARC_REL: + //TODO: Implement Arcs. + //TODO: Requires changes in Paper.js's Path to do. + //TODO: http://www.w3.org/TR/SVG/implnote.html + break; + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: + prevCommand = segments.getItem(i - 1); + controlPoint = new Point(prevCommand.x2, prevCommand.y2); + controlPoint = controlPoint.subtract([prevCommand.x, prevCommand.y]); + controlPoint = controlPoint.add(path.lastSegment.point); + controlPoint = path.lastSegment.point.subtract(controlPoint); + controlPoint = path.lastSegment.point.add(controlPoint); + path.cubicCurveTo( + controlPoint, + relativeToPoint.add([segment.x2, segment.y2]), + segmentTo + ); + break; + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: + for (j = i; j >= 0; --j) { + prevCommand = segments.getItem(j); + if (prevCommand.pathSegType == SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS || + prevCommand.pathSegType == SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL + ) { + controlPoint = new Point(prevCommand.x1, prevCommand.y1); + controlPoint = controlPoint.subtract([prevCommand.x, prevCommand.y]); + controlPoint = controlPoint.add(path.segments[j].point); + break; + } + } + for (j; j < i; ++j) { + controlPoint = path.segments[j].point.subtract(controlPoint); + controlPoint = path.segments[j].point.add(controlPoint); + } + path.quadraticCurveTo(controlPoint, segmentTo); + break; + } + } + + return path; + }, + + /** + * Creates a Path.Poly item in Paper.js using an imported Polygon or + * Polyline SVG node + * + * @name ImportSVG#importPoly + * @function + * @param {XML DOM} svgPoly An SVG polygon or polyline node + * @return {Path.Poly} poly A Path.Poly item for Paper.js + * - svg polyline node (xml dom) + * - svg polygon node (xml dom) + * returns a Path item + */ + _importPoly: function(svgPoly) { + var poly = new Path(); + var points = svgPoly.points; + var start = points.getItem(0); + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (svgPoly.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + return poly; + }, + + /** + * Converts various SVG styles and attributes into Paper.js styles and + * attributes + * This method is destructive to item (changes happen to it) + * + * @name ImportSVG#importAttributesAndStyles + * @function + * @param {XML DOM} svg An SVG node + * @param {Item} item A Paper.js item + */ + _importAttributesAndStyles: function(svg, item) { + var name, + value, + cssName; + for (var i = 0; i < svg.style.length; ++i) { + name = svg.style[i]; + cssName = name.replace(/-(.)/g, function(match, p) { + return p.toUpperCase(); + }); + value = svg.style[cssName]; + this._applyAttributeOrStyle(name, value, item, svg); + } + for (var i = 0; i < svg.attributes.length; ++i) { + name = svg.attributes[i].name; + value = svg.attributes[i].value; + this._applyAttributeOrStyle(name, value, item, svg); + } + }, + + /** + * Parses an SVG style attibute and applies it to a Paper.js item + * This method is destructive to item (changes happen to it) + * + * @name ImportSVG#applyAttributeOrStyle + * @function + * @param {Style Name} name An SVG style name + * @param {Style Value} value The value of an SVG style + * @param {Item} item A Paper.js item + * @param {XML DOM} svg An SVG node + */ + _applyAttributeOrStyle: function(name, value, item, svg) { + if (!value) { + return; + } + switch (name) { + case 'id': + item.name = value; + break; + case 'fill': + if (value != 'none') { + item.fillColor = value; + } + break; + case 'stroke': + if (value != 'none') { + item.strokeColor = value; + } + break; + case 'stroke-width': + item.strokeWidth = parseFloat(value, 10); + break; + case 'stroke-linecap': + item.strokeCap = value; + break; + case 'stroke-linejoin': + item.strokeJoin = value; + break; + case 'stroke-dasharray': + value = value.replace(/px/g, ''); + value = value.replace(/, /g, ','); + value = value.replace(/ /g, ','); + value = value.split(','); + for (var i in value) { + value[i] = parseFloat(value[i], 10); + } + item.dashArray = value; + break; + case 'stroke-dashoffset': + item.dashOffset = parseFloat(value, 10); + break; + case 'stroke-miterlimit': + item.miterLimit = parseFloat(value, 10); + break; + case 'transform': + this._applyTransform(item, svg); + case 'opacity': + item.opacity = parseFloat(value, 10); + case 'visibility': + item.visibility = (value == 'visible') ? true : false; + break; + case 'font': + case 'font-family': + case 'font-size': + //Implemented in characterStyle below. + break; + default: + // Not supported yet. + break; + } + if (item.characterStyle) { + switch (name) { + case 'font': + var text = document.createElement('span'); + text.style.font = value; + for (var i = 0; i < text.style.length; ++i) { + var n = text.style[i]; + this._applyAttributeOrStyle(n, text.style[n], item, svg); + } + break; + case 'font-family': + var fonts = value.split(','); + fonts[0] = fonts[0].replace(/^\s+|\s+$/g, ""); + item.characterStyle.font = fonts[0]; + break; + case 'font-size': + item.characterStyle.fontSize = parseFloat(value, 10); + break; + } + } + }, + + /** + * Applies the transformations specified on the SVG node to the newly + * made Paper.js item + * This method is destructive to item + * + * @name ImportSVG#applyTransform + * @function + * @param {XML DOM} An SVG node + * @param {Item} A Paper.js item + */ + _applyTransform: function(item, svg) { + var transforms = svg.transform.baseVal; + var transform; + var matrix = new Matrix(); + + for (var i = 0; i < transforms.numberOfItems; ++i) { + transform = transforms.getItem(i); + if (transform.type == SVGTransform.SVG_TRANSFORM_UNKNOWN) { + continue; + } + var transformMatrix = new Matrix( + transform.matrix.a, + transform.matrix.c, + transform.matrix.b, + transform.matrix.d, + transform.matrix.e, + transform.matrix.f + ); + switch (transform.type) { + case SVGTransform.SVG_TRANSFORM_TRANSLATE: + break; + case SVGTransform.SVG_TRANSFORM_SCALE: + break; + + //Compensate for SVG's theta rotation going the opposite direction + case SVGTransform.SVG_TRANSFORM_MATRIX: + var temp = transformMatrix.getShearX(); + transformMatrix.setShearX(transformMatrix.getShearY()); + transformMatrix.setShearY(temp); + break; + case SVGTransform.SVG_TRANSFORM_SKEWX: + transformMatrix.setShearX(transformMatrix.getShearY()); + transformMatrix.setShearY(0); + break; + case SVGTransform.SVG_TRANSFORM_SKEWY: + transformMatrix.setShearY(transformMatrix.getShearX()); + transformMatrix.setShearX(0); + break; + case SVGTransform.SVG_TRANSFORM_ROTATE: + transformMatrix.setShearX(transformMatrix.getShearX() * -1); + transformMatrix.setShearY(transformMatrix.getShearY() * -1); + break; + } + matrix.concatenate(transformMatrix); + } + item.transform(matrix); + } +}); diff --git a/test/tests/ExportSVG.js b/test/tests/ExportSVG.js new file mode 100644 index 00000000..9bdbda24 --- /dev/null +++ b/test/tests/ExportSVG.js @@ -0,0 +1,556 @@ +/** +* Paper.js +* +* This file is part of Paper.js, a JavaScript Vector Graphics Library, +* based on Scriptographer.org and designed to be largely API compatible. +* http://paperjs.org/ +* http://scriptographer.org/ +* +* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey +* http://lehni.org/ & http://jonathanpuckey.com/ +* +* Distributed under the MIT license. See LICENSE file for details. +* +* All rights reserved. +* +* This test file created by Stetson-Team-Alpha +*/ + +module('ExportSVG'); + +test('compare line path functions', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'line'); + var x1 = 5, + x2 = 45, + y1 = 5, + y2 = 45; + shape.setAttribute('x1', x1); + shape.setAttribute('y1', y1); + shape.setAttribute('x2', x2); + shape.setAttribute('y2', y2); + + var line = new Path.Line([x1, y1], [x2, y2]); + + var epjs = new ExportSVG(); + var exportedLine = epjs.exportPath(line); + + var shapex1 = shape.getAttribute('x1'); + var shapey1 = shape.getAttribute('y1'); + var shapex2 = shape.getAttribute('x2'); + var shapey2 = shape.getAttribute('y2'); + + var exportedx1 = exportedLine.getAttribute('x1'); + var exportedy1 = exportedLine.getAttribute('y1'); + var exportedx2 = exportedLine.getAttribute('x2'); + var exportedy2 = exportedLine.getAttribute('y2'); + + equals(shapex1, exportedx1); + equals(shapey1, exportedy1); + equals(shapex2, exportedx2); + equals(shapey2, exportedy2); + +}); + +test('compare negative line path functions', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'line'); + var x1 = -5, + x2 = -45, + y1 = -5, + y2 = -45; + shape.setAttribute('x1', x1); + shape.setAttribute('y1', y1); + shape.setAttribute('x2', x2); + shape.setAttribute('y2', y2); + + var line = new Path.Line([x1, y1], [x2, y2]); + + var epjs = new ExportSVG(); + var exportedLine = epjs.exportPath(line); + + var shapex1 = shape.getAttribute('x1'); + var shapey1 = shape.getAttribute('y1'); + var shapex2 = shape.getAttribute('x2'); + var shapey2 = shape.getAttribute('y2'); + + var exportedx1 = exportedLine.getAttribute('x1'); + var exportedy1 = exportedLine.getAttribute('y1'); + var exportedx2 = exportedLine.getAttribute('x2'); + var exportedy2 = exportedLine.getAttribute('y2'); + + equals(shapex1, exportedx1); + equals(shapey1, exportedy1); + equals(shapex2, exportedx2); + equals(shapey2, exportedy2); + +}); + +test('compare invalid line path functions', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'line'); + var x1 = null, + x2 = null, + y1 = null, + y2 = null; + shape.setAttribute('x1', x1); + shape.setAttribute('y1', y1); + shape.setAttribute('x2', x2); + shape.setAttribute('y2', y2); + + var line = new Path.Line([x1, y1], [x2, y2]); + + var epjs = new ExportSVG(); + var exportedLine = epjs.exportPath(line); + + var shapex1 = shape.getAttribute('x1'); + var shapey1 = shape.getAttribute('y1'); + var shapex2 = shape.getAttribute('x2'); + var shapey2 = shape.getAttribute('y2'); + + var exportedx1 = exportedLine.getAttribute('x1'); + var exportedy1 = exportedLine.getAttribute('y1'); + var exportedx2 = exportedLine.getAttribute('x2'); + var exportedy2 = exportedLine.getAttribute('y2'); + + equals(shapex1, exportedx1); + equals(shapey1, exportedy1); + equals(shapex2, exportedx2); + equals(shapey2, exportedy2); + +}); + +/*test('compare rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'rect'); + var x = 25, + y = 25, + width = 100, + height = 100; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var point = new Point(100, 100); + var size = new Size(100, 100); + var path = new Path.Rectangle(point, size); + + var epjs = new ExportSVG(); + var exportedRectangle = new epjs.exportPath(path); + + var shapex1 = shape.getAttribute('x'); + var shapey1 = shape.getAttribute('y1'); + var shapewidth = shape.getAttribute('width'); + var shapeheight = shape.getAttribute('height'); + + var exportedx = exportedRectangle.getAttribute('x1'); + var exportedy = exportedRectangle.getAttribute('y1'); + + var exportedwidth = exportedRectangle.getAttribute('width'); + var exportedheight = exportedRectangle.getAttribute('height'); + + equals(shapex, exportedx); + equals(shapey, exportedy); + equals(shapewidth, exportedwidth); + equals(shapeheight, exportedheight); +}); + +test('compare negative rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'rect'); + var x = -25, + y = -25, + width = -100, + height = -100; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var rect = new Rectangle(topLeft, size); + + var epjs = new ExportSVG(); + var exportedRectangle = new epjs.exportPath(rect); + + var shapex = shape.getAttribute('x'); + var shapey = shape.getAttribute('y'); + var shapewidth = shape.getAttribute('width'); + var shapeheight = shape.getAttribute('height'); + + var exportedx = exportedRectangle.getAttribute('x'); + var exportedy = exportedRectangle.getAttribute('y'); + var exportedwidth = exportedRectangle.getAttribute('width'); + var exportedheight = exportedRectangle.getAttribute('height'); + + equals(shapex, exportedx); + equals(shapey, exportedy); + equals(shapewidth, exportedwidth); + equals(shapeheight, exportedheight); +}); + +test('compare invalid rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'rect'); + var x = null, + y = null, + width = null, + height = 100; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var rect = new Rectangle(topLeft, size); + + var epjs = new ExportSVG(); + var exportedRectangle = new epjs.exportPath(rect); + + var shapex = shape.getAttribute('x'); + var shapey = shape.getAttribute('y'); + var shapewidth = shape.getAttribute('width'); + var shapeheight = shape.getAttribute('height'); + + var exportedx = exportedRectangle.getAttribute('x'); + var exportedy = exportedRectangle.getAttribute('y'); + var exportedwidth = exportedRectangle.getAttribute('width'); + var exportedheight = exportedRectangle.getAttribute('height'); + + equals(shapex, exportedx); + equals(shapey, exportedy); + equals(shapewidth, exportedwidth); + equals(shapeheight, exportedheight); +}); + +test('compare rounded rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'rect'); + var x = 25, + y = 25, + rx = 50, + ry = 50, + width = 100, + height = 100; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('rx', rx); + shape.setAttribute('ry', ry); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var cornerSize = new Size(rx, ry); + var rect = new Rectangle(topLeft, size); + var roundRect = new Path.RoundRectangle(rect, cornerSize); + + var epjs = new ExportSVG(); + var exportedRectangle = new epjs.exportPath(rect); + + var shapex = shape.getAttribute('x'); + var shapey = shape.getAttribute('y'); + var shapecx = shape.getAttribute('rx'); + var shapecy = shape.getAttribute('ry'); + var shapewidth = shape.getAttribute('width'); + var shapeheight = shape.getAttribute('height'); + + var exportedx = exportedRectangle.getAttribute('x'); + var exportedy = exportedRectangle.getAttribute('y'); + var exportedcx = exportedRectangle.getAttribute('rx'); + var exportedcy = exportedRectangle.getAttribute('ry'); + var exportedwidth = exportedRectangle.getAttribute('width'); + var exportedheight = exportedRectangle.getAttribute('height'); + + equals(shapex, exportedx); + equals(shapey, exportedy); + equals(shapewidth, exportedwidth); + equals(shapeheight, exportedheight); +}); + +test('compare negative rounded rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'rect'); + var x = -25, + y = -25, + rx = -50, + ry = -50, + width = -100, + height = -100; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('rx', rx); + shape.setAttribute('ry', ry); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var cornerSize = new Size(rx, ry); + var rect = new Rectangle(topLeft, size); + var roundRect = new Path.RoundRectangle(rect, cornerSize); + + var epjs = new ExportSVG(); + var exportedRectangle = new epjs.exportPath(rect); + + var shapex = shape.getAttribute('x'); + var shapey = shape.getAttribute('y'); + var shapecx = shape.getAttribute('rx'); + var shapecy = shape.getAttribute('ry'); + var shapewidth = shape.getAttribute('width'); + var shapeheight = shape.getAttribute('height'); + + var exportedx = exportedRectangle.getAttribute('x'); + var exportedy = exportedRectangle.getAttribute('y'); + var exportedcx = exportedRectangle.getAttribute('rx'); + var exportedcy = exportedRectangle.getAttribute('ry'); + var exportedwidth = exportedRectangle.getAttribute('width'); + var exportedheight = exportedRectangle.getAttribute('height'); + + equals(shapex, exportedx); + equals(shapey, exportedy); + equals(shapewidth, exportedwidth); + equals(shapeheight, exportedheight); +}); + +test('compare invalid rounded rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'rect'); + var x = null, + y = null, + rx = null, + ry = null, + width = null, + height = null; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('rx', rx); + shape.setAttribute('ry', ry); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var cornerSize = new Size(rx, ry); + var rect = new Rectangle(topLeft, size); + var roundRect = new Path.RoundRectangle(rect, cornerSize); + + var epjs = new ExportSVG(); + var exportedRectangle = new epjs.exportPath(rect); + + var shapex = shape.getAttribute('x'); + var shapey = shape.getAttribute('y'); + var shapecx = shape.getAttribute('rx'); + var shapecy = shape.getAttribute('ry'); + var shapewidth = shape.getAttribute('width'); + var shapeheight = shape.getAttribute('height'); + + var exportedx = exportedRectangle.getAttribute('x'); + var exportedy = exportedRectangle.getAttribute('y'); + var exportedcx = exportedRectangle.getAttribute('rx'); + var exportedcy = exportedRectangle.getAttribute('ry'); + var exportedwidth = exportedRectangle.getAttribute('width'); + var exportedheight = exportedRectangle.getAttribute('height'); + + equals(shapex, exportedx); + equals(shapey, exportedy); + equals(shapewidth, exportedwidth); + equals(shapeheight, exportedheight); +});*/ + +test('compare oval values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'ellipse'); + var cx = 100, + cy = 80, + rx = 50; + ry = 30; + shape.setAttribute('cx', cx); + shape.setAttribute('cy', cy); + shape.setAttribute('rx', rx); + shape.setAttribute('ry', ry); + + var center = new Point(cx, cy); + var offset = new Point(rx, ry); + var topLeft = center.subtract(offset); + var bottomRight = center.add(offset); + + var rect = new Rectangle(topLeft, bottomRight); + var oval = new Path.Oval(rect); + + var epjs = new ExportSVG(); + var exportedOval = epjs.exportPath(oval); + + var shapecx = shape.getAttribute('cx'); + var shapecy = shape.getAttribute('cy'); + var shaperx = shape.getAttribute('rx'); + var shapery = shape.getAttribute('ry'); + + var exportedcx = exportedOval.getAttribute('cx'); + var exportedcy = exportedOval.getAttribute('cy'); + var exportedrx = exportedOval.getAttribute('rx'); + var exportedry = exportedOval.getAttribute('ry'); + + equals(shapecx, exportedcx); + equals(shapecy, exportedcy); + equals(shaperx, exportedrx); + equals(shapery, exportedry); + +}); + +test('compare circle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'circle'); + var cx = 100, + cy = 80, + r = 50; + shape.setAttribute('cx', cx); + shape.setAttribute('cy', cy); + shape.setAttribute('r', r); + + var center = new Point(cx, cy); + var circle = new Path.Circle(center, r); + + var epjs = new ExportSVG(); + var exportedCircle = epjs.exportPath(circle); + + var shapecx = shape.getAttribute('cx'); + var shapecy = shape.getAttribute('cy'); + var shaper = shape.getAttribute('r'); + + var exportedcx = exportedCircle.getAttribute('cx'); + var exportedcy = exportedCircle.getAttribute('cy'); + var exportedr = exportedCircle.getAttribute('r'); + + equals(shapecx, exportedcx); + equals(shapecy, exportedcy); + equals(shaper, exportedr); + +}); + +test('compare polygon values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'polygon'); + var svgpoints = "100,10 40,180 190,60 10,60 160,180"; + shape.setAttribute('points', svgpoints); + + var poly = new Path(); + var points = shape.points; + var start = points.getItem(0) + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (shape.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + var epjs = new ExportSVG(); + var exportedPolygon = epjs.exportPath(poly); + + var svgPoints = shape.getAttribute('points'); + + var exportedPoints = shape.getAttribute('points'); + + equals(svgPoints, exportedPoints); + +}); + +test('compare negative polygon values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'polygon'); + var svgpoints = "-100,-10 -40,-180 -190,-60 -10,-60 -160,-180"; + shape.setAttribute('points', svgpoints); + + var poly = new Path(); + var points = shape.points; + var start = points.getItem(0) + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (shape.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + var epjs = new ExportSVG(); + var exportedPolygon = epjs.exportPath(poly); + + var svgPoints = shape.getAttribute('points'); + + var exportedPoints = shape.getAttribute('points'); + + equals(svgPoints, exportedPoints); + +}); + +test('compare polyline values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'polyline'); + var svgpoints = "5,5 45,45 5,45 45,5"; + shape.setAttribute('points', svgpoints); + + var poly = new Path(); + var points = shape.points; + var start = points.getItem(0) + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (shape.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + var epjs = new ExportSVG(); + var exportedPolygon = epjs.exportPath(poly); + + var svgPoints = shape.getAttribute('points'); + + var exportedPoints = shape.getAttribute('points'); + + equals(svgPoints, exportedPoints); + +}); + +test('compare negative polyline values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'polyline'); + var svgpoints = "-5,-5 -45,-45 -5,-45 -45,-5"; + shape.setAttribute('points', svgpoints); + + var poly = new Path(); + var points = shape.points; + var start = points.getItem(0) + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (shape.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + var epjs = new ExportSVG(); + var exportedPolygon = epjs.exportPath(poly); + + var svgPoints = shape.getAttribute('points'); + + var exportedPoints = shape.getAttribute('points'); + + equals(svgPoints, exportedPoints); + +}); diff --git a/test/tests/ImportSVG.js b/test/tests/ImportSVG.js new file mode 100644 index 00000000..0f3f613f --- /dev/null +++ b/test/tests/ImportSVG.js @@ -0,0 +1,451 @@ +/* +* Paper.js +* +* This file is part of Paper.js, a JavaScript Vector Graphics Library, +* based on Scriptographer.org and designed to be largely API compatible. +* http://paperjs.org/ +* http://scriptographer.org/ +* +* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey +* http://lehni.org/ & http://jonathanpuckey.com/ +* +* Distributed under the MIT license. See LICENSE file for details. +* +* All rights reserved. +* +* This test file created by Stetson-Team-Alpha +*/ + +module('ImportSVG'); + +test('make an svg line', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'line'); + var x1 = 5, + x2 = 45, + y1 = 5, + y2 = 45; + shape.setAttribute('x1', x1); + shape.setAttribute('y1', y1); + shape.setAttribute('x2', x2); + shape.setAttribute('y2', y2); + + var isvg = new ImportSVG(); + var importedLine = isvg.importSVG(shape); + + var line = new Path.Line([x1, y1], [x2, y2]); + + compareSegmentLists(importedLine.segments, line.segments, true); +}); + +test('make an svg line with invalid values', function() { + var svgns = 'http://www.w3.org/2000/svg'; + var shape = document.createElementNS(svgns, 'line'); + shape.setAttribute('x1', null); + shape.setAttribute('y1', null); + shape.setAttribute('x2', null); + shape.setAttribute('y2', null); + + var isvg = new ImportSVG(); + var importedLine = isvg.importSVG(shape); + + var line = new Path.Line([0, 0], [0, 0]); + + compareSegmentLists(importedLine.segments, line.segments, true); + +}); + +test('compare rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'rect'); + var x = 25, + y = 25, + width = 100, + height = 100; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var isvg = new ImportSVG(); + var importedRectangle = isvg.importSVG(shape); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var rectangle = new Rectangle(topLeft, size); + var realRectangle = new Path.Rectangle(rectangle); + + compareSegmentLists(importedRectangle.segments, realRectangle.segments, true); +}); + + +test('compare negative rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'rect'); + var x = -925, + y = -111, + width = -100, + height = -18; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var isvg = new ImportSVG(); + var importedRectangle = isvg.importSVG(shape); + var topLeft = new Point(x, y); + var size = new Size(width, height); + var rectangle = new Rectangle(topLeft, size); + var realRectangle = new Path.Rectangle(rectangle); + + compareSegmentLists(importedRectangle.segments, realRectangle.segments, true); + }); + + +test('compare invalid rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'rect'); + + shape.setAttribute('x', null); + shape.setAttribute('y', null); + shape.setAttribute('width', null); + shape.setAttribute('height', null); + + var isvg = new ImportSVG(); + var importedRectangle = isvg.importSVG(shape); + + var topLeft = new Point(0, 0); + var size = new Size(0, 0); + var rectangle = new Rectangle(topLeft, size); + var realRectangle = new Path.Rectangle(rectangle); + + compareSegmentLists(importedRectangle.segments, realRectangle.segments, true); + }); + +test('compare round rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'rect'); + var x = 25, + y = 25, + rx = 50, + ry = 50, + width = 100, + height = 100; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('rx', rx); + shape.setAttribute('ry', ry); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var isvg = new ImportSVG(); + var importedRectangle = isvg.importSVG(shape); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var cornerSize = new Size(rx, ry); + var rectangle = new Rectangle(topLeft, size); + var roundRect = new Path.RoundRectangle(rectangle, cornerSize); + + compareSegmentLists(importedRectangle.segments, roundRect.segments, true); +}); + +test('compare negative round rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'rect'); + var x = -25, + y = -25, + rx = -50, + ry = -50, + width = -100, + height = -100; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('rx', rx); + shape.setAttribute('ry', ry); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var isvg = new ImportSVG(); + var importedRectangle = isvg.importSVG(shape); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var cornerSize = new Size(rx, ry); + var rectangle = new Rectangle(topLeft, size); + var roundRect = new Path.RoundRectangle(rectangle, cornerSize); + + compareSegmentLists(importedRectangle.segments, roundRect.segments, true); +}); + +test('compare invalid round rectangle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'rect'); + var x = null, + y = null, + rx = null, + ry = null, + width = null, + height = null; + shape.setAttribute('x', x); + shape.setAttribute('y', y); + shape.setAttribute('rx', 1); + shape.setAttribute('ry', 1); + shape.setAttribute('width', width); + shape.setAttribute('height', height); + + var isvg = new ImportSVG(); + var importedRectangle = isvg.importSVG(shape); + + var topLeft = new Point(x, y); + var size = new Size(width, height); + var cornerSize = new Size(rx, ry); + var rectangle = new Rectangle(topLeft, size); + var roundRect = new Path.RoundRectangle(rectangle, cornerSize); + + compareSegmentLists(importedRectangle.segments, roundRect.segments, true); +}); + +test('compare oval values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'ellipse'); + var cx = 300, + cy = 80, + rx = 100, + ry = 50; + shape.setAttribute('cx', cx); + shape.setAttribute('cy', cy); + shape.setAttribute('rx', rx); + shape.setAttribute('ry', ry); + + var isvg = new ImportSVG(); + var importedOval = isvg.importSVG(shape); + + var center = new Point(cx, cy); + var offset = new Point(rx, ry); + var topLeft = center.subtract(offset); + var bottomRight = center.add(offset); + + var rect = new Rectangle(topLeft, bottomRight); + var oval = new Path.Oval(rect); + + compareSegmentLists(importedOval.segments, oval.segments, true); + + +}); + +test('compare negative oval values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'ellipse'); + var cx = -111, + cy = -2, + rx = -292, + ry = -1; + shape.setAttribute('cx', cx); + shape.setAttribute('cy', cy); + shape.setAttribute('rx', rx); + shape.setAttribute('ry', ry); + + var isvg = new ImportSVG(); + var importedOval = isvg.importSVG(shape); + + var center = new Point(cx, cy); + var offset = new Point(rx, ry); + var topLeft = center.subtract(offset); + var bottomRight = center.add(offset); + + var rect = new Rectangle(topLeft, bottomRight); + var oval = new Path.Oval(rect); + + compareSegmentLists(importedOval.segments, oval.segments, true); + +}); + +test('compare invalid oval values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'ellipse'); + shape.setAttribute('cx', null); + shape.setAttribute('cy', null); + shape.setAttribute('rx', null); + shape.setAttribute('ry', null); + + var isvg = new ImportSVG(); + var importedOval = isvg.importSVG(shape); + + var center = new Point(0, 0); + var offset = new Point(0, 0); + var topLeft = center.subtract(offset); + var bottomRight = center.add(offset); + + var rect = new Rectangle(topLeft, bottomRight); + var oval = new Path.Oval(rect); + + compareSegmentLists(importedOval.segments, oval.segments, true); + +}); + +test('compare circle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'circle'); + var cx = 100, + cy = 80, + r = 50; + shape.setAttribute('cx', cx); + shape.setAttribute('cy', cy); + shape.setAttribute('r', r); + + var isvg = new ImportSVG(); + var importedCircle = isvg.importSVG(shape); + + var center = new Point(cx, cy); + var circle = new Path.Circle(center, r); + + compareSegmentLists(importedCircle.segments, circle.segments, true); + +}); + +test('compare negative circle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'circle'); + var cx = -234, + cy = -77, + r = -1110; + shape.setAttribute('cx', cx); + shape.setAttribute('cy', cy); + shape.setAttribute('r', r); + + var isvg = new ImportSVG(); + var importedCircle = isvg.importSVG(shape); + + var center = new Point(cx, cy); + var circle = new Path.Circle(center, r); + + compareSegmentLists(importedCircle.segments, circle.segments, true); + +}); + + +test('compare invalid circle values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'circle'); + shape.setAttribute('cx', null); + shape.setAttribute('cy', null); + shape.setAttribute('r', null); + + var isvg = new ImportSVG(); + var importedCircle = isvg.importSVG(shape); + + var center = new Point(0, 0); + var circle = new Path.Circle(center, 0); + + compareSegmentLists(importedCircle.segments, circle.segments, true); + +}); + +test('compare polygon values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'polygon'); + var svgpoints = "100,10 40,180 190,60 10,60 160,180"; + shape.setAttribute('points', svgpoints); + + var isvg = new ImportSVG(); + var importedPolygon = isvg.importSVG(shape); + + var poly = new Path(); + var points = shape.points; + var start = points.getItem(0) + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (shape.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + compareSegmentLists(importedPolygon.segments, poly.segments, true); + +}); + +test('compare negative polygon values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'polygon'); + var svgpoints = "-100,-10 -40,-180 -190,-60 -10,-60 -160,-180"; + shape.setAttribute('points', svgpoints); + + var isvg = new ImportSVG(); + var importedPolygon = isvg.importSVG(shape); + + var poly = new Path(); + var points = shape.points; + var start = points.getItem(0) + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (shape.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + compareSegmentLists(importedPolygon.segments, poly.segments, true); + +}); + +test('compare polyline values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'polyline'); + var svgpoints = "5,5 45,45 5,45 45,5"; + shape.setAttribute('points', svgpoints); + + var isvg = new ImportSVG(); + var importedPolyline = isvg.importSVG(shape); + + var poly = new Path(); + var points = shape.points; + var start = points.getItem(0) + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (shape.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + compareSegmentLists(importedPolyline.segments, poly.segments, true); + +}); + + test('compare negative polyline values', function() { + var svgns = 'http://www.w3.org/2000/svg' + var shape = document.createElementNS(svgns, 'polyline'); + var svgpoints = "-5,-5 -45,-45 -5,-45 -45,-5"; + shape.setAttribute('points', svgpoints); + + var isvg = new ImportSVG(); + var importedPolyline = isvg.importSVG(shape); + + var poly = new Path(); + var points = shape.points; + var start = points.getItem(0) + var point; + poly.moveTo([start.x, start.y]); + + for (var i = 1; i < points.length; ++i) { + point = points.getItem(i); + poly.lineTo([point.x, point.y]); + } + if (shape.nodeName.toLowerCase() == 'polygon') { + poly.closePath(); + } + + compareSegmentLists(importedPolyline.segments, poly.segments, true); + +}); diff --git a/test/tests/load.js b/test/tests/load.js index f08f287a..26d33e03 100644 --- a/test/tests/load.js +++ b/test/tests/load.js @@ -27,3 +27,6 @@ /*#*/ include('PlacedSymbol.js'); /*#*/ include('HitResult.js'); + +/*#*/ include('ImportSVG.js'); +/*#*/ include('ExportSVG.js');