diff --git a/HEADER.js b/HEADER.js
index d83b412dbcd..72f63b52376 100644
--- a/HEADER.js
+++ b/HEADER.js
@@ -73,6 +73,7 @@ fabric.SHARED_ATTRIBUTES = [
*/
fabric.DPI = 96;
fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)';
+fabric.rePathCommand = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:[eE][-+]?\d+)?)/ig;
fabric.fontPaths = { };
fabric.iMatrix = [1, 0, 0, 1, 0, 0];
diff --git a/src/elements_parser.js b/src/elements_parser.js
index 14f2ccbb7ff..b8d07ec95b3 100644
--- a/src/elements_parser.js
+++ b/src/elements_parser.js
@@ -1,4 +1,4 @@
-fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {
+fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions, doc) {
this.elements = elements;
this.callback = callback;
this.options = options;
@@ -6,6 +6,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
this.svgUid = (options && options.svgUid) || 0;
this.parsingOptions = parsingOptions;
this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g;
+ this.doc = doc;
};
(function(proto) {
@@ -52,7 +53,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
_options = obj.parsePreserveAspectRatioAttribute(el);
}
obj._removeTransformMatrix(_options);
- _this.resolveClipPath(obj);
+ _this.resolveClipPath(obj, el);
_this.reviver && _this.reviver(el, obj);
_this.instances[index] = obj;
_this.checkIfDone();
@@ -60,12 +61,13 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
};
proto.extractPropertyDefinition = function(obj, property, storage) {
- var value = obj[property];
- if (!(/^url\(/).test(value)) {
+ var value = obj[property], regex = this.regexUrl;
+ if (!regex.test(value)) {
return;
}
- var id = this.regexUrl.exec(value)[1];
- this.regexUrl.lastIndex = 0;
+ regex.lastIndex = 0;
+ var id = regex.exec(value)[1];
+ regex.lastIndex = 0;
return fabric[storage][this.svgUid][id];
};
@@ -86,12 +88,19 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
};
};
- proto.resolveClipPath = function(obj) {
+ proto.resolveClipPath = function(obj, usingElement) {
var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'),
element, klass, objTransformInv, container, gTransform, options;
if (clipPath) {
container = [];
objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix());
+ // move the clipPath tag as sibling to the real element that is using it
+ var clipPathTag = clipPath[0].parentNode;
+ var clipPathOwner = usingElement;
+ while (clipPathOwner.parentNode && clipPathOwner.getAttribute('clip-path') !== obj.clipPath) {
+ clipPathOwner = clipPathOwner.parentNode;
+ }
+ clipPathOwner.parentNode.appendChild(clipPathTag);
for (var i = 0; i < clipPath.length; i++) {
element = clipPath[i];
klass = this.findTag(element);
@@ -112,7 +121,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
clipPath.calcTransformMatrix()
);
if (clipPath.clipPath) {
- this.resolveClipPath(clipPath);
+ this.resolveClipPath(clipPath, clipPathOwner);
}
var options = fabric.util.qrDecompose(gTransform);
clipPath.flipX = false;
diff --git a/src/log.js b/src/log.js
index 4e57732fbea..d09cf1e5085 100644
--- a/src/log.js
+++ b/src/log.js
@@ -2,26 +2,10 @@
* Wrapper around `console.log` (when available)
* @param {*} [values] Values to log
*/
-fabric.log = function() { };
+fabric.log = console.log;
/**
* Wrapper around `console.warn` (when available)
* @param {*} [values] Values to log as a warning
*/
-fabric.warn = function() { };
-
-/* eslint-disable */
-if (typeof console !== 'undefined') {
-
- ['log', 'warn'].forEach(function(methodName) {
-
- if (typeof console[methodName] !== 'undefined' &&
- typeof console[methodName].apply === 'function') {
-
- fabric[methodName] = function() {
- return console[methodName].apply(console, arguments);
- };
- }
- });
-}
-/* eslint-enable */
+fabric.warn = console.warn;
diff --git a/src/parser.js b/src/parser.js
index f8428bef845..5c93e9f8577 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -55,7 +55,9 @@
colorAttributes = {
stroke: 'strokeOpacity',
fill: 'fillOpacity'
- };
+ },
+
+ fSize = 'font-size', cPath = 'clip-path';
fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);
fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);
@@ -847,13 +849,21 @@
}, { });
// add values parsed from style, which take precedence over attributes
// (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)
- ownAttributes = extend(ownAttributes,
- extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));
-
+ var cssAttrs = extend(
+ getGlobalStylesForElement(element, svgUid),
+ fabric.parseStyleAttribute(element)
+ );
+ ownAttributes = extend(
+ ownAttributes,
+ cssAttrs
+ );
+ if (cssAttrs[cPath]) {
+ element.setAttribute(cPath, cssAttrs[cPath]);
+ }
fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE;
- if (ownAttributes['font-size']) {
+ if (ownAttributes[fSize]) {
// looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.
- ownAttributes['font-size'] = fontSize = parseUnit(ownAttributes['font-size'], parentFontSize);
+ ownAttributes[fSize] = fontSize = parseUnit(ownAttributes[fSize], parentFontSize);
}
var normalizedAttr, normalizedValue, normalizedStyle = {};
diff --git a/src/shapes/path.class.js b/src/shapes/path.class.js
index a2cfb4c4352..70eb3eb3069 100644
--- a/src/shapes/path.class.js
+++ b/src/shapes/path.class.js
@@ -500,7 +500,7 @@
coords = [],
currentPath,
parsed,
- re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/ig,
+ re = fabric.rePathCommand,
match,
coordsStr;
diff --git a/test/visual/assets/emoji-b.svg b/test/visual/assets/emoji-b.svg
new file mode 100644
index 00000000000..0c2c8cd4077
--- /dev/null
+++ b/test/visual/assets/emoji-b.svg
@@ -0,0 +1 @@
+
diff --git a/test/visual/assets/gold-logo.svg b/test/visual/assets/gold-logo.svg
new file mode 100644
index 00000000000..751f8d39418
--- /dev/null
+++ b/test/visual/assets/gold-logo.svg
@@ -0,0 +1,801 @@
+
diff --git a/test/visual/golden/clippath-8.png b/test/visual/golden/clippath-8.png
index 861210b215c..d77a6414078 100644
Binary files a/test/visual/golden/clippath-8.png and b/test/visual/golden/clippath-8.png differ
diff --git a/test/visual/golden/emoji-b.png b/test/visual/golden/emoji-b.png
new file mode 100644
index 00000000000..c15ed0615cb
Binary files /dev/null and b/test/visual/golden/emoji-b.png differ
diff --git a/test/visual/golden/gold-logo.png b/test/visual/golden/gold-logo.png
new file mode 100644
index 00000000000..ade6e762099
Binary files /dev/null and b/test/visual/golden/gold-logo.png differ
diff --git a/test/visual/svg_import.js b/test/visual/svg_import.js
index ed04987e4f5..ac53459f1cb 100644
--- a/test/visual/svg_import.js
+++ b/test/visual/svg_import.js
@@ -79,7 +79,9 @@
'vector-effect',
'svg-with-no-dim-rect',
'notoemoji-person',
- //'clippath-8',
+ // 'clippath-8',
+ 'emoji-b',
+ 'gold-logo'
].map(createTestFromSVG);
tests.forEach(visualTestLoop(QUnit));