Compute pixel scale based on matrix max scale before doing the fill or storke. (#124)
|
@ -34,6 +34,12 @@ type
|
||||||
when defined(release):
|
when defined(release):
|
||||||
{.push checks: off.}
|
{.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 =
|
proc parameterCount(kind: PathCommandKind): int =
|
||||||
case kind:
|
case kind:
|
||||||
of Close: 0
|
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.} =
|
proc polygon*(path: var Path, pos: Vec2, size: float32, sides: int) {.inline.} =
|
||||||
path.polygon(pos.x, pos.y, size, sides)
|
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.
|
## Converts SVG-like commands to line segments.
|
||||||
|
|
||||||
var
|
var
|
||||||
|
@ -507,7 +513,7 @@ proc commandsToShapes*(path: Path): seq[seq[Vec2]] =
|
||||||
prevCommandKind = Move
|
prevCommandKind = Move
|
||||||
prevCtrl, prevCtrl2: Vec2
|
prevCtrl, prevCtrl2: Vec2
|
||||||
|
|
||||||
const errorMargin = 0.2
|
let errorMargin = 0.2 / pixelScale
|
||||||
|
|
||||||
proc addSegment(shape: var seq[Vec2], at, to: Vec2) =
|
proc addSegment(shape: var seq[Vec2], at, to: Vec2) =
|
||||||
# Don't add any 0 length lines
|
# Don't add any 0 length lines
|
||||||
|
@ -1250,11 +1256,11 @@ proc strokeShapes(
|
||||||
if strokeShape.len > 0:
|
if strokeShape.len > 0:
|
||||||
result.add(strokeShape)
|
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:
|
when type(path) is string:
|
||||||
parsePath(path).commandsToShapes()
|
parsePath(path).commandsToShapes(pixelScale)
|
||||||
elif type(path) is Path:
|
elif type(path) is Path:
|
||||||
path.commandsToShapes()
|
path.commandsToShapes(pixelScale)
|
||||||
elif type(path) is seq[seq[Segment]]:
|
elif type(path) is seq[seq[Segment]]:
|
||||||
path
|
path
|
||||||
|
|
||||||
|
@ -1275,7 +1281,11 @@ proc fillPath*(
|
||||||
windingRule = wrNonZero,
|
windingRule = wrNonZero,
|
||||||
blendMode = bmNormal
|
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 shape in shapes.mitems:
|
||||||
for segment in shape.mitems:
|
for segment in shape.mitems:
|
||||||
when type(transform) is Vec2:
|
when type(transform) is Vec2:
|
||||||
|
@ -1324,7 +1334,11 @@ proc strokePath*(
|
||||||
strokeWidth = 1.0,
|
strokeWidth = 1.0,
|
||||||
blendMode = bmNormal
|
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 shape in strokeShapes.mitems:
|
||||||
for segment in shape.mitems:
|
for segment in shape.mitems:
|
||||||
when type(transform) is Vec2:
|
when type(transform) is Vec2:
|
||||||
|
|
BIN
tests/images/paths/pixelScale.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 106 B After Width: | Height: | Size: 109 B |
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 111 B |
Before Width: | Height: | Size: 129 B After Width: | Height: | Size: 128 B |
Before Width: | Height: | Size: 356 KiB After Width: | Height: | Size: 356 KiB |
11
tests/test_pixelScale_fill.nim
Normal 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")
|