diff --git a/src/ol/pluggablemap.js b/src/ol/pluggablemap.js index a105c4a901..2926d4fb7a 100644 --- a/src/ol/pluggablemap.js +++ b/src/ol/pluggablemap.js @@ -1139,11 +1139,15 @@ ol.PluggableMap.prototype.renderFrame_ = function(time) { layerStates[ol.getUid(layerStatesArray[i].layer)] = layerStatesArray[i]; } viewState = view.getState(); + var center = viewState.center; + var pixelResolution = viewState.resolution / this.pixelRatio_; + center[0] = Math.round(center[0] / pixelResolution) * pixelResolution; + center[1] = Math.round(center[1] / pixelResolution) * pixelResolution; frameState = /** @type {olx.FrameState} */ ({ animate: false, coordinateToPixelTransform: this.coordinateToPixelTransform_, extent: extent, - focus: !this.focus_ ? viewState.center : this.focus_, + focus: !this.focus_ ? center : this.focus_, index: this.frameIndex_++, layerStates: layerStates, layerStatesArray: layerStatesArray, diff --git a/src/ol/render/canvas/textreplay.js b/src/ol/render/canvas/textreplay.js index d19beae119..48f09bcbe1 100644 --- a/src/ol/render/canvas/textreplay.js +++ b/src/ol/render/canvas/textreplay.js @@ -281,7 +281,7 @@ ol.render.canvas.TextReplay.prototype.drawText = function(geometry, feature) { */ ol.render.canvas.TextReplay.prototype.getImage = function(text, textKey, fillKey, strokeKey) { var label; - var key = strokeKey + textKey + text + fillKey; + var key = strokeKey + textKey + text + fillKey + this.pixelRatio; var labelCache = ol.render.canvas.labelCache; if (!labelCache.containsKey(key)) { @@ -323,19 +323,19 @@ ol.render.canvas.TextReplay.prototype.getImage = function(text, textKey, fillKey if (fillKey) { context.fillStyle = fillState.fillStyle; } - context.textBaseline = 'top'; + context.textBaseline = 'middle'; context.textAlign = 'center'; var leftRight = (0.5 - align); var x = align * label.width / scale + leftRight * strokeWidth; var i; if (strokeKey) { for (i = 0; i < numLines; ++i) { - context.strokeText(lines[i], x + leftRight * widths[i], 0.5 * strokeWidth + i * lineHeight); + context.strokeText(lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight); } } if (fillKey) { for (i = 0; i < numLines; ++i) { - context.fillText(lines[i], x + leftRight * widths[i], 0.5 * strokeWidth + i * lineHeight); + context.fillText(lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight); } } } diff --git a/test/rendering/ol/layer/expected/vector-canvas-declutter-group.png b/test/rendering/ol/layer/expected/vector-canvas-declutter-group.png index 584b381e7e..790327f5de 100644 Binary files a/test/rendering/ol/layer/expected/vector-canvas-declutter-group.png and b/test/rendering/ol/layer/expected/vector-canvas-declutter-group.png differ diff --git a/test/rendering/ol/layer/expected/vector-canvas-declutter-image-zindex.png b/test/rendering/ol/layer/expected/vector-canvas-declutter-image-zindex.png index f049e6fc7d..1a8896618e 100644 Binary files a/test/rendering/ol/layer/expected/vector-canvas-declutter-image-zindex.png and b/test/rendering/ol/layer/expected/vector-canvas-declutter-image-zindex.png differ diff --git a/test/rendering/ol/style/expected/text-canvas-hidpi.png b/test/rendering/ol/style/expected/text-canvas-hidpi.png index 7577d3b62f..24fc152cd5 100644 Binary files a/test/rendering/ol/style/expected/text-canvas-hidpi.png and b/test/rendering/ol/style/expected/text-canvas-hidpi.png differ diff --git a/test/rendering/ol/style/expected/text-linestring-auto.png b/test/rendering/ol/style/expected/text-linestring-auto.png index b9fed7e3ae..1344a0a6e7 100644 Binary files a/test/rendering/ol/style/expected/text-linestring-auto.png and b/test/rendering/ol/style/expected/text-linestring-auto.png differ diff --git a/test/rendering/ol/style/expected/text-linestring-center.png b/test/rendering/ol/style/expected/text-linestring-center.png index 5a9b15ed15..fa5c833f87 100644 Binary files a/test/rendering/ol/style/expected/text-linestring-center.png and b/test/rendering/ol/style/expected/text-linestring-center.png differ diff --git a/test/rendering/ol/style/expected/text-linestring-left-nice-rotated.png b/test/rendering/ol/style/expected/text-linestring-left-nice-rotated.png index c00181f8b2..6cb19bc94b 100644 Binary files a/test/rendering/ol/style/expected/text-linestring-left-nice-rotated.png and b/test/rendering/ol/style/expected/text-linestring-left-nice-rotated.png differ diff --git a/test/rendering/ol/style/expected/text-linestring-left-nice.png b/test/rendering/ol/style/expected/text-linestring-left-nice.png index 623e8a1832..f47a44ea75 100644 Binary files a/test/rendering/ol/style/expected/text-linestring-left-nice.png and b/test/rendering/ol/style/expected/text-linestring-left-nice.png differ diff --git a/test/rendering/ol/style/expected/text-linestring-left.png b/test/rendering/ol/style/expected/text-linestring-left.png index 2a9a0e8bc0..f0ba066ec1 100644 Binary files a/test/rendering/ol/style/expected/text-linestring-left.png and b/test/rendering/ol/style/expected/text-linestring-left.png differ diff --git a/test/rendering/ol/style/expected/text-linestring-nice-rotated.png b/test/rendering/ol/style/expected/text-linestring-nice-rotated.png index c9fa522176..65bc3bea66 100644 Binary files a/test/rendering/ol/style/expected/text-linestring-nice-rotated.png and b/test/rendering/ol/style/expected/text-linestring-nice-rotated.png differ diff --git a/test/rendering/ol/style/expected/text-linestring-nice-scale.png b/test/rendering/ol/style/expected/text-linestring-nice-scale.png index c3f001c20b..846d3a7051 100644 Binary files a/test/rendering/ol/style/expected/text-linestring-nice-scale.png and b/test/rendering/ol/style/expected/text-linestring-nice-scale.png differ diff --git a/test/rendering/ol/style/expected/text-linestring-nice.png b/test/rendering/ol/style/expected/text-linestring-nice.png index 56e5446eee..aa4a1c2286 100644 Binary files a/test/rendering/ol/style/expected/text-linestring-nice.png and b/test/rendering/ol/style/expected/text-linestring-nice.png differ diff --git a/test/rendering/ol/style/expected/text-multilinestring.png b/test/rendering/ol/style/expected/text-multilinestring.png index 117aec74f8..42c442caa9 100644 Binary files a/test/rendering/ol/style/expected/text-multilinestring.png and b/test/rendering/ol/style/expected/text-multilinestring.png differ diff --git a/test/rendering/ol/style/expected/text-multipolygon.png b/test/rendering/ol/style/expected/text-multipolygon.png index b3bceb36a1..6c65bcfc58 100644 Binary files a/test/rendering/ol/style/expected/text-multipolygon.png and b/test/rendering/ol/style/expected/text-multipolygon.png differ diff --git a/test/rendering/ol/style/text.test.js b/test/rendering/ol/style/text.test.js index 320cd855ee..6c267e4834 100644 --- a/test/rendering/ol/style/text.test.js +++ b/test/rendering/ol/style/text.test.js @@ -163,7 +163,7 @@ describe('ol.rendering.style.Text', function() { it('renders correct stroke with pixelRatio != 1', function(done) { createMap('canvas', 2); createFeatures(); - expectResemble(map, 'rendering/ol/style/expected/text-canvas-hidpi.png', 2.8, done); + expectResemble(map, 'rendering/ol/style/expected/text-canvas-hidpi.png', 2.9, done); }); it('renders text correctly with scale != 1', function(done) { @@ -260,6 +260,101 @@ describe('ol.rendering.style.Text', function() { expectResemble(map, 'rendering/ol/style/expected/text-align-offset-canvas.png', 6, done); }); + it('renders text along a MultiLineString', function(done) { + createMap('canvas'); + var line = new ol.geom.LineString(); + line.setFlatCoordinates('XY', nicePath); + var geom = new ol.geom.MultiLineString(null); + geom.appendLineString(line); + line = line.clone(); + line.translate(0, 50); + geom.appendLineString(line); + line = line.clone(); + line.translate(0, -100); + geom.appendLineString(line); + var feature = new ol.Feature(geom); + feature.setStyle(new ol.style.Style({ + text: new ol.style.Text({ + text: 'Hello world', + placement: 'line', + font: 'bold 30px sans-serif' + }) + })); + vectorSource.addFeature(feature); + map.getView().fit(vectorSource.getExtent()); + expectResemble(map, 'rendering/ol/style/expected/text-multilinestring.png', 7, done); + }); + + it('renders text along a Polygon', function(done) { + createMap('canvas'); + var geom = new ol.geom.Polygon(null); + geom.setFlatCoordinates('XY', polygon, [polygon.length]); + var feature = new ol.Feature(geom); + feature.setStyle(new ol.style.Style({ + text: new ol.style.Text({ + text: 'Hello world', + font: 'bold 24px sans-serif', + placement: 'line', + overflow: true + }) + })); + vectorSource.addFeature(feature); + map.getView().fit(vectorSource.getExtent()); + expectResemble(map, 'rendering/ol/style/expected/text-polygon.png', IMAGE_TOLERANCE, done); + }); + + it('renders text along a MultiPolygon', function(done) { + createMap('canvas'); + var geom = new ol.geom.Polygon(null); + geom.setFlatCoordinates('XY', polygon, [polygon.length]); + var multiPolygon = new ol.geom.MultiPolygon(null); + multiPolygon.appendPolygon(geom); + geom = geom.clone(); + geom.translate(0, 30); + multiPolygon.appendPolygon(geom); + geom = geom.clone(); + geom.translate(0, -60); + multiPolygon.appendPolygon(geom); + var feature = new ol.Feature(multiPolygon); + feature.setStyle(new ol.style.Style({ + text: new ol.style.Text({ + text: 'Hello world', + font: 'bold 24px sans-serif', + placement: 'line', + overflow: true + }) + })); + vectorSource.addFeature(feature); + map.getView().fit(vectorSource.getExtent()); + expectResemble(map, 'rendering/ol/style/expected/text-multipolygon.png', 4.4, done); + }); + + it('renders text background', function(done) { + createMap('canvas'); + createFeatures(); + var features = vectorSource.getFeatures(); + features[0].getStyle().getText().setBackgroundFill(new ol.style.Fill({ + color: 'red' + })); + features[1].getStyle().getText().setBackgroundFill(new ol.style.Fill({ + color: 'red' + })); + features[1].getStyle().getText().setBackgroundStroke(new ol.style.Stroke({ + color: 'blue', + width: 3 + })); + features[2].getStyle().getText().setBackgroundFill(new ol.style.Fill({ + color: 'red' + })); + features[2].getStyle().getText().setBackgroundStroke(new ol.style.Stroke({ + color: 'blue', + width: 3 + })); + features[2].getStyle().getText().setPadding([5, 10, 15, 0]); + map.getView().fit(vectorSource.getExtent()); + expectResemble(map, 'rendering/ol/style/expected/text-background.png', IMAGE_TOLERANCE, done); + }); + describe('Text along an ugly upside down path, keep text upright', function() { it('renders text along a linestring with auto-align', function(done) { @@ -347,97 +442,7 @@ describe('ol.rendering.style.Text', function() { createLineString(nicePath, 'left'); expectResemble(map, 'rendering/ol/style/expected/text-linestring-left-nice-rotated.png', 4.5, done); }); - }); - it('renders text along a MultiLineString', function(done) { - createMap('canvas'); - var line = new ol.geom.LineString(); - line.setFlatCoordinates('XY', nicePath); - var geom = new ol.geom.MultiLineString(null); - geom.appendLineString(line); - line.translate(0, 50); - geom.appendLineString(line); - line.translate(0, -100); - geom.appendLineString(line); - var feature = new ol.Feature(geom); - feature.setStyle(new ol.style.Style({ - text: new ol.style.Text({ - text: 'Hello world', - placement: 'line', - font: 'bold 30px sans-serif' - }) - })); - vectorSource.addFeature(feature); - map.getView().fit(vectorSource.getExtent()); - expectResemble(map, 'rendering/ol/style/expected/text-multilinestring.png', 7, done); - }); - - it('renders text along a Polygon', function(done) { - createMap('canvas'); - var geom = new ol.geom.Polygon(null); - geom.setFlatCoordinates('XY', polygon, [polygon.length]); - var feature = new ol.Feature(geom); - feature.setStyle(new ol.style.Style({ - text: new ol.style.Text({ - text: 'Hello world', - font: 'bold 24px sans-serif', - placement: 'line', - overflow: true - }) - })); - vectorSource.addFeature(feature); - map.getView().fit(vectorSource.getExtent()); - expectResemble(map, 'rendering/ol/style/expected/text-polygon.png', IMAGE_TOLERANCE, done); - }); - - it('renders text along a MultiPolygon', function(done) { - createMap('canvas'); - var geom = new ol.geom.Polygon(null); - geom.setFlatCoordinates('XY', polygon, [polygon.length]); - var multiPolygon = new ol.geom.MultiPolygon(null); - multiPolygon.appendPolygon(geom); - geom.translate(0, 30); - multiPolygon.appendPolygon(geom); - geom.translate(0, -60); - multiPolygon.appendPolygon(geom); - var feature = new ol.Feature(multiPolygon); - feature.setStyle(new ol.style.Style({ - text: new ol.style.Text({ - text: 'Hello world', - font: 'bold 24px sans-serif', - placement: 'line', - overflow: true - }) - })); - vectorSource.addFeature(feature); - map.getView().fit(vectorSource.getExtent()); - expectResemble(map, 'rendering/ol/style/expected/text-multipolygon.png', 4.4, done); - }); - - it('renders text background', function(done) { - createMap('canvas'); - createFeatures(); - var features = vectorSource.getFeatures(); - features[0].getStyle().getText().setBackgroundFill(new ol.style.Fill({ - color: 'red' - })); - features[1].getStyle().getText().setBackgroundFill(new ol.style.Fill({ - color: 'red' - })); - features[1].getStyle().getText().setBackgroundStroke(new ol.style.Stroke({ - color: 'blue', - width: 3 - })); - features[2].getStyle().getText().setBackgroundFill(new ol.style.Fill({ - color: 'red' - })); - features[2].getStyle().getText().setBackgroundStroke(new ol.style.Stroke({ - color: 'blue', - width: 3 - })); - features[2].getStyle().getText().setPadding([5, 10, 15, 0]); - map.getView().fit(vectorSource.getExtent()); - expectResemble(map, 'rendering/ol/style/expected/text-background.png', IMAGE_TOLERANCE, done); }); where('WebGL').it('tests the webgl renderer without rotation', function(done) {