=this.text.length&&this.selectionEnd>=this.text.length)return;this.abortCursorAnimation(),this._currentCursorOpacity=1,e.shiftKey?this.moveCursorRightWithShift(e):this.moveCursorRightWithoutShift(e),this.initDelayedCursor()},moveCursorRightWithShift:function(e){this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd?this._moveRight(e,"selectionStart"):(this._selectionDirection="right",this._moveRight(e,"selectionEnd"),this.text.charAt(this.selectionEnd-1)==="\n"&&this.selectionEnd++,this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length))},moveCursorRightWithoutShift:function(e){this._selectionDirection="right",this.selectionStart===this.selectionEnd?(this._moveRight(e,"selectionStart"),this.selectionEnd=this.selectionStart):(this.selectionEnd+=this.getNumNewLinesInSelectedText(),this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length),this.selectionStart=this.selectionEnd)},removeChars:function(e){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(e):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.selectionEnd=this.selectionStart,this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll().renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(e){if(this.selectionStart!==0)if(e.metaKey){var t=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(t,this.selectionStart),this.selectionStart=t}else if(e.altKey){var n=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(n,this.selectionStart),this.selectionStart=n}else{var r=this.text.slice(this.selectionStart-1,this.selectionStart)==="\n";this.removeStyleObject(r),this.selectionStart--,this.text=this.text.slice(0,this.selectionStart)+this.text.slice(this.selectionStart+1)}}}),fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(e,t,n,r,i,s){this.styles[t]?this._setSVGTextLineChars(e,t,n,r,i,s):this.callSuper("_setSVGTextLineText",e,t,n,r,i)},_setSVGTextLineChars:function(e,t,n,r,i,s){var o=t===0||this.useNative?"y":"dy",u=e.split(""),a=0,f=this._getSVGLineLeftOffset(t),l=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t);for(var h=0,p=u.length;h'].join("")},_createTextCharSpan:function(e,t,n,r,i,s){var o=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text"},t));return['',fabric.util.string.escapeXml(e),""].join("")}}),function(){function request(e,t,n){var r=URL.parse(e);r.port||(r.port=r.protocol.indexOf("https:")===0?443:80);var i=r.port===443?HTTPS:HTTP,s=i.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(e){var r="";t&&e.setEncoding(t),e.on("end",function(){n(r)}),e.on("data",function(t){e.statusCode===200&&(r+=t)})});s.on("error",function(e){e.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(e.message)}),s.end()}function requestFs(e,t){var n=require("fs");n.readFile(e,function(e,n){if(e)throw fabric.log(e),e;t(n)})}if(typeof document!="undefined"&&typeof window!="undefined")return;var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(e,t,n){function r(r){i.src=new Buffer(r,"binary"),i._src=e,t&&t.call(n,i)}var i=new Image;e&&(e instanceof Buffer||e.indexOf("data")===0)?(i.src=i._src=e,t&&t.call(n,i)):e&&e.indexOf("http")!==0?requestFs(e,r):e?request(e,"binary",r):t&&t.call(n,e)},fabric.loadSVGFromURL=function(e,t,n){e=e.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),e.indexOf("http")!==0?requestFs(e,function(e){fabric.loadSVGFromString(e.toString(),t,n)}):request(e,"",function(e){fabric.loadSVGFromString(e,t,n)})},fabric.loadSVGFromString=function(e,t,n){var r=(new DOMParser).parseFromString(e);fabric.parseSVGDocument(r.documentElement,function(e,n){t&&t(e,n)},n)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){var r=new fabric.Image(n);r._initConfig(e),r._initFilters(e,function(e){r.filters=e||[],t&&t(r)})})},fabric.createCanvasForNode=function(e,t,n,r){r=r||n;var i=fabric.document.createElement("canvas"),s=new Canvas(e||600,t||600,r);i.style={},i.width=s.width,i.height=s.height;var o=fabric.Canvas||fabric.StaticCanvas,u=new o(i,n);return u.contextContainer=s.getContext("2d"),u.nodeCanvas=s,u.Font=Canvas.Font,u},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(e){return this.nodeCanvas.createJPEGStream(e)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(e){return origSetWidth.call(this,e),this.nodeCanvas.width=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(e){return origSetHeight.call(this,e),this.nodeCanvas.height=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}();
\ No newline at end of file
diff --git a/dist/fabric.min.js.gz b/dist/fabric.min.js.gz
index 83ad6517..fae0f8ee 100644
Binary files a/dist/fabric.min.js.gz and b/dist/fabric.min.js.gz differ
diff --git a/dist/fabric.require.js b/dist/fabric.require.js
index 222584f1..bbd13441 100644
--- a/dist/fabric.require.js
+++ b/dist/fabric.require.js
@@ -3034,27 +3034,37 @@ if (typeof console !== 'undefined') {
if (!elements || (elements && !elements.length)) return;
var viewBoxAttr = doc.getAttribute('viewBox'),
- widthAttr = doc.getAttribute('width'),
- heightAttr = doc.getAttribute('height'),
+ widthAttr = parseFloat(doc.getAttribute('width')),
+ heightAttr = parseFloat(doc.getAttribute('height')),
width = null,
height = null,
+ viewBoxWidth,
+ viewBoxHeight,
minX,
minY;
if (viewBoxAttr && (viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))) {
- minX = parseInt(viewBoxAttr[1], 10);
- minY = parseInt(viewBoxAttr[2], 10);
- width = parseInt(viewBoxAttr[3], 10);
- height = parseInt(viewBoxAttr[4], 10);
+ minX = parseFloat(viewBoxAttr[1]);
+ minY = parseFloat(viewBoxAttr[2]);
+ viewBoxWidth = parseFloat(viewBoxAttr[3]);
+ viewBoxHeight = parseFloat(viewBoxAttr[4]);
}
- // values of width/height attributes overwrite those extracted from viewbox attribute
- width = widthAttr ? parseFloat(widthAttr) : width;
- height = heightAttr ? parseFloat(heightAttr) : height;
+ if (viewBoxWidth && widthAttr && viewBoxWidth !== widthAttr) {
+ width = viewBoxWidth;
+ height = viewBoxHeight;
+ }
+ else {
+ // values of width/height attributes overwrite those extracted from viewbox attribute
+ width = widthAttr ? widthAttr : viewBoxWidth;
+ height = heightAttr ? heightAttr : viewBoxHeight;
+ }
var options = {
width: width,
- height: height
+ height: height,
+ widthAttr: widthAttr,
+ heightAttr: heightAttr
};
fabric.gradientDefs = fabric.getGradientDefs(doc);
@@ -15083,6 +15093,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
}
this.setOptions(options);
+
+ if (options.widthAttr) {
+ this.scaleX = options.widthAttr / options.width;
+ }
+ if (options.heightAttr) {
+ this.scaleY = options.heightAttr / options.height;
+ }
+
this.setCoords();
if (options.sourcePath) {
diff --git a/src/parser.js b/src/parser.js
index 4fcbd5b3..fa459837 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -410,27 +410,37 @@
if (!elements || (elements && !elements.length)) return;
var viewBoxAttr = doc.getAttribute('viewBox'),
- widthAttr = doc.getAttribute('width'),
- heightAttr = doc.getAttribute('height'),
+ widthAttr = parseFloat(doc.getAttribute('width')),
+ heightAttr = parseFloat(doc.getAttribute('height')),
width = null,
height = null,
+ viewBoxWidth,
+ viewBoxHeight,
minX,
minY;
if (viewBoxAttr && (viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))) {
- minX = parseInt(viewBoxAttr[1], 10);
- minY = parseInt(viewBoxAttr[2], 10);
- width = parseInt(viewBoxAttr[3], 10);
- height = parseInt(viewBoxAttr[4], 10);
+ minX = parseFloat(viewBoxAttr[1]);
+ minY = parseFloat(viewBoxAttr[2]);
+ viewBoxWidth = parseFloat(viewBoxAttr[3]);
+ viewBoxHeight = parseFloat(viewBoxAttr[4]);
}
- // values of width/height attributes overwrite those extracted from viewbox attribute
- width = widthAttr ? parseFloat(widthAttr) : width;
- height = heightAttr ? parseFloat(heightAttr) : height;
+ if (viewBoxWidth && widthAttr && viewBoxWidth !== widthAttr) {
+ width = viewBoxWidth;
+ height = viewBoxHeight;
+ }
+ else {
+ // values of width/height attributes overwrite those extracted from viewbox attribute
+ width = widthAttr ? widthAttr : viewBoxWidth;
+ height = heightAttr ? heightAttr : viewBoxHeight;
+ }
var options = {
width: width,
- height: height
+ height: height,
+ widthAttr: widthAttr,
+ heightAttr: heightAttr
};
fabric.gradientDefs = fabric.getGradientDefs(doc);
diff --git a/src/shapes/path_group.class.js b/src/shapes/path_group.class.js
index 7ba425e0..1b383705 100644
--- a/src/shapes/path_group.class.js
+++ b/src/shapes/path_group.class.js
@@ -51,6 +51,14 @@
}
this.setOptions(options);
+
+ if (options.widthAttr) {
+ this.scaleX = options.widthAttr / options.width;
+ }
+ if (options.heightAttr) {
+ this.scaleY = options.heightAttr / options.height;
+ }
+
this.setCoords();
if (options.sourcePath) {