From fc1b9b96a9012b5156d940da0e3273a4cc7d8b11 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:42:06 +0200 Subject: [PATCH 01/27] Update object.svg_export.js Added missing properties and transforMatrx export. --- src/mixins/object.svg_export.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/mixins/object.svg_export.js b/src/mixins/object.svg_export.js index 6b0346a8..e04ddb3e 100644 --- a/src/mixins/object.svg_export.js +++ b/src/mixins/object.svg_export.js @@ -10,7 +10,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot var fill = this.fill ? (this.fill.toLive ? 'url(#SVGID_' + this.fill.id + ')' : this.fill) : 'none', - + fillRule = (this.fillRule === 'destination-over' ? 'evenodd' : this.fillRule), stroke = this.stroke ? (this.stroke.toLive ? 'url(#SVGID_' + this.stroke.id + ')' : this.stroke) : 'none', @@ -33,6 +33,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', 'fill: ', fill, '; ', + 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility @@ -44,6 +45,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @return {String} */ getSvgTransform: function() { + if (this.group) return ''; var toFixed = fabric.util.toFixed, angle = this.getAngle(), vpt = this.getViewportTransform(), @@ -51,7 +53,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, - translatePart = 'translate(' + + translatePart = this.type === 'path-group' ? '' : 'translate(' + toFixed(center.x, NUM_FRACTION_DIGITS) + ' ' + toFixed(center.y, NUM_FRACTION_DIGITS) + @@ -68,16 +70,24 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ' ' + toFixed(this.scaleY * vpt[3], NUM_FRACTION_DIGITS) + ')'), - - flipXPart = this.flipX ? 'matrix(-1 0 0 1 0 0) ' : '', - - flipYPart = this.flipY ? 'matrix(1 0 0 -1 0 0)' : ''; + addTranslateX = this.type === 'path-group' ? this.width * vpt[0] : 0, + flipXPart = this.flipX ? ' matrix(-1 0 0 1 ' + addTranslateX + ' 0) ' : '', + addTranslateY = this.type === 'path-group' ? this.height * vpt[3] : 0, + flipYPart = this.flipY ? ' matrix(1 0 0 -1 0 ' + addTranslateY + ')' : ''; return [ translatePart, anglePart, scalePart, flipXPart, flipYPart ].join(''); }, + /** + * Returns transform-string for svg-export from the transform matrix of single elements + * @return {String} + */ + getSvgTransformMatrix: function() { + return this.transformMatrix ? ' matrix(' + this.transformMatrix.join(' ') + ')' : ''; + }, + /** * @private */ From 5e0dc2211b2ae2165819a686ac657a50c4034ae1 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:42:58 +0200 Subject: [PATCH 02/27] Update parser.js Adding scaling of translating that was wiped by some commit --- src/parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser.js b/src/parser.js index 9b1ce184..dd3717a8 100644 --- a/src/parser.js +++ b/src/parser.js @@ -527,7 +527,7 @@ if (heightAttr && heightAttr !== viewBoxHeight) { scaleY = heightAttr / viewBoxHeight; } - addSvgTransform(doc, [scaleX, 0, 0, scaleY, -minX, -minY]); + addSvgTransform(doc, [scaleX, 0, 0, scaleY, scaleX * -minX, scaleY * -minY]); } var descendants = fabric.util.toArray(doc.getElementsByTagName('*')); From c1202428655c69c04957e1acd51be6565fc65937 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:43:51 +0200 Subject: [PATCH 03/27] Simplified circle class and fixed SVG export --- src/shapes/circle.class.js | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/shapes/circle.class.js b/src/shapes/circle.class.js index c8b40240..9c315fff 100644 --- a/src/shapes/circle.class.js +++ b/src/shapes/circle.class.js @@ -79,15 +79,19 @@ * @return {String} svg representation of an instance */ toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(); - + var markup = this._createBaseSVGMarkup(), x = 0, y = 0; + if (this.group) { + x = this.left + this.radius; + y = this.top + this.radius; + } markup.push( '' + ' ', this.getSvgTransformMatrix(), + '"/>\n' ); return reviver ? reviver(markup.join('')) : markup.join(''); @@ -101,11 +105,9 @@ */ _render: function(ctx, noTransform) { ctx.beginPath(); - // multiply by currently set alpha (the one that was set by path group where this object is contained, for example) - ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity; - ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.radius, 0, piBy2, false); + ctx.arc(noTransform ? this.left + this.radius : 0, noTransform ? this.top + this.radius : 0, this.radius, 0, piBy2, false); this._renderFill(ctx); - this.stroke && this._renderStroke(ctx); + this._renderStroke(ctx); }, /** @@ -169,22 +171,13 @@ throw new Error('value of `r` attribute is required and can not be negative'); } - if (!('left' in parsedAttributes)) { - parsedAttributes.left = 0; - } - if (!('top' in parsedAttributes)) { - parsedAttributes.top = 0; - } - if (!('transformMatrix' in parsedAttributes)) { - parsedAttributes.left -= options.width ? (options.width / 2) : 0; - parsedAttributes.top -= options.height ? (options.height / 2) : 0; - } + parsedAttributes.left = parsedAttributes.left || 0; + parsedAttributes.top = parsedAttributes.top || 0; var obj = new fabric.Circle(extend(parsedAttributes, options)); - obj.cx = parseFloat(element.getAttribute('cx')) || 0; - obj.cy = parseFloat(element.getAttribute('cy')) || 0; - + obj.left -= obj.radius; + obj.top -= obj.radius; return obj; }; From 15b6798d0e50584fff9827d988725124e6b4f9a9 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:44:19 +0200 Subject: [PATCH 04/27] Simplified ellipse class and fixed SVG export --- src/shapes/ellipse.class.js | 49 ++++++++++++------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/src/shapes/ellipse.class.js b/src/shapes/ellipse.class.js index 678ae63f..e4ca0b07 100644 --- a/src/shapes/ellipse.class.js +++ b/src/shapes/ellipse.class.js @@ -77,34 +77,26 @@ * @return {String} svg representation of an instance */ toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(); - + var markup = this._createBaseSVGMarkup(), x = 0, y = 0; + if (this.group) { + x = this.left + this.rx; + y = this.top + this.ry; + } markup.push( '' + this.getSvgTransformMatrix(), + '"/>\n' ); return reviver ? reviver(markup.join('')) : markup.join(''); }, /* _TO_SVG_END_ */ - /** - * Renders this instance on a given context - * @param {CanvasRenderingContext2D} ctx context to render on - * @param {Boolean} [noTransform] When true, context is not transformed - */ - render: function(ctx, noTransform) { - // do not use `get` for perf. reasons - if (this.rx === 0 || this.ry === 0) { - return; - } - return this.callSuper('render', ctx, noTransform); - }, - /** * @private * @param {CanvasRenderingContext2D} ctx context to render on @@ -112,10 +104,9 @@ */ _render: function(ctx, noTransform) { ctx.beginPath(); - ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity; ctx.save(); ctx.transform(1, 0, 0, this.ry/this.rx, 0, 0); - ctx.arc(noTransform ? this.left : 0, noTransform ? this.top * this.rx/this.ry : 0, this.rx, 0, piBy2, false); + ctx.arc(noTransform ? this.left + this.rx : 0, noTransform ? (this.top + this.ry) * this.rx/this.ry : 0, this.rx, 0, piBy2, false); ctx.restore(); this._renderFill(ctx); this._renderStroke(ctx); @@ -152,21 +143,13 @@ var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); - if (!('left' in parsedAttributes)) { - parsedAttributes.left = 0; - } - if (!('top' in parsedAttributes)) { - parsedAttributes.top = 0; - } - if (!('transformMatrix' in parsedAttributes)) { - parsedAttributes.left -= options.width ? (options.width / 2) : 0; - parsedAttributes.top -= options.height ? (options.height / 2) : 0; - } + parsedAttributes.left = parsedAttributes.left || 0; + parsedAttributes.top = parsedAttributes.top || 0; + var ellipse = new fabric.Ellipse(extend(parsedAttributes, options)); - ellipse.cx = parseFloat(element.getAttribute('cx')) || 0; - ellipse.cy = parseFloat(element.getAttribute('cy')) || 0; - + ellipse.top -= ellipse.ry; + ellipse.left -= ellipse.rx; return ellipse; }; /* _FROM_SVG_END_ */ From 09ba1e115b68deab96addd8c4a698e0823be1fb6 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:45:07 +0200 Subject: [PATCH 05/27] ToSvg , added some \n --- src/shapes/group.class.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shapes/group.class.js b/src/shapes/group.class.js index 5dace2a8..62d21a16 100644 --- a/src/shapes/group.class.js +++ b/src/shapes/group.class.js @@ -482,7 +482,7 @@ //jscs:disable validateIndentation '' + '">\n' //jscs:enable validateIndentation ]; @@ -490,7 +490,7 @@ markup.push(this._objects[i].toSVG(reviver)); } - markup.push(''); + markup.push('\n'); return reviver ? reviver(markup.join('')) : markup.join(''); }, From 32278413e303bb3f7d5ffbd1605b96bf968d1065 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:48:29 +0200 Subject: [PATCH 06/27] Update image.class.js Removed render method, added support for x and y positioning, fixed toSVG --- src/shapes/image.class.js | 64 +++++++++------------------------------ 1 file changed, 14 insertions(+), 50 deletions(-) diff --git a/src/shapes/image.class.js b/src/shapes/image.class.js index 849dc2a8..f5e43bf4 100644 --- a/src/shapes/image.class.js +++ b/src/shapes/image.class.js @@ -112,46 +112,6 @@ }; }, - /** - * Renders image on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Boolean} [noTransform] When true, context is not transformed - */ - render: function(ctx, noTransform) { - // do not render if object is not visible - if (!this.visible) { - return; - } - - ctx.save(); - var m = this.transformMatrix, - isInPathGroup = this.group && this.group.type === 'path-group'; - - // this._resetWidthHeight(); - if (isInPathGroup) { - ctx.translate(-this.group.width/2, -this.group.height/2); - } - if (m) { - ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - } - if (!noTransform) { - this.transform(ctx); - } - if (isInPathGroup) { - ctx.translate(this.width/2, this.height/2); - } - - this._setShadow(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); - this._render(ctx); - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - this._renderStroke(ctx); - this.clipTo && ctx.restore(); - ctx.restore(); - }, - /** * @private * @param {CanvasRenderingContext2D} ctx Context to render on @@ -209,20 +169,24 @@ * @return {String} svg representation of an instance */ toSVG: function(reviver) { - var markup = []; - + var markup = [], x = -this.width / 2, y = -this.height / 2; + if (this.group) { + x = this.left; + y = this.top; + } markup.push( - '', + '\n', '' + '>\n' ); if (this.stroke || this.strokeDashArray) { @@ -233,12 +197,12 @@ 'x="', (-1 * this.width / 2), '" y="', (-1 * this.height / 2), '" width="', this.width, '" height="', this.height, '" style="', this.getSvgStyles(), - '"/>' + '"/>\n' ); this.fill = origFill; } - markup.push(''); + markup.push('\n'); return reviver ? reviver(markup.join('')) : markup.join(''); }, @@ -332,12 +296,12 @@ * @private * @param {CanvasRenderingContext2D} ctx Context to render on */ - _render: function(ctx) { + _render: function(ctx, noTransform) { this._element && ctx.drawImage( this._element, - -this.width / 2, - -this.height / 2, + noTransform ? this.left : -this.width/2, + noTransform ? this.top : -this.height/2, this.width, this.height ); From d40deb6d58e834ac8c20d69bb7fbeed9a82347ee Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:49:34 +0200 Subject: [PATCH 07/27] Fixed toSVG for line, changes in rendering logic --- src/shapes/line.class.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/shapes/line.class.js b/src/shapes/line.class.js index 204dcd5f..df73af6b 100644 --- a/src/shapes/line.class.js +++ b/src/shapes/line.class.js @@ -150,11 +150,10 @@ * @private * @param {CanvasRenderingContext2D} ctx Context to render on */ - _render: function(ctx) { + _render: function(ctx, noTransform) { ctx.beginPath(); - var isInPathGroup = this.group && this.group.type === 'path-group'; - if (isInPathGroup) { + if (noTransform) { // Line coords are distances from left-top of canvas to origin of line. // // To render line in a path-group, we need to translate them to @@ -164,9 +163,6 @@ cp.x, cp.y ); - if (!this.transformMatrix) { - ctx.translate(-this.group.width / 2, -this.group.height / 2); - } } if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) { @@ -234,8 +230,10 @@ * @return {String} svg representation of an instance */ toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(); - + var markup = this._createBaseSVGMarkup(), addTranslate = ''; + if (!this.group) { + addTranslate = 'translate(' + (-this.width/2) + ', ' + (-this.height/2) + ') '; + } markup.push( '' + '" transform="', this.getSvgTransform(), addTranslate, + this.getSvgTransformMatrix(), + '"/>\n' ); return reviver ? reviver(markup.join('')) : markup.join(''); From f84091054ff8c1a8648d7585ef8389ff425a04a5 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:50:39 +0200 Subject: [PATCH 08/27] Object: Moved globalAlpha here, changes in render --- src/shapes/object.class.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/shapes/object.class.js b/src/shapes/object.class.js index 96cef203..7c433305 100644 --- a/src/shapes/object.class.js +++ b/src/shapes/object.class.js @@ -960,12 +960,14 @@ this._setStrokeStyles(ctx); this._setFillStyles(ctx); - var m = this.transformMatrix; - if (m && this.group) { + if (this.group && this.group.type === 'path-group') { ctx.translate(-this.group.width/2, -this.group.height/2); - ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + var m = this.transformMatrix; + if (m) { + ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } } - + ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity; this._setShadow(ctx); this.clipTo && fabric.util.clipContext(this, ctx); this._render(ctx, noTransform); From eef2e21c07d44673770b5a4a6c75a9ae6764083a Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:51:20 +0200 Subject: [PATCH 09/27] changed toSvg method --- src/shapes/path.class.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/shapes/path.class.js b/src/shapes/path.class.js index 9d70b524..e6c1fffe 100644 --- a/src/shapes/path.class.js +++ b/src/shapes/path.class.js @@ -545,15 +545,13 @@ var path = chunks.join(' '); markup.push( - //jscs:disable validateIndentation - '', - '', - '' + //jscs:disable validateIndentation + '\n' //jscs:enable validateIndentation ); From 4a54069532858f12bc77086c6152097ed6acde1f Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:54:08 +0200 Subject: [PATCH 10/27] pathgroup: fixes toSVG method --- src/shapes/path_group.class.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/shapes/path_group.class.js b/src/shapes/path_group.class.js index 9575dfe3..0c39d5fd 100644 --- a/src/shapes/path_group.class.js +++ b/src/shapes/path_group.class.js @@ -149,19 +149,20 @@ */ toSVG: function(reviver) { var objects = this.getObjects(), + translatePart = 'translate(' + this.left + ' ' + this.top + ')', markup = [ //jscs:disable validateIndentation '' + 'transform="', translatePart, this.getSvgTransform(), '" ', + '>\n' //jscs:enable validateIndentation ]; for (var i = 0, len = objects.length; i < len; i++) { markup.push(objects[i].toSVG(reviver)); } - markup.push(''); + markup.push('\n'); return reviver ? reviver(markup.join('')) : markup.join(''); }, From ece0c1549f44ab1bd25346ae79d9a1f2ba25c4f3 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:56:08 +0200 Subject: [PATCH 11/27] Polygon: Fixes toSVG method, removed normalization --- src/shapes/polygon.class.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/shapes/polygon.class.js b/src/shapes/polygon.class.js index e20e9947..5d4713c9 100644 --- a/src/shapes/polygon.class.js +++ b/src/shapes/polygon.class.js @@ -111,7 +111,8 @@ 'points="', points.join(''), '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), - '"/>' + ' ', this.getSvgTransformMatrix(), + '"/>\n' ); return reviver ? reviver(markup.join('')) : markup.join(''); @@ -125,7 +126,6 @@ _render: function(ctx) { var point; ctx.beginPath(); - ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity; ctx.moveTo(this.points[0].x, this.points[0].y); for (var i = 0, len = this.points.length; i < len; i++) { point = this.points[i]; @@ -184,6 +184,7 @@ if (!element) { return null; } + options || (options = { }); var points = fabric.parsePointsAttribute(element.getAttribute('points')), @@ -193,9 +194,6 @@ return null; } - if (!('transformMatrix' in parsedAttributes)) { - fabric.util.normalizePoints(points, options); - } return new fabric.Polygon(points, extend(parsedAttributes, options), true); }; /* _FROM_SVG_END_ */ From ac7c208e4d3d3aee92240753db7cd94e3b055a33 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:57:32 +0200 Subject: [PATCH 12/27] Polyline: Fixes toSVG method, remove normalization --- src/shapes/polyline.class.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/shapes/polyline.class.js b/src/shapes/polyline.class.js index 2fbfc3d3..7257e665 100644 --- a/src/shapes/polyline.class.js +++ b/src/shapes/polyline.class.js @@ -95,7 +95,8 @@ 'points="', points.join(''), '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), - '"/>' + ' ', this.getSvgTransformMatrix(), + '"/>\n' ); return reviver ? reviver(markup.join('')) : markup.join(''); @@ -169,9 +170,10 @@ var points = fabric.parsePointsAttribute(element.getAttribute('points')), parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES); - if (!('transformMatrix' in parsedAttributes)) { - fabric.util.normalizePoints(points, options); + if (points === null) { + return null; } + return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options), true); }; /* _FROM_SVG_END_ */ From ff2a24c3aed5a21ba1cd0b233229d377a16a2c9d Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 12:58:50 +0200 Subject: [PATCH 13/27] Simplified rect class and fixed SVG export --- src/shapes/rect.class.js | 87 ++++++++++------------------------------ 1 file changed, 21 insertions(+), 66 deletions(-) diff --git a/src/shapes/rect.class.js b/src/shapes/rect.class.js index 565a7a51..44246bc5 100644 --- a/src/shapes/rect.class.js +++ b/src/shapes/rect.class.js @@ -50,17 +50,6 @@ */ ry: 0, - /** - * @type Number - * @default - */ - x: 0, - - /** - * @type Number - * @default - */ - y: 0, /** * Used to specify dash pattern for stroke on this object @@ -79,8 +68,6 @@ this.callSuper('initialize', options); this._initRxRy(); - this.x = options.x || 0; - this.y = options.y || 0; }, /** @@ -100,7 +87,7 @@ * @private * @param {CanvasRenderingContext2D} ctx Context to render on */ - _render: function(ctx) { + _render: function(ctx, noTransform) { // optimize 1x1 case (used in spray brush) if (this.width === 1 && this.height === 1) { @@ -112,24 +99,15 @@ ry = this.ry ? Math.min(this.ry, this.height / 2) : 0, w = this.width, h = this.height, - x = -w / 2, - y = -h / 2, - isInPathGroup = this.group && this.group.type === 'path-group', + x = noTransform ? this.left : 0, + y = noTransform ? this.top : 0, isRounded = rx !== 0 || ry !== 0, k = 1 - 0.5522847498 /* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */; ctx.beginPath(); - ctx.globalAlpha = isInPathGroup ? (ctx.globalAlpha * this.opacity) : this.opacity; - if (this.transformMatrix && isInPathGroup) { - ctx.translate( - this.width / 2 + this.x, - this.height / 2 + this.y); - } - if (!this.transformMatrix && isInPathGroup) { - ctx.translate( - -this.group.width / 2 + this.width / 2 + this.x, - -this.group.height / 2 + this.height / 2 + this.y); + if (!noTransform) { + ctx.translate(-this.width / 2, -this.height / 2); } ctx.moveTo(x + rx, y); @@ -170,22 +148,6 @@ ctx.closePath(); }, - /** - * Since coordinate system differs from that of SVG - * @private - */ - _normalizeLeftTopProperties: function(parsedAttributes) { - if ('left' in parsedAttributes) { - this.set('left', parsedAttributes.left + this.getWidth() / 2); - } - this.set('x', parsedAttributes.left || 0); - if ('top' in parsedAttributes) { - this.set('top', parsedAttributes.top + this.getHeight() / 2); - } - this.set('y', parsedAttributes.top || 0); - return this; - }, - /** * Returns object representation of an instance * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output @@ -194,9 +156,7 @@ toObject: function(propertiesToInclude) { var object = extend(this.callSuper('toObject', propertiesToInclude), { rx: this.get('rx') || 0, - ry: this.get('ry') || 0, - x: this.get('x'), - y: this.get('y') + ry: this.get('ry') || 0 }); if (!this.includeDefaultValues) { this._removeDefaultValues(object); @@ -211,16 +171,20 @@ * @return {String} svg representation of an instance */ toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(); - + var markup = this._createBaseSVGMarkup(), x = this.left, y = this.top; + if (!this.group) { + x = -this.width / 2; + y = -this.height / 2; + } markup.push( ''); + this.getSvgTransformMatrix(), + '"/>\n'); return reviver ? reviver(markup.join('')) : markup.join(''); }, @@ -244,15 +208,6 @@ */ fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' ')); - /** - * @private - */ - function _setDefaultLeftTopValues(attributes) { - attributes.left = attributes.left || 0; - attributes.top = attributes.top || 0; - return attributes; - } - /** * Returns {@link fabric.Rect} instance from an SVG element * @static @@ -265,14 +220,14 @@ if (!element) { return null; } - + options = options || { }; + var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES); - parsedAttributes = _setDefaultLeftTopValues(parsedAttributes); - - var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); - rect._normalizeLeftTopProperties(parsedAttributes); - - return rect; + + parsedAttributes.left = parsedAttributes.left || 0; + parsedAttributes.top = parsedAttributes.top || 0; + + return new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); }; /* _FROM_SVG_END_ */ From 74f796fe3e9ae8668424b85f155c53e6ef949c2a Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:01:51 +0200 Subject: [PATCH 14/27] Fixed toSVG for text. --- src/shapes/text.class.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/shapes/text.class.js b/src/shapes/text.class.js index 1f18eed8..7a2104ad 100644 --- a/src/shapes/text.class.js +++ b/src/shapes/text.class.js @@ -849,8 +849,8 @@ : (this.height/2) - (textLines.length * this.fontSize) - this._totalLineHeight; return { - textLeft: textLeft, - textTop: textTop, + textLeft: textLeft + (this.group ? this.left : 0), + textTop: textTop + (this.group ? this.top : 0), lineTop: lineTop }; }, @@ -860,7 +860,7 @@ */ _wrapSVGTextAndBg: function(markup, textAndBg, shadowSpans, offsets) { markup.push( - '', + '\n', textAndBg.textBgRects.join(''), '', shadowSpans.join(''), textAndBg.textSpans.join(''), - '', - '' + '\n', + '\n' ); }, @@ -992,7 +992,7 @@ toFixed(this._boundaries[i].width, 2), '" height="', toFixed(this._boundaries[i].height, 2), - '">'); + '">\n'); }, _setSVGBg: function(textBgRects) { From c02315f36b925d163b94880a5ae78558d079ee80 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:03:04 +0200 Subject: [PATCH 15/27] remove normalize func not more used --- src/util/misc.js | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/util/misc.js b/src/util/misc.js index 5bf9de7c..e35439ab 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -505,26 +505,6 @@ return (String(fn).match(/function[^{]*\{([\s\S]*)\}/) || {})[1]; }, - /** - * Normalizes polygon/polyline points according to their dimensions - * @param {Array} points - * @param {Object} options - */ - normalizePoints: function(points, options) { - var minX = fabric.util.array.min(points, 'x'), - minY = fabric.util.array.min(points, 'y'); - - minX = minX < 0 ? minX : 0; - minY = minX < 0 ? minY : 0; - - for (var i = 0, len = points.length; i < len; i++) { - // normalize coordinates, according to containing box - // (dimensions of which are passed via `options`) - points[i].x -= (options.width / 2 + minX) || 0; - points[i].y -= (options.height / 2 + minY) || 0; - } - }, - /** * Returns true if context has transparent pixel * at specified location (taking tolerance into account) From 491b4d1c33cd25e28f8e6d5d09ea2f249ea77360 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:07:01 +0200 Subject: [PATCH 16/27] Fixed test for rect, x and y are no more used. --- test/unit/canvas.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/canvas.js b/test/unit/canvas.js index 4f7b4142..7cc0f5d1 100644 --- a/test/unit/canvas.js +++ b/test/unit/canvas.js @@ -46,7 +46,7 @@ var RECT_JSON = '{"objects":[{"type":"rect","originX":"left","originY":"top","left":0,"top":0,"width":10,"height":10,"fill":"rgb(0,0,0)",'+ '"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,'+ '"shadow":null,'+ - '"visible":true,"clipTo":null,"backgroundColor":"","rx":0,"ry":0,"x":0,"y":0}],"background":"#ff5555","overlay":"rgba(0,0,0,0.2)"}'; + '"visible":true,"clipTo":null,"backgroundColor":"","rx":0,"ry":0}],"background":"#ff5555","overlay":"rgba(0,0,0,0.2)"}'; var el = fabric.document.createElement('canvas'); el.width = 600; el.height = 600; From 8500f28f8f8a07871c2bdf8f2553b3702039985b Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:08:40 +0200 Subject: [PATCH 17/27] removed x and y no more used for rect --- test/unit/canvas_static.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/canvas_static.js b/test/unit/canvas_static.js index bcc6241a..87114c02 100644 --- a/test/unit/canvas_static.js +++ b/test/unit/canvas_static.js @@ -33,12 +33,12 @@ var RECT_JSON = '{"objects":[{"type":"rect","originX":"left","originY":"top","left":0,"top":0,"width":10,"height":10,"fill":"rgb(0,0,0)",'+ '"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,'+ '"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,'+ - '"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","rx":0,"ry":0,"x":0,"y":0}],"background":"#ff5555","overlay":"rgba(0,0,0,0.2)"}'; + '"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","rx":0,"ry":0}],"background":"#ff5555","overlay":"rgba(0,0,0,0.2)"}'; var RECT_JSON_WITH_PADDING = '{"objects":[{"type":"rect","originX":"left","originY":"top","left":0,"top":0,"width":10,"height":20,"fill":"rgb(0,0,0)",'+ '"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,'+ '"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,'+ - '"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","padding":123,"foo":"bar","rx":0,"ry":0,"x":0,"y":0}],"background":""}'; + '"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","padding":123,"foo":"bar","rx":0,"ry":0}],"background":""}'; function getAbsolutePath(path) { var isAbsolute = /^https?:/.test(path); From d2da5956cdc5edb84b4398d40b9e4ad93c3f8943 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:11:59 +0200 Subject: [PATCH 18/27] fix tests for circle --- test/unit/circle.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/circle.js b/test/unit/circle.js index 39429ed9..a961183c 100644 --- a/test/unit/circle.js +++ b/test/unit/circle.js @@ -152,8 +152,8 @@ ok(oCircle instanceof fabric.Circle); equal(oCircle.get('radius'), radius); - equal(oCircle.get('left'), left); - equal(oCircle.get('top'), top); + equal(oCircle.get('left'), left - radius); + equal(oCircle.get('top'), top - radius); equal(oCircle.get('fill'), fill); equal(oCircle.get('opacity'), opacity); equal(oCircle.get('strokeWidth'), strokeWidth); From 99cb87bfca3a4b5dcc36ac235a5c6aca93e383e7 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:15:10 +0200 Subject: [PATCH 19/27] fixes test for ellipses --- test/unit/ellipse.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/ellipse.js b/test/unit/ellipse.js index 087e2a76..88f43e1b 100644 --- a/test/unit/ellipse.js +++ b/test/unit/ellipse.js @@ -111,8 +111,8 @@ equal(oEllipse.get('rx'), rx); equal(oEllipse.get('ry'), ry); - equal(oEllipse.get('left'), left); - equal(oEllipse.get('top'), top); + equal(oEllipse.get('left'), left - rx); + equal(oEllipse.get('top'), top - ry); equal(oEllipse.get('fill'), fill); equal(oEllipse.get('opacity'), opacity); equal(oEllipse.get('strokeWidth'), strokeWidth); From c5a5ce3ce9e745682f3496d7f166b24638303ab1 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:16:12 +0200 Subject: [PATCH 20/27] fixed differences for new transforms --- test/unit/group.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/group.js b/test/unit/group.js index c6e93a21..047d3282 100644 --- a/test/unit/group.js +++ b/test/unit/group.js @@ -384,7 +384,7 @@ test('toObject without default values', function() { var group = makeGroupWith2Objects(); ok(typeof group.toSVG == 'function'); - var expectedSVG = ''; + var expectedSVG = '\n\n\n\n'; equal(group.toSVG(), expectedSVG); }); From 78a5221143e6da3db5423f011aeee6076779893a Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:19:07 +0200 Subject: [PATCH 21/27] Mirrored tests from polygons --- test/unit/polyline.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/test/unit/polyline.js b/test/unit/polyline.js index 9239cb9b..6cac84d4 100644 --- a/test/unit/polyline.js +++ b/test/unit/polyline.js @@ -116,16 +116,13 @@ deepEqual(polylineWithAttrs.get('transformMatrix'), [ 2, 0, 0, 2, -10, -20 ]); var elPolylineWithoutPoints = fabric.document.createElement('polyline'); + equal(fabric.Polyline.fromElement(elPolylineWithoutPoints), null); - var error; - try { - fabric.Polyline.fromElement(elPolylineWithoutPoints); - } - catch(err) { - error = err; - } + var elPolylineWithEmptyPoints = fabric.document.createElement('polyline'); + elPolylineWithEmptyPoints.setAttribute('points', ''); - ok(typeof error !== 'undefined', 'missing points attribute should result in error'); - equal(fabric.Polyline.fromElement(), null); + equal(fabric.Polyline.fromElement(elPolylineWithEmptyPoints), null); + + equal(fabric.Polyline.fromElement(), null); }); })(); From 0538fe68c9371ef94467c9364c5e1462faecf075 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:19:53 +0200 Subject: [PATCH 22/27] Fixes tests for rects --- test/unit/rect.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/unit/rect.js b/test/unit/rect.js index c11d6da3..5addeeec 100644 --- a/test/unit/rect.js +++ b/test/unit/rect.js @@ -27,8 +27,6 @@ 'clipTo': null, 'rx': 0, 'ry': 0, - 'x': 0, - 'y': 0 }; QUnit.module('fabric.Rect'); @@ -99,8 +97,8 @@ ok(rectWithAttrs instanceof fabric.Rect); var expectedObject = fabric.util.object.extend(REFERENCE_RECT, { - left: 121, - top: 186.5, + left: 10, + top: 20, width: 222, height: 333, fill: 'rgb(255,255,255)', @@ -112,9 +110,7 @@ strokeLineJoin: 'bevil', strokeMiterLimit: 5, rx: 11, - ry: 12, - x: 10, - y: 20 + ry: 12 }); deepEqual(rectWithAttrs.toObject(), expectedObject); }); @@ -135,7 +131,7 @@ var rect = new fabric.Rect({ width: 100, height: 100, rx: 20, ry: 30 }); var svg = rect.toSVG(); - equal(svg, ''); + equal(svg, '\n'); }); test('toObject without default values', function() { From 3064d5e569b1a3157fa71bb7227192146d050474 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 5 Aug 2014 13:22:12 +0200 Subject: [PATCH 23/27] Updated test for text --- test/unit/text.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/text.js b/test/unit/text.js index da5e9e86..d5c32366 100644 --- a/test/unit/text.js +++ b/test/unit/text.js @@ -46,7 +46,7 @@ 'useNative': true }; - var TEXT_SVG = 'x'; + var TEXT_SVG = '\nx\n\n'; test('constructor', function() { ok(fabric.Text); From c4b3d1881d792723cf8a01bd7db10e59a7cead06 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Wed, 6 Aug 2014 13:54:04 +0200 Subject: [PATCH 24/27] Update image.class.js Fixed rendering of borders and svg transformation --- src/shapes/image.class.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shapes/image.class.js b/src/shapes/image.class.js index f5e43bf4..e1dc63e9 100644 --- a/src/shapes/image.class.js +++ b/src/shapes/image.class.js @@ -175,14 +175,13 @@ y = this.top; } markup.push( - '\n', + '\n', '\n' @@ -305,6 +304,7 @@ this.width, this.height ); + this._renderStroke(ctx); }, /** From 6367e30dba6cf3d6e29058ee97f1a1361478fe23 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Wed, 6 Aug 2014 19:20:13 +0200 Subject: [PATCH 25/27] Update line.class.js Don't ask why. For me half dimension was more than enough. --- src/shapes/line.class.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shapes/line.class.js b/src/shapes/line.class.js index df73af6b..60eda72f 100644 --- a/src/shapes/line.class.js +++ b/src/shapes/line.class.js @@ -232,7 +232,9 @@ toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), addTranslate = ''; if (!this.group) { - addTranslate = 'translate(' + (-this.width/2) + ', ' + (-this.height/2) + ') '; + var x = this.width / 2 + (this.x1 > this.x2 ? this.x2 : this.x1), + y = this.height / 2 + (this.y1 > this.y2 ? this.y2 : this.y1); + addTranslate = 'translate(' + (-x) + ', ' + (-y) + ') '; } markup.push( ' Date: Wed, 6 Aug 2014 23:48:07 +0200 Subject: [PATCH 26/27] Update line.class.js Just cosmetic. --- src/shapes/line.class.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/shapes/line.class.js b/src/shapes/line.class.js index 60eda72f..a9c297f2 100644 --- a/src/shapes/line.class.js +++ b/src/shapes/line.class.js @@ -232,16 +232,16 @@ toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), addTranslate = ''; if (!this.group) { - var x = this.width / 2 + (this.x1 > this.x2 ? this.x2 : this.x1), - y = this.height / 2 + (this.y1 > this.y2 ? this.y2 : this.y1); - addTranslate = 'translate(' + (-x) + ', ' + (-y) + ') '; + var x = - this.width / 2 - (this.x1 > this.x2 ? this.x2 : this.x1), + y = - this.height / 2 - (this.y1 > this.y2 ? this.y2 : this.y1); + addTranslate = 'translate(' + x + ', ' + y + ') '; } markup.push( '