diff --git a/externs/olx.js b/externs/olx.js index 53d33fedda..a07c80774f 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -7145,6 +7145,7 @@ olx.style.RegularShapeOptions.prototype.atlasManager; * lineCap: (string|undefined), * lineJoin: (string|undefined), * lineDash: (Array.|undefined), + * lineDashOffset: (number|undefined), * miterLimit: (number|undefined), * width: (number|undefined)}} */ @@ -7191,6 +7192,14 @@ olx.style.StrokeOptions.prototype.lineJoin; olx.style.StrokeOptions.prototype.lineDash; +/** + * Line dash offset. Default is '0'. + * @type {number|undefined} + * @api + */ +olx.style.StrokeOptions.prototype.lineDashOffset; + + /** * Miter limit. Default is `10`. * @type {number|undefined} diff --git a/src/ol/render/canvas.js b/src/ol/render/canvas.js index 8b8d5fcf5d..8384b2e952 100644 --- a/src/ol/render/canvas.js +++ b/src/ol/render/canvas.js @@ -29,6 +29,13 @@ ol.render.canvas.defaultLineCap = 'round'; ol.render.canvas.defaultLineDash = []; +/** + * @const + * @type {number} + */ +ol.render.canvas.defaultLineDashOffset = 0; + + /** * @const * @type {string} diff --git a/src/ol/render/canvas/immediate.js b/src/ol/render/canvas/immediate.js index ca29ebe329..757b24bce5 100644 --- a/src/ol/render/canvas/immediate.js +++ b/src/ol/render/canvas/immediate.js @@ -819,6 +819,7 @@ ol.render.canvas.Immediate.prototype.setFillStrokeStyle = function(fillStyle, st var strokeStyleColor = strokeStyle.getColor(); var strokeStyleLineCap = strokeStyle.getLineCap(); var strokeStyleLineDash = strokeStyle.getLineDash(); + var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset(); var strokeStyleLineJoin = strokeStyle.getLineJoin(); var strokeStyleWidth = strokeStyle.getWidth(); var strokeStyleMiterLimit = strokeStyle.getMiterLimit(); @@ -827,6 +828,8 @@ ol.render.canvas.Immediate.prototype.setFillStrokeStyle = function(fillStyle, st strokeStyleLineCap : ol.render.canvas.defaultLineCap, lineDash: strokeStyleLineDash ? strokeStyleLineDash : ol.render.canvas.defaultLineDash, + lineDashOffset: strokeStyleLineDashOffset ? + strokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset, lineJoin: strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : ol.render.canvas.defaultLineJoin, lineWidth: this.pixelRatio_ * (strokeStyleWidth !== undefined ? @@ -898,6 +901,7 @@ ol.render.canvas.Immediate.prototype.setTextStyle = function(textStyle) { var textStrokeStyleColor = textStrokeStyle.getColor(); var textStrokeStyleLineCap = textStrokeStyle.getLineCap(); var textStrokeStyleLineDash = textStrokeStyle.getLineDash(); + var textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset(); var textStrokeStyleLineJoin = textStrokeStyle.getLineJoin(); var textStrokeStyleWidth = textStrokeStyle.getWidth(); var textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit(); @@ -906,6 +910,8 @@ ol.render.canvas.Immediate.prototype.setTextStyle = function(textStyle) { textStrokeStyleLineCap : ol.render.canvas.defaultLineCap, lineDash: textStrokeStyleLineDash ? textStrokeStyleLineDash : ol.render.canvas.defaultLineDash, + lineDashOffset: textStrokeStyleLineDashOffset ? + textStrokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset, lineJoin: textStrokeStyleLineJoin !== undefined ? textStrokeStyleLineJoin : ol.render.canvas.defaultLineJoin, lineWidth: textStrokeStyleWidth !== undefined ? diff --git a/src/ol/render/canvas/linestringreplay.js b/src/ol/render/canvas/linestringreplay.js index f995be8512..5814f7f974 100644 --- a/src/ol/render/canvas/linestringreplay.js +++ b/src/ol/render/canvas/linestringreplay.js @@ -33,6 +33,7 @@ ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, o * @type {{currentStrokeStyle: (ol.ColorLike|undefined), * currentLineCap: (string|undefined), * currentLineDash: Array., + * currentLineDashOffset: (number|undefined), * currentLineJoin: (string|undefined), * currentLineWidth: (number|undefined), * currentMiterLimit: (number|undefined), @@ -40,6 +41,7 @@ ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, o * strokeStyle: (ol.ColorLike|undefined), * lineCap: (string|undefined), * lineDash: Array., + * lineDashOffset: (number|undefined), * lineJoin: (string|undefined), * lineWidth: (number|undefined), * miterLimit: (number|undefined)}|null} @@ -48,6 +50,7 @@ ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, o currentStrokeStyle: undefined, currentLineCap: undefined, currentLineDash: null, + currentLineDashOffset: undefined, currentLineJoin: undefined, currentLineWidth: undefined, currentMiterLimit: undefined, @@ -55,6 +58,7 @@ ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, o strokeStyle: undefined, lineCap: undefined, lineDash: null, + lineDashOffset: undefined, lineJoin: undefined, lineWidth: undefined, miterLimit: undefined @@ -107,12 +111,14 @@ ol.render.canvas.LineStringReplay.prototype.setStrokeStyle_ = function() { var strokeStyle = state.strokeStyle; var lineCap = state.lineCap; var lineDash = state.lineDash; + var lineDashOffset = state.lineDashOffset; var lineJoin = state.lineJoin; var lineWidth = state.lineWidth; var miterLimit = state.miterLimit; if (state.currentStrokeStyle != strokeStyle || state.currentLineCap != lineCap || !ol.array.equals(state.currentLineDash, lineDash) || + state.currentLineDashOffset != lineDashOffset || state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) { @@ -122,13 +128,14 @@ ol.render.canvas.LineStringReplay.prototype.setStrokeStyle_ = function() { } this.instructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, - strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, true, 1 + strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, lineDashOffset, true, 1 ], [ ol.render.canvas.Instruction.BEGIN_PATH ]); state.currentStrokeStyle = strokeStyle; state.currentLineCap = lineCap; state.currentLineDash = lineDash; + state.currentLineDashOffset = lineDashOffset; state.currentLineJoin = lineJoin; state.currentLineWidth = lineWidth; state.currentMiterLimit = miterLimit; @@ -151,7 +158,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, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 ], [ ol.render.canvas.Instruction.BEGIN_PATH ]); @@ -178,7 +185,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, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 ], [ ol.render.canvas.Instruction.BEGIN_PATH ]); @@ -222,6 +229,9 @@ ol.render.canvas.LineStringReplay.prototype.setFillStrokeStyle = function(fillSt var strokeStyleLineDash = strokeStyle.getLineDash(); this.state_.lineDash = strokeStyleLineDash ? strokeStyleLineDash : ol.render.canvas.defaultLineDash; + var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset(); + this.state_.lineDashOffset = strokeStyleLineDashOffset ? + strokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset; var strokeStyleLineJoin = strokeStyle.getLineJoin(); this.state_.lineJoin = strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : ol.render.canvas.defaultLineJoin; diff --git a/src/ol/render/canvas/polygonreplay.js b/src/ol/render/canvas/polygonreplay.js index 52165fb6d4..42f317c0fd 100644 --- a/src/ol/render/canvas/polygonreplay.js +++ b/src/ol/render/canvas/polygonreplay.js @@ -36,6 +36,7 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, over * currentStrokeStyle: (ol.ColorLike|undefined), * currentLineCap: (string|undefined), * currentLineDash: Array., + * currentLineDashOffset: (number|undefined), * currentLineJoin: (string|undefined), * currentLineWidth: (number|undefined), * currentMiterLimit: (number|undefined), @@ -43,6 +44,7 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, over * strokeStyle: (ol.ColorLike|undefined), * lineCap: (string|undefined), * lineDash: Array., + * lineDashOffset: (number|undefined), * lineJoin: (string|undefined), * lineWidth: (number|undefined), * miterLimit: (number|undefined)}|null} @@ -52,6 +54,7 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, over currentStrokeStyle: undefined, currentLineCap: undefined, currentLineDash: null, + currentLineDashOffset: undefined, currentLineJoin: undefined, currentLineWidth: undefined, currentMiterLimit: undefined, @@ -59,6 +62,7 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, over strokeStyle: undefined, lineCap: undefined, lineDash: null, + lineDashOffset: undefined, lineJoin: undefined, lineWidth: undefined, miterLimit: undefined @@ -137,7 +141,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, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 ]); } var flatCoordinates = circleGeometry.getFlatCoordinates(); @@ -179,7 +183,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, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 ]); } var ends = polygonGeometry.getEnds(); @@ -211,7 +215,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, true, 1 + state.miterLimit, state.lineDash, state.lineDashOffset, true, 1 ]); } var endss = multiPolygonGeometry.getEndss(); @@ -285,6 +289,9 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle var strokeStyleLineDash = strokeStyle.getLineDash(); state.lineDash = strokeStyleLineDash ? strokeStyleLineDash.slice() : ol.render.canvas.defaultLineDash; + var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset(); + state.lineDashOffset = strokeStyleLineDashOffset ? + strokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset; var strokeStyleLineJoin = strokeStyle.getLineJoin(); state.lineJoin = strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : ol.render.canvas.defaultLineJoin; @@ -304,6 +311,7 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle state.strokeStyle = undefined; state.lineCap = undefined; state.lineDash = null; + state.lineDashOffset = undefined; state.lineJoin = undefined; state.lineWidth = undefined; state.miterLimit = undefined; @@ -321,6 +329,7 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function(geometr var strokeStyle = state.strokeStyle; var lineCap = state.lineCap; var lineDash = state.lineDash; + var lineDashOffset = state.lineDashOffset; var lineJoin = state.lineJoin; var lineWidth = state.lineWidth; var miterLimit = state.miterLimit; @@ -337,16 +346,18 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function(geometr if (state.currentStrokeStyle != strokeStyle || state.currentLineCap != lineCap || !ol.array.equals(state.currentLineDash, lineDash) || + state.currentLineDashOffset != lineDashOffset || state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) { this.instructions.push([ ol.render.canvas.Instruction.SET_STROKE_STYLE, - strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, true, 1 + strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, lineDashOffset, true, 1 ]); state.currentStrokeStyle = strokeStyle; state.currentLineCap = lineCap; state.currentLineDash = lineDash; + state.currentLineDashOffset = lineDashOffset; state.currentLineJoin = lineJoin; state.currentLineWidth = lineWidth; state.currentMiterLimit = miterLimit; diff --git a/src/ol/render/canvas/replay.js b/src/ol/render/canvas/replay.js index 9d188e86c7..d5392e06ff 100644 --- a/src/ol/render/canvas/replay.js +++ b/src/ol/render/canvas/replay.js @@ -465,9 +465,9 @@ ol.render.canvas.Replay.prototype.replay_ = function( ++i; break; case ol.render.canvas.Instruction.SET_STROKE_STYLE: - var usePixelRatio = instruction[7] !== undefined ? - instruction[7] : true; - var renderedPixelRatio = instruction[8]; + var usePixelRatio = instruction[8] !== undefined ? + instruction[8] : true; + var renderedPixelRatio = instruction[9]; var lineWidth = /** @type {number} */ (instruction[2]); if (pendingStroke) { @@ -481,13 +481,17 @@ ol.render.canvas.Replay.prototype.replay_ = function( 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[8] = pixelRatio; + instruction[7] = lineDashOffset; + instruction[9] = pixelRatio; } + context.lineDashOffset = lineDashOffset; context.setLineDash(lineDash); } prevX = NaN; diff --git a/src/ol/render/canvas/textreplay.js b/src/ol/render/canvas/textreplay.js index 3f7ef786fa..34ac54582c 100644 --- a/src/ol/render/canvas/textreplay.js +++ b/src/ol/render/canvas/textreplay.js @@ -160,6 +160,7 @@ ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = function(strokeSta 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 && @@ -169,7 +170,7 @@ ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = function(strokeSta var setStrokeStyleInstruction = [ ol.render.canvas.Instruction.SET_STROKE_STYLE, strokeState.strokeStyle, strokeState.lineWidth, strokeState.lineCap, strokeState.lineJoin, - strokeState.miterLimit, strokeState.lineDash, false, 1 + strokeState.miterLimit, strokeState.lineDash, strokeState.lineDashOffset, false, 1 ]; this.instructions.push(setStrokeStyleInstruction); this.hitDetectionInstructions.push(setStrokeStyleInstruction); @@ -177,6 +178,7 @@ ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = function(strokeSta this.replayStrokeState_ = { lineCap: strokeState.lineCap, lineDash: strokeState.lineDash, + lineDashOffset: strokeState.lineDashOffset, lineJoin: strokeState.lineJoin, lineWidth: strokeState.lineWidth, miterLimit: strokeState.miterLimit, @@ -185,6 +187,7 @@ ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = function(strokeSta } 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; @@ -253,6 +256,7 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { var textStrokeStyleColor = textStrokeStyle.getColor(); var textStrokeStyleLineCap = textStrokeStyle.getLineCap(); var textStrokeStyleLineDash = textStrokeStyle.getLineDash(); + var textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset(); var textStrokeStyleLineJoin = textStrokeStyle.getLineJoin(); var textStrokeStyleWidth = textStrokeStyle.getWidth(); var textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit(); @@ -260,6 +264,8 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { textStrokeStyleLineCap : ol.render.canvas.defaultLineCap; var lineDash = textStrokeStyleLineDash ? textStrokeStyleLineDash.slice() : ol.render.canvas.defaultLineDash; + var lineDashOffset = textStrokeStyleLineDashOffset !== undefined ? + textStrokeStyleLineDashOffset : ol.render.canvas.defaultLineDashOffset; var lineJoin = textStrokeStyleLineJoin !== undefined ? textStrokeStyleLineJoin : ol.render.canvas.defaultLineJoin; var lineWidth = textStrokeStyleWidth !== undefined ? @@ -272,6 +278,7 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { this.textStrokeState_ = { lineCap: lineCap, lineDash: lineDash, + lineDashOffset: lineDashOffset, lineJoin: lineJoin, lineWidth: lineWidth, miterLimit: miterLimit, @@ -281,6 +288,7 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { var textStrokeState = this.textStrokeState_; textStrokeState.lineCap = lineCap; textStrokeState.lineDash = lineDash; + textStrokeState.lineDashOffset = lineDashOffset; textStrokeState.lineJoin = lineJoin; textStrokeState.lineWidth = lineWidth; textStrokeState.miterLimit = miterLimit; diff --git a/src/ol/render/webgl.js b/src/ol/render/webgl.js index c484743cf9..f273ac5b43 100644 --- a/src/ol/render/webgl.js +++ b/src/ol/render/webgl.js @@ -22,6 +22,13 @@ if (ol.ENABLE_WEBGL) { ol.render.webgl.defaultLineDash = []; + /** + * @const + * @type {number} + */ + ol.render.webgl.defaultLineDashOffset = 0; + + /** * @const * @type {string} diff --git a/src/ol/render/webgl/circlereplay.js b/src/ol/render/webgl/circlereplay.js index 4967bbd0e8..3bd574fa6d 100644 --- a/src/ol/render/webgl/circlereplay.js +++ b/src/ol/render/webgl/circlereplay.js @@ -54,6 +54,7 @@ if (ol.ENABLE_WEBGL) { * @type {{fillColor: (Array.|null), * strokeColor: (Array.|null), * lineDash: Array., + * lineDashOffset: (number|undefined), * lineWidth: (number|undefined), * changed: boolean}|null} */ @@ -61,6 +62,7 @@ if (ol.ENABLE_WEBGL) { fillColor: null, strokeColor: null, lineDash: null, + lineDashOffset: undefined, lineWidth: undefined, changed: false }; @@ -380,6 +382,9 @@ if (ol.ENABLE_WEBGL) { var strokeStyleLineDash = strokeStyle.getLineDash(); this.state_.lineDash = strokeStyleLineDash ? strokeStyleLineDash : ol.render.webgl.defaultLineDash; + var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset(); + this.state_.lineDashOffset = strokeStyleLineDashOffset ? + strokeStyleLineDashOffset : ol.render.webgl.defaultLineDashOffset; strokeStyleColor = strokeStyle.getColor(); if (!(strokeStyleColor instanceof CanvasGradient) && !(strokeStyleColor instanceof CanvasPattern)) { diff --git a/src/ol/render/webgl/linestringreplay.js b/src/ol/render/webgl/linestringreplay.js index 5d1089b072..f0b5f9b400 100644 --- a/src/ol/render/webgl/linestringreplay.js +++ b/src/ol/render/webgl/linestringreplay.js @@ -50,6 +50,7 @@ if (ol.ENABLE_WEBGL) { * @type {{strokeColor: (Array.|null), * lineCap: (string|undefined), * lineDash: Array., + * lineDashOffset: (number|undefined), * lineJoin: (string|undefined), * lineWidth: (number|undefined), * miterLimit: (number|undefined), @@ -59,6 +60,7 @@ if (ol.ENABLE_WEBGL) { strokeColor: null, lineCap: undefined, lineDash: null, + lineDashOffset: undefined, lineJoin: undefined, lineWidth: undefined, miterLimit: undefined, @@ -634,6 +636,9 @@ if (ol.ENABLE_WEBGL) { var strokeStyleLineDash = strokeStyle.getLineDash(); this.state_.lineDash = strokeStyleLineDash ? strokeStyleLineDash : ol.render.webgl.defaultLineDash; + var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset(); + this.state_.lineDashOffset = strokeStyleLineDashOffset ? + strokeStyleLineDashOffset : ol.render.webgl.defaultLineDashOffset; var strokeStyleLineJoin = strokeStyle.getLineJoin(); this.state_.lineJoin = strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : ol.render.webgl.defaultLineJoin; diff --git a/src/ol/style/stroke.js b/src/ol/style/stroke.js index 7a6b6b8f6f..1649913a4a 100644 --- a/src/ol/style/stroke.js +++ b/src/ol/style/stroke.js @@ -36,6 +36,12 @@ ol.style.Stroke = function(opt_options) { */ this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null; + /** + * @private + * @type {number|undefined} + */ + this.lineDashOffset_ = options.lineDashOffset; + /** * @private * @type {string|undefined} @@ -73,6 +79,7 @@ ol.style.Stroke.prototype.clone = function() { color: (color && color.slice) ? color.slice() : color || undefined, lineCap: this.getLineCap(), lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined, + lineDashOffset: this.getLineDashOffset(), lineJoin: this.getLineJoin(), miterLimit: this.getMiterLimit(), width: this.getWidth() @@ -110,6 +117,16 @@ ol.style.Stroke.prototype.getLineDash = function() { }; +/** + * Get the line dash offset for the stroke. + * @return {number|undefined} Line dash offset. + * @api + */ +ol.style.Stroke.prototype.getLineDashOffset = function() { + return this.lineDashOffset_; +}; + + /** * Get the line join type for the stroke. * @return {string|undefined} Line join. @@ -182,6 +199,18 @@ ol.style.Stroke.prototype.setLineDash = function(lineDash) { }; +/** + * Set the line dash offset. + * + * @param {number|undefined} lineDashOffset Line dash offset. + * @api + */ +ol.style.Stroke.prototype.setLineDashOffset = function(lineDashOffset) { + this.lineDashOffset_ = lineDashOffset; + this.checksum_ = undefined; +}; + + /** * Set the line join. * @@ -238,6 +267,8 @@ ol.style.Stroke.prototype.getChecksum = function() { this.lineCap_.toString() : '-') + ',' + (this.lineDash_ ? this.lineDash_.toString() : '-') + ',' + + (this.lineDashOffset_ !== undefined ? + this.lineDashOffset_ : '-') + ',' + (this.lineJoin_ !== undefined ? this.lineJoin_ : '-') + ',' + (this.miterLimit_ !== undefined ? diff --git a/test/spec/ol/renderer/canvas/replay.test.js b/test/spec/ol/renderer/canvas/replay.test.js index 60a3a6f2c3..55fedd61de 100644 --- a/test/spec/ol/renderer/canvas/replay.test.js +++ b/test/spec/ol/renderer/canvas/replay.test.js @@ -34,7 +34,8 @@ describe('ol.render.canvas.ReplayGroup', function() { }); style2 = new ol.style.Style({ fill: new ol.style.Fill({color: 'white'}), - stroke: new ol.style.Stroke({color: 'black', width: 1, lineDash: [3, 6]}) + stroke: new ol.style.Stroke({color: 'black', width: 1, lineDash: [3, 6], + lineDashOffset: 2}) }); fillCount = 0; strokeCount = 0; @@ -140,14 +141,22 @@ describe('ol.render.canvas.ReplayGroup', function() { expect(beginPathCount).to.be(3); }); - it('applies the pixelRatio to the linedash array', function() { - var lineDash, lineDashCount = 0; + it('applies the pixelRatio to the linedash array and offset', function() { + var lineDash, lineDashCount = 0, + lineDashOffset, lineDashOffsetCount = 0; context.setLineDash = function(lineDash_) { lineDashCount++; lineDash = lineDash_.slice(); }; + Object.defineProperty(context, 'lineDashOffset', { + set: function(lineDashOffset_) { + lineDashOffsetCount++; + lineDashOffset = lineDashOffset_; + } + }); + ol.renderer.vector.renderFeature(replay, feature1, style2, 1); ol.renderer.vector.renderFeature(replay, feature2, style2, 1); replay.replay(context, 2, transform, 0, {}); @@ -155,6 +164,10 @@ describe('ol.render.canvas.ReplayGroup', function() { expect(lineDashCount).to.be(1); expect(style2.getStroke().getLineDash()).to.eql([3, 6]); expect(lineDash).to.eql([6, 12]); + + expect(lineDashOffsetCount).to.be(1); + expect(style2.getStroke().getLineDashOffset()).to.be(2); + expect(lineDashOffset).to.be(4); }); }); diff --git a/test/spec/ol/style/stroke.test.js b/test/spec/ol/style/stroke.test.js index 352b9e6954..18f25ecb0b 100644 --- a/test/spec/ol/style/stroke.test.js +++ b/test/spec/ol/style/stroke.test.js @@ -19,6 +19,7 @@ describe('ol.style.Stroke', function() { lineCap: 'square', lineJoin: 'miter', lineDash: [1, 2, 3], + lineDashOffset: 2, miterLimit: 20, width: 5 }); @@ -27,6 +28,7 @@ describe('ol.style.Stroke', function() { expect(original.getLineCap()).to.eql(clone.getLineCap()); expect(original.getLineJoin()).to.eql(clone.getLineJoin()); expect(original.getLineDash()).to.eql(clone.getLineDash()); + expect(original.getLineDashOffset()).to.eql(clone.getLineDashOffset()); expect(original.getMiterLimit()).to.eql(clone.getMiterLimit()); expect(original.getWidth()).to.eql(clone.getWidth()); }); diff --git a/test_rendering/spec/ol/style/expected/linestring-strokes-canvas-hidpi.png b/test_rendering/spec/ol/style/expected/linestring-strokes-canvas-hidpi.png index 600e4c1336..2d2fcd2f3f 100644 Binary files a/test_rendering/spec/ol/style/expected/linestring-strokes-canvas-hidpi.png and b/test_rendering/spec/ol/style/expected/linestring-strokes-canvas-hidpi.png differ diff --git a/test_rendering/spec/ol/style/expected/linestring-strokes-canvas.png b/test_rendering/spec/ol/style/expected/linestring-strokes-canvas.png index 9eb1f39a99..d2f488e3c9 100644 Binary files a/test_rendering/spec/ol/style/expected/linestring-strokes-canvas.png and b/test_rendering/spec/ol/style/expected/linestring-strokes-canvas.png differ diff --git a/test_rendering/spec/ol/style/expected/linestring-strokes-webgl.png b/test_rendering/spec/ol/style/expected/linestring-strokes-webgl.png index 95e1a9a602..41d05f8ae6 100644 Binary files a/test_rendering/spec/ol/style/expected/linestring-strokes-webgl.png and b/test_rendering/spec/ol/style/expected/linestring-strokes-webgl.png differ diff --git a/test_rendering/spec/ol/style/linestring.test.js b/test_rendering/spec/ol/style/linestring.test.js index d6eda66cb1..344b597bfb 100644 --- a/test_rendering/spec/ol/style/linestring.test.js +++ b/test_rendering/spec/ol/style/linestring.test.js @@ -91,6 +91,23 @@ describe('ol.rendering.style.LineString', function() { }) })); vectorSource.addFeature(feature); + + feature = new ol.Feature({ + geometry: new ol.geom.LineString( + [[-20, -15], [-2, 5], [15, -15]] + ) + }); + feature.setStyle(new ol.style.Style({ + stroke: new ol.style.Stroke({ + color: '#000000', + width: 2, + lineCap: 'square', + lineDash: [4, 8], + lineDashOffset: 6, + lineJoin: 'round' + }) + })); + vectorSource.addFeature(feature); } it('tests the canvas renderer', function(done) {