From 7a4ae3a6ac1b09de4142fac6b9b7209b3f0af117 Mon Sep 17 00:00:00 2001 From: Thomas Chandelle Date: Tue, 8 Nov 2016 15:38:00 +0100 Subject: [PATCH] Line Dash offset --- externs/olx.js | 9 +++++ src/ol/render/canvas.js | 7 ++++ src/ol/render/canvas/immediate.js | 6 ++++ src/ol/render/canvas/linestringreplay.js | 16 +++++++-- src/ol/render/canvas/polygonreplay.js | 19 ++++++++--- src/ol/render/canvas/replay.js | 12 ++++--- src/ol/render/canvas/textreplay.js | 10 +++++- src/ol/render/webgl.js | 7 ++++ src/ol/render/webgl/circlereplay.js | 5 +++ src/ol/render/webgl/linestringreplay.js | 5 +++ src/ol/style/stroke.js | 31 ++++++++++++++++++ test/spec/ol/renderer/canvas/replay.test.js | 19 +++++++++-- test/spec/ol/style/stroke.test.js | 2 ++ .../linestring-strokes-canvas-hidpi.png | Bin 928 -> 1013 bytes .../expected/linestring-strokes-canvas.png | Bin 515 -> 590 bytes .../expected/linestring-strokes-webgl.png | Bin 549 -> 274 bytes .../spec/ol/style/linestring.test.js | 17 ++++++++++ 17 files changed, 150 insertions(+), 15 deletions(-) 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 600e4c1336f190a4deb8cd8e03ae8b8565a1bbcf..2d2fcd2f3fff5ca3ff0fb7750a64024e875f358c 100644 GIT binary patch delta 991 zcmV<510ejM2lWS#B!9d~L_t(|ob8%DmZCruh3^u|yaNm;Bh`o{bgaSD65K(%gYL*w zb};ThcF?l{b@C1rTmTawM})^u+ZF|QzjI#F^=x0gi$xU|fDl3mA%u|U=HR$$=S78;0r_MWdKejHEYedp;}As2E|WmbNF`w+KVEG$Kaw%dkJeK8BHBN))NU z_Qd)dDtNdc`G0%HeEt&u`ZZ<|x>}x#IK9^cv(G0XUhwjga$UviPA<)@a=zM_QT`l6wxf!grvMG_y*KvYc!zh5viH zga&EM5`V?!`kC=EF??JPg}UT_yWrOME|!qR$d5@mY`7sbfS_c|$5o6?JLQl%7N|cQ z5<&eWOU>)?4v%WBEhpV14=QWXpW+HUtY$ZCv>% z9y|x>%csjg)g;rLH-mM&qS){QZkML~gUG=>jDO7AuQ7_J@O+NRt8yXK^O+eRv@b7- zkw0NK$$2!s@SWLyAFXcYZ&LI@#*kkZj>=AWCdSP5`QM_t=n*|xB zi7#&r$$kxN7Ss}TzPuGAF`ns-bRX5ed|0b!p_pe9BPBq!FW(AUD56a-yh}*Fe5<|i zAdAtdT}I0|xbD1K?}bKpyznmJ!s3#x(Swufv*Cea5JCtcgb+d=!+*;@i^$?eu|og= N002ovPDHLkV1nRQ=Cc3* delta 906 zcmV;519klM2cQR#B!6c~L_t(|obB5$Y!hJ^$MLUd0wfhJYNBFICYU53maU><0Z$F+s@090&vnB#^9xiis|1dKD8DMZ9f#?cHD- zdGEdUexKw~75BV-^8UXA5fKp)kz_lhm^#icZXD+q8^`&@o_``V8ui(w%|nVQ>jmi- z!*zovB{rfchF#F>|%Pubzs3=YRR?5uoy>}LWpA( z%si5DornynXNZW13(tX)>m_#pg|oRf2y^1N%cr3OERP zw%sqDVs4q>c-|zsNj6RRy~^W=o*ygsfp3id5kE0^({3abAsVq*1;@|6C-RzRey1s(NG1r>pBS+))-FaHuoEH2@iqy z=*2S+c)!oXbDWVE1y#wH)w;(M@e^@8vTLk3?!r=l)`b@H4pB z-OGo)kv@0*mE=ne1<=nd)% zR4`CrBS+u{u(loG0uW|05Qm|o85}DON<|!p#HjvBPimv;`TG*T_nZPAPdh|(coxy& z)SVcdM>HUYCI;;7U?^RSh@Osj)kr`hdOCikL+(mMbij;Ecz;~w<|aPAy^W{t#K&PR zBX@W4$$TDjSK|6QK5F<`{Ug?ELWLj~UteVEQmog68ktDbo^&yUAfJ`Z2tg)k+LOy= zU(ROx&ctff*JdVFjqo(>$;F~CXR|$L!q|x0TdS8C*NG5hA_Ux5=l^j9;J#}S zrf>k8ucZ_~0)IdPVC~DP2Zs{;{^L5!u1f%BZ+acTkc(wdPvtoag52aMfS?P3RbVJL zp|3q=zYDYPFKr8~0)@KE66&r4s<0(gZ6p9Tj}{?{HRKc%D1ks;+zHeca#nN|2pp~h zPYD#oEf)e9wJn09xNS^pAb@HPx-Bzw(3V3K2c8ynX@8J|K($|q{Me%NYIA=IN8VC( zH_~l4G|UwsKek+p?=Fr?a%ywjO6?Yck_Bx|Xc&rz$pFBEWzJt0 zCo6uUUw^r9CJRVp02It7TaG;yK9smFU07*qoM6N<$ Ef*&CPTL1t6 delta 490 zcmVZ$>+fwksNy>rG=LqjJ6ZwA;vBld+kVF|snH<$rOJPUpSS>%FyIQMdaV zuD6kuAdZ6|Nkl76gSIP5648p|ATTl^r5H*nG6xk+Z6--XOG=U5-*06X7u(J#iZ(MT zMV2I@wO&TzI0({IJUdWEKj}rvjnY&`0HoX~x!CMRCOjUGXRRp$*FYbb{+#3(1(bnI ztFNCe9oHxWFMnF+i%lmVAu9P4sItUm1Ms7mvnD8tMb6J*q^9cG2HB|pu9b*7B)G7ATX3#%4Vmy|QZ3Nsy zeVGh(zxdCK(W!p#2WsEsW|pmOiz~*Lvs~ppxwUUu+`+B@3{Yj3tHi$ljaj$04T{Wo gK`Wv*xX0sxFIlFE#w1 zBXkd7v*F;Ha} zd|E1!RCI8}8F8G6Gm

8O%(R6dLPYJy{-)LM6|r5{^(e$n(YYzAsK)zpYqW_8fV+ zoPPBM0(D%yuE@@*7X+$MMQin~t+;x~-s3KG?6@SzV)4$J6n`G#=ks%xmbyVaDs7!3 z>Bwet%Cgg1OlrN!WX;mD1G3$o_3ki4xbgU-b1)@Amdg{5VzYA0W}iQC{~Lr=D(4`P zBdG1qZ+7P*o2IM#6UDStPKynWI2D?mW^jZk)lCTDE`$KTF2yR5B!)oV5_xuNSt7w> zEq}Y=GXkwaVu*(Z0KcdK1b~V>mLPC%fPDdC5duU*s{tT9#bB&JD6t3$ zFjhIu_Xq`n39;>pz-X%zPbg?7>RKA#K()Ee9El+$Qwd=t?~nr`w<@_1C%wY83@J}?h~Xb(IMRNMtr$Nc6=1s)S3dy=(5EDt=5 zEAXyplBFDh1=^P*t*G4h*;=~xNU>|FkP5nl)WY6O!sPDZ1BiRciG<&jaEUV-c6uZL P0000