diff --git a/CHANGELOG.md b/CHANGELOG.md
index 18742e5621a..ca382d4b97b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,32 @@
# Changelog
+## [4.0.0-beta.5]
+
+fix(fabric.Object): getObjectScaling takes in account rotation of objects inside groups. [#6118](https://github.com/fabricjs/fabric.js/pull/6118)
+
+## [4.0.0-beta.4]
+
+fix(fabric.Group): will draw shadow will call parent method. [#6116](https://github.com/fabricjs/fabric.js/pull/6116)
+
+## [4.0.0-beta.3]
+
+fix(controls): control offset rendering code had extras `beginPath` that would clear all but not the last of them [#6114](https://github.com/fabricjs/fabric.js/pull/6114)
+
+## [4.0.0-beta.2]
+
+fix(controls): Control.getVisibility will always receive the fabric.Object argument.
+
+## [4.0.0-beta.1]
+
+breaking: All your old control code override will not work
+breaking: `uniScaleTransform` has been renamed in `uniformScaling`, meaning changed and the default value swapped. The behaviour is unchanged, but now the description and the name match.
+breaking: LockScalingFlip with the scaling flip behaviour are missing now, maybe reimplemented later.
+breaking: Object.lockUniScaling is removed. Alternatives to get the same identical functionality with less code are being evaluated.
+breaking: Canvas.onBeforeScaleRotate is removed, developers need to migrate to the event `before:transform’
+
+## [3.6.2]
+- fix fabric.Object.toDataURL blurriness on images with odd pixel number [#6131](https://github.com/fabricjs/fabric.js/pull/6131)
+
## [3.6.1]
- fix(gradient, text): ISSUE-6014 ISSUE-6077 support percentage gradient in text [#6090](https://github.com/fabricjs/fabric.js/pull/6090)
- fix(filters): ISSUE-6072 convolution filter is off by one [#6088](https://github.com/fabricjs/fabric.js/pull/6088)
diff --git a/HEADER.js b/HEADER.js
index 7e8cf675fda..d099017689e 100644
--- a/HEADER.js
+++ b/HEADER.js
@@ -1,6 +1,6 @@
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
-var fabric = fabric || { version: '3.6.1' };
+var fabric = fabric || { version: '3.6.2' };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
diff --git a/dist/fabric.js b/dist/fabric.js
index 3d17c64105f..9161901105b 100644
--- a/dist/fabric.js
+++ b/dist/fabric.js
@@ -1,7 +1,7 @@
/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
-var fabric = fabric || { version: '3.6.1' };
+var fabric = fabric || { version: '3.6.2' };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
@@ -9362,38 +9362,40 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
* @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}
* @see {@link fabric.Canvas#initialize} for constructor definition
*
- * @fires object:modified
- * @fires object:rotated
- * @fires object:scaled
- * @fires object:moved
- * @fires object:skewed
- * @fires object:rotating
- * @fires object:scaling
- * @fires object:moving
- * @fires object:skewing
+ * @fires object:modified at the end of a transform or any change when statefull is true
+ * @fires object:rotated at the end of a rotation transform
+ * @fires object:scaled at the end of a scale transform
+ * @fires object:moved at the end of translation transform
+ * @fires object:skewed at the end of a skew transform
+ * @fires object:rotating while an object is being rotated from the control
+ * @fires object:scaling while an object is being scaled by controls
+ * @fires object:moving while an object is being dragged
+ * @fires object:skewing while an object is being skewed from the controls
* @fires object:selected this event is deprecated. use selection:created
*
- * @fires before:transform
+ * @fires before:transform before a transform is is started
* @fires before:selection:cleared
* @fires selection:cleared
* @fires selection:updated
* @fires selection:created
*
- * @fires path:created
+ * @fires path:created after a drawing operation ends and the path is added
* @fires mouse:down
* @fires mouse:move
* @fires mouse:up
- * @fires mouse:down:before
- * @fires mouse:move:before
- * @fires mouse:up:before
+ * @fires mouse:down:before on mouse down, before the inner fabric logic runs
+ * @fires mouse:move:before on mouse move, before the inner fabric logic runs
+ * @fires mouse:up:before on mouse up, before the inner fabric logic runs
* @fires mouse:over
* @fires mouse:out
- * @fires mouse:dblclick
+ * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.
*
* @fires dragover
* @fires dragenter
* @fires dragleave
* @fires drop
+ * @fires after:render at the end of the render process, receives the context in the callback
+ * @fires before:render at start the render process, receives the context in the callback
*
*/
fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {
@@ -14485,7 +14487,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
// skip canvas zoom and calculate with setCoords now.
boundingRect = this.getBoundingRect(true, true),
shadow = this.shadow, scaling,
- shadowOffset = { x: 0, y: 0 }, shadowBlur;
+ shadowOffset = { x: 0, y: 0 }, shadowBlur,
+ width, height;
if (shadow) {
shadowBlur = shadow.blur;
@@ -14499,10 +14502,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * (abs(scaling.scaleX));
shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * (abs(scaling.scaleY));
}
- el.width = boundingRect.width + shadowOffset.x;
- el.height = boundingRect.height + shadowOffset.y;
- el.width += el.width % 2 ? 2 - el.width % 2 : 0;
- el.height += el.height % 2 ? 2 - el.height % 2 : 0;
+ width = boundingRect.width + shadowOffset.x;
+ height = boundingRect.height + shadowOffset.y;
+ // if the current width/height is not an integer
+ // we need to make it so.
+ el.width = Math.ceil(width);
+ el.height = Math.ceil(height);
var canvas = new fabric.StaticCanvas(el, {
enableRetinaScaling: false,
renderOnAddRemove: false,
diff --git a/dist/fabric.min.js b/dist/fabric.min.js
index 44415fec785..c57dd063e93 100644
--- a/dist/fabric.min.js
+++ b/dist/fabric.min.js
@@ -1 +1 @@
-var fabric=fabric||{version:"3.6.1"};if("undefined"!=typeof exports?exports.fabric=fabric:"function"==typeof define&&define.amd&&define([],function(){return fabric}),"undefined"!=typeof document&&"undefined"!=typeof window)document instanceof("undefined"!=typeof HTMLDocument?HTMLDocument:Document)?fabric.document=document:fabric.document=document.implementation.createHTMLDocument(""),fabric.window=window;else{var jsdom=require("jsdom"),virtualWindow=new jsdom.JSDOM(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]},resources:"usable"}).window;fabric.document=virtualWindow.document,fabric.jsdomImplForWrapper=require("jsdom/lib/jsdom/living/generated/utils").implForWrapper,fabric.nodeCanvas=require("jsdom/lib/jsdom/utils").Canvas,fabric.window=virtualWindow,DOMParser=fabric.window.DOMParser}function resizeCanvasIfNeeded(t){var e=t.targetCanvas,i=e.width,r=e.height,n=t.destinationWidth,s=t.destinationHeight;i===n&&r===s||(e.width=n,e.height=s)}function copyGLTo2DDrawImage(t,e){var i=t.canvas,r=e.targetCanvas,n=r.getContext("2d");n.translate(0,r.height),n.scale(1,-1);var s=i.height-r.height;n.drawImage(i,0,s,r.width,r.height,0,0,r.width,r.height)}function copyGLTo2DPutImageData(t,e){var i=e.targetCanvas.getContext("2d"),r=e.destinationWidth,n=e.destinationHeight,s=r*n*4,o=new Uint8Array(this.imageBuffer,0,s),a=new Uint8ClampedArray(this.imageBuffer,0,s);t.readPixels(0,0,r,n,t.RGBA,t.UNSIGNED_BYTE,o);var h=new ImageData(a,r,n);i.putImageData(h,0,0)}fabric.isTouchSupported="ontouchstart"in fabric.window||"ontouchstart"in fabric.document||fabric.window&&fabric.window.navigator&&0/g,">")},graphemeSplit:function(t){var e,i=0,r=[];for(i=0;i/i,"")));if(!e||!e.documentElement)return n&&n(null),!1;C.parseSVGDocument(e.documentElement,function(t,e,i,r){n&&n(t,e,i,r)},i,r)}})},loadSVGFromString:function(t,n,e,i){var r;if(t=t.trim(),void 0!==C.window.DOMParser){var s=new C.window.DOMParser;s&&s.parseFromString&&(r=s.parseFromString(t,"text/xml"))}else C.window.ActiveXObject&&((r=new ActiveXObject("Microsoft.XMLDOM")).async="false",r.loadXML(t.replace(//i,"")));C.parseSVGDocument(r.documentElement,function(t,e,i,r){n(t,e,i,r)},e,i)}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r,n,s){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0,this.parsingOptions=n,this.regexUrl=/^url\(['"]?#([^'"]+)['"]?\)/g,this.doc=s},function(t){t.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},t.createObjects=function(){var i=this;this.elements.forEach(function(t,e){t.setAttribute("svgUid",i.svgUid),i.createObject(t,e)})},t.findTag=function(t){return fabric[fabric.util.string.capitalize(t.tagName.replace("svg:",""))]},t.createObject=function(t,e){var i=this.findTag(t);if(i&&i.fromElement)try{i.fromElement(t,this.createCallback(e,t),this.options)}catch(t){fabric.log(t)}else this.checkIfDone()},t.createCallback=function(i,r){var n=this;return function(t){var e;n.resolveGradient(t,r,"fill"),n.resolveGradient(t,r,"stroke"),t instanceof fabric.Image&&t._originalElement&&(e=t.parsePreserveAspectRatioAttribute(r)),t._removeTransformMatrix(e),n.resolveClipPath(t,r),n.reviver&&n.reviver(r,t),n.instances[i]=t,n.checkIfDone()}},t.extractPropertyDefinition=function(t,e,i){var r=t[e],n=this.regexUrl;if(n.test(r)){n.lastIndex=0;var s=n.exec(r)[1];return n.lastIndex=0,fabric[i][this.svgUid][s]}},t.resolveGradient=function(t,e,i){var r=this.extractPropertyDefinition(t,i,"gradientDefs");if(r){var n=e.getAttribute(i+"-opacity"),s=fabric.Gradient.fromElement(r,t,n,this.options);t.set(i,s)}},t.createClipPathCallback=function(t,e){return function(t){t._removeTransformMatrix(),t.fillRule=t.clipRule,e.push(t)}},t.resolveClipPath=function(t,e){var i,r,n,s,o=this.extractPropertyDefinition(t,"clipPath","clipPaths");if(o){n=[],r=fabric.util.invertTransform(t.calcTransformMatrix());for(var a=o[0].parentNode,h=e;h.parentNode&&h.getAttribute("clip-path")!==t.clipPath;)h=h.parentNode;h.parentNode.appendChild(a);for(var c=0;ct.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,e){return void 0===e&&(e=.5),e=Math.max(Math.min(1,e),0),new i(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new i(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new i(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new i(this.x,this.y)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var f=t.fabric||(t.fabric={});function d(t){this.status=t,this.points=[]}f.Intersection?f.warn("fabric.Intersection is already defined"):(f.Intersection=d,f.Intersection.prototype={constructor:d,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},f.Intersection.intersectLineLine=function(t,e,i,r){var n,s=(r.x-i.x)*(t.y-i.y)-(r.y-i.y)*(t.x-i.x),o=(e.x-t.x)*(t.y-i.y)-(e.y-t.y)*(t.x-i.x),a=(r.y-i.y)*(e.x-t.x)-(r.x-i.x)*(e.y-t.y);if(0!==a){var h=s/a,c=o/a;0<=h&&h<=1&&0<=c&&c<=1?(n=new d("Intersection")).appendPoint(new f.Point(t.x+h*(e.x-t.x),t.y+h*(e.y-t.y))):n=new d}else n=new d(0===s||0===o?"Coincident":"Parallel");return n},f.Intersection.intersectLinePolygon=function(t,e,i){var r,n,s,o,a=new d,h=i.length;for(o=0;oo.r2,c=this.gradientTransform?this.gradientTransform.concat():fabric.iMatrix.concat(),l=-this.offsetX,u=-this.offsetY,f=!!e.additionalTransform,d="pixels"===this.gradientUnits?"userSpaceOnUse":"objectBoundingBox";if(a.sort(function(t,e){return t.offset-e.offset}),"objectBoundingBox"===d?(l/=t.width,u/=t.height):(l+=t.width/2,u+=t.height/2),"path"===t.type&&(l-=t.pathOffset.x,u-=t.pathOffset.y),c[4]-=l,c[5]-=u,s='id="SVGID_'+this.id+'" gradientUnits="'+d+'"',s+=' gradientTransform="'+(f?e.additionalTransform+" ":"")+fabric.util.matrixToSVG(c)+'" ',"linear"===this.type?n=["\n']:"radial"===this.type&&(n=["\n']),"radial"===this.type){if(h)for((a=a.concat()).reverse(),i=0,r=a.length;i\n')}return n.push("linear"===this.type?"\n":"\n"),n.join("")},toLive:function(t,e){var i,r,n,s=fabric.util.object.clone(this.coords),o=s.x1,a=s.y1,h=s.x2,c=s.y2,l=this.colorStops;if(this.type){for(e instanceof fabric.Text&&"percentage"===this.gradientUnits&&(o*=e.width,a*=e.height,h*=e.width,c*=e.height),"linear"===this.type?i=t.createLinearGradient(o,a,h,c):"radial"===this.type&&(i=t.createRadialGradient(o,a,s.r1,h,c,s.r2)),r=0,n=l.length;r\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e="function"==typeof this.source?this.source():this.source;if(!e)return"";if(void 0!==e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}})}(),function(t){"use strict";var o=t.fabric||(t.fabric={}),a=o.util.toFixed;o.Shadow?o.warn("fabric.Shadow is already defined."):(o.Shadow=o.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,nonScaling:!1,initialize:function(t){for(var e in"string"==typeof t&&(t=this._parseShadow(t)),t)this[e]=t[e];this.id=o.Object.__uid++},_parseShadow:function(t){var e=t.trim(),i=o.Shadow.reOffsetsAndBlur.exec(e)||[];return{color:(e.replace(o.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseInt(i[1],10)||0,offsetY:parseInt(i[2],10)||0,blur:parseInt(i[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var e=40,i=40,r=o.Object.NUM_FRACTION_DIGITS,n=o.util.rotateVector({x:this.offsetX,y:this.offsetY},o.util.degreesToRadians(-t.angle)),s=new o.Color(this.color);return t.width&&t.height&&(e=100*a((Math.abs(n.x)+this.blur)/t.width,r)+20,i=100*a((Math.abs(n.y)+this.blur)/t.height,r)+20),t.flipX&&(n.x*=-1),t.flipY&&(n.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke,nonScaling:this.nonScaling};var e={},i=o.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke","nonScaling"].forEach(function(t){this[t]!==i[t]&&(e[t]=this[t])},this),e}}),o.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)fabric.warn("fabric.StaticCanvas is already defined.");else{var n=fabric.util.object.extend,t=fabric.util.getElementOffset,c=fabric.util.removeFromArray,a=fabric.util.toFixed,s=fabric.util.transformPoint,o=fabric.util.invertTransform,i=fabric.util.getNodeCanvas,r=fabric.util.createCanvasElement,e=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this.renderAndResetBound=this.renderAndReset.bind(this),this.requestRenderAllBound=this.requestRenderAll.bind(this),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,clipPath:void 0,_initStatic:function(t,e){var i=this.requestRenderAllBound;this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){if(this._isRetinaScaling()){var t=fabric.devicePixelRatio;this.__initRetinaScaling(t,this.lowerCanvasEl,this.contextContainer),this.upperCanvasEl&&this.__initRetinaScaling(t,this.upperCanvasEl,this.contextTop)}},__initRetinaScaling:function(t,e,i){e.setAttribute("width",this.width*t),e.setAttribute("height",this.height*t),i.scale(t,t)},calcOffset:function(){return this._offset=t(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage("overlayImage",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage("backgroundImage",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor("overlayColor",t,e)},setBackgroundColor:function(t,e){return this.__setBgOverlayColor("backgroundColor",t,e)},_setImageSmoothing:function(){var t=this.getContext();t.imageSmoothingEnabled=t.imageSmoothingEnabled||t.webkitImageSmoothingEnabled||t.mozImageSmoothingEnabled||t.msImageSmoothingEnabled||t.oImageSmoothingEnabled,t.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(i,t,r,n){return"string"==typeof t?fabric.util.loadImage(t,function(t){if(t){var e=new fabric.Image(t,n);(this[i]=e).canvas=this}r&&r(t)},this,n&&n.crossOrigin):(n&&t.setOptions(n),(this[i]=t)&&(t.canvas=this),r&&r(t)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(){var t=r();if(!t)throw e;if(t.style||(t.style={}),void 0===t.getContext)throw e;return t},_initOptions:function(t){var e=this.lowerCanvasEl;this._setOptions(t),this.width=this.width||parseInt(e.width,10)||0,this.height=this.height||parseInt(e.height,10)||0,this.lowerCanvasEl.style&&(e.width=this.width,e.height=this.height,e.style.width=this.width+"px",e.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){t&&t.getContext?this.lowerCanvasEl=t:this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;for(var r in e=e||{},t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px",this.hasLostContext=!0),e.backstoreOnly||this._setCssDimension(r,i);return this._isCurrentlyDrawing&&this.freeDrawingBrush&&this.freeDrawingBrush._setBrushStyles(),this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.requestRenderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i,r,n=this._activeObject;for(this.viewportTransform=t,i=0,r=this._objects.length;i\n'),this._setSVGBgOverlayColor(i,"background"),this._setSVGBgOverlayImage(i,"backgroundImage",e),this._setSVGObjects(i,e),this.clipPath&&i.push("\n"),this._setSVGBgOverlayColor(i,"overlay"),this._setSVGBgOverlayImage(i,"overlayImage",e),i.push(""),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,r=e.width||this.width,n=e.height||this.height,s='viewBox="0 0 '+this.width+" "+this.height+'" ',o=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?s='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,s='viewBox="'+a(-i[4]/i[0],o)+" "+a(-i[5]/i[3],o)+" "+a(this.width/i[0],o)+" "+a(this.height/i[3],o)+'" '),t.push(""),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,r=e.width||this.width,n=e.height||this.height,s='viewBox="0 0 '+this.width+" "+this.height+'" ',o=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?s='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,s='viewBox="'+a(-i[4]/i[0],o)+" "+a(-i[5]/i[3],o)+" "+a(this.width/i[0],o)+" "+a(this.height/i[3],o)+'" '),t.push("