From f444800fc6cbb63792c5834e7de01e819808d4b1 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Mon, 26 Sep 2016 06:13:01 -0600 Subject: [PATCH] Only call beginPath once per MultiPolygon --- src/ol/render/canvas/immediate.js | 14 +-- test/test-extensions.js | 7 +- .../spec/ol/data/tiles/osm/0/0/0.png | Bin 0 -> 6821 bytes test_rendering/spec/ol/layer/clip.test.js | 110 ++++++++++++++++++ .../ol/layer/expected/multipolygon-clip.png | Bin 0 -> 5651 bytes 5 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 test_rendering/spec/ol/data/tiles/osm/0/0/0.png create mode 100644 test_rendering/spec/ol/layer/clip.test.js create mode 100644 test_rendering/spec/ol/layer/expected/multipolygon-clip.png diff --git a/src/ol/render/canvas/immediate.js b/src/ol/render/canvas/immediate.js index 7a97a0ac23..cfba4e5711 100644 --- a/src/ol/render/canvas/immediate.js +++ b/src/ol/render/canvas/immediate.js @@ -681,16 +681,16 @@ ol.render.canvas.Immediate.prototype.drawMultiPolygon = function(geometry) { var endss = geometry.getEndss(); var stride = geometry.getStride(); var i, ii; + context.beginPath(); for (i = 0, ii = endss.length; i < ii; ++i) { var ends = endss[i]; - context.beginPath(); offset = this.drawRings_(flatCoordinates, offset, ends, stride); - if (this.fillState_) { - context.fill(); - } - if (this.strokeState_) { - context.stroke(); - } + } + if (this.fillState_) { + context.fill(); + } + if (this.strokeState_) { + context.stroke(); } } if (this.text_ !== '') { diff --git a/test/test-extensions.js b/test/test-extensions.js index 1c5c8c1c60..d42f09208e 100644 --- a/test/test-extensions.js +++ b/test/test-extensions.js @@ -383,7 +383,12 @@ function resembleCanvas(canvas, referenceImage, tolerance, done) { if (showMap) { - document.body.appendChild(canvas); + var wrapper = document.createElement('div'); + wrapper.style.width = canvas.width + 'px'; + wrapper.style.height = canvas.height + 'px'; + wrapper.appendChild(canvas); + document.body.appendChild(wrapper); + document.body.appendChild(document.createTextNode(referenceImage)); } resemble(referenceImage) diff --git a/test_rendering/spec/ol/data/tiles/osm/0/0/0.png b/test_rendering/spec/ol/data/tiles/osm/0/0/0.png new file mode 100644 index 0000000000000000000000000000000000000000..732e9096b14fc522e5f15b27068377c63779aba5 GIT binary patch literal 6821 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 0 && loaded === loading) { + callback(); + } + } + + source.on('tileloadstart', function() { + ++loading; + }); + source.on('tileloadend', function() { + ++loaded; + setTimeout(check, 10); + }); + source.on('tileloaderror', function() { + callback(new Error('Tile loading failed')); + called = true; + }); + } + + + describe('MultiPolygon clipping', function() { + + var map = null; + beforeEach(function() { + map = new ol.Map({ + target: createMapDiv(256, 256), + view: new ol.View({ + center: [0, 0], + zoom: 0 + }) + }); + }); + + afterEach(function() { + disposeMap(map); + map = null; + }); + + it('clips to all parts of the MultiPolygon', function(done) { + + var source = new ol.source.XYZ({ + url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png' + }); + + var layer = new ol.layer.Tile({ + source: source + }); + + var geometry = new ol.geom.MultiPolygon([ + [[[-80, -40], [-40, 0], [-80, 40], [-120, 0], [-80, -40]]], + [[[80, -40], [120, 0], [80, 40], [40, 0], [80, -40]]] + ]).transform('EPSG:4326', 'EPSG:3857'); + + var style = new ol.style.Style({ + stroke: new ol.style.Stroke({ + width: 2, + color: 'blue' + }) + }); + + layer.on('precompose', function(event) { + var context = event.context; + context.save(); + + var vectorContext = event.vectorContext; + vectorContext.setStyle(style); + vectorContext.drawGeometry(geometry); + + context.clip(); + }); + + layer.on('postcompose', function(event) { + var context = event.context; + context.restore(); + + var vectorContext = event.vectorContext; + vectorContext.setStyle(style); + vectorContext.drawGeometry(geometry); + }); + + onLoad(source, function(err) { + if (err) { + return done(err); + } + expectResemble(map, 'spec/ol/layer/expected/multipolygon-clip.png', IMAGE_TOLERANCE, done); + }); + + map.addLayer(layer); + + }); + }); +}); diff --git a/test_rendering/spec/ol/layer/expected/multipolygon-clip.png b/test_rendering/spec/ol/layer/expected/multipolygon-clip.png new file mode 100644 index 0000000000000000000000000000000000000000..709fd55a09b35e3419c9aad7224eb3f87fff4eb9 GIT binary patch literal 5651 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 H@QD8(3DMyB literal 0 HcmV?d00001