diff --git a/src/ol/renderer/canvas/tilelayer.js b/src/ol/renderer/canvas/tilelayer.js index 983398573c..2f94b6920e 100644 --- a/src/ol/renderer/canvas/tilelayer.js +++ b/src/ol/renderer/canvas/tilelayer.js @@ -12,7 +12,6 @@ goog.require('ol.extent'); goog.require('ol.render.canvas'); goog.require('ol.render.EventType'); goog.require('ol.renderer.canvas.Layer'); -goog.require('ol.size'); /** @@ -240,14 +239,12 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram var hasRenderListeners = layer.hasListener(ol.render.EventType.RENDER); var renderContext = context; - var drawOffsetX, drawOffsetY, drawScale, drawSize; + var drawScale = 1; + var drawOffsetX, drawOffsetY, drawSize; if (rotation || hasRenderListeners) { renderContext = this.context; var renderCanvas = renderContext.canvas; - var drawZ = tileGrid.getZForResolution(resolution); - var drawTileSize = source.getTilePixelSize(drawZ, pixelRatio, projection); - var tileSize = ol.size.toSize(tileGrid.getTileSize(drawZ)); - drawScale = drawTileSize[0] / tileSize[0]; + drawScale = source.getTilePixelRatio(pixelRatio) / pixelRatio; var width = context.canvas.width * drawScale; var height = context.canvas.height * drawScale; // Make sure the canvas is big enough for all possible rotation angles @@ -294,14 +291,18 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram var ox = drawOffsetX || 0; var oy = drawOffsetY || 0; renderContext.save(); - var cx = (renderContext.canvas.width * pixelRatio) / 2; - var cy = (renderContext.canvas.height * pixelRatio) / 2; + var cx = (renderContext.canvas.width) / 2; + var cy = (renderContext.canvas.height) / 2; ol.render.canvas.rotateAtOffset(renderContext, -rotation, cx, cy); renderContext.beginPath(); - renderContext.moveTo(topLeft[0] * pixelRatio + ox, topLeft[1] * pixelRatio + oy); - renderContext.lineTo(topRight[0] * pixelRatio + ox, topRight[1] * pixelRatio + oy); - renderContext.lineTo(bottomRight[0] * pixelRatio + ox, bottomRight[1] * pixelRatio + oy); - renderContext.lineTo(bottomLeft[0] * pixelRatio + ox, bottomLeft[1] * pixelRatio + oy); + renderContext.moveTo(drawScale * (topLeft[0] * pixelRatio + ox), + drawScale * (topLeft[1] * pixelRatio + oy)); + renderContext.lineTo(drawScale * (topRight[0] * pixelRatio + ox), + drawScale * (topRight[1] * pixelRatio + oy)); + renderContext.lineTo(drawScale * (bottomRight[0] * pixelRatio + ox), + drawScale * (bottomRight[1] * pixelRatio + oy)); + renderContext.lineTo(drawScale * (bottomLeft[0] * pixelRatio + ox), + drawScale * (bottomLeft[1] * pixelRatio + oy)); renderContext.clip(); ol.render.canvas.rotateAtOffset(renderContext, rotation, cx, cy); } diff --git a/test/spec/ol/renderer/canvas/tilelayer.test.js b/test/spec/ol/renderer/canvas/tilelayer.test.js new file mode 100644 index 0000000000..27d6a44066 --- /dev/null +++ b/test/spec/ol/renderer/canvas/tilelayer.test.js @@ -0,0 +1,48 @@ +goog.provide('ol.test.renderer.canvas.TileLayer'); + +goog.require('ol.transform'); +goog.require('ol.layer.Tile'); +goog.require('ol.renderer.Map'); +goog.require('ol.renderer.canvas.TileLayer'); +goog.require('ol.source.XYZ'); + + +describe('ol.renderer.canvas.TileLayer', function() { + + describe('#composeFrame()', function() { + it('uses correct draw scale when rotating (HiDPI)', function() { + var layer = new ol.layer.Tile({ + source: new ol.source.XYZ() + }); + var renderer = new ol.renderer.canvas.TileLayer(layer); + renderer.renderedTiles = []; + var frameState = { + viewState: { + center: [2, 3], + projection: ol.proj.get('EPSG:3857'), + resolution: 1, + rotation: Math.PI + }, + size: [10, 10], + pixelRatio: 2, + coordinateToPixelTransform: ol.transform.create(), + pixelToCoordinateTransform: ol.transform.create() + }; + renderer.getImageTransform = function() { + return ol.transform.create(); + }; + ol.renderer.Map.prototype.calculateMatrices2D(frameState); + var layerState = layer.getLayerState(); + var canvas = document.createElement('canvas'); + canvas.width = 200; + canvas.height = 100; + var context = { + canvas: canvas, + drawImage: sinon.spy() + }; + renderer.composeFrame(frameState, layerState, context); + expect(context.drawImage.firstCall.args[0].width).to.be(112); + }); + }); + +}); diff --git a/test/spec/ol/source/tilewms.test.js b/test/spec/ol/source/tilewms.test.js index 72f986e95a..6f57355081 100644 --- a/test/spec/ol/source/tilewms.test.js +++ b/test/spec/ol/source/tilewms.test.js @@ -265,11 +265,13 @@ describe('ol.source.TileWMS', function() { }); describe('#setUrl()', function() { - var source = new ol.source.TileWMS(options); - var url = 'http://foo/'; - source.setUrl(url); - var tileUrl = source.tileUrlFunction([0, 0, 0], 1, ol.proj.get('EPSG:4326')); - expect(tileUrl.indexOf(url)).to.be(0); + it('sets the correct url', function() { + var source = new ol.source.TileWMS(options); + var url = 'http://foo/'; + source.setUrl(url); + var tileUrl = source.tileUrlFunction([0, 0, 0], 1, ol.proj.get('EPSG:4326')); + expect(tileUrl.indexOf(url)).to.be(0); + }); }); describe('#setUrls()', function() { diff --git a/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-hidpi.png b/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-hidpi.png new file mode 100644 index 0000000000..fff644a675 Binary files /dev/null and b/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-hidpi.png differ diff --git a/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-rotate-hidpi.png b/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-rotate-hidpi.png new file mode 100644 index 0000000000..164e80b392 Binary files /dev/null and b/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-rotate-hidpi.png differ diff --git a/test_rendering/spec/ol/layer/tile.test.js b/test_rendering/spec/ol/layer/tile.test.js index c213ee9aa0..bf64f20188 100644 --- a/test_rendering/spec/ol/layer/tile.test.js +++ b/test_rendering/spec/ol/layer/tile.test.js @@ -19,11 +19,12 @@ describe('ol.rendering.layer.Tile', function() { var target, map; - function createMap(renderer, opt_center, opt_size) { + function createMap(renderer, opt_center, opt_size, opt_pixelRatio) { var size = opt_size !== undefined ? opt_size : [50, 50]; target = createMapDiv(size[0], size[1]); map = new ol.Map({ + pixelRatio: opt_pixelRatio || 1, target: target, renderer: renderer, view: new ol.View({ @@ -152,6 +153,24 @@ describe('ol.rendering.layer.Tile', function() { IMAGE_TOLERANCE, done); }); }); + + it('tests canvas layer extent clipping (HiDPI)', function(done) { + map = createMap('canvas', undefined, undefined, 2); + waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() { + expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-hidpi.png', + IMAGE_TOLERANCE, done); + }); + }); + + it('tests canvas layer extent clipping with rotation (HiDPI)', function(done) { + map = createMap('canvas', undefined, undefined, 2); + map.getView().setRotation(Math.PI / 2); + waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() { + expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-rotate-hidpi.png', + IMAGE_TOLERANCE, done); + }); + }); + }); describe('tile layer with opacity', function() {