diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index b907b04eb5..cacf01d346 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -1196,7 +1196,9 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution) { * lineDash: Array., * lineJoin: (string|undefined), * lineWidth: (number|undefined), - * miterLimit: (number|undefined)}|null} + * miterLimit: (number|undefined), + * pendingFill: number, + * pendingStroke: number}|null} */ this.state_ = { currentFillStyle: undefined, @@ -1212,7 +1214,9 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution) { lineDash: null, lineJoin: undefined, lineWidth: undefined, - miterLimit: undefined + miterLimit: undefined, + pendingFill: 0, + pendingStroke: 0 }; }; @@ -1229,8 +1233,13 @@ goog.inherits(ol.render.canvas.PolygonReplay, ol.render.canvas.Replay); */ ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = function(flatCoordinates, offset, ends, stride) { var state = this.state_; + if (state.pendingFill > 200 || state.pendingStroke > 200) { + this.fillStroke_(); + } var beginPathInstruction = [ol.render.canvas.Instruction.BEGIN_PATH]; - this.instructions.push(beginPathInstruction); + if (!state.pendingFill && !state.pendingStroke) { + this.instructions.push(beginPathInstruction); + } this.hitDetectionInstructions.push(beginPathInstruction); var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { @@ -1246,19 +1255,15 @@ ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = function(flatCo closePathInstruction); offset = end; } - // FIXME is it quicker to fill and stroke each polygon individually, - // FIXME or all polygons together? - var fillInstruction = [ol.render.canvas.Instruction.FILL]; - this.hitDetectionInstructions.push(fillInstruction); + this.hitDetectionInstructions.push([ol.render.canvas.Instruction.FILL]); if (state.fillStyle !== undefined) { - this.instructions.push(fillInstruction); + state.pendingFill++; } if (state.strokeStyle !== undefined) { goog.asserts.assert(state.lineWidth !== undefined, 'state.lineWidth should be defined'); - var strokeInstruction = [ol.render.canvas.Instruction.STROKE]; - this.instructions.push(strokeInstruction); - this.hitDetectionInstructions.push(strokeInstruction); + state.pendingStroke++; + this.hitDetectionInstructions.push([ol.render.canvas.Instruction.STROKE]); } return offset; }; @@ -1298,19 +1303,20 @@ ol.render.canvas.PolygonReplay.prototype.drawCircle = function(circleGeometry, f flatCoordinates, 0, flatCoordinates.length, stride, false); var beginPathInstruction = [ol.render.canvas.Instruction.BEGIN_PATH]; var circleInstruction = [ol.render.canvas.Instruction.CIRCLE, myBegin]; - this.instructions.push(beginPathInstruction, circleInstruction); - this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction); - var fillInstruction = [ol.render.canvas.Instruction.FILL]; - this.hitDetectionInstructions.push(fillInstruction); + if (!state.pendingFill && !state.pendingStroke) { + this.instructions.push(beginPathInstruction); + } + this.instructions.push(circleInstruction); + this.hitDetectionInstructions.push(circleInstruction, beginPathInstruction); + this.hitDetectionInstructions.push([ol.render.canvas.Instruction.FILL]); if (state.fillStyle !== undefined) { - this.instructions.push(fillInstruction); + state.pendingFill++; } if (state.strokeStyle !== undefined) { goog.asserts.assert(state.lineWidth !== undefined, 'state.lineWidth should be defined'); - var strokeInstruction = [ol.render.canvas.Instruction.STROKE]; - this.instructions.push(strokeInstruction); - this.hitDetectionInstructions.push(strokeInstruction); + state.pendingStroke++; + this.hitDetectionInstructions.push([ol.render.canvas.Instruction.STROKE]); } this.endGeometry(circleGeometry, feature); }; @@ -1391,13 +1397,28 @@ ol.render.canvas.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygo }; +/** + * @private + */ +ol.render.canvas.PolygonReplay.prototype.fillStroke_ = function() { + var state = this.state_; + if (state.pendingFill) { + this.instructions.push([ol.render.canvas.Instruction.FILL]); + state.pendingFill = 0; + } + if (state.pendingStroke) { + this.instructions.push([ol.render.canvas.Instruction.STROKE]); + state.pendingStroke = 0; + } +}; + + /** * @inheritDoc */ ol.render.canvas.PolygonReplay.prototype.finish = function() { goog.asserts.assert(this.state_, 'this.state_ should not be null'); this.reverseHitDetectionInstructions_(); - this.state_ = null; // We want to preserve topology when drawing polygons. Polygons are // simplified using quantization and point elimination. However, we might // have received a mix of quantized and non-quantized geometries, so ensure @@ -1410,6 +1431,8 @@ ol.render.canvas.PolygonReplay.prototype.finish = function() { coordinates[i] = ol.geom.flat.simplify.snap(coordinates[i], tolerance); } } + this.fillStroke_(); + this.state_ = null; }; @@ -1492,6 +1515,7 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() { var lineWidth = state.lineWidth; var miterLimit = state.miterLimit; if (fillStyle !== undefined && state.currentFillStyle != fillStyle) { + this.fillStroke_(); this.instructions.push( [ol.render.canvas.Instruction.SET_FILL_STYLE, fillStyle]); state.currentFillStyle = state.fillStyle; @@ -1509,6 +1533,7 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() { state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) { + this.fillStroke_(); this.instructions.push( [ol.render.canvas.Instruction.SET_STROKE_STYLE, strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash]);