From 35bd92b7138db9bddc579545266b48f0726e5bd1 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 31 Aug 2017 16:19:33 +0200 Subject: [PATCH 1/5] Prerender labels and cache them as images --- src/ol/render/canvas/imagereplay.js | 5 +- src/ol/render/canvas/instruction.js | 14 +- src/ol/render/canvas/linestringreplay.js | 5 +- src/ol/render/canvas/polygonreplay.js | 5 +- src/ol/render/canvas/replay.js | 71 +----- src/ol/render/canvas/replaygroup.js | 13 +- src/ol/render/canvas/textreplay.js | 265 ++++++++++---------- src/ol/render/replay.js | 18 ++ src/ol/render/webgl/textreplay.js | 24 +- src/ol/renderer/canvas/vectorlayer.js | 4 +- src/ol/renderer/canvas/vectortilelayer.js | 2 +- src/ol/source/imagevector.js | 2 +- src/ol/structs/lrucache.js | 16 +- src/ol/tilecache.js | 15 +- test/spec/ol/renderer/canvas/replay.test.js | 10 +- 15 files changed, 211 insertions(+), 258 deletions(-) diff --git a/src/ol/render/canvas/imagereplay.js b/src/ol/render/canvas/imagereplay.js index 77dbbe8071..c0e1c7af76 100644 --- a/src/ol/render/canvas/imagereplay.js +++ b/src/ol/render/canvas/imagereplay.js @@ -11,11 +11,12 @@ goog.require('ol.render.canvas.Replay'); * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The replay can have overlapping geometries. * @struct */ -ol.render.canvas.ImageReplay = function(tolerance, maxExtent, resolution, overlaps) { - ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps); +ol.render.canvas.ImageReplay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) { + ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, pixelRatio, overlaps); /** * @private diff --git a/src/ol/render/canvas/instruction.js b/src/ol/render/canvas/instruction.js index 78419e7692..ee786500ce 100644 --- a/src/ol/render/canvas/instruction.js +++ b/src/ol/render/canvas/instruction.js @@ -10,12 +10,10 @@ ol.render.canvas.Instruction = { CLOSE_PATH: 3, CUSTOM: 4, DRAW_IMAGE: 5, - DRAW_TEXT: 6, - END_GEOMETRY: 7, - FILL: 8, - MOVE_TO_LINE_TO: 9, - SET_FILL_STYLE: 10, - SET_STROKE_STYLE: 11, - SET_TEXT_STYLE: 12, - STROKE: 13 + END_GEOMETRY: 6, + FILL: 7, + MOVE_TO_LINE_TO: 8, + SET_FILL_STYLE: 9, + SET_STROKE_STYLE: 10, + STROKE: 11 }; diff --git a/src/ol/render/canvas/linestringreplay.js b/src/ol/render/canvas/linestringreplay.js index 218b18c1ea..7fd125aa83 100644 --- a/src/ol/render/canvas/linestringreplay.js +++ b/src/ol/render/canvas/linestringreplay.js @@ -15,12 +15,13 @@ goog.require('ol.render.canvas.Replay'); * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The replay can have overlapping geometries. * @struct */ -ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, overlaps) { +ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) { - ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps); + ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, pixelRatio, overlaps); /** * @private diff --git a/src/ol/render/canvas/polygonreplay.js b/src/ol/render/canvas/polygonreplay.js index 54f8585348..0aaccae4dc 100644 --- a/src/ol/render/canvas/polygonreplay.js +++ b/src/ol/render/canvas/polygonreplay.js @@ -17,12 +17,13 @@ goog.require('ol.render.canvas.Replay'); * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The replay can have overlapping geometries. * @struct */ -ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, overlaps) { +ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) { - ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps); + ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, pixelRatio, overlaps); /** * @private diff --git a/src/ol/render/canvas/replay.js b/src/ol/render/canvas/replay.js index 08713d9595..68539e4856 100644 --- a/src/ol/render/canvas/replay.js +++ b/src/ol/render/canvas/replay.js @@ -20,10 +20,11 @@ goog.require('ol.transform'); * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The replay can have overlapping geometries. * @struct */ -ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) { +ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) { ol.render.VectorContext.call(this); /** @@ -45,6 +46,11 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) { */ this.overlaps = overlaps; + /** + * @protected + * @type {number} + */ + this.pixelRatio = pixelRatio; /** * @protected * @type {number} @@ -342,7 +348,7 @@ ol.render.canvas.Replay.prototype.replay_ = function( while (i < ii) { var instruction = instructions[i]; var type = /** @type {ol.render.canvas.Instruction} */ (instruction[0]); - var /** @type {ol.Feature|ol.render.Feature} */ feature, fill, stroke, text, x, y; + var /** @type {ol.Feature|ol.render.Feature} */ feature, x, y; switch (type) { case ol.render.canvas.Instruction.BEGIN_GEOMETRY: feature = /** @type {ol.Feature|ol.render.Feature} */ (instruction[1]); @@ -465,61 +471,6 @@ ol.render.canvas.Replay.prototype.replay_ = function( } ++i; break; - case ol.render.canvas.Instruction.DRAW_TEXT: - d = /** @type {number} */ (instruction[1]); - dd = /** @type {number} */ (instruction[2]); - text = /** @type {string} */ (instruction[3]); - var offsetX = /** @type {number} */ (instruction[4]) * pixelRatio; - var offsetY = /** @type {number} */ (instruction[5]) * pixelRatio; - rotation = /** @type {number} */ (instruction[6]); - scale = /** @type {number} */ (instruction[7]) * pixelRatio; - fill = /** @type {boolean} */ (instruction[8]); - stroke = /** @type {boolean} */ (instruction[9]); - rotateWithView = /** @type {boolean} */ (instruction[10]); - if (rotateWithView) { - rotation += viewRotation; - } - for (; d < dd; d += 2) { - x = pixelCoordinates[d] + offsetX; - y = pixelCoordinates[d + 1] + offsetY; - if (scale != 1 || rotation !== 0) { - ol.transform.compose(localTransform, x, y, scale, scale, rotation, -x, -y); - context.setTransform.apply(context, localTransform); - } - - // Support multiple lines separated by \n - var lines = text.split('\n'); - var numLines = lines.length; - var fontSize, lineY; - if (numLines > 1) { - // Estimate line height using width of capital M, and add padding - fontSize = Math.round(context.measureText('M').width * 1.5); - lineY = y - (((numLines - 1) / 2) * fontSize); - } else { - // No need to calculate line height/offset for a single line - fontSize = 0; - lineY = y; - } - - for (var lineIndex = 0; lineIndex < numLines; lineIndex++) { - var line = lines[lineIndex]; - if (stroke) { - context.strokeText(line, x, lineY); - } - if (fill) { - context.fillText(line, x, lineY); - } - - // Move next line down by fontSize px - lineY = lineY + fontSize; - } - - if (scale != 1 || rotation !== 0) { - context.setTransform.apply(context, resetTransform); - } - } - ++i; - break; case ol.render.canvas.Instruction.END_GEOMETRY: if (featureCallback !== undefined) { feature = /** @type {ol.Feature|ol.render.Feature} */ (instruction[1]); @@ -610,12 +561,6 @@ ol.render.canvas.Replay.prototype.replay_ = function( } ++i; break; - case ol.render.canvas.Instruction.SET_TEXT_STYLE: - context.font = /** @type {string} */ (instruction[1]); - context.textAlign = /** @type {string} */ (instruction[2]); - context.textBaseline = /** @type {string} */ (instruction[3]); - ++i; - break; case ol.render.canvas.Instruction.STROKE: if (batchSize) { pendingStroke++; diff --git a/src/ol/render/canvas/replaygroup.js b/src/ol/render/canvas/replaygroup.js index a4ee79a49a..bda8170ebe 100644 --- a/src/ol/render/canvas/replaygroup.js +++ b/src/ol/render/canvas/replaygroup.js @@ -22,12 +22,13 @@ goog.require('ol.transform'); * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Max extent. * @param {number} resolution Resolution. + * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The replay group can have overlapping geometries. * @param {number=} opt_renderBuffer Optional rendering buffer. * @struct */ ol.render.canvas.ReplayGroup = function( - tolerance, maxExtent, resolution, overlaps, opt_renderBuffer) { + tolerance, maxExtent, resolution, pixelRatio, overlaps, opt_renderBuffer) { ol.render.ReplayGroup.call(this); /** @@ -48,6 +49,12 @@ ol.render.canvas.ReplayGroup = function( */ this.overlaps_ = overlaps; + /** + * @private + * @type {number} + */ + this.pixelRatio_ = pixelRatio; + /** * @private * @type {number} @@ -296,7 +303,7 @@ ol.render.canvas.ReplayGroup.prototype.getReplay = function(zIndex, replayType) if (replay === undefined) { var Constructor = ol.render.canvas.ReplayGroup.BATCH_CONSTRUCTORS_[replayType]; replay = new Constructor(this.tolerance_, this.maxExtent_, - this.resolution_, this.overlaps_); + this.resolution_, this.pixelRatio_, this.overlaps_); replays[replayType] = replay; } return replay; @@ -402,7 +409,7 @@ ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function( * @private * @type {Object.} + * number, number, boolean)>} */ ol.render.canvas.ReplayGroup.BATCH_CONSTRUCTORS_ = { 'Circle': ol.render.canvas.PolygonReplay, diff --git a/src/ol/render/canvas/textreplay.js b/src/ol/render/canvas/textreplay.js index 2310e6847a..8bd81a7e9c 100644 --- a/src/ol/render/canvas/textreplay.js +++ b/src/ol/render/canvas/textreplay.js @@ -2,9 +2,12 @@ goog.provide('ol.render.canvas.TextReplay'); goog.require('ol'); goog.require('ol.colorlike'); +goog.require('ol.has'); goog.require('ol.render.canvas'); goog.require('ol.render.canvas.Instruction'); goog.require('ol.render.canvas.Replay'); +goog.require('ol.render.replay'); +goog.require('ol.structs.LRUCache'); /** @@ -13,30 +16,13 @@ goog.require('ol.render.canvas.Replay'); * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Maximum extent. * @param {number} resolution Resolution. + * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The replay can have overlapping geometries. * @struct */ -ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution, overlaps) { +ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) { - ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps); - - /** - * @private - * @type {?ol.CanvasFillState} - */ - this.replayFillState_ = null; - - /** - * @private - * @type {?ol.CanvasStrokeState} - */ - this.replayStrokeState_ = null; - - /** - * @private - * @type {?ol.CanvasTextState} - */ - this.replayTextState_ = null; + ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, pixelRatio, overlaps); /** * @private @@ -92,140 +78,153 @@ ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution, overlap */ this.textState_ = null; + while (ol.render.canvas.TextReplay.labelCache_.canExpireCache()) { + ol.render.canvas.TextReplay.labelCache_.pop(); + } + }; ol.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay); +/** + * @private + * @type {ol.structs.LRUCache.} + */ +ol.render.canvas.TextReplay.labelCache_ = new ol.structs.LRUCache(); + + +/** + * @param {string} font Font to use for measuring. + * @param {Array.} lines Lines to measure. + * @param {Array.} widths Array will be populated with the widths of + * each line. + * @return {ol.Size} Measuremnt. + */ +ol.render.canvas.TextReplay.measureText = (function() { + var textContainer; + return function(font, lines, widths) { + if (!textContainer) { + textContainer = document.createElement('span'); + textContainer.style.visibility = 'hidden'; + textContainer.style.whiteSpace = 'nowrap'; + } + textContainer.style.font = font; + document.body.appendChild(textContainer); + var numLines = lines.length; + var width = 0; + var currentWidth, i; + for (i = 0; i < numLines; ++i) { + textContainer.textContent = lines[i]; + currentWidth = textContainer.offsetWidth; + width = Math.max(width, currentWidth); + widths.push(currentWidth); + } + var measurement = [width, textContainer.offsetHeight * numLines]; + document.body.removeChild(textContainer); + return measurement; + }; +})(); + + /** * @inheritDoc */ ol.render.canvas.TextReplay.prototype.drawText = function(flatCoordinates, offset, end, stride, geometry, feature) { - if (this.text_ === '' || !this.textState_ || - (!this.textFillState_ && !this.textStrokeState_)) { + var fillState = this.textFillState_; + var strokeState = this.textStrokeState_; + var textState = this.textState_; + if (this.text_ === '' || !textState || (!fillState && !strokeState)) { return; } - if (this.textFillState_) { - this.setReplayFillState_(this.textFillState_); - } - if (this.textStrokeState_) { - this.setReplayStrokeState_(this.textStrokeState_); - } - this.setReplayTextState_(this.textState_); this.beginGeometry(geometry, feature); + var myBegin = this.coordinates.length; var myEnd = this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false, false); - var fill = !!this.textFillState_; - var stroke = !!this.textStrokeState_; + var fill = !!fillState; + var stroke = !!strokeState; + var pixelRatio = this.pixelRatio; + var textAlign = textState.textAlign; + var align = ol.render.replay.TEXT_ALIGN[textAlign]; + var textBaseline = textState.textBaseline; + var baseline = ol.render.replay.TEXT_ALIGN[textBaseline]; + var strokeWidth = stroke && strokeState.lineWidth ? strokeState.lineWidth : 0; + + var label; + var text = this.text_; + var key = + (stroke ? + (typeof strokeState.strokeStyle == 'string' ? strokeState.strokeStyle : ol.getUid(strokeState.strokeStyle)) + + strokeState.lineCap + strokeState.lineDashOffset + '|' + strokeWidth + + strokeState.lineJoin + strokeState.miterLimit + + '[' + strokeState.lineDash.join() + ']' : '') + + textState.font + textAlign + text + + (fill ? + (typeof fillState.fillStyle == 'string' ? fillState.fillStyle : ('|' + ol.getUid(fillState.fillStyle))) : ''); + + var lines = text.split('\n'); + var numLines = lines.length; + + if (!ol.render.canvas.TextReplay.labelCache_.containsKey(key)) { + label = /** @type {HTMLCanvasElement} */ (document.createElement('canvas')); + ol.render.canvas.TextReplay.labelCache_.set(key, label); + var context = label.getContext('2d'); + var widths = []; + var metrics = ol.render.canvas.TextReplay.measureText(textState.font, lines, widths); + var lineHeight = metrics[1] / numLines; + label.width = Math.ceil(metrics[0] + 2 * strokeWidth) * pixelRatio; + label.height = Math.ceil(metrics[1] + 2 * strokeWidth) * pixelRatio; + context.scale(pixelRatio, pixelRatio); + context.font = textState.font; + if (stroke) { + context.strokeStyle = strokeState.strokeStyle; + context.lineWidth = strokeState.lineWidth; + context.lineCap = strokeState.lineCap; + context.lineJoin = strokeState.lineJoin; + context.miterLimit = strokeState.miterLimit; + if (ol.has.CANVAS_LINE_DASH) { + context.setLineDash(strokeState.lineDash); + context.lineDashOffset = strokeState.lineDashOffset; + } + } + if (fill) { + context.fillStyle = fillState.fillStyle; + } + context.textBaseline = 'top'; + context.textAlign = 'left'; + var x = align * label.width / pixelRatio + 2 * (0.5 - align) * strokeWidth; + var i; + if (stroke) { + for (i = 0; i < numLines; ++i) { + context.strokeText(lines[i], x - align * widths[i], strokeWidth + i * lineHeight); + } + } + if (fill) { + for (i = 0; i < numLines; ++i) { + context.fillText(lines[i], x - align * widths[i], strokeWidth + i * lineHeight); + } + } + } + label = ol.render.canvas.TextReplay.labelCache_.get(key); + + var anchorX = align * label.width / pixelRatio + 2 * (0.5 - align) * strokeWidth; + var anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth; + var drawTextInstruction = [ - ol.render.canvas.Instruction.DRAW_TEXT, myBegin, myEnd, this.text_, - this.textOffsetX_, this.textOffsetY_, this.textRotation_, this.textScale_, - fill, stroke, this.textRotateWithView_]; + ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, label, + anchorX - this.textOffsetX_ * pixelRatio, anchorY - this.textOffsetY_ * pixelRatio, + label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_, + this.textScale_ / pixelRatio, //FIXME missing HiDPI support in DRAW_IMAGE + true, label.width + ]; + this.instructions.push(drawTextInstruction); this.hitDetectionInstructions.push(drawTextInstruction); + this.endGeometry(geometry, feature); }; -/** - * @param {ol.CanvasFillState} fillState Fill state. - * @private - */ -ol.render.canvas.TextReplay.prototype.setReplayFillState_ = function(fillState) { - var replayFillState = this.replayFillState_; - if (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 (!replayFillState) { - this.replayFillState_ = { - fillStyle: fillState.fillStyle - }; - } else { - replayFillState.fillStyle = fillState.fillStyle; - } -}; - - -/** - * @param {ol.CanvasStrokeState} strokeState Stroke state. - * @private - */ -ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = function(strokeState) { - var replayStrokeState = this.replayStrokeState_; - if (replayStrokeState && - replayStrokeState.lineCap == strokeState.lineCap && - replayStrokeState.lineDash == strokeState.lineDash && - replayStrokeState.lineDashOffset == strokeState.lineDashOffset && - 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, strokeState.lineDashOffset, false, 1 - ]; - this.instructions.push(setStrokeStyleInstruction); - this.hitDetectionInstructions.push(setStrokeStyleInstruction); - if (!replayStrokeState) { - this.replayStrokeState_ = { - lineCap: strokeState.lineCap, - lineDash: strokeState.lineDash, - lineDashOffset: strokeState.lineDashOffset, - lineJoin: strokeState.lineJoin, - lineWidth: strokeState.lineWidth, - miterLimit: strokeState.miterLimit, - strokeStyle: strokeState.strokeStyle - }; - } else { - replayStrokeState.lineCap = strokeState.lineCap; - replayStrokeState.lineDash = strokeState.lineDash; - replayStrokeState.lineDashOffset = strokeState.lineDashOffset; - replayStrokeState.lineJoin = strokeState.lineJoin; - replayStrokeState.lineWidth = strokeState.lineWidth; - replayStrokeState.miterLimit = strokeState.miterLimit; - replayStrokeState.strokeStyle = strokeState.strokeStyle; - } -}; - - -/** - * @param {ol.CanvasTextState} textState Text state. - * @private - */ -ol.render.canvas.TextReplay.prototype.setReplayTextState_ = function(textState) { - var replayTextState = this.replayTextState_; - if (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 (!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 */ diff --git a/src/ol/render/replay.js b/src/ol/render/replay.js index 3737e5ef03..54744f6087 100644 --- a/src/ol/render/replay.js +++ b/src/ol/render/replay.js @@ -15,3 +15,21 @@ ol.render.replay.ORDER = [ ol.render.ReplayType.TEXT, ol.render.ReplayType.DEFAULT ]; + +/** + * @const + * @enum {number} + */ +ol.render.replay.TEXT_ALIGN = { + left: 0, + end: 0, + center: 0.5, + right: 1, + start: 1, + top: 0, + middle: 0.5, + hanging: 0.2, + alphabetic: 0.8, + ideographic: 0.8, + bottom: 1 +}; diff --git a/src/ol/render/webgl/textreplay.js b/src/ol/render/webgl/textreplay.js index f4fbca41ba..23fb5bbd2d 100644 --- a/src/ol/render/webgl/textreplay.js +++ b/src/ol/render/webgl/textreplay.js @@ -4,6 +4,7 @@ goog.require('ol'); goog.require('ol.colorlike'); goog.require('ol.dom'); goog.require('ol.has'); +goog.require('ol.render.replay'); goog.require('ol.render.webgl'); goog.require('ol.render.webgl.TextureReplay'); goog.require('ol.style.AtlasManager'); @@ -348,8 +349,8 @@ ol.render.webgl.TextReplay.prototype.setTextStyle = function(textStyle) { state.font = textStyle.getFont() || ol.render.webgl.defaultFont; state.scale = textStyle.getScale() || 1; this.text_ = /** @type {string} */ (textStyle.getText()); - var textAlign = ol.render.webgl.TextReplay.Align_[textStyle.getTextAlign()]; - var textBaseline = ol.render.webgl.TextReplay.Align_[textStyle.getTextBaseline()]; + var textAlign = ol.render.replay.TEXT_ALIGN[textStyle.getTextAlign()]; + var textBaseline = ol.render.replay.TEXT_ALIGN[textStyle.getTextBaseline()]; this.textAlign_ = textAlign === undefined ? ol.render.webgl.defaultTextAlign : textAlign; this.textBaseline_ = textBaseline === undefined ? @@ -430,22 +431,3 @@ ol.render.webgl.TextReplay.prototype.getTextures = function(opt_all) { ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() { return this.textures_; }; - - -/** - * @enum {number} - * @private - */ -ol.render.webgl.TextReplay.Align_ = { - left: 0, - end: 0, - center: 0.5, - right: 1, - start: 1, - top: 0, - middle: 0.5, - hanging: 0.2, - alphabetic: 0.8, - ideographic: 0.8, - bottom: 1 -}; diff --git a/src/ol/renderer/canvas/vectorlayer.js b/src/ol/renderer/canvas/vectorlayer.js index f494d0f9b8..8073052d9f 100644 --- a/src/ol/renderer/canvas/vectorlayer.js +++ b/src/ol/renderer/canvas/vectorlayer.js @@ -321,8 +321,8 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = function(frameState, lay this.dirty_ = false; var replayGroup = new ol.render.canvas.ReplayGroup( - ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, - resolution, vectorSource.getOverlaps(), vectorLayer.getRenderBuffer()); + ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, resolution, + pixelRatio, vectorSource.getOverlaps(), vectorLayer.getRenderBuffer()); vectorSource.loadFeatures(extent, resolution, projection); /** * @param {ol.Feature} feature Feature. diff --git a/src/ol/renderer/canvas/vectortilelayer.js b/src/ol/renderer/canvas/vectortilelayer.js index 995ed8a920..de0b30b621 100644 --- a/src/ol/renderer/canvas/vectortilelayer.js +++ b/src/ol/renderer/canvas/vectortilelayer.js @@ -167,7 +167,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function( } replayState.dirty = false; var replayGroup = new ol.render.canvas.ReplayGroup(0, sharedExtent, - resolution, source.getOverlaps(), layer.getRenderBuffer()); + resolution, pixelRatio, source.getOverlaps(), layer.getRenderBuffer()); var squaredTolerance = ol.renderer.vector.getSquaredTolerance( resolution, pixelRatio); diff --git a/src/ol/source/imagevector.js b/src/ol/source/imagevector.js index cad4e7e4a7..4dc6aa1963 100644 --- a/src/ol/source/imagevector.js +++ b/src/ol/source/imagevector.js @@ -113,7 +113,7 @@ ol.source.ImageVector.prototype.canvasFunctionInternal_ = function(extent, resol var replayGroup = new ol.render.canvas.ReplayGroup( ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, - resolution, this.source_.getOverlaps(), this.renderBuffer_); + resolution, pixelRatio, this.source_.getOverlaps(), this.renderBuffer_); this.source_.loadFeatures(extent, resolution, projection); diff --git a/src/ol/structs/lrucache.js b/src/ol/structs/lrucache.js index c0032e5d27..bdced622cc 100644 --- a/src/ol/structs/lrucache.js +++ b/src/ol/structs/lrucache.js @@ -10,8 +10,14 @@ goog.require('ol.asserts'); * @constructor * @struct * @template T + * @param {number=} opt_highWaterMark High water mark. */ -ol.structs.LRUCache = function() { +ol.structs.LRUCache = function(opt_highWaterMark) { + + /** + * @type {number} + */ + this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048; /** * @private @@ -40,6 +46,14 @@ ol.structs.LRUCache = function() { }; +/** + * @return {boolean} Can expire cache. + */ +ol.structs.LRUCache.prototype.canExpireCache = function() { + return this.getCount() > this.highWaterMark; +}; + + /** * FIXME empty description for jsdoc */ diff --git a/src/ol/tilecache.js b/src/ol/tilecache.js index 35c7fa42da..1ba7bbada9 100644 --- a/src/ol/tilecache.js +++ b/src/ol/tilecache.js @@ -12,25 +12,12 @@ goog.require('ol.structs.LRUCache'); */ ol.TileCache = function(opt_highWaterMark) { - ol.structs.LRUCache.call(this); - - /** - * @type {number} - */ - this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048; + ol.structs.LRUCache.call(this, opt_highWaterMark); }; ol.inherits(ol.TileCache, ol.structs.LRUCache); -/** - * @return {boolean} Can expire cache. - */ -ol.TileCache.prototype.canExpireCache = function() { - return this.getCount() > this.highWaterMark; -}; - - /** * @param {Object.} usedTiles Used tiles. */ diff --git a/test/spec/ol/renderer/canvas/replay.test.js b/test/spec/ol/renderer/canvas/replay.test.js index 96cda25469..bf208221d2 100644 --- a/test/spec/ol/renderer/canvas/replay.test.js +++ b/test/spec/ol/renderer/canvas/replay.test.js @@ -30,7 +30,7 @@ describe('ol.render.canvas.ReplayGroup', function() { beforeEach(function() { transform = ol.transform.create(); - replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, false); + replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, 1, false); feature0 = new ol.Feature(new ol.geom.Polygon( [[[-90, 0], [-45, 45], [0, 0], [1, 1], [0, -45], [-90, 0]]])); feature1 = new ol.Feature(new ol.geom.Polygon( @@ -174,7 +174,7 @@ describe('ol.render.canvas.ReplayGroup', function() { }); it('does not batch when overlaps is set to true', function() { - replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, true); + replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, 1, true); ol.renderer.vector.renderFeature(replay, feature1, style1, 1); ol.renderer.vector.renderFeature(replay, feature2, style1, 1); ol.renderer.vector.renderFeature(replay, feature3, style1, 1); @@ -240,7 +240,7 @@ describe('ol.render.canvas.ReplayGroup', function() { [polygon.getGeometry().getCoordinates(), polygon.getGeometry().getCoordinates()])); var geometrycollection = new ol.Feature(new ol.geom.GeometryCollection( [point.getGeometry(), linestring.getGeometry(), polygon.getGeometry()])); - replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, true); + replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, 1, true); ol.renderer.vector.renderFeature(replay, point, style, 1); ol.renderer.vector.renderFeature(replay, multipoint, style, 1); ol.renderer.vector.renderFeature(replay, linestring, style, 1); @@ -284,7 +284,7 @@ describe('ol.render.canvas.Replay', function() { it('creates a new replay batch', function() { var tolerance = 10; var extent = [-180, -90, 180, 90]; - var replay = new ol.render.canvas.Replay(tolerance, extent, 1, true); + var replay = new ol.render.canvas.Replay(tolerance, extent, 1, 1, true); expect(replay).to.be.a(ol.render.canvas.Replay); }); @@ -294,7 +294,7 @@ describe('ol.render.canvas.Replay', function() { var replay; beforeEach(function() { - replay = new ol.render.canvas.Replay(1, [-180, -90, 180, 90], 1, true); + replay = new ol.render.canvas.Replay(1, [-180, -90, 180, 90], 1, 1, true); }); it('appends coordinates that are within the max extent', function() { From 6469d3e86444ebeefdc096d679f6bc900dcba30d Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 31 Aug 2017 16:20:33 +0200 Subject: [PATCH 2/5] Handle pixelRatio on replay creation instead of replay --- src/ol/render/canvas/imagereplay.js | 2 +- src/ol/render/canvas/linestringreplay.js | 7 ++- src/ol/render/canvas/polygonreplay.js | 9 +-- src/ol/render/canvas/replay.js | 62 ++++++++++----------- src/ol/render/canvas/replaygroup.js | 6 +- src/ol/render/canvas/textreplay.js | 18 +++--- src/ol/renderer/canvas/vectorlayer.js | 9 +-- src/ol/renderer/canvas/vectortilelayer.js | 4 +- src/ol/source/imagevector.js | 2 +- test/spec/ol/renderer/canvas/replay.test.js | 27 +++++---- 10 files changed, 72 insertions(+), 74 deletions(-) diff --git a/src/ol/render/canvas/imagereplay.js b/src/ol/render/canvas/imagereplay.js index c0e1c7af76..8dc0ca37f0 100644 --- a/src/ol/render/canvas/imagereplay.js +++ b/src/ol/render/canvas/imagereplay.js @@ -132,7 +132,7 @@ ol.render.canvas.ImageReplay.prototype.drawPoint = function(pointGeometry, featu // Remaining arguments to DRAW_IMAGE are in alphabetical order this.anchorX_, this.anchorY_, this.height_, this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, - this.scale_, this.snapToPixel_, this.width_ + this.scale_ * this.pixelRatio, this.snapToPixel_, this.width_ ]); this.hitDetectionInstructions.push([ ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, diff --git a/src/ol/render/canvas/linestringreplay.js b/src/ol/render/canvas/linestringreplay.js index 7fd125aa83..fccaa66553 100644 --- a/src/ol/render/canvas/linestringreplay.js +++ b/src/ol/render/canvas/linestringreplay.js @@ -130,7 +130,8 @@ ol.render.canvas.LineStringReplay.prototype.setStrokeStyle_ = function() { state.lastStroke = 0; this.instructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, - strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, lineDashOffset, true, 1 + strokeStyle, lineWidth * this.pixelRatio, lineCap, lineJoin, miterLimit, + this.applyPixelRatio(lineDash), lineDashOffset * this.pixelRatio ], [ ol.render.canvas.Instruction.BEGIN_PATH ]); @@ -160,7 +161,7 @@ ol.render.canvas.LineStringReplay.prototype.drawLineString = function(lineString this.hitDetectionInstructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, - state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset ], [ ol.render.canvas.Instruction.BEGIN_PATH ]); @@ -187,7 +188,7 @@ ol.render.canvas.LineStringReplay.prototype.drawMultiLineString = function(multi this.hitDetectionInstructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, - state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset ], [ ol.render.canvas.Instruction.BEGIN_PATH ]); diff --git a/src/ol/render/canvas/polygonreplay.js b/src/ol/render/canvas/polygonreplay.js index 0aaccae4dc..273df81e22 100644 --- a/src/ol/render/canvas/polygonreplay.js +++ b/src/ol/render/canvas/polygonreplay.js @@ -142,7 +142,7 @@ ol.render.canvas.PolygonReplay.prototype.drawCircle = function(circleGeometry, f this.hitDetectionInstructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, - state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset ]); } var flatCoordinates = circleGeometry.getFlatCoordinates(); @@ -184,7 +184,7 @@ ol.render.canvas.PolygonReplay.prototype.drawPolygon = function(polygonGeometry, this.hitDetectionInstructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, - state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset ]); } var ends = polygonGeometry.getEnds(); @@ -216,7 +216,7 @@ ol.render.canvas.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygo this.hitDetectionInstructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, - state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset ]); } var endss = multiPolygonGeometry.getEndss(); @@ -353,7 +353,8 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function(geometr state.currentMiterLimit != miterLimit) { this.instructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, - strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, lineDashOffset, true, 1 + strokeStyle, lineWidth * this.pixelRatio, lineCap, lineJoin, miterLimit, + this.applyPixelRatio(lineDash), lineDashOffset * this.pixelRatio ]); state.currentStrokeStyle = strokeStyle; state.currentLineCap = lineCap; diff --git a/src/ol/render/canvas/replay.js b/src/ol/render/canvas/replay.js index 68539e4856..1af6291bfb 100644 --- a/src/ol/render/canvas/replay.js +++ b/src/ol/render/canvas/replay.js @@ -51,6 +51,7 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, pixelRatio, * @type {number} */ this.pixelRatio = pixelRatio; + /** * @protected * @type {number} @@ -133,6 +134,19 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, pixelRatio, ol.inherits(ol.render.canvas.Replay, ol.render.VectorContext); +/** + * @protected + * @param {Array.} dashArray Dash array. + * @return {Array.} Dash array with pixel ratio applied + */ +ol.render.canvas.Replay.prototype.applyPixelRatio = function(dashArray) { + var pixelRatio = this.pixelRatio; + return pixelRatio == 1 ? dashArray : dashArray.map(function(dash) { + return dash * pixelRatio; + }); +}; + + /** * @param {Array.} flatCoordinates Flat coordinates. * @param {number} offset Offset. @@ -293,7 +307,6 @@ ol.render.canvas.Replay.prototype.fill_ = function(context, rotation) { /** * @private * @param {CanvasRenderingContext2D} context Context. - * @param {number} pixelRatio Pixel ratio. * @param {ol.Transform} transform Transform. * @param {number} viewRotation View rotation. * @param {Object.} skippedFeaturesHash Ids of features @@ -307,7 +320,7 @@ ol.render.canvas.Replay.prototype.fill_ = function(context, rotation) { * @template T */ ol.render.canvas.Replay.prototype.replay_ = function( - context, pixelRatio, transform, viewRotation, skippedFeaturesHash, + context, transform, viewRotation, skippedFeaturesHash, instructions, featureCallback, opt_hitExtent) { /** @type {Array.} */ var pixelCoordinates; @@ -336,7 +349,7 @@ ol.render.canvas.Replay.prototype.replay_ = function( var state = /** @type {olx.render.State} */ ({ context: context, - pixelRatio: pixelRatio, + pixelRatio: this.pixelRatio, resolution: this.resolution, rotation: viewRotation }); @@ -422,16 +435,16 @@ ol.render.canvas.Replay.prototype.replay_ = function( dd = /** @type {number} */ (instruction[2]); var image = /** @type {HTMLCanvasElement|HTMLVideoElement|Image} */ (instruction[3]); + var scale = /** @type {number} */ (instruction[12]); // Remaining arguments in DRAW_IMAGE are in alphabetical order - var anchorX = /** @type {number} */ (instruction[4]) * pixelRatio; - var anchorY = /** @type {number} */ (instruction[5]) * pixelRatio; + var anchorX = /** @type {number} */ (instruction[4]) * scale; + var anchorY = /** @type {number} */ (instruction[5]) * scale; var height = /** @type {number} */ (instruction[6]); var opacity = /** @type {number} */ (instruction[7]); var originX = /** @type {number} */ (instruction[8]); var originY = /** @type {number} */ (instruction[9]); var rotateWithView = /** @type {boolean} */ (instruction[10]); var rotation = /** @type {number} */ (instruction[11]); - var scale = /** @type {number} */ (instruction[12]); var snapToPixel = /** @type {boolean} */ (instruction[13]); var width = /** @type {number} */ (instruction[14]); if (rotateWithView) { @@ -444,11 +457,11 @@ ol.render.canvas.Replay.prototype.replay_ = function( x = Math.round(x); y = Math.round(y); } - if (scale != 1 || rotation !== 0) { + if (rotation !== 0) { var centerX = x + anchorX; var centerY = y + anchorY; ol.transform.compose(localTransform, - centerX, centerY, scale, scale, rotation, -centerX, -centerY); + centerX, centerY, 1, 1, rotation, -centerX, -centerY); context.setTransform.apply(context, localTransform); } var alpha = context.globalAlpha; @@ -460,12 +473,12 @@ ol.render.canvas.Replay.prototype.replay_ = function( var h = (height + originY > image.height) ? image.height - originY : height; context.drawImage(image, originX, originY, w, h, - x, y, w * pixelRatio, h * pixelRatio); + x, y, w * scale, h * scale); if (opacity != 1) { context.globalAlpha = alpha; } - if (scale != 1 || rotation !== 0) { + if (rotation !== 0) { context.setTransform.apply(context, resetTransform); } } @@ -530,34 +543,18 @@ ol.render.canvas.Replay.prototype.replay_ = function( ++i; break; case ol.render.canvas.Instruction.SET_STROKE_STYLE: - var usePixelRatio = instruction[8] !== undefined ? - instruction[8] : true; - var renderedPixelRatio = instruction[9]; - - var lineWidth = /** @type {number} */ (instruction[2]); if (pendingStroke) { context.stroke(); pendingStroke = 0; } context.strokeStyle = /** @type {ol.ColorLike} */ (instruction[1]); - context.lineWidth = usePixelRatio ? lineWidth * pixelRatio : lineWidth; + context.lineWidth = /** @type {number} */ (instruction[2]); context.lineCap = /** @type {string} */ (instruction[3]); context.lineJoin = /** @type {string} */ (instruction[4]); context.miterLimit = /** @type {number} */ (instruction[5]); if (ol.has.CANVAS_LINE_DASH) { - var lineDash = /** @type {Array.} */ (instruction[6]); - var lineDashOffset = /** @type {number} */ (instruction[7]); - if (usePixelRatio && pixelRatio !== renderedPixelRatio) { - lineDash = lineDash.map(function(dash) { - return dash * pixelRatio / renderedPixelRatio; - }); - lineDashOffset *= pixelRatio / renderedPixelRatio; - instruction[6] = lineDash; - instruction[7] = lineDashOffset; - instruction[9] = pixelRatio; - } - context.lineDashOffset = lineDashOffset; - context.setLineDash(lineDash); + context.lineDashOffset = /** @type {number} */ (instruction[7]); + context.setLineDash(/** @type {Array.} */ (instruction[6])); } ++i; break; @@ -586,16 +583,15 @@ ol.render.canvas.Replay.prototype.replay_ = function( /** * @param {CanvasRenderingContext2D} context Context. - * @param {number} pixelRatio Pixel ratio. * @param {ol.Transform} transform Transform. * @param {number} viewRotation View rotation. * @param {Object.} skippedFeaturesHash Ids of features * to skip. */ ol.render.canvas.Replay.prototype.replay = function( - context, pixelRatio, transform, viewRotation, skippedFeaturesHash) { + context, transform, viewRotation, skippedFeaturesHash) { var instructions = this.instructions; - this.replay_(context, pixelRatio, transform, viewRotation, + this.replay_(context, transform, viewRotation, skippedFeaturesHash, instructions, undefined, undefined); }; @@ -617,7 +613,7 @@ ol.render.canvas.Replay.prototype.replayHitDetection = function( context, transform, viewRotation, skippedFeaturesHash, opt_featureCallback, opt_hitExtent) { var instructions = this.hitDetectionInstructions; - return this.replay_(context, 1, transform, viewRotation, + return this.replay_(context, transform, viewRotation, skippedFeaturesHash, instructions, opt_featureCallback, opt_hitExtent); }; diff --git a/src/ol/render/canvas/replaygroup.js b/src/ol/render/canvas/replaygroup.js index bda8170ebe..c110ddb8b7 100644 --- a/src/ol/render/canvas/replaygroup.js +++ b/src/ol/render/canvas/replaygroup.js @@ -320,7 +320,6 @@ ol.render.canvas.ReplayGroup.prototype.isEmpty = function() { /** * @param {CanvasRenderingContext2D} context Context. - * @param {number} pixelRatio Pixel ratio. * @param {ol.Transform} transform Transform. * @param {number} viewRotation View rotation. * @param {Object.} skippedFeaturesHash Ids of features @@ -328,7 +327,7 @@ ol.render.canvas.ReplayGroup.prototype.isEmpty = function() { * @param {Array.=} opt_replayTypes Ordered replay types * to replay. Default is {@link ol.render.replay.ORDER} */ -ol.render.canvas.ReplayGroup.prototype.replay = function(context, pixelRatio, +ol.render.canvas.ReplayGroup.prototype.replay = function(context, transform, viewRotation, skippedFeaturesHash, opt_replayTypes) { /** @type {Array.} */ @@ -353,8 +352,7 @@ ol.render.canvas.ReplayGroup.prototype.replay = function(context, pixelRatio, for (j = 0, jj = replayTypes.length; j < jj; ++j) { replay = replays[replayTypes[j]]; if (replay !== undefined) { - replay.replay(context, pixelRatio, transform, viewRotation, - skippedFeaturesHash); + replay.replay(context, transform, viewRotation, skippedFeaturesHash); } } } diff --git a/src/ol/render/canvas/textreplay.js b/src/ol/render/canvas/textreplay.js index 8bd81a7e9c..69682a0aa2 100644 --- a/src/ol/render/canvas/textreplay.js +++ b/src/ol/render/canvas/textreplay.js @@ -210,16 +210,18 @@ ol.render.canvas.TextReplay.prototype.drawText = function(flatCoordinates, offse var anchorX = align * label.width / pixelRatio + 2 * (0.5 - align) * strokeWidth; var anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth; - var drawTextInstruction = [ + this.instructions.push([ ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, label, - anchorX - this.textOffsetX_ * pixelRatio, anchorY - this.textOffsetY_ * pixelRatio, + (anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio, label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_, - this.textScale_ / pixelRatio, //FIXME missing HiDPI support in DRAW_IMAGE - true, label.width - ]; - - this.instructions.push(drawTextInstruction); - this.hitDetectionInstructions.push(drawTextInstruction); + this.textScale_, true, label.width + ]); + this.hitDetectionInstructions.push([ + ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, label, + (anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio, + label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_, + this.textScale_ / pixelRatio, true, label.width + ]); this.endGeometry(geometry, feature); }; diff --git a/src/ol/renderer/canvas/vectorlayer.js b/src/ol/renderer/canvas/vectorlayer.js index 8073052d9f..b900bf2131 100644 --- a/src/ol/renderer/canvas/vectorlayer.js +++ b/src/ol/renderer/canvas/vectorlayer.js @@ -157,8 +157,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay var height = frameState.size[1] * pixelRatio; ol.render.canvas.rotateAtOffset(replayContext, -rotation, width / 2, height / 2); - replayGroup.replay(replayContext, pixelRatio, transform, rotation, - skippedFeatureUids); + replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids); if (vectorSource.getWrapX() && projection.canWrapX() && !ol.extent.containsExtent(projectionExtent, extent)) { var startX = extent[0]; @@ -169,8 +168,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay --world; offsetX = worldWidth * world; transform = this.getTransform(frameState, offsetX); - replayGroup.replay(replayContext, pixelRatio, transform, rotation, - skippedFeatureUids); + replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids); startX += worldWidth; } world = 0; @@ -179,8 +177,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay ++world; offsetX = worldWidth * world; transform = this.getTransform(frameState, offsetX); - replayGroup.replay(replayContext, pixelRatio, transform, rotation, - skippedFeatureUids); + replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids); startX -= worldWidth; } // restore original transform for render and compose events diff --git a/src/ol/renderer/canvas/vectortilelayer.js b/src/ol/renderer/canvas/vectortilelayer.js index de0b30b621..b914fe7ccf 100644 --- a/src/ol/renderer/canvas/vectortilelayer.js +++ b/src/ol/renderer/canvas/vectortilelayer.js @@ -388,7 +388,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, fra context.clip(); } } - replayGroup.replay(context, pixelRatio, transform, rotation, {}, replays); + replayGroup.replay(context, transform, rotation, {}, replays); context.restore(); clips.push(currentClip); zs.push(currentZ); @@ -461,7 +461,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function( ol.transform.scale(transform, pixelScale, -pixelScale); ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]); var replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString()); - replayGroup.replay(context, pixelRatio, transform, 0, {}, replays, true); + replayGroup.replay(context, transform, 0, {}, replays, true); } } }; diff --git a/src/ol/source/imagevector.js b/src/ol/source/imagevector.js index 4dc6aa1963..68a4f8f565 100644 --- a/src/ol/source/imagevector.js +++ b/src/ol/source/imagevector.js @@ -143,7 +143,7 @@ ol.source.ImageVector.prototype.canvasFunctionInternal_ = function(extent, resol var transform = this.getTransform_(ol.extent.getCenter(extent), resolution, pixelRatio, size); - replayGroup.replay(this.canvasContext_, pixelRatio, transform, 0, {}); + replayGroup.replay(this.canvasContext_, transform, 0, {}); this.replayGroup_ = replayGroup; diff --git a/test/spec/ol/renderer/canvas/replay.test.js b/test/spec/ol/renderer/canvas/replay.test.js index bf208221d2..429a7d52c6 100644 --- a/test/spec/ol/renderer/canvas/replay.test.js +++ b/test/spec/ol/renderer/canvas/replay.test.js @@ -91,18 +91,18 @@ describe('ol.render.canvas.ReplayGroup', function() { it('omits lineTo for repeated coordinates', function() { ol.renderer.vector.renderFeature(replay, feature0, fill0, 1); - replay.replay(context, 1, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(lineToCount).to.be(4); lineToCount = 0; ol.transform.scale(transform, 0.25, 0.25); - replay.replay(context, 1, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(lineToCount).to.be(3); }); it('does not omit moveTo for repeated coordinates', function() { ol.renderer.vector.renderFeature(replay, feature0, fill0, 1); ol.renderer.vector.renderFeature(replay, feature1, fill1, 1); - replay.replay(context, 1, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(moveToCount).to.be(2); }); @@ -110,7 +110,7 @@ describe('ol.render.canvas.ReplayGroup', function() { ol.renderer.vector.renderFeature(replay, feature1, style1, 1); ol.renderer.vector.renderFeature(replay, feature2, style1, 1); ol.renderer.vector.renderFeature(replay, feature3, style1, 1); - replay.replay(context, 1, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(fillCount).to.be(1); expect(strokeCount).to.be(1); expect(beginPathCount).to.be(1); @@ -120,7 +120,7 @@ describe('ol.render.canvas.ReplayGroup', function() { ol.renderer.vector.renderFeature(replay, feature1, style1, 1); ol.renderer.vector.renderFeature(replay, feature2, style1, 1); ol.renderer.vector.renderFeature(replay, feature3, style2, 1); - replay.replay(context, 1, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(fillCount).to.be(2); expect(strokeCount).to.be(2); expect(beginPathCount).to.be(2); @@ -130,7 +130,7 @@ describe('ol.render.canvas.ReplayGroup', function() { ol.renderer.vector.renderFeature(replay, feature1, style1, 1); ol.renderer.vector.renderFeature(replay, feature2, style2, 1); ol.renderer.vector.renderFeature(replay, feature3, style1, 1); - replay.replay(context, 1, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(fillCount).to.be(3); expect(strokeCount).to.be(3); expect(beginPathCount).to.be(3); @@ -142,7 +142,7 @@ describe('ol.render.canvas.ReplayGroup', function() { ol.renderer.vector.renderFeature(replay, feature3, style2, 1); var skippedUids = {}; skippedUids[ol.getUid(feature1)] = true; - replay.replay(context, 1, transform, 0, skippedUids); + replay.replay(context, transform, 0, skippedUids); expect(fillCount).to.be(1); expect(strokeCount).to.be(1); expect(beginPathCount).to.be(1); @@ -154,7 +154,7 @@ describe('ol.render.canvas.ReplayGroup', function() { ol.renderer.vector.renderFeature(replay, feature3, style2, 1); var skippedUids = {}; skippedUids[ol.getUid(feature3)] = true; - replay.replay(context, 1, transform, 0, skippedUids); + replay.replay(context, transform, 0, skippedUids); expect(fillCount).to.be(1); expect(strokeCount).to.be(1); expect(beginPathCount).to.be(1); @@ -167,7 +167,7 @@ describe('ol.render.canvas.ReplayGroup', function() { var skippedUids = {}; skippedUids[ol.getUid(feature1)] = true; skippedUids[ol.getUid(feature2)] = true; - replay.replay(context, 1, transform, 0, skippedUids); + replay.replay(context, transform, 0, skippedUids); expect(fillCount).to.be(1); expect(strokeCount).to.be(1); expect(beginPathCount).to.be(1); @@ -178,13 +178,16 @@ describe('ol.render.canvas.ReplayGroup', function() { ol.renderer.vector.renderFeature(replay, feature1, style1, 1); ol.renderer.vector.renderFeature(replay, feature2, style1, 1); ol.renderer.vector.renderFeature(replay, feature3, style1, 1); - replay.replay(context, 1, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(fillCount).to.be(3); expect(strokeCount).to.be(3); expect(beginPathCount).to.be(3); }); it('applies the pixelRatio to the linedash array and offset', function() { + // replay with a pixelRatio of 2 + replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, 2, true); + var lineDash, lineDashCount = 0, lineDashOffset, lineDashOffsetCount = 0; @@ -202,7 +205,7 @@ describe('ol.render.canvas.ReplayGroup', function() { ol.renderer.vector.renderFeature(replay, feature1, style2, 1); ol.renderer.vector.renderFeature(replay, feature2, style2, 1); - replay.replay(context, 2, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(lineDashCount).to.be(1); expect(style2.getStroke().getLineDash()).to.eql([3, 6]); @@ -249,7 +252,7 @@ describe('ol.render.canvas.ReplayGroup', function() { ol.renderer.vector.renderFeature(replay, multipolygon, style, 1); ol.renderer.vector.renderFeature(replay, geometrycollection, style, 1); ol.transform.scale(transform, 0.1, 0.1); - replay.replay(context, 1, transform, 0, {}); + replay.replay(context, transform, 0, {}); expect(calls.length).to.be(9); expect(calls[0].geometry).to.be(point.getGeometry()); expect(calls[0].feature).to.be(point); From b5966b8ff3b58472ca92a9fb1d0283b94a5806b8 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 31 Aug 2017 21:51:36 +0200 Subject: [PATCH 3/5] Add more text style tests --- .../expected/text-align-offset-canvas.png | Bin 0 -> 8317 bytes test/rendering/ol/style/text.test.js | 88 ++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 test/rendering/ol/style/expected/text-align-offset-canvas.png diff --git a/test/rendering/ol/style/expected/text-align-offset-canvas.png b/test/rendering/ol/style/expected/text-align-offset-canvas.png new file mode 100644 index 0000000000000000000000000000000000000000..92b38dcbf9d084c4d06757941db23630e96387dc GIT binary patch literal 8317 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

p$dB0{l; zT6rL}QX2@;&BGsyI*z-UfZSY7>n3zpy0vJCDOBbczvkJ2yJxSC40{R*mx7a+lVfDvK4`ZL)WticU%3O1trl;VGijJmYvm9_v zOCsRE6L!m-rs`bG&1YaS^J2h9b9J@EJY80o;||(>&TqS*7QGN+c^wn;M?7X|$X3W~ zs^Uo>@6)3W^i59H#LCWcH)aqswX-c;tq1|Bsm8dKkwgr*na{_%gc-?$;OT#ZS6iv2 z@@ce#_QZ`Dy&<3hvaj+ytwh2+cpz~V>6v^73_nJLoZW-Y-~me*Ub2T46nMU;3DzrO z;6aQ+7mE!Hyo&$FF2^tV{#Wpk0I|Q%0{lDK|38?iGg Date: Fri, 1 Sep 2017 13:56:14 +0200 Subject: [PATCH 4/5] Remove unnecessary array creation --- src/ol/renderer/canvas/vectortilelayer.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ol/renderer/canvas/vectortilelayer.js b/src/ol/renderer/canvas/vectortilelayer.js index b914fe7ccf..23474f5711 100644 --- a/src/ol/renderer/canvas/vectortilelayer.js +++ b/src/ol/renderer/canvas/vectortilelayer.js @@ -187,9 +187,6 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function( } } if (styles) { - if (!Array.isArray(styles)) { - styles = [styles]; - } var dirty = this.renderFeature(feature, squaredTolerance, styles, replayGroup); this.dirty_ = this.dirty_ || dirty; From 56a7f9f027e7b742957a2c618a7b7f7390bce1a2 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Fri, 1 Sep 2017 16:44:27 +0200 Subject: [PATCH 5/5] Help the compiler understand --- src/ol/render/replay.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/ol/render/replay.js b/src/ol/render/replay.js index 54744f6087..3827508289 100644 --- a/src/ol/render/replay.js +++ b/src/ol/render/replay.js @@ -20,16 +20,15 @@ ol.render.replay.ORDER = [ * @const * @enum {number} */ -ol.render.replay.TEXT_ALIGN = { - left: 0, - end: 0, - center: 0.5, - right: 1, - start: 1, - top: 0, - middle: 0.5, - hanging: 0.2, - alphabetic: 0.8, - ideographic: 0.8, - bottom: 1 -}; +ol.render.replay.TEXT_ALIGN = {}; +ol.render.replay.TEXT_ALIGN['left'] = 0; +ol.render.replay.TEXT_ALIGN['end'] = 0; +ol.render.replay.TEXT_ALIGN['center'] = 0.5; +ol.render.replay.TEXT_ALIGN['right'] = 1; +ol.render.replay.TEXT_ALIGN['start'] = 1; +ol.render.replay.TEXT_ALIGN['top'] = 0; +ol.render.replay.TEXT_ALIGN['middle'] = 0.5; +ol.render.replay.TEXT_ALIGN['hanging'] = 0.2; +ol.render.replay.TEXT_ALIGN['alphabetic'] = 0.8; +ol.render.replay.TEXT_ALIGN['ideographic'] = 0.8; +ol.render.replay.TEXT_ALIGN['bottom'] = 1;