diff --git a/src/pixie/fileformats/svg.nim b/src/pixie/fileformats/svg.nim index beed00d..35e0b00 100644 --- a/src/pixie/fileformats/svg.nim +++ b/src/pixie/fileformats/svg.nim @@ -14,6 +14,7 @@ type Ctx = object strokeLineCap: LineCap strokeLineJoin: LineJoin strokeMiterLimit: float32 + strokeDashArray: seq[float32] transform: Mat3 shouldStroke: bool @@ -43,6 +44,7 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx = strokeLineCap = node.attr("stroke-linecap") strokeLineJoin = node.attr("stroke-linejoin") strokeMiterLimit = node.attr("stroke-miterlimit") + strokeDashArray = node.attr("stroke-dasharray") transform = node.attr("transform") style = node.attr("style") @@ -70,6 +72,9 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx = of "stroke-miterlimit": if strokeMiterLimit.len == 0: strokeMiterLimit = parts[1].strip() + of "stroke-dasharray": + if strokeDashArray.len == 0: + strokeDashArray = parts[1].strip() if fillRule == "": discard # Inherit @@ -149,6 +154,13 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx = else: result.strokeMiterLimit = parseFloat(strokeMiterLimit) + if strokeDashArray == "": + discard + else: + var values = strokeDashArray.replace(',', ' ').split(' ') + for value in values: + result.strokeDashArray.add(parseFloat(value)) + if transform == "": discard # Inherit else: @@ -230,7 +242,8 @@ proc stroke(img: Image, ctx: Ctx, path: Path) {.inline.} = ctx.stroke, ctx.transform, ctx.strokeWidth, - miterLimit = ctx.strokeMiterLimit + miterLimit = ctx.strokeMiterLimit, + dashes = ctx.strokeDashArray ) proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) = @@ -270,10 +283,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) = var path: Path path.moveTo(x1, y1) path.lineTo(x2, y2) - path.closePath() - if ctx.fill != ColorRGBX(): - img.fill(ctx, path) if ctx.shouldStroke: img.stroke(ctx, path) @@ -305,11 +315,13 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) = path.lineTo(vecs[i]) # The difference between polyline and polygon is whether we close the path + # and fill or not if node.tag == "polygon": path.closePath() - if ctx.fill != ColorRGBX(): - img.fill(ctx, path) + if ctx.fill != ColorRGBX(): + img.fill(ctx, path) + if ctx.shouldStroke: img.stroke(ctx, path) diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index 2555420..f027f84 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -1424,15 +1424,16 @@ proc strokeShapes( shape[0] )) + var dashes = dashes + if dashes.len mod 2 != 0: + dashes.add(dashes) + for i in 1 ..< shape.len: let pos = shape[i] prevPos = shape[i - 1] if dashes.len > 0: - var dashes = dashes - if dashes.len mod 2 != 0: - dashes.add(dashes) var distance = dist(prevPos, pos) let dir = dir(pos, prevPos) var currPos = prevPos diff --git a/tests/images/paths/dashes.png b/tests/images/paths/dashes.png index 5389bd8..3681bb0 100644 Binary files a/tests/images/paths/dashes.png and b/tests/images/paths/dashes.png differ diff --git a/tests/images/svg/dashes.png b/tests/images/svg/dashes.png new file mode 100644 index 0000000..3e1f667 Binary files /dev/null and b/tests/images/svg/dashes.png differ diff --git a/tests/images/svg/dashes.svg b/tests/images/svg/dashes.svg new file mode 100644 index 0000000..cb340e7 --- /dev/null +++ b/tests/images/svg/dashes.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/tests/test_svg.nim b/tests/test_svg.nim index 562c3dc..ac620aa 100644 --- a/tests/test_svg.nim +++ b/tests/test_svg.nim @@ -12,7 +12,8 @@ const files = [ "quad01", "Ghostscript_Tiger", "scale", - "miterlimit" + "miterlimit", + "dashes" ] for file in files: