Skip to content

Commit

Permalink
ISSUE-5512 Clippath transform parsing (#5983)
Browse files Browse the repository at this point in the history
  • Loading branch information
asturur authored Nov 20, 2019
1 parent 45dfd82 commit a8b7a18
Show file tree
Hide file tree
Showing 11 changed files with 842 additions and 34 deletions.
1 change: 1 addition & 0 deletions HEADER.js
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
25 changes: 17 additions & 8 deletions src/elements_parser.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
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;
this.reviver = reviver;
this.svgUid = (options && options.svgUid) || 0;
this.parsingOptions = parsingOptions;
this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g;
this.doc = doc;
};

(function(proto) {
Expand Down Expand Up @@ -52,20 +53,21 @@ 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();
};
};

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];
};

Expand All @@ -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);
Expand All @@ -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;
Expand Down
20 changes: 2 additions & 18 deletions src/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
22 changes: 16 additions & 6 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
colorAttributes = {
stroke: 'strokeOpacity',
fill: 'fillOpacity'
};
},

fSize = 'font-size', cPath = 'clip-path';

fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);
fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);
Expand Down Expand Up @@ -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 = {};
Expand Down
2 changes: 1 addition & 1 deletion src/shapes/path.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@
coords = [],
currentPath,
parsed,
re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/ig,
re = fabric.rePathCommand,
match,
coordsStr;

Expand Down
1 change: 1 addition & 0 deletions test/visual/assets/emoji-b.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit a8b7a18

Please sign in to comment.