From ad8e4debbe0d2540f79afbed468c6ae0a166d7c4 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 15 Nov 2017 23:13:21 +0100 Subject: [PATCH] Make text states available for replay time --- src/ol/render/canvas/replay.js | 18 ++-- src/ol/render/canvas/textreplay.js | 95 +++++++++++++----- .../text-linestring-nice-multi-font.png | Bin 0 -> 22356 bytes test/rendering/ol/style/text.test.js | 11 ++ 4 files changed, 93 insertions(+), 31 deletions(-) create mode 100644 test/rendering/ol/style/expected/text-linestring-nice-multi-font.png diff --git a/src/ol/render/canvas/replay.js b/src/ol/render/canvas/replay.js index 0a78d62b73..89e8dd84fc 100644 --- a/src/ol/render/canvas/replay.js +++ b/src/ol/render/canvas/replay.js @@ -15,6 +15,7 @@ goog.require('ol.obj'); goog.require('ol.render.VectorContext'); goog.require('ol.render.canvas'); goog.require('ol.render.canvas.Instruction'); +goog.require('ol.render.replay'); goog.require('ol.transform'); @@ -691,29 +692,30 @@ ol.render.canvas.Replay.prototype.replay_ = function( var baseline = /** @type {number} */ (instruction[3]); declutterGroup = /** @type {ol.DeclutterGroup} */ (instruction[4]); var exceedLength = /** @type {number} */ (instruction[5]); - var fill = /** @type {boolean} */ (instruction[6]); + var fillKey = /** @type {string} */ (instruction[6]); var maxAngle = /** @type {number} */ (instruction[7]); var measure = /** @type {function(string):number} */ (instruction[8]); var offsetY = /** @type {number} */ (instruction[9]); - var stroke = /** @type {boolean} */ (instruction[10]); + var strokeKey = /** @type {string} */ (instruction[10]); var strokeWidth = /** @type {number} */ (instruction[11]); var text = /** @type {string} */ (instruction[12]); - var textAlign = /** @type {number} */ (instruction[13]); + var textKey = /** @type {string} */ (instruction[13]); var textScale = /** @type {number} */ (instruction[14]); var pathLength = ol.geom.flat.length.lineString(pixelCoordinates, begin, end, 2); var textLength = measure(text); if (exceedLength || textLength <= pathLength) { - var startM = (pathLength - textLength) * textAlign; + var textAlign = /** @type {ol.render.canvas.TextReplay} */ (this).textStates[textKey].textAlign; + var startM = (pathLength - textLength) * ol.render.replay.TEXT_ALIGN[textAlign]; var parts = ol.geom.flat.textpath.lineString( pixelCoordinates, begin, end, 2, text, measure, startM, maxAngle); if (parts) { var c, cc, chars, label, part; - if (stroke) { + if (strokeKey) { for (c = 0, cc = parts.length; c < cc; ++c) { part = parts[c]; // x, y, anchorX, rotation, chunk chars = /** @type {string} */ (part[4]); - label = /** @type {ol.render.canvas.TextReplay} */ (this).getImage(chars, false, true); + label = /** @type {ol.render.canvas.TextReplay} */ (this).getImage(chars, textKey, '', strokeKey); anchorX = /** @type {number} */ (part[2]) + strokeWidth; anchorY = baseline * label.height + (0.5 - baseline) * 2 * strokeWidth - offsetY; this.replayImage_(context, @@ -723,11 +725,11 @@ ol.render.canvas.Replay.prototype.replay_ = function( ol.render.canvas.defaultPadding, null, null); } } - if (fill) { + if (fillKey) { for (c = 0, cc = parts.length; c < cc; ++c) { part = parts[c]; // x, y, anchorX, rotation, chunk chars = /** @type {string} */ (part[4]); - label = /** @type {ol.render.canvas.TextReplay} */ (this).getImage(chars, true, false); + label = /** @type {ol.render.canvas.TextReplay} */ (this).getImage(chars, textKey, fillKey, ''); anchorX = /** @type {number} */ (part[2]); anchorY = baseline * label.height - offsetY; this.replayImage_(context, diff --git a/src/ol/render/canvas/textreplay.js b/src/ol/render/canvas/textreplay.js index 12a258908e..f5dedfe530 100644 --- a/src/ol/render/canvas/textreplay.js +++ b/src/ol/render/canvas/textreplay.js @@ -78,18 +78,33 @@ ol.render.canvas.TextReplay = function( */ this.textFillState_ = null; + /** + * @type {Object.} + */ + this.fillStates = {}; + /** * @private * @type {?ol.CanvasStrokeState} */ this.textStrokeState_ = null; + /** + * @type {Object.} + */ + this.strokeStates = {}; + /** * @private * @type {ol.CanvasTextState} */ this.textState_ = /** @type {ol.CanvasTextState} */ ({}); + /** + * @type {Object.} + */ + this.textStates = {}; + /** * @private * @type {string} @@ -110,7 +125,7 @@ ol.render.canvas.TextReplay = function( /** * @private - * @type {Object.} + * @type {Object.>} */ this.widths_ = {}; @@ -248,7 +263,7 @@ ol.render.canvas.TextReplay.prototype.drawText = function(geometry, feature) { this.endGeometry(geometry, feature); } else { - var label = this.getImage(this.text_, !!this.textFillState_, !!this.textStrokeState_); + var label = this.getImage(this.text_, this.textKey_, this.fillKey_, this.strokeKey_); var width = label.width / this.pixelRatio; switch (geometryType) { case ol.geom.GeometryType.POINT: @@ -303,23 +318,24 @@ ol.render.canvas.TextReplay.prototype.drawText = function(geometry, feature) { /** * @param {string} text Text. - * @param {boolean} fill Fill. - * @param {boolean} stroke Stroke. + * @param {string} textKey Text style key. + * @param {string} fillKey Fill style key. + * @param {string} strokeKey Stroke style key. * @return {HTMLCanvasElement} Image. */ -ol.render.canvas.TextReplay.prototype.getImage = function(text, fill, stroke) { +ol.render.canvas.TextReplay.prototype.getImage = function(text, textKey, fillKey, strokeKey) { var label; - var key = (stroke ? this.strokeKey_ : '') + this.textKey_ + text + (fill ? this.fillKey_ : ''); + var key = strokeKey + textKey + text + fillKey; var labelCache = ol.render.canvas.labelCache; if (!labelCache.containsKey(key)) { - var strokeState = this.textStrokeState_; - var fillState = this.textFillState_; - var textState = this.textState_; + var strokeState = strokeKey ? this.strokeStates[strokeKey] || this.textStrokeState_ : null; + var fillState = fillKey ? this.fillStates[fillKey] || this.textFillState_ : null; + var textState = this.textStates[textKey] || this.textState_; var pixelRatio = this.pixelRatio; var scale = textState.scale * pixelRatio; var align = ol.render.replay.TEXT_ALIGN[textState.textAlign || ol.render.canvas.defaultTextAlign]; - var strokeWidth = stroke && strokeState.lineWidth ? strokeState.lineWidth : 0; + var strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0; var lines = text.split('\n'); var numLines = lines.length; @@ -337,7 +353,7 @@ ol.render.canvas.TextReplay.prototype.getImage = function(text, fill, stroke) { context.scale(scale, scale); } context.font = textState.font; - if (stroke) { + if (strokeKey) { context.strokeStyle = strokeState.strokeStyle; context.lineWidth = strokeWidth * (ol.has.SAFARI ? scale : 1); context.lineCap = strokeState.lineCap; @@ -348,7 +364,7 @@ ol.render.canvas.TextReplay.prototype.getImage = function(text, fill, stroke) { context.lineDashOffset = strokeState.lineDashOffset; } } - if (fill) { + if (fillKey) { context.fillStyle = fillState.fillStyle; } context.textBaseline = 'top'; @@ -356,12 +372,12 @@ ol.render.canvas.TextReplay.prototype.getImage = function(text, fill, stroke) { var leftRight = (0.5 - align); var x = align * label.width / scale + leftRight * strokeWidth; var i; - if (stroke) { + if (strokeKey) { for (i = 0; i < numLines; ++i) { context.strokeText(lines[i], x + leftRight * widths[i], 0.5 * strokeWidth + i * lineHeight); } } - if (fill) { + if (fillKey) { for (i = 0; i < numLines; ++i) { context.fillText(lines[i], x + leftRight * widths[i], 0.5 * strokeWidth + i * lineHeight); } @@ -413,23 +429,56 @@ ol.render.canvas.TextReplay.prototype.drawTextImage_ = function(label, begin, en * @param {ol.DeclutterGroup} declutterGroup Declutter group. */ ol.render.canvas.TextReplay.prototype.drawChars_ = function(begin, end, declutterGroup) { - var pixelRatio = this.pixelRatio; var strokeState = this.textStrokeState_; - var fill = !!this.textFillState_; - var stroke = !!strokeState; var textState = this.textState_; + var fillState = this.textFillState_; + + var strokeKey = this.strokeKey_; + if (strokeState) { + if (!(strokeKey in this.strokeStates)) { + this.strokeStates[strokeKey] = /** @type {ol.CanvasStrokeState} */ ({ + strokeStyle: strokeState.strokeStyle, + lineCap: strokeState.lineCap, + lineDashOffset: strokeState.lineDashOffset, + lineWidth: strokeState.lineWidth, + lineJoin: strokeState.lineJoin, + miterLimit: strokeState.miterLimit, + lineDash: strokeState.lineDash + }); + } + } + var textKey = this.textKey_; + if (!(this.textKey_ in this.textStates)) { + this.textStates[this.textKey_] = /** @type {ol.CanvasTextState} */ ({ + font: textState.font, + textAlign: textState.textAlign || ol.render.canvas.defaultTextAlign, + scale: textState.scale + }); + } + var fillKey = this.fillKey_; + if (fillState) { + if (!(fillKey in this.fillStates)) { + this.fillStates[fillKey] = /** @type {ol.CanvasFillState} */ ({ + fillStyle: fillState.fillStyle + }); + } + } + + var pixelRatio = this.pixelRatio; var baseline = ol.render.replay.TEXT_ALIGN[textState.textBaseline]; var offsetY = this.textOffsetY_ * pixelRatio; - var textAlign = ol.render.replay.TEXT_ALIGN[textState.textAlign || ol.render.canvas.defaultTextAlign]; var text = this.text_; var font = textState.font; var textScale = textState.scale; var strokeWidth = strokeState ? strokeState.lineWidth * textScale / 2 : 0; - var widths = this.widths_; + var widths = this.widths_[font]; + if (!widths) { + this.widths_[font] = widths = {}; + } this.instructions.push([ol.render.canvas.Instruction.DRAW_CHARS, begin, end, baseline, declutterGroup, - textState.exceedLength, fill, textState.maxAngle, + textState.exceedLength, fillKey, textState.maxAngle, function(text) { var width = widths[text]; if (!width) { @@ -437,11 +486,11 @@ ol.render.canvas.TextReplay.prototype.drawChars_ = function(begin, end, declutte } return width * textScale * pixelRatio; }, - offsetY, stroke, strokeWidth * pixelRatio, text, textAlign, 1 + offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1 ]); this.hitDetectionInstructions.push([ol.render.canvas.Instruction.DRAW_CHARS, begin, end, baseline, declutterGroup, - textState.exceedLength, fill, textState.maxAngle, + textState.exceedLength, fillKey, textState.maxAngle, function(text) { var width = widths[text]; if (!width) { @@ -449,7 +498,7 @@ ol.render.canvas.TextReplay.prototype.drawChars_ = function(begin, end, declutte } return width * textScale; }, - offsetY, stroke, strokeWidth, text, textAlign, 1 / pixelRatio + offsetY, strokeKey, strokeWidth, text, textKey, 1 / pixelRatio ]); }; diff --git a/test/rendering/ol/style/expected/text-linestring-nice-multi-font.png b/test/rendering/ol/style/expected/text-linestring-nice-multi-font.png new file mode 100644 index 0000000000000000000000000000000000000000..3d97ec922ade520684cb051839c97165be38f505 GIT binary patch literal 22356 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