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 0000000000..a569c3e115 Binary files /dev/null and b/test/rendering/ol/style/expected/text-canvas-scale.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 new file mode 100644 index 0000000000..c3f001c20b Binary files /dev/null and b/test/rendering/ol/style/expected/text-linestring-nice-scale.png differ 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);