diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index d55e98b304..5b0afe232f 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -1313,6 +1313,305 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() { +/** + * @constructor + * @extends {ol.render.canvas.Replay} + * @param {number} tolerance Tolerance. + * @protected + * @struct + */ +ol.render.canvas.TextReplay = function(tolerance) { + + goog.base(this, tolerance); + + /** + * @private + * @type {?ol.render.canvas.FillState} + */ + this.replayFillState_ = null; + + /** + * @private + * @type {?ol.render.canvas.StrokeState} + */ + this.replayStrokeState_ = null; + + /** + * @private + * @type {?ol.render.canvas.TextState} + */ + this.replayTextState_ = null; + + /** + * @private + * @type {string} + */ + this.text_ = ''; + + /** + * @private + * @type {number} + */ + this.textRotation_ = 0; + + /** + * @private + * @type {number} + */ + this.textScale_ = 0; + + /** + * @private + * @type {?ol.render.canvas.FillState} + */ + this.textFillState_ = null; + + /** + * @private + * @type {?ol.render.canvas.StrokeState} + */ + this.textStrokeState_ = null; + + /** + * @private + * @type {?ol.render.canvas.TextState} + */ + this.textState_ = null; + +}; +goog.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay); + + +/** + * @inheritDoc + */ +ol.render.canvas.TextReplay.prototype.drawText = + function(flatCoordinates, offset, end, stride, geometry, data) { + if (this.text_ === '' || + goog.isNull(this.textState_) || + (goog.isNull(this.textFillState_) && + goog.isNull(this.textStrokeState_))) { + return; + } + ol.extent.extendFlatCoordinates( + this.extent_, flatCoordinates, offset, end, stride); + if (!goog.isNull(this.textFillState_)) { + this.setReplayFillState_(this.textFillState_); + } + if (!goog.isNull(this.textStrokeState_)) { + this.setReplayStrokeState_(this.textStrokeState_); + } + this.setReplayTextState_(this.textState_); + this.beginGeometry(geometry); + var myBegin = this.coordinates.length; + var myEnd = + this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false); + var fill = !goog.isNull(this.textFillState_); + var stroke = !goog.isNull(this.textStrokeState_); + var drawTextInstruction = [ + ol.render.canvas.Instruction.DRAW_TEXT, myBegin, myEnd, this.text_, + this.textRotation_, this.textScale_, fill, stroke]; + this.instructions.push(drawTextInstruction); + this.hitDetectionInstructions.push(drawTextInstruction); + this.endGeometry(geometry, data); +}; + + +/** + * @param {ol.render.canvas.FillState} fillState Fill state. + * @private + */ +ol.render.canvas.TextReplay.prototype.setReplayFillState_ = + function(fillState) { + var replayFillState = this.replayFillState_; + if (!goog.isNull(replayFillState) && + replayFillState.fillStyle == fillState.fillStyle) { + return; + } + var setFillStyleInstruction = + [ol.render.canvas.Instruction.SET_FILL_STYLE, fillState.fillStyle]; + this.instructions.push(setFillStyleInstruction); + this.hitDetectionInstructions.push(setFillStyleInstruction); + if (goog.isNull(replayFillState)) { + this.replayFillState_ = { + fillStyle: fillState.fillStyle + }; + } else { + replayFillState.fillStyle = fillState.fillStyle; + } +}; + + +/** + * @param {ol.render.canvas.StrokeState} strokeState Stroke state. + * @private + */ +ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = + function(strokeState) { + var replayStrokeState = this.replayStrokeState_; + if (!goog.isNull(replayStrokeState) && + replayStrokeState.lineCap == strokeState.lineCap && + replayStrokeState.lineDash == strokeState.lineDash && + replayStrokeState.lineJoin == strokeState.lineJoin && + replayStrokeState.lineWidth == strokeState.lineWidth && + replayStrokeState.miterLimit == strokeState.miterLimit && + replayStrokeState.strokeStyle == strokeState.strokeStyle) { + return; + } + var setStrokeStyleInstruction = [ + ol.render.canvas.Instruction.SET_STROKE_STYLE, strokeState.strokeStyle, + strokeState.lineWidth, strokeState.lineCap, strokeState.lineJoin, + strokeState.miterLimit, strokeState.lineDash + ]; + this.instructions.push(setStrokeStyleInstruction); + this.hitDetectionInstructions.push(setStrokeStyleInstruction); + if (goog.isNull(replayStrokeState)) { + this.replayStrokeState_ = { + lineCap: strokeState.lineCap, + lineDash: strokeState.lineDash, + lineJoin: strokeState.lineJoin, + lineWidth: strokeState.lineWidth, + miterLimit: strokeState.miterLimit, + strokeStyle: strokeState.strokeStyle + }; + } else { + replayStrokeState.lineCap = strokeState.lineCap; + replayStrokeState.lineDash = strokeState.lineDash; + replayStrokeState.lineJoin = strokeState.lineJoin; + replayStrokeState.lineWidth = strokeState.lineWidth; + replayStrokeState.miterLimit = strokeState.miterLimit; + replayStrokeState.strokeStyle = strokeState.strokeStyle; + } +}; + + +/** + * @param {ol.render.canvas.TextState} textState Text state. + * @private + */ +ol.render.canvas.TextReplay.prototype.setReplayTextState_ = + function(textState) { + var replayTextState = this.replayTextState_; + if (!goog.isNull(replayTextState) && + replayTextState.font == textState.font && + replayTextState.textAlign == textState.textAlign && + replayTextState.textBaseline == textState.textBaseline) { + return; + } + var setTextStyleInstruction = [ol.render.canvas.Instruction.SET_TEXT_STYLE, + textState.font, textState.textAlign, textState.textBaseline]; + this.instructions.push(setTextStyleInstruction); + this.hitDetectionInstructions.push(setTextStyleInstruction); + if (goog.isNull(replayTextState)) { + this.replayTextState_ = { + font: textState.font, + textAlign: textState.textAlign, + textBaseline: textState.textBaseline + }; + } else { + replayTextState.font = textState.font; + replayTextState.textAlign = textState.textAlign; + replayTextState.textBaseline = textState.textBaseline; + } +}; + + +/** + * @inheritDoc + */ +ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { + if (goog.isNull(textStyle)) { + this.text_ = ''; + } else { + var textFillStyle = textStyle.getFill(); + if (goog.isNull(textFillStyle)) { + this.textFillState_ = null; + } else { + var textFillStyleColor = textFillStyle.getColor(); + var fillStyle = ol.color.asString(!goog.isNull(textFillStyleColor) ? + textFillStyleColor : ol.render.canvas.defaultFillStyle); + if (goog.isNull(this.textFillState_)) { + this.textFillState_ = { + fillStyle: fillStyle + }; + } else { + var textFillState = this.textFillState_; + textFillState.fillStyle = fillStyle; + } + } + var textStrokeStyle = textStyle.getStroke(); + if (goog.isNull(textStrokeStyle)) { + this.textStrokeState_ = null; + } else { + var textStrokeStyleColor = textStrokeStyle.getColor(); + var textStrokeStyleLineCap = textStrokeStyle.getLineCap(); + var textStrokeStyleLineDash = textStrokeStyle.getLineDash(); + var textStrokeStyleLineJoin = textStrokeStyle.getLineJoin(); + var textStrokeStyleWidth = textStrokeStyle.getWidth(); + var textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit(); + var lineCap = goog.isDef(textStrokeStyleLineCap) ? + textStrokeStyleLineCap : ol.render.canvas.defaultLineCap; + var lineDash = goog.isDefAndNotNull(textStrokeStyleLineDash) ? + textStrokeStyleLineDash : ol.render.canvas.defaultLineDash; + var lineJoin = goog.isDef(textStrokeStyleLineJoin) ? + textStrokeStyleLineJoin : ol.render.canvas.defaultLineJoin; + var lineWidth = goog.isDef(textStrokeStyleWidth) ? + textStrokeStyleWidth : ol.render.canvas.defaultLineWidth; + var miterLimit = goog.isDef(textStrokeStyleMiterLimit) ? + textStrokeStyleMiterLimit : ol.render.canvas.defaultMiterLimit; + var strokeStyle = ol.color.asString(!goog.isNull(textStrokeStyleColor) ? + textStrokeStyleColor : ol.render.canvas.defaultStrokeStyle); + if (goog.isNull(this.textStrokeState_)) { + this.textStrokeState_ = { + lineCap: lineCap, + lineDash: lineDash, + lineJoin: lineJoin, + lineWidth: lineWidth, + miterLimit: miterLimit, + strokeStyle: strokeStyle + }; + } else { + var textStrokeState = this.textStrokeState_; + textStrokeState.lineCap = lineCap; + textStrokeState.lineDash = lineDash; + textStrokeState.lineJoin = lineJoin; + textStrokeState.lineWidth = lineWidth; + textStrokeState.miterLimit = miterLimit; + textStrokeState.strokeStyle = strokeStyle; + } + } + var textFont = textStyle.getFont(); + var textRotation = textStyle.getRotation(); + var textScale = textStyle.getScale(); + var textText = textStyle.getText(); + var textTextAlign = textStyle.getTextAlign(); + var textTextBaseline = textStyle.getTextBaseline(); + var font = goog.isDef(textFont) ? + textFont : ol.render.canvas.defaultFont; + var textAlign = goog.isDef(textTextAlign) ? + textTextAlign : ol.render.canvas.defaultTextAlign; + var textBaseline = goog.isDef(textTextBaseline) ? + textTextBaseline : ol.render.canvas.defaultTextBaseline; + if (goog.isNull(this.textState_)) { + this.textState_ = { + font: font, + textAlign: textAlign, + textBaseline: textBaseline + }; + } else { + var textState = this.textState_; + textState.font = font; + textState.textAlign = textAlign; + textState.textBaseline = textBaseline; + } + this.text_ = goog.isDef(textText) ? textText : ''; + this.textRotation_ = goog.isDef(textRotation) ? textRotation : 0; + this.textScale_ = goog.isDef(textScale) ? textScale : 1; + } +}; + + + /** * @constructor * @implements {ol.render.IReplayGroup} @@ -1547,5 +1846,6 @@ ol.render.canvas.ReplayGroup.prototype.isEmpty = function() { ol.render.canvas.BATCH_CONSTRUCTORS_ = { 'Image': ol.render.canvas.ImageReplay, 'LineString': ol.render.canvas.LineStringReplay, - 'Polygon': ol.render.canvas.PolygonReplay + 'Polygon': ol.render.canvas.PolygonReplay, + 'Text': ol.render.canvas.TextReplay };