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
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)

View file

@ -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

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",
"Ghostscript_Tiger",
"scale",
"miterlimit"
"miterlimit",
"dashes"
]
for file in files: