svg stroke-dasharray

This commit is contained in:
Ryan Oldenburg 2021-05-23 22:29:59 -05:00
parent 1e39ce2c80
commit 00dd3faa95
6 changed files with 44 additions and 10 deletions

View file

@ -14,6 +14,7 @@ type Ctx = object
strokeLineCap: LineCap strokeLineCap: LineCap
strokeLineJoin: LineJoin strokeLineJoin: LineJoin
strokeMiterLimit: float32 strokeMiterLimit: float32
strokeDashArray: seq[float32]
transform: Mat3 transform: Mat3
shouldStroke: bool shouldStroke: bool
@ -43,6 +44,7 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx =
strokeLineCap = node.attr("stroke-linecap") strokeLineCap = node.attr("stroke-linecap")
strokeLineJoin = node.attr("stroke-linejoin") strokeLineJoin = node.attr("stroke-linejoin")
strokeMiterLimit = node.attr("stroke-miterlimit") strokeMiterLimit = node.attr("stroke-miterlimit")
strokeDashArray = node.attr("stroke-dasharray")
transform = node.attr("transform") transform = node.attr("transform")
style = node.attr("style") style = node.attr("style")
@ -70,6 +72,9 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx =
of "stroke-miterlimit": of "stroke-miterlimit":
if strokeMiterLimit.len == 0: if strokeMiterLimit.len == 0:
strokeMiterLimit = parts[1].strip() strokeMiterLimit = parts[1].strip()
of "stroke-dasharray":
if strokeDashArray.len == 0:
strokeDashArray = parts[1].strip()
if fillRule == "": if fillRule == "":
discard # Inherit discard # Inherit
@ -149,6 +154,13 @@ proc decodeCtx(inherited: Ctx, node: XmlNode): Ctx =
else: else:
result.strokeMiterLimit = parseFloat(strokeMiterLimit) result.strokeMiterLimit = parseFloat(strokeMiterLimit)
if strokeDashArray == "":
discard
else:
var values = strokeDashArray.replace(',', ' ').split(' ')
for value in values:
result.strokeDashArray.add(parseFloat(value))
if transform == "": if transform == "":
discard # Inherit discard # Inherit
else: else:
@ -230,7 +242,8 @@ proc stroke(img: Image, ctx: Ctx, path: Path) {.inline.} =
ctx.stroke, ctx.stroke,
ctx.transform, ctx.transform,
ctx.strokeWidth, ctx.strokeWidth,
miterLimit = ctx.strokeMiterLimit miterLimit = ctx.strokeMiterLimit,
dashes = ctx.strokeDashArray
) )
proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) = 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 var path: Path
path.moveTo(x1, y1) path.moveTo(x1, y1)
path.lineTo(x2, y2) path.lineTo(x2, y2)
path.closePath()
if ctx.fill != ColorRGBX():
img.fill(ctx, path)
if ctx.shouldStroke: if ctx.shouldStroke:
img.stroke(ctx, path) img.stroke(ctx, path)
@ -305,11 +315,13 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
path.lineTo(vecs[i]) path.lineTo(vecs[i])
# The difference between polyline and polygon is whether we close the path # The difference between polyline and polygon is whether we close the path
# and fill or not
if node.tag == "polygon": if node.tag == "polygon":
path.closePath() path.closePath()
if ctx.fill != ColorRGBX(): if ctx.fill != ColorRGBX():
img.fill(ctx, path) img.fill(ctx, path)
if ctx.shouldStroke: if ctx.shouldStroke:
img.stroke(ctx, path) img.stroke(ctx, path)

View file

@ -1424,15 +1424,16 @@ proc strokeShapes(
shape[0] shape[0]
)) ))
var dashes = dashes
if dashes.len mod 2 != 0:
dashes.add(dashes)
for i in 1 ..< shape.len: for i in 1 ..< shape.len:
let let
pos = shape[i] pos = shape[i]
prevPos = shape[i - 1] prevPos = shape[i - 1]
if dashes.len > 0: if dashes.len > 0:
var dashes = dashes
if dashes.len mod 2 != 0:
dashes.add(dashes)
var distance = dist(prevPos, pos) var distance = dist(prevPos, pos)
let dir = dir(pos, prevPos) let dir = dir(pos, prevPos)
var currPos = prevPos var currPos = prevPos

Binary file not shown.

Before

Width:  |  Height:  |  Size: 824 B

After

Width:  |  Height:  |  Size: 837 B

BIN
tests/images/svg/dashes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,20 @@
<svg viewBox="0 0 600 200" transform="scale(20, 20)" xmlns="http://www.w3.org/2000/svg">
<!-- No dashes nor gaps -->
<line x1="0" y1="1" x2="30" y2="1" stroke="black" />
<!-- Dashes and gaps of the same size -->
<line x1="0" y1="3" x2="30" y2="3" stroke="black"
stroke-dasharray="4" />
<!-- Dashes and gaps of different sizes -->
<line x1="0" y1="5" x2="30" y2="5" stroke="black"
stroke-dasharray="4 1" />
<!-- Dashes and gaps of various sizes with an odd number of values -->
<line x1="0" y1="7" x2="30" y2="7" stroke="black"
stroke-dasharray="4 1 2" />
<!-- Dashes and gaps of various sizes with an even number of values -->
<line x1="0" y1="9" x2="30" y2="9" stroke="black"
stroke-dasharray="4 1 2 3" />
</svg>

After

Width:  |  Height:  |  Size: 778 B

View file

@ -12,7 +12,8 @@ const files = [
"quad01", "quad01",
"Ghostscript_Tiger", "Ghostscript_Tiger",
"scale", "scale",
"miterlimit" "miterlimit",
"dashes"
] ]
for file in files: for file in files: