diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index 4b55813774..ddfcd46144 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -349,8 +349,11 @@ ol.render.canvas.Replay.prototype.replay_ = function( context.globalAlpha = alpha * opacity; } - context.drawImage(image, originX, originY, width, height, - x, y, width * pixelRatio, height * pixelRatio); + var w = (width + originX > image.width) ? image.width - originX : width; + var h = (height + originY > image.height) ? image.height - originY : height; + + context.drawImage(image, originX, originY, w, h, + x, y, w * pixelRatio, h * pixelRatio); if (opacity != 1) { context.globalAlpha = alpha; diff --git a/test_rendering/spec/ol/data/me0.svg b/test_rendering/spec/ol/data/me0.svg new file mode 100644 index 0000000000..55ed860cd3 --- /dev/null +++ b/test_rendering/spec/ol/data/me0.svg @@ -0,0 +1,58 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/test_rendering/spec/ol/style/expected/icon-canvas-svg-offset.png b/test_rendering/spec/ol/style/expected/icon-canvas-svg-offset.png new file mode 100644 index 0000000000..2f8c277bf0 Binary files /dev/null and b/test_rendering/spec/ol/style/expected/icon-canvas-svg-offset.png differ diff --git a/test_rendering/spec/ol/style/expected/icon-canvas-svg-offset2.png b/test_rendering/spec/ol/style/expected/icon-canvas-svg-offset2.png new file mode 100644 index 0000000000..22eacf94d9 Binary files /dev/null and b/test_rendering/spec/ol/style/expected/icon-canvas-svg-offset2.png differ diff --git a/test_rendering/spec/ol/style/expected/icon-canvas-svg-scale.png b/test_rendering/spec/ol/style/expected/icon-canvas-svg-scale.png new file mode 100644 index 0000000000..58de0baf34 Binary files /dev/null and b/test_rendering/spec/ol/style/expected/icon-canvas-svg-scale.png differ diff --git a/test_rendering/spec/ol/style/icon.test.js b/test_rendering/spec/ol/style/icon.test.js index bc1116396f..3effc5e4ee 100644 --- a/test_rendering/spec/ol/style/icon.test.js +++ b/test_rendering/spec/ol/style/icon.test.js @@ -4,8 +4,17 @@ describe('ol.rendering.style.Icon', function() { var target, map, vectorSource; - function createMap(renderer) { - target = createMapDiv(50, 50); + var imgInfo = { + anchor: [0.5, 46], + anchorXUnits: 'fraction', + anchorYUnits: 'pixels', + opacity: 0.75, + scale: 0.5, + imgSize: [32, 48] + }; + + function createMap(renderer, width, height) { + target = createMapDiv(width ? width : 50, height ? height : 50); vectorSource = new ol.source.Vector(); var vectorLayer = new ol.layer.Vector({ @@ -30,7 +39,7 @@ describe('ol.rendering.style.Icon', function() { disposeMap(map); }); - function createFeatures(callback) { + function createFeatures(src, imgInfo, callback) { var feature; feature = new ol.Feature({ geometry: new ol.geom.Point([0, 0]) @@ -38,35 +47,63 @@ describe('ol.rendering.style.Icon', function() { var img = new Image(); img.onload = function() { + imgInfo.img = img; feature.setStyle(new ol.style.Style({ - image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({ - anchor: [0.5, 46], - anchorXUnits: 'fraction', - anchorYUnits: 'pixels', - opacity: 0.75, - scale: 0.5, - img: img, - imgSize: [32, 48] - })) + image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ (imgInfo)) })); vectorSource.addFeature(feature); callback(); }; - img.src = 'spec/ol/data/icon.png'; + img.src = src; } it('tests the canvas renderer', function(done) { map = createMap('canvas'); - createFeatures(function() { + createFeatures('spec/ol/data/icon.png', imgInfo, function() { expectResemble(map, 'spec/ol/style/expected/icon-canvas.png', IMAGE_TOLERANCE, done); }); }); + it('scales svg correctly in the canvas renderer', function(done) { + map = createMap('canvas', 512, 512); + createFeatures('spec/ol/data/me0.svg', { + scale: 96 / 512, + imgSize: [512, 512] + }, function() { + expectResemble(map, 'spec/ol/style/expected/icon-canvas-svg-scale.png', + IMAGE_TOLERANCE, done); + }); + }); + + it('uses offset correctly in the canvas renderer', function(done) { + map = createMap('canvas', 256, 512); + createFeatures('spec/ol/data/me0.svg', { + offset: [0, 256], + size: [256, 256], + imgSize: [512, 512] + }, function() { + expectResemble(map, 'spec/ol/style/expected/icon-canvas-svg-offset.png', + IMAGE_TOLERANCE, done); + }); + }); + + it('uses offset correctly if it is larger than size in the canvas renderer', function(done) { + map = createMap('canvas', 256, 512); + createFeatures('spec/ol/data/me0.svg', { + offset: [0, 374], + size: [256, 256], + imgSize: [512, 512] + }, function() { + expectResemble(map, 'spec/ol/style/expected/icon-canvas-svg-offset2.png', + IMAGE_TOLERANCE, done); + }); + }); + it('tests the WebGL renderer', function(done) { assertWebGL(); map = createMap('webgl'); - createFeatures(function() { + createFeatures('spec/ol/data/icon.png', imgInfo, function() { expectResemble(map, 'spec/ol/style/expected/icon-webgl.png', 2.0, done); });