Merge pull request #223 from guzba/master

fill closes subpaths
This commit is contained in:
treeform 2021-06-05 23:40:10 -07:00 committed by GitHub
commit 58577b9635
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 23 additions and 14 deletions

View file

@ -619,7 +619,9 @@ proc polygon*(path: var Path, pos: Vec2, size: float32, sides: int) {.inline.} =
## Adds a n-sided regular polygon at (x, y) with the parameter size.
path.polygon(pos.x, pos.y, size, sides)
proc commandsToShapes*(path: Path, pixelScale: float32 = 1.0): seq[seq[Vec2]] =
proc commandsToShapes*(
path: Path, closeSubpaths = false, pixelScale: float32 = 1.0
): seq[seq[Vec2]] =
## Converts SVG-like commands to sequences of vectors.
var
start, at: Vec2
@ -817,6 +819,8 @@ proc commandsToShapes*(path: Path, pixelScale: float32 = 1.0): seq[seq[Vec2]] =
case command.kind:
of Move:
if shape.len > 0:
if closeSubpaths:
shape.addSegment(at, start)
result.add(shape)
shape = newSeq[Vec2]()
at.x = command.numbers[0]
@ -975,14 +979,12 @@ proc commandsToShapes*(path: Path, pixelScale: float32 = 1.0): seq[seq[Vec2]] =
prevCommandKind = command.kind
if shape.len > 0:
if closeSubpaths:
shape.addSegment(at, start)
result.add(shape)
proc shapesToSegments(shapes: seq[seq[Vec2]]): seq[(Segment, int16)] =
## Converts the shapes into a set of filtered segments with winding value.
var segmentCount: int
for shape in shapes:
segmentCount += shape.len - 1
for shape in shapes:
for segment in shape.segments:
if segment.at.y == segment.to.y: # Skip horizontal
@ -1620,15 +1622,13 @@ proc strokeShapes(
result.add(shapeStroke)
proc parseSomePath(
path: SomePath, pixelScale: float32 = 1.0
path: SomePath, closeSubpaths: bool, pixelScale: float32 = 1.0
): seq[seq[Vec2]] {.inline.} =
## Given SomePath, parse it in different ways.
when type(path) is string:
parsePath(path).commandsToShapes(pixelScale)
parsePath(path).commandsToShapes(closeSubpaths, pixelScale)
elif type(path) is Path:
path.commandsToShapes(pixelScale)
elif type(path) is seq[seq[Vec2]]:
path
path.commandsToShapes(closeSubpaths, pixelScale)
proc transform(shapes: var seq[seq[Vec2]], transform: Vec2 | Mat3) =
when type(transform) is Vec2:
@ -1649,7 +1649,7 @@ proc fillPath*(
windingRule = wrNonZero
) =
## Fills a path.
var shapes = parseSomePath(path, transform.pixelScale())
var shapes = parseSomePath(path, true, transform.pixelScale())
shapes.transform(transform)
mask.fillShapes(shapes, windingRule)
@ -1663,7 +1663,7 @@ proc fillPath*(
## Fills a path.
if paint.kind == pkSolid:
if paint.color.a > 0 or paint.blendMode == bmOverwrite:
var shapes = parseSomePath(path, transform.pixelScale())
var shapes = parseSomePath(path, true, transform.pixelScale())
shapes.transform(transform)
image.fillShapes(shapes, paint.color, windingRule, paint.blendMode)
return
@ -1703,7 +1703,7 @@ proc strokePath*(
) =
## Strokes a path.
var strokeShapes = strokeShapes(
parseSomePath(path, transform.pixelScale()),
parseSomePath(path, false, transform.pixelScale()),
strokeWidth,
lineCap,
lineJoin,
@ -1728,7 +1728,7 @@ proc strokePath*(
if paint.kind == pkSolid:
if paint.color.a > 0 or paint.blendMode == bmOverwrite:
var strokeShapes = strokeShapes(
parseSomePath(path, transform.pixelScale()),
parseSomePath(path, false, transform.pixelScale()),
strokeWidth,
lineCap,
lineJoin,

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 644 KiB

After

Width:  |  Height:  |  Size: 644 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 KiB

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 519 KiB

After

Width:  |  Height:  |  Size: 519 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

After

Width:  |  Height:  |  Size: 3.9 MiB

View file

@ -325,6 +325,15 @@ block:
miterTest(145, 3.32)
miterTest(145, 3.33)
block:
# Test self closing subpaths on fill
let
image = newImage(60, 60)
path = parsePath("M0 0 L0 0 L60 0 L60 60 L0 60")
image.fill(rgba(255, 255, 255, 255))
image.fillPath(path, rgba(127, 127, 127, 255))
image.writeFile("tests/images/paths/selfclosing.png")
# Potential error cases, ensure they do not crash
block: