From 380690a6a3262481be13b0be570a2ac2bbfa2d0c Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 11 Oct 2017 15:40:51 +0200 Subject: [PATCH] Pre-render text images for configured scale --- src/ol/render/canvas/textreplay.js | 25 ++++++++-------- .../ol/style/expected/text-canvas-scale.png | Bin 0 -> 6722 bytes .../expected/text-linestring-nice-scale.png | Bin 0 -> 19970 bytes test/rendering/ol/style/text.test.js | 27 ++++++++++++++---- 4 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 test/rendering/ol/style/expected/text-canvas-scale.png create mode 100644 test/rendering/ol/style/expected/text-linestring-nice-scale.png diff --git a/src/ol/render/canvas/textreplay.js b/src/ol/render/canvas/textreplay.js index 70cf025580..d6504675d9 100644 --- a/src/ol/render/canvas/textreplay.js +++ b/src/ol/render/canvas/textreplay.js @@ -310,6 +310,7 @@ ol.render.canvas.TextReplay.prototype.getImage_ = function(text, fill, stroke) { var fillState = this.textFillState_; var textState = this.textState_; var pixelRatio = this.pixelRatio; + var scale = this.textScale_ * pixelRatio; var align = ol.render.replay.TEXT_ALIGN[textState.textAlign || ol.render.canvas.defaultTextAlign]; var strokeWidth = stroke && strokeState.lineWidth ? strokeState.lineWidth : 0; @@ -319,15 +320,15 @@ ol.render.canvas.TextReplay.prototype.getImage_ = function(text, fill, stroke) { var height = lineHeight * numLines; var renderWidth = (width + 2 * strokeWidth); var context = ol.dom.createCanvasContext2D( - Math.ceil(renderWidth * pixelRatio), - Math.ceil((height + 2 * strokeWidth) * pixelRatio)); + Math.ceil(renderWidth * scale), + Math.ceil((height + 2 * strokeWidth) * scale)); label = context.canvas; ol.render.canvas.TextReplay.labelCache_.set(key, label); - context.scale(pixelRatio, pixelRatio); + context.scale(scale, scale); context.font = textState.font; if (stroke) { context.strokeStyle = strokeState.strokeStyle; - context.lineWidth = strokeWidth * (ol.has.SAFARI ? pixelRatio : 1); + context.lineWidth = strokeWidth * (ol.has.SAFARI ? scale : 1); context.lineCap = strokeState.lineCap; context.lineJoin = strokeState.lineJoin; context.miterLimit = strokeState.miterLimit; @@ -342,7 +343,7 @@ ol.render.canvas.TextReplay.prototype.getImage_ = function(text, fill, stroke) { context.textBaseline = 'top'; context.textAlign = 'center'; var leftRight = (0.5 - align); - var x = align * label.width / pixelRatio + leftRight * 2 * strokeWidth; + var x = align * label.width / scale + leftRight * 2 * strokeWidth; var i; if (stroke) { for (i = 0; i < numLines; ++i) { @@ -378,12 +379,12 @@ ol.render.canvas.TextReplay.prototype.drawTextImage_ = function(label, begin, en this.instructions.push([ol.render.canvas.Instruction.DRAW_IMAGE, begin, end, label, (anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio, label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_, - this.textScale_, true, label.width + 1, true, label.width ]); this.hitDetectionInstructions.push([ol.render.canvas.Instruction.DRAW_IMAGE, begin, end, label, (anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio, label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_, - this.textScale_ / pixelRatio, true, label.width + 1 / pixelRatio, true, label.width ]); }; @@ -424,14 +425,14 @@ ol.render.canvas.TextReplay.prototype.drawChars_ = function(begin, end) { this.instructions.push([ol.render.canvas.Instruction.DRAW_CHARS, begin, end, labels, baseline, textState.exceedLength, textState.maxAngle, - ol.render.canvas.TextReplay.getTextWidth.bind(widths, context, pixelRatio), - offsetY, this.text_, align, this.textScale_ + ol.render.canvas.TextReplay.getTextWidth.bind(widths, context, pixelRatio * this.textScale_), + offsetY, this.text_, align, 1 ]); this.hitDetectionInstructions.push([ol.render.canvas.Instruction.DRAW_CHARS, begin, end, labels, baseline, textState.exceedLength, textState.maxAngle, - ol.render.canvas.TextReplay.getTextWidth.bind(widths, context, 1), - offsetY, this.text_, align, this.textScale_ / pixelRatio + ol.render.canvas.TextReplay.getTextWidth.bind(widths, context, this.textScale_), + offsetY, this.text_, align, 1 / pixelRatio ]); }; @@ -531,7 +532,7 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { strokeState.lineCap + strokeState.lineDashOffset + '|' + strokeState.lineWidth + strokeState.lineJoin + strokeState.miterLimit + '[' + strokeState.lineDash.join() + ']' : ''; - this.textKey_ = textState.font + textState.textAlign; + this.textKey_ = textState.font + (textState.textAlign || '?') + this.textScale_; this.fillKey_ = fillState ? (typeof fillState.fillStyle == 'string' ? fillState.fillStyle : ('|' + ol.getUid(fillState.fillStyle))) : ''; diff --git a/test/rendering/ol/style/expected/text-canvas-scale.png b/test/rendering/ol/style/expected/text-canvas-scale.png new file mode 100644 index 0000000000000000000000000000000000000000..a569c3e11596b0d1bda6bb9bf45ad3319417ac39 GIT binary patch literal 6722 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 Xhua$OUNHrp?Z)8g>gTe~DWM4fM&wKx literal 0 HcmV?d00001 diff --git a/test/rendering/ol/style/text.test.js b/test/rendering/ol/style/text.test.js index 8c561f947a..3d130150c4 100644 --- a/test/rendering/ol/style/text.test.js +++ b/test/rendering/ol/style/text.test.js @@ -46,15 +46,17 @@ describe('ol.rendering.style.Text', function() { describe('#render', function() { - function createFeatures() { + function createFeatures(opt_scale) { + var scale = opt_scale || 1; var feature; feature = new ol.Feature({ geometry: new ol.geom.Point([-20, 18]) }); feature.setStyle(new ol.style.Style({ text: new ol.style.Text({ + scale: scale, text: 'hello', - font: '10px' + font: '10px sans-serif' }) })); vectorSource.addFeature(feature); @@ -64,10 +66,11 @@ describe('ol.rendering.style.Text', function() { }); feature.setStyle(new ol.style.Style({ text: new ol.style.Text({ + scale: scale, text: 'hello', fill: new ol.style.Fill({ color: 'red', - font: '12px' + font: '12px sans-serif' }), stroke: new ol.style.Stroke({ color: '#000', @@ -82,9 +85,10 @@ describe('ol.rendering.style.Text', function() { }); feature.setStyle(new ol.style.Style({ text: new ol.style.Text({ + scale: scale, rotateWithView: true, text: 'hello', - font: '10px', + font: '10px sans-serif', stroke: new ol.style.Stroke({ color: [10, 10, 10, 0.5] }) @@ -100,7 +104,7 @@ describe('ol.rendering.style.Text', function() { var uglyPath = [163, 22, 159, 30, 150, 30, 143, 24, 151, 17]; var polygon = [151, 17, 163, 22, 159, 30, 150, 30, 143, 24, 151, 17]; - function createLineString(coords, textAlign, maxAngle, strokeColor, strokeWidth) { + function createLineString(coords, textAlign, maxAngle, strokeColor, strokeWidth, scale) { var geom = new ol.geom.LineString(); geom.setFlatCoordinates('XY', coords); var style = new ol.style.Style({ @@ -110,6 +114,7 @@ describe('ol.rendering.style.Text', function() { text: new ol.style.Text({ text: 'Hello world', font: 'bold 14px sans-serif', + scale: scale || 1, textAlign: textAlign, maxAngle: maxAngle, placement: 'line', @@ -161,6 +166,12 @@ describe('ol.rendering.style.Text', function() { expectResemble(map, 'rendering/ol/style/expected/text-canvas-hidpi.png', 2.8, done); }); + it('renders text correctly with scale != 1', function(done) { + createMap('canvas'); + createFeatures(3); + expectResemble(map, 'rendering/ol/style/expected/text-canvas-scale.png', 6, done); + }); + it('renders multiline text with alignment options', function(done) { createMap('canvas'); var feature; @@ -293,6 +304,12 @@ describe('ol.rendering.style.Text', function() { expectResemble(map, 'rendering/ol/style/expected/text-linestring-nice.png', 2.8, done); }); + it('renders text along a linestring with scale != 1', function(done) { + createMap('canvas'); + createLineString(nicePath, undefined, undefined, undefined, undefined, 2); + expectResemble(map, 'rendering/ol/style/expected/text-linestring-nice-scale.png', 8, done); + }); + it('aligns text along a linestring correctly with `textBaseline` option', function(done) { createMap('canvas'); createLineString(nicePath, undefined, undefined, 'cyan', 3);