diff --git a/src/ol/render/canvas/imagereplay.js b/src/ol/render/canvas/imagereplay.js index 86ef562ce2..3d14617a3a 100644 --- a/src/ol/render/canvas/imagereplay.js +++ b/src/ol/render/canvas/imagereplay.js @@ -109,7 +109,7 @@ ol.inherits(ol.render.canvas.ImageReplay, ol.render.canvas.Replay); */ ol.render.canvas.ImageReplay.prototype.drawCoordinates_ = function(flatCoordinates, offset, end, stride) { return this.appendFlatCoordinates( - flatCoordinates, offset, end, stride, false); + flatCoordinates, offset, end, stride, false, false); }; diff --git a/src/ol/render/canvas/linestringreplay.js b/src/ol/render/canvas/linestringreplay.js index b0aa86c0fa..83ccbc483b 100644 --- a/src/ol/render/canvas/linestringreplay.js +++ b/src/ol/render/canvas/linestringreplay.js @@ -75,7 +75,7 @@ ol.inherits(ol.render.canvas.LineStringReplay, ol.render.canvas.Replay); ol.render.canvas.LineStringReplay.prototype.drawFlatCoordinates_ = function(flatCoordinates, offset, end, stride) { var myBegin = this.coordinates.length; var myEnd = this.appendFlatCoordinates( - flatCoordinates, offset, end, stride, false); + flatCoordinates, offset, end, stride, false, false); var moveToLineToInstruction = [ol.render.canvas.Instruction.MOVE_TO_LINE_TO, myBegin, myEnd]; this.instructions.push(moveToLineToInstruction); diff --git a/src/ol/render/canvas/polygonreplay.js b/src/ol/render/canvas/polygonreplay.js index d5f5c76ce2..5d93591df8 100644 --- a/src/ol/render/canvas/polygonreplay.js +++ b/src/ol/render/canvas/polygonreplay.js @@ -87,7 +87,7 @@ ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = function(flatCo var end = ends[i]; var myBegin = this.coordinates.length; var myEnd = this.appendFlatCoordinates( - flatCoordinates, offset, end, stride, true); + flatCoordinates, offset, end, stride, true, !stroke); var moveToLineToInstruction = [ol.render.canvas.Instruction.MOVE_TO_LINE_TO, myBegin, myEnd]; this.instructions.push(moveToLineToInstruction); @@ -148,7 +148,7 @@ ol.render.canvas.PolygonReplay.prototype.drawCircle = function(circleGeometry, f var stride = circleGeometry.getStride(); var myBegin = this.coordinates.length; this.appendFlatCoordinates( - flatCoordinates, 0, flatCoordinates.length, stride, false); + flatCoordinates, 0, flatCoordinates.length, stride, false, false); var beginPathInstruction = [ol.render.canvas.Instruction.BEGIN_PATH]; var circleInstruction = [ol.render.canvas.Instruction.CIRCLE, myBegin]; this.instructions.push(beginPathInstruction, circleInstruction); diff --git a/src/ol/render/canvas/replay.js b/src/ol/render/canvas/replay.js index c092ebe04e..2136448a2b 100644 --- a/src/ol/render/canvas/replay.js +++ b/src/ol/render/canvas/replay.js @@ -120,14 +120,18 @@ ol.inherits(ol.render.canvas.Replay, ol.render.VectorContext); * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. - * @param {boolean} close Close. + * @param {boolean} closed Last input coordinate equals first. + * @param {boolean} skipFirst Skip first coordinate. * @protected * @return {number} My end. */ -ol.render.canvas.Replay.prototype.appendFlatCoordinates = function(flatCoordinates, offset, end, stride, close) { +ol.render.canvas.Replay.prototype.appendFlatCoordinates = function(flatCoordinates, offset, end, stride, closed, skipFirst) { var myEnd = this.coordinates.length; var extent = this.getBufferedMaxExtent(); + if (skipFirst) { + offset += stride; + } var lastCoord = [flatCoordinates[offset], flatCoordinates[offset + 1]]; var nextCoord = [NaN, NaN]; var skipped = true; @@ -157,8 +161,8 @@ ol.render.canvas.Replay.prototype.appendFlatCoordinates = function(flatCoordinat lastRel = nextRel; } - // When we want to close or there is only one point to append: - if ((close && skipped) || i === offset + stride) { + // Last coordinate equals first or only one point to append: + if ((closed && skipped) || i === offset + stride) { this.coordinates[myEnd++] = lastCoord[0]; this.coordinates[myEnd++] = lastCoord[1]; } diff --git a/src/ol/render/canvas/textreplay.js b/src/ol/render/canvas/textreplay.js index 7453382063..ba2794f6b4 100644 --- a/src/ol/render/canvas/textreplay.js +++ b/src/ol/render/canvas/textreplay.js @@ -115,7 +115,7 @@ ol.render.canvas.TextReplay.prototype.drawText = function(flatCoordinates, offse this.beginGeometry(geometry, feature); var myBegin = this.coordinates.length; var myEnd = - this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false); + this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false, false); var fill = !!this.textFillState_; var stroke = !!this.textStrokeState_; var drawTextInstruction = [ diff --git a/test/spec/ol/renderer/canvas/replay.test.js b/test/spec/ol/renderer/canvas/replay.test.js index 493d538dea..68ee494d1c 100644 --- a/test/spec/ol/renderer/canvas/replay.test.js +++ b/test/spec/ol/renderer/canvas/replay.test.js @@ -165,19 +165,25 @@ describe('ol.render.canvas.Replay', function() { it('appends coordinates that are within the max extent', function() { var flat = [-110, 45, 110, 45, 110, -45, -110, -45]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql(flat); }); it('appends polygon coordinates that are within the max extent', function() { var flat = [-110, 45, 110, 45, 110, -45, -110, -45, -110, 45]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, true); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false); expect(replay.coordinates).to.eql(flat); }); + it('appends polygon coordinates that are within the max extent (skipping first)', function() { + var flat = [-110, 45, 110, 45, 110, -45, -110, -45, -110, 45]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true); + expect(replay.coordinates).to.eql([110, 45, 110, -45, -110, -45, -110, 45]); + }); + it('works with a single coordinate (inside)', function() { var flat = [-110, 45]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql(flat); }); @@ -185,7 +191,7 @@ describe('ol.render.canvas.Replay', function() { // this could be changed, but to make the code simpler for properly // closing rings, we always add the first point var flat = [-110, 145]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql(flat); }); @@ -193,21 +199,27 @@ describe('ol.render.canvas.Replay', function() { // this could be changed, but to make the code simpler for properly // closing rings, we always add the first point var flat = [-110, 145, -110, 145]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, true); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false); expect(replay.coordinates).to.eql(flat); }); + it('skips first polygon vertex upon request (also when outside)', function() { + var flat = [-110, 145, -110, 145]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true); + expect(replay.coordinates).to.eql([-110, 145]); + }); + it('appends points when segments cross (top to bottom)', function() { // this means we get a few extra points when coordinates are not // part of a linestring or ring, but only a few extra var flat = [0, 200, 0, -200]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql(flat); }); it('appends points when segments cross (top to inside)', function() { var flat = [0, 200, 0, 0]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql(flat); }); @@ -215,7 +227,7 @@ describe('ol.render.canvas.Replay', function() { // this could be changed, but to make the code simpler for properly // closing rings, we always add the first segment var flat = [-10, 200, 10, 200]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql(flat); }); @@ -223,46 +235,70 @@ describe('ol.render.canvas.Replay', function() { // this could be changed, but to make the code simpler for properly // closing rings, we always add the first segment var flat = [-10, 200, 10, 200, -10, 200]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, true); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false); expect(replay.coordinates).to.eql(flat); }); + it('skips first polygon segment upon request (also when outside)', function() { + var flat = [-10, 200, 10, 200, -10, 200]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true); + expect(replay.coordinates).to.eql([10, 200, -10, 200]); + }); + it('eliminates segments outside (and not changing rel)', function() { var flat = [0, 0, 0, 200, 5, 200, 10, 200]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql([0, 0, 0, 200]); }); it('eliminates polygon segments outside (and not changing rel)', function() { var flat = [0, 0, 0, 200, 5, 200, 10, 200, 0, 0]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, true); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false); expect(replay.coordinates).to.eql([0, 0, 0, 200, 10, 200, 0, 0]); }); + it('eliminates polygon segments outside (skipping first and not changing rel)', function() { + var flat = [0, 0, 0, 10, 0, 200, 5, 200, 10, 200, 0, 0]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true); + expect(replay.coordinates).to.eql([0, 10, 0, 200, 10, 200, 0, 0]); + }); + it('eliminates segments outside (and not changing rel)', function() { var flat = [0, 0, 0, 200, 10, 200]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql([0, 0, 0, 200]); }); it('includes polygon segments outside (and not changing rel) when on last segment', function() { var flat = [0, 0, 0, 200, 10, 200, 0, 0]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, true); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false); expect(replay.coordinates).to.eql(flat); }); + it('includes polygon segments outside (skipping first and not changing rel) when on last segment', function() { + var flat = [0, 0, 0, 200, 10, 200, 0, 0]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true); + expect(replay.coordinates).to.eql([0, 200, 10, 200, 0, 0]); + }); + it('includes outside segments that change relationship', function() { var flat = [0, 0, 0, 200, 200, 200, 250, 200]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, false); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, false, false); expect(replay.coordinates).to.eql([0, 0, 0, 200, 200, 200]); }); it('includes outside polygon segments that change relationship when on last segment', function() { var flat = [0, 0, 0, 200, 200, 200, 250, 200, 0, 0]; - replay.appendFlatCoordinates(flat, 0, flat.length, 2, true); + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, false); expect(replay.coordinates).to.eql(flat); }); + it('includes outside polygon segments that change relationship when on last segment (when skipping first)', function() { + var flat = [0, 0, 0, 200, 200, 200, 250, 200, 0, 0]; + replay.appendFlatCoordinates(flat, 0, flat.length, 2, true, true); + expect(replay.coordinates).to.eql([0, 200, 200, 200, 250, 200, 0, 0]); + }); + }); });