From 025f02397eb1da84b90e6e2a8564c790f8654bdf Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 6 Dec 2015 20:46:32 +0100 Subject: [PATCH 01/16] update test for non delegated opacity --- 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 7cac351fd2c..4497ac25148 100644 --- a/test/unit/group.js +++ b/test/unit/group.js @@ -127,7 +127,7 @@ equal(group.set('opacity', 0.12345), group, 'should be chainable'); equal(group.get('opacity'), 0.12345, 'group\'s "own" property should be set properly'); - equal(firstObject.get('opacity'), 0.12345, 'objects\' value should be set properly'); + equal(firstObject.get('opacity'), 1, 'objects\' value of non delegated property should stay same'); group.set('left', 1234); equal(group.get('left'), 1234, 'group\'s own "left" property should be set properly'); From b93a46b353a2b2698651f8bb0f715f9ce7c99fee Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 7 Dec 2015 22:19:37 +0100 Subject: [PATCH 02/16] Update misc.js --- src/util/misc.js | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/util/misc.js b/src/util/misc.js index f191b00ce55..36225db0c2d 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -74,13 +74,31 @@ */ rotatePoint: function(point, origin, radians) { point.subtractEquals(origin); + var v = rotateVector(point); + return new fabric.Point(v.x, v.y).addEquals(origin); + }, + + /** + * Rotates `vector` with `radians` + * @static + * @memberOf fabric.util + * @param {Object} vector The vector to rotate + * @param {Object.x} x coordinate of vector + * @param {Object.y} y coordinate of vector + * @param {Number} radians The radians of the angle for the rotation + * @return {Object} The new rotated point + */ + rotateVector: function(vector, radians) { var sin = Math.sin(radians), cos = Math.cos(radians), - rx = point.x * cos - point.y * sin, - ry = point.x * sin + point.y * cos; - return new fabric.Point(rx, ry).addEquals(origin); + rx = vector.x * cos - vector.y * sin, + ry = vector.x * sin + vector.y * cos; + return { + x: rx, + y: ry + }; }, - + /** * Apply transform t to point p * @static From 815b0acb20f3e081151ce0159dbc1fc51c31a838 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 7 Dec 2015 22:24:48 +0100 Subject: [PATCH 03/16] Update shadow.class.js --- src/shadow.class.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/shadow.class.js b/src/shadow.class.js index 2a1c8ffdd34..681383c7e33 100644 --- a/src/shadow.class.js +++ b/src/shadow.class.js @@ -111,13 +111,15 @@ * @return {String} SVG representation of a shadow */ toSVG: function(object) { - var fBoxX = 40, fBoxY = 40; + var fBoxX = 40, fBoxY = 40, + offset = fabric.util.rotateVector({x: this.offsetX, y: this.offsetY}, + fabric.util.degreesToRadians(-object.angle)); if (object.width && object.height) { //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion // we add some extra space to filter box to contain the blur ( 20 ) - fBoxX = toFixed((Math.abs(this.offsetX) + this.blur) / object.width, 2) * 100 + 20; - fBoxY = toFixed((Math.abs(this.offsetY) + this.blur) / object.height, 2) * 100 + 20; + fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, 2) * 100 + 20; + fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, 2) * 100 + 20; } return ( @@ -125,7 +127,7 @@ 'x="-' + fBoxX + '%" width="' + (100 + 2 * fBoxX) + '%" ' + '>\n' + '\t\n' + - '\t\n' + + '\t\n' + '\t\n' + '\t\n' + '\t\n' + From d9b7becb67fee448d9181de51dcea0b25c798848 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 7 Dec 2015 22:33:43 +0100 Subject: [PATCH 04/16] Update misc.js --- src/util/misc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/misc.js b/src/util/misc.js index 36225db0c2d..e41c059f114 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -98,7 +98,7 @@ y: ry }; }, - + /** * Apply transform t to point p * @static From 27ee9d3f705d4aaa2eb7846c46db9feb311e774e Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 7 Dec 2015 22:40:24 +0100 Subject: [PATCH 05/16] add test for rotated object --- test/unit/shadow.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/unit/shadow.js b/test/unit/shadow.js index 3fa28c7462f..cd91d76cc55 100644 --- a/test/unit/shadow.js +++ b/test/unit/shadow.js @@ -170,5 +170,15 @@ shadow.color = '#000000'; equal(shadow.toSVG(object), '\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'); }); + + test('toSVG with rotated object', function() { + // reset uid + fabric.Object.__uid = 0; + + var shadow = new fabric.Shadow({color: '#FF0000', offsetX: 10, offsetY: 10, blur: 2}); + var object = new fabric.Object({fill: '#FF0000', angle: 45}); + + equal(shadow.toSVG(object), '\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'); + }); })(); From b037095d6b60087ce48309607527e8ac318a86a2 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 7 Dec 2015 22:42:23 +0100 Subject: [PATCH 06/16] Update misc.js --- src/util/misc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/misc.js b/src/util/misc.js index e41c059f114..48a86bca25c 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -74,7 +74,7 @@ */ rotatePoint: function(point, origin, radians) { point.subtractEquals(origin); - var v = rotateVector(point); + var v = fabric.util.rotateVector(point); return new fabric.Point(v.x, v.y).addEquals(origin); }, From f7f64d9ea2560e91c52601a36ff182f61ef18527 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Mon, 7 Dec 2015 22:55:18 +0100 Subject: [PATCH 07/16] Update misc.js --- src/util/misc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/misc.js b/src/util/misc.js index 48a86bca25c..919619805c9 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -74,7 +74,7 @@ */ rotatePoint: function(point, origin, radians) { point.subtractEquals(origin); - var v = fabric.util.rotateVector(point); + var v = fabric.util.rotateVector(point, radians); return new fabric.Point(v.x, v.y).addEquals(origin); }, From 41a3aa8a4ce76f84d031e8fd75458d5887e6bd73 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 8 Dec 2015 11:52:07 +0100 Subject: [PATCH 08/16] Update text.class.js --- src/shapes/text.class.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shapes/text.class.js b/src/shapes/text.class.js index fd9fc500427..965656bdeea 100644 --- a/src/shapes/text.class.js +++ b/src/shapes/text.class.js @@ -926,7 +926,8 @@ _setSVGTextLineText: function(i, textSpans, height, textLeftOffset, textTopOffset) { var yPos = this.fontSize * (this._fontSizeMult - this._fontSizeFraction) - - textTopOffset + height - this.height / 2; + - textTopOffset + height - this.height / 2, + textLine = this.textAlign === 'justify' ? this._setSVGTextLineWords(i) : fabric.util.string.escapeXml(._textLines[i]); textSpans.push( ' elements since setting opacity // on containing one doesn't work in Illustrator this._getFillAttributes(this.fill), '>', - fabric.util.string.escapeXml(this._textLines[i]), + textLine, '' ); }, From 2dfc5b9fbdbd24fc10c05e97eca38f1e60141f36 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 8 Dec 2015 11:56:58 +0100 Subject: [PATCH 09/16] use NUM_FRACTION_DIGIT --- src/shadow.class.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/shadow.class.js b/src/shadow.class.js index 681383c7e33..9195c2473f6 100644 --- a/src/shadow.class.js +++ b/src/shadow.class.js @@ -3,7 +3,8 @@ 'use strict'; var fabric = global.fabric || (global.fabric = { }), - toFixed = fabric.util.toFixed; + toFixed = fabric.util.toFixed, + NUM_FRACTION_DIGIT = fabric.Object.NUM_FRACTION_DIGITS; if (fabric.Shadow) { fabric.warn('fabric.Shadow is already defined.'); @@ -118,16 +119,17 @@ if (object.width && object.height) { //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion // we add some extra space to filter box to contain the blur ( 20 ) - fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, 2) * 100 + 20; - fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, 2) * 100 + 20; + fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGIT) * 100 + 20; + fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGIT) * 100 + 20; } return ( '\n' + '\t\n' + - '\t\n' + + toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGIT) + '">\n' + + '\t\n' + '\t\n' + '\t\n' + '\t\n' + From 411c8b446a700a9876f7ebf864086812954c6ae0 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 8 Dec 2015 12:20:45 +0100 Subject: [PATCH 10/16] Update shadow.class.js --- src/shadow.class.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/shadow.class.js b/src/shadow.class.js index 9195c2473f6..78ecc1e79a0 100644 --- a/src/shadow.class.js +++ b/src/shadow.class.js @@ -3,8 +3,7 @@ 'use strict'; var fabric = global.fabric || (global.fabric = { }), - toFixed = fabric.util.toFixed, - NUM_FRACTION_DIGIT = fabric.Object.NUM_FRACTION_DIGITS; + toFixed = fabric.util.toFixed; if (fabric.Shadow) { fabric.warn('fabric.Shadow is already defined.'); @@ -112,24 +111,24 @@ * @return {String} SVG representation of a shadow */ toSVG: function(object) { - var fBoxX = 40, fBoxY = 40, + var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, offset = fabric.util.rotateVector({x: this.offsetX, y: this.offsetY}, fabric.util.degreesToRadians(-object.angle)); if (object.width && object.height) { //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion // we add some extra space to filter box to contain the blur ( 20 ) - fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGIT) * 100 + 20; - fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGIT) * 100 + 20; + fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + 20; + fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + 20; } return ( '\n' + '\t\n' + - '\t\n' + + toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS) + '">\n' + + '\t\n' + '\t\n' + '\t\n' + '\t\n' + From 61daf814701da31f2f5fe78d920878dfbd1ba683 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Tue, 8 Dec 2015 19:53:44 +0100 Subject: [PATCH 11/16] Update text.class.js --- src/shapes/text.class.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/shapes/text.class.js b/src/shapes/text.class.js index 965656bdeea..66666676cd8 100644 --- a/src/shapes/text.class.js +++ b/src/shapes/text.class.js @@ -926,8 +926,12 @@ _setSVGTextLineText: function(i, textSpans, height, textLeftOffset, textTopOffset) { var yPos = this.fontSize * (this._fontSizeMult - this._fontSizeFraction) - - textTopOffset + height - this.height / 2, - textLine = this.textAlign === 'justify' ? this._setSVGTextLineWords(i) : fabric.util.string.escapeXml(._textLines[i]); + - textTopOffset + height - this.height / 2; + if (this.textAlign === 'justify') { + // i call from here to do not intefere with IText + this.setSVGTextLineJustifed(i, textSpans, height, textLeftOffset, textTopOffset); + return; + } textSpans.push( ' elements since setting opacity // on containing one doesn't work in Illustrator this._getFillAttributes(this.fill), '>', - textLine, + fabric.util.string.escapeXml(this._textLines[i]), '' ); }, + setSVGTextLineJustifed: function(i, textSpans, height, textLeftOffset, textTopOffset) { + textSpans.push('justified'); + }, + _setSVGTextLineBg: function(textBgRects, i, textLeftOffset, textTopOffset, height) { textBgRects.push( '\t\t Date: Wed, 9 Dec 2015 08:16:27 +0100 Subject: [PATCH 12/16] Update shadow.class.js --- src/shadow.class.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shadow.class.js b/src/shadow.class.js index 78ecc1e79a0..f6ab9ab012b 100644 --- a/src/shadow.class.js +++ b/src/shadow.class.js @@ -113,13 +113,13 @@ toSVG: function(object) { var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, offset = fabric.util.rotateVector({x: this.offsetX, y: this.offsetY}, - fabric.util.degreesToRadians(-object.angle)); + fabric.util.degreesToRadians(-object.angle)), BLUR_BOX = 20; if (object.width && object.height) { //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion // we add some extra space to filter box to contain the blur ( 20 ) - fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + 20; - fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + 20; + fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; + fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; } return ( From 185d8e2d31ffc0faa0ec4bd318aca123cef56c2d Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Wed, 9 Dec 2015 09:41:37 +0100 Subject: [PATCH 13/16] Update text.class.js --- src/shapes/text.class.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/shapes/text.class.js b/src/shapes/text.class.js index 66666676cd8..a84b84c8837 100644 --- a/src/shapes/text.class.js +++ b/src/shapes/text.class.js @@ -479,11 +479,12 @@ // stretch the line var words = line.split(/\s+/), - wordsWidth = this._getWidthOfWords(ctx, line, lineIndex), + charOffset = 0, + wordsWidth = this._getWidthOfWords(ctx, line, lineIndex, 0), widthDiff = this.width - wordsWidth, numSpaces = words.length - 1, spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0, - leftOffset = 0, charOffset = 0, word; + leftOffset = 0, word; for (var i = 0, len = words.length; i < len; i++) { while (line[charOffset] === ' ' && charOffset < line.length) { @@ -491,7 +492,7 @@ } word = words[i]; this._renderChars(method, ctx, word, left + leftOffset, top, lineIndex, charOffset); - leftOffset += ctx.measureText(word).width + spaceWidth; + leftOffset += this._getWidthOfWords(ctx, word, lineIndex, charOffset) + spaceWidth; charOffset += word.length; } }, @@ -889,9 +890,9 @@ (this.fontStyle ? 'font-style="' + this.fontStyle + '" ': ''), (this.fontWeight ? 'font-weight="' + this.fontWeight + '" ': ''), (this.textDecoration ? 'text-decoration="' + this.textDecoration + '" ': ''), - 'style="', this.getSvgStyles(), '" >', + 'style="', this.getSvgStyles(), '" >\n', textAndBg.textSpans.join(''), - '\n', + '\t\t\n', '\t\n' ); }, @@ -929,11 +930,11 @@ - textTopOffset + height - this.height / 2; if (this.textAlign === 'justify') { // i call from here to do not intefere with IText - this.setSVGTextLineJustifed(i, textSpans, height, textLeftOffset, textTopOffset); + this._setSVGTextLineJustifed(i, textSpans, height, textLeftOffset, textTopOffset); return; } textSpans.push( - ' elements since setting opacity + // on containing one doesn't work in Illustrator + attributes, '>', + fabric.util.string.escapeXml(word), + '\n' + ); + textLeftOffset += this._getWidthOfWords(ctx, word) + spaceWidth; + } + }, _setSVGTextLineBg: function(textBgRects, i, textLeftOffset, textTopOffset, height) { From f63cd9862f4d43a7aaef374ac017f8929aef6aa4 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Thu, 10 Dec 2015 09:36:24 +0100 Subject: [PATCH 16/16] Update text.js --- test/unit/text.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/unit/text.js b/test/unit/text.js index c62e3ce8243..b21746db789 100644 --- a/test/unit/text.js +++ b/test/unit/text.js @@ -49,7 +49,8 @@ 'transformMatrix': null }; - var TEXT_SVG = '\t\n\t\tx\n\t\n'; + var TEXT_SVG = '\t\n\t\t\n\t\t\tx\n\t\t\n\t\n'; + var TEXT_SVG_JUSTIFIED = '\t\n\t\t\n\t\t\tx\n\t\t\ty\n\t\t\n\t\n'; test('constructor', function() { ok(fabric.Text); @@ -261,5 +262,17 @@ equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG.replace('font-family="Times New Roman"', 'font-family="\'Arial Black\', Arial"'))); }); + test('toSVG justified', function() { + var text = new fabric.Text('x y'); + + function removeTranslate(str) { + return str.replace(/translate\(.*?\)/, ''); + } + + // temp workaround for text objects not obtaining width under node + text.width = 100; + text.textAlign = 'justify' + equal(removeTranslate(text.toSVG()), removeTranslate(TEXT_SVG_JUSTIFIED)); + }); })();