Compute pixel scale based on matrix max scale before doing the fill or storke. (#124)

This commit is contained in:
treeform 2021-02-22 23:53:26 -08:00 committed by GitHub
parent 515dd51b2a
commit e41b8434eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 32 additions and 7 deletions

View file

@ -34,6 +34,12 @@ type
when defined(release):
{.push checks: off.}
proc maxScale(m: Mat3): float32 =
max(
vec2(m[0, 0], m[0, 1]).length,
vec2(m[1, 0], m[1, 1]).length
)
proc parameterCount(kind: PathCommandKind): int =
case kind:
of Close: 0
@ -495,7 +501,7 @@ proc polygon*(path: var Path, x, y, size: float32, sides: int) =
proc polygon*(path: var Path, pos: Vec2, size: float32, sides: int) {.inline.} =
path.polygon(pos.x, pos.y, size, sides)
proc commandsToShapes*(path: Path): seq[seq[Vec2]] =
proc commandsToShapes*(path: Path, pixelScale: float32 = 1.0): seq[seq[Vec2]] =
## Converts SVG-like commands to line segments.
var
@ -507,7 +513,7 @@ proc commandsToShapes*(path: Path): seq[seq[Vec2]] =
prevCommandKind = Move
prevCtrl, prevCtrl2: Vec2
const errorMargin = 0.2
let errorMargin = 0.2 / pixelScale
proc addSegment(shape: var seq[Vec2], at, to: Vec2) =
# Don't add any 0 length lines
@ -1250,11 +1256,11 @@ proc strokeShapes(
if strokeShape.len > 0:
result.add(strokeShape)
proc parseSomePath(path: SomePath): seq[seq[Vec2]] {.inline.} =
proc parseSomePath(path: SomePath, pixelScale:float32 = 1.0): seq[seq[Vec2]] {.inline.} =
when type(path) is string:
parsePath(path).commandsToShapes()
parsePath(path).commandsToShapes(pixelScale)
elif type(path) is Path:
path.commandsToShapes()
path.commandsToShapes(pixelScale)
elif type(path) is seq[seq[Segment]]:
path
@ -1275,7 +1281,11 @@ proc fillPath*(
windingRule = wrNonZero,
blendMode = bmNormal
) =
var shapes = parseSomePath(path)
when type(transform) is Mat3:
let pixelScale = transform.maxScale()
else:
let pixelScale = 1.0
var shapes = parseSomePath(path, pixelScale)
for shape in shapes.mitems:
for segment in shape.mitems:
when type(transform) is Vec2:
@ -1324,7 +1334,11 @@ proc strokePath*(
strokeWidth = 1.0,
blendMode = bmNormal
) =
var strokeShapes = strokeShapes(parseSomePath(path), strokeWidth)
when type(transform) is Mat3:
let pixelScale = transform.maxScale()
else:
let pixelScale = 1.0
var strokeShapes = strokeShapes(parseSomePath(path, pixelScale), strokeWidth)
for shape in strokeShapes.mitems:
for segment in shape.mitems:
when type(transform) is Vec2:

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 B

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 B

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 KiB

After

Width:  |  Height:  |  Size: 356 KiB

View file

@ -0,0 +1,11 @@
import pixie
let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
var p = parsePath("M1 0.5C1 0.776142 0.776142 1 0.5 1C0.223858 1 0 0.776142 0 0.5C0 0.223858 0.223858 0 0.5 0C0.776142 0 1 0.223858 1 0.5Z")
image.fillPath(p, rgba(255, 0, 0, 255), scale(vec2(200, 200)))
image.strokePath(p, rgba(0, 255, 0, 255), scale(vec2(200, 200)), strokeWidth=0.01)
image.writeFile("tests/images/paths/pixelScale.png")