diff --git a/.travis.yml b/.travis.yml index 326f3a74406..86b4e0d88e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,14 +85,14 @@ jobs: script: npm run build:fast && npm run test:visual - stage: Visual Tests env: LAUNCHER=Chrome - install: npm install testem@1.18.4 qunit@2.6.1 + install: npm install testem@1.18.4 qunit@2.6.2 script: npm run build:fast && testem ci --port 8080 -f testem-visual.json -l $LAUNCHER addons: apt: packages: # avoid installing packages - stage: Visual Tests env: LAUNCHER=Firefox - install: npm install testem@1.18.4 qunit@2.6.1 + install: npm install testem@1.18.4 qunit@2.6.2 script: npm run build:fast && testem ci --port 8080 -f testem-visual.json -l $LAUNCHER addons: apt: diff --git a/package.json b/package.json index 4c7a67138bf..8ec36b8b8ac 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "eslint": "4.18.x", "istanbul": "0.4.x", "onchange": "^3.x.x", - "qunit": "^2.6.1", + "qunit": "2.6.2", "testem": "^1.18.4", "uglify-js": "3.3.x", "pixelmatch": "^4.0.2", diff --git a/src/shapes/image.class.js b/src/shapes/image.class.js index 6e3af836d1b..6c2166f702a 100644 --- a/src/shapes/image.class.js +++ b/src/shapes/image.class.js @@ -505,14 +505,15 @@ }, _renderFill: function(ctx) { - var w = this.width, h = this.height, sW = w * this._filterScalingX, sH = h * this._filterScalingY, - x = -w / 2, y = -h / 2, elementToDraw = this._element; - elementToDraw && ctx.drawImage(elementToDraw, - this.cropX * this._filterScalingX, - this.cropY * this._filterScalingY, - sW, - sH, - x, y, w, h); + var elementToDraw = this._element, + w = this.width, h = this.height, + sW = Math.min(elementToDraw.naturalWidth || elementToDraw.width, w * this._filterScalingX), + sH = Math.min(elementToDraw.naturalHeight || elementToDraw.height, h * this._filterScalingY), + x = -w / 2, y = -h / 2, + sX = Math.max(0, this.cropX * this._filterScalingX), + sY = Math.max(0, this.cropY * this._filterScalingY); + + elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, w, h); }, /** diff --git a/test/unit/image.js b/test/unit/image.js index ad8248a65b0..0d40de91f98 100644 --- a/test/unit/image.js +++ b/test/unit/image.js @@ -29,43 +29,43 @@ IMG_HEIGHT = 110; var REFERENCE_IMG_OBJECT = { - 'version': fabric.version, - 'type': 'image', - 'originX': 'left', - 'originY': 'top', - 'left': 0, - 'top': 0, - 'width': IMG_WIDTH, // node-canvas doesn't seem to allow setting width/height on image objects - 'height': IMG_HEIGHT, // or does it now? - 'fill': 'rgb(0,0,0)', - 'stroke': null, - 'strokeWidth': 0, - 'strokeDashArray': null, - 'strokeLineCap': 'butt', - 'strokeDashOffset': 0, - 'strokeLineJoin': 'miter', - 'strokeMiterLimit': 4, - 'scaleX': 1, - 'scaleY': 1, - 'angle': 0, - 'flipX': false, - 'flipY': false, - 'opacity': 1, - 'src': IMG_SRC, - 'shadow': null, - 'visible': true, - 'backgroundColor': '', - 'clipTo': null, - 'filters': [], - 'fillRule': 'nonzero', - 'paintFirst': 'fill', - 'globalCompositeOperation': 'source-over', - 'skewX': 0, - 'skewY': 0, - 'transformMatrix': null, - 'crossOrigin': '', - 'cropX': 0, - 'cropY': 0 + version: fabric.version, + type: 'image', + originX: 'left', + originY: 'top', + left: 0, + top: 0, + width: IMG_WIDTH, // node-canvas doesn't seem to allow setting width/height on image objects + height: IMG_HEIGHT, // or does it now? + fill: 'rgb(0,0,0)', + stroke: null, + strokeWidth: 0, + strokeDashArray: null, + strokeLineCap: 'butt', + strokeDashOffset: 0, + strokeLineJoin: 'miter', + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + src: IMG_SRC, + shadow: null, + visible: true, + backgroundColor: '', + clipTo: null, + filters: [], + fillRule: 'nonzero', + paintFirst: 'fill', + globalCompositeOperation: 'source-over', + skewX: 0, + skewY: 0, + transformMatrix: null, + crossOrigin: '', + cropX: 0, + cropY: 0 }; function _createImageElement() { @@ -780,4 +780,26 @@ done(); }); }); + + QUnit.test('_renderFill respects source boundaries ', function (assert) { + fabric.Image.prototype._renderFill.call({ + cropX: -1, + cropY: -1, + _filterScalingX: 1, + _filterScalingY: 1, + width: 300, + height: 300, + _element: { + naturalWidth: 200, + height: 200, + }, + }, { + drawImage: function(src, sX, sY, sW, sH) { + assert.ok(sX >= 0, 'sX should be positive'); + assert.ok(sY >= 0, 'sY should be positive'); + assert.ok(sW <= 200, 'sW should not be larger than image width'); + assert.ok(sH <= 200, 'sH should not be larger than image height'); + } + }); + }); })();