diff --git a/src/pixie/context.nim b/src/pixie/context.nim index fd81133..0c60051 100644 --- a/src/pixie/context.nim +++ b/src/pixie/context.nim @@ -17,6 +17,7 @@ type font*: Font textAlign*: HAlignMode path: Path + lineDash: seq[float32] mat: Mat3 mask: Mask layer: Image @@ -30,6 +31,7 @@ type lineJoin: LineJoin font: Font textAlign: HAlignMode + lineDash: seq[float32] mat: Mat3 mask: Mask layer: Image @@ -60,6 +62,7 @@ proc state(ctx: Context): ContextState = result.lineJoin = ctx.lineJoin result.font = ctx.font result.textAlign = ctx.textAlign + result.lineDash = ctx.lineDash result.mat = ctx.mat result.mask = if ctx.mask != nil: ctx.mask.copy() else: nil @@ -94,6 +97,7 @@ proc restore*(ctx: Context) = ctx.lineJoin = state.lineJoin ctx.font = state.font ctx.textAlign = state.textAlign + ctx.lineDash = state.lineDash ctx.mat = state.mat ctx.mask = state.mask ctx.layer = state.layer @@ -124,7 +128,8 @@ proc stroke(ctx: Context, image: Image, path: Path) {.inline.} = ctx.lineWidth, ctx.lineCap, ctx.lineJoin, - ctx.miterLimit + ctx.miterLimit, + ctx.lineDash ) proc fillText(ctx: Context, image: Image, text: string, at: Vec2) {.inline.} = @@ -162,7 +167,8 @@ proc strokeText(ctx: Context, image: Image, text: string, at: Vec2) {.inline.} = hAlign = ctx.textAlign, lineCap = ctx.lineCap, lineJoin = ctx.lineJoin, - miterLimit = ctx.miterLimit + miterLimit = ctx.miterLimit, + dashes = ctx.lineDash ) proc beginPath*(ctx: Context) {.inline.} = @@ -375,6 +381,12 @@ proc measureText*(ctx: Context, text: string): TextMetrics = let bounds = typeset(ctx.font, text).computeBounds() result.width = bounds.x +proc getLineDash*(ctx: Context): seq[float32] {.inline.} = + ctx.lineDash + +proc setLineDash*(ctx: Context, lineDash: seq[float32]) {.inline.} = + ctx.lineDash = lineDash + proc getTransform*(ctx: Context): Mat3 {.inline.} = ## Retrieves the current transform matrix being applied to the context. ctx.mat diff --git a/src/pixie/fonts.nim b/src/pixie/fonts.nim index c52d667..4159620 100644 --- a/src/pixie/fonts.nim +++ b/src/pixie/fonts.nim @@ -443,7 +443,8 @@ proc strokeText*( strokeWidth = 1.0, lineCap = lcButt, lineJoin = ljMiter, - miterLimit = defaultMiterLimit + miterLimit = defaultMiterLimit, + dashes: seq[float32] = @[] ) = ## Strokes the text arrangement. for spanIndex, (start, stop) in arrangement.spans: @@ -456,10 +457,25 @@ proc strokeText*( ) when type(target) is Image: target.strokePath( - path, font.paint, transform, strokeWidth, lineCap, lineJoin + path, + font.paint, + transform, + strokeWidth, + lineCap, + lineJoin, + miterLimit, + dashes ) else: # target is Mask - target.strokePath(path, transform, strokeWidth, lineCap, lineJoin) + target.strokePath( + path, + transform, + strokeWidth, + lineCap, + lineJoin, + miterLimit, + dashes + ) proc strokeText*( target: Image | Mask, @@ -472,7 +488,8 @@ proc strokeText*( vAlign = vaTop, lineCap = lcButt, lineJoin = ljMiter, - miterLimit = defaultMiterLimit + miterLimit = defaultMiterLimit, + dashes: seq[float32] = @[] ) {.inline.} = ## Typesets and strokes the text. Optional parameters: ## transform: translation or matrix to apply @@ -487,5 +504,7 @@ proc strokeText*( transform, strokeWidth, lineCap, - lineJoin + lineJoin, + miterLimit, + dashes ) diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index c4a613f..2555420 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -1432,7 +1432,7 @@ proc strokeShapes( if dashes.len > 0: var dashes = dashes if dashes.len mod 2 != 0: - dashes.add(dashes[^1]) + dashes.add(dashes) var distance = dist(prevPos, pos) let dir = dir(pos, prevPos) var currPos = prevPos @@ -1549,7 +1549,7 @@ proc strokePath*( lineCap = lcButt, lineJoin = ljMiter, miterLimit = defaultMiterLimit, - dashes: seq[float32] = @[], + dashes: seq[float32] = @[] ) = ## Strokes a path. var strokeShapes = strokeShapes( diff --git a/tests/images/context/setLineDash_1.png b/tests/images/context/setLineDash_1.png new file mode 100644 index 0000000..e57dbf8 Binary files /dev/null and b/tests/images/context/setLineDash_1.png differ diff --git a/tests/test_context.nim b/tests/test_context.nim index 744f2da..b3d3152 100644 --- a/tests/test_context.nim +++ b/tests/test_context.nim @@ -490,3 +490,28 @@ block: let metrics = ctx.measureText("Hello world") doAssert metrics.width == 61 + +block: + let + image = newImage(300, 150) + ctx = newContext(image) + + var y = 15.float32 + + proc drawDashedLine(pattern: seq[float32]) = + ctx.beginPath(); + ctx.setLineDash(pattern); + ctx.moveTo(0, y); + ctx.lineTo(300, y); + ctx.stroke(); + y += 20; + + drawDashedLine(@[]); + drawDashedLine(@[1.float32, 1]); + drawDashedLine(@[10.float32, 10]); + drawDashedLine(@[20.float32, 5]); + drawDashedLine(@[15.float32, 3, 3, 3]); + drawDashedLine(@[20.float32, 3, 3, 3, 3, 3, 3, 3]); + drawDashedLine(@[12.float32, 3, 3]); + + image.writeFile("tests/images/context/setLineDash_1.png")