more binding prep

This commit is contained in:
Ryan Oldenburg 2021-08-17 14:43:15 -05:00
parent 5868034f08
commit 412baf6c19
6 changed files with 72 additions and 79 deletions

View file

@ -505,9 +505,9 @@ proc circle*(ctx: Context, cx, cy, r: float32) {.inline.} =
## Adds a circle to the current path. ## Adds a circle to the current path.
ctx.path.circle(cx, cy, r) ctx.path.circle(cx, cy, r)
proc circle*(ctx: Context, center: Vec2, r: float32) {.inline.} = proc circle*(ctx: Context, circle: Circle) {.inline.} =
## Adds a circle to the current path. ## Adds a circle to the current path.
ctx.path.circle(center, r) ctx.path.circle(circle)
proc polygon*(ctx: Context, x, y, size: float32, sides: int) {.inline.} = proc polygon*(ctx: Context, x, y, size: float32, sides: int) {.inline.} =
## Adds an n-sided regular polygon at (x, y) of size to the current path. ## Adds an n-sided regular polygon at (x, y) of size to the current path.
@ -563,7 +563,7 @@ proc strokeEllipse*(ctx: Context, center: Vec2, rx, ry: float32) =
proc fillCircle*(ctx: Context, circle: Circle) = proc fillCircle*(ctx: Context, circle: Circle) =
## Draws a circle that is filled according to the current fillStyle ## Draws a circle that is filled according to the current fillStyle
let path = newPath() let path = newPath()
path.circle(circle.pos, circle.radius) path.circle(circle)
ctx.fill(path) ctx.fill(path)
proc fillCircle*(ctx: Context, center: Vec2, radius: float32) = proc fillCircle*(ctx: Context, center: Vec2, radius: float32) =
@ -576,7 +576,7 @@ proc strokeCircle*(ctx: Context, circle: Circle) =
## Draws a circle that is stroked (outlined) according to the current ## Draws a circle that is stroked (outlined) according to the current
## strokeStyle and other context settings. ## strokeStyle and other context settings.
let path = newPath() let path = newPath()
path.circle(circle.pos, circle.radius) path.circle(circle)
ctx.stroke(path) ctx.stroke(path)
proc strokeCircle*(ctx: Context, center: Vec2, radius: float32) = proc strokeCircle*(ctx: Context, center: Vec2, radius: float32) =

View file

@ -437,7 +437,7 @@ proc parseSvgFont*(buf: string): Typeface =
proc textUber( proc textUber(
target: Image | Mask, target: Image | Mask,
arrangement: Arrangement, arrangement: Arrangement,
transform: Vec2 | Mat3 = vec2(0, 0), transform = mat3(),
strokeWidth = 1.0, strokeWidth = 1.0,
lineCap = lcButt, lineCap = lcButt,
lineJoin = ljMiter, lineJoin = ljMiter,
@ -518,7 +518,7 @@ proc textUber(
proc fillText*( proc fillText*(
target: Image | Mask, target: Image | Mask,
arrangement: Arrangement, arrangement: Arrangement,
transform: Vec2 | Mat3 = vec2(0, 0) transform = mat3()
) {.inline.} = ) {.inline.} =
## Fills the text arrangement. ## Fills the text arrangement.
textUber( textUber(
@ -531,7 +531,7 @@ proc fillText*(
target: Image | Mask, target: Image | Mask,
font: Font, font: Font,
text: string, text: string,
transform: Vec2 | Mat3 = vec2(0, 0), transform = mat3(),
bounds = vec2(0, 0), bounds = vec2(0, 0),
hAlign = haLeft, hAlign = haLeft,
vAlign = vaTop vAlign = vaTop
@ -546,7 +546,7 @@ proc fillText*(
proc strokeText*( proc strokeText*(
target: Image | Mask, target: Image | Mask,
arrangement: Arrangement, arrangement: Arrangement,
transform: Vec2 | Mat3 = vec2(0, 0), transform = mat3(),
strokeWidth = 1.0, strokeWidth = 1.0,
lineCap = lcButt, lineCap = lcButt,
lineJoin = ljMiter, lineJoin = ljMiter,
@ -570,7 +570,7 @@ proc strokeText*(
target: Image | Mask, target: Image | Mask,
font: Font, font: Font,
text: string, text: string,
transform: Vec2 | Mat3 = vec2(0, 0), transform = mat3(),
strokeWidth = 1.0, strokeWidth = 1.0,
bounds = vec2(0, 0), bounds = vec2(0, 0),
hAlign = haLeft, hAlign = haLeft,

View file

@ -815,7 +815,7 @@ proc drawUber(a, b: Image | Mask, mat = mat3(), blendMode = bmNormal) =
zeroMem(a.data[a.dataIndex(xMax, y)].addr, 4 * (a.width - xMax)) zeroMem(a.data[a.dataIndex(xMax, y)].addr, 4 * (a.width - xMax))
proc draw*( proc draw*(
a, b: Image, transform: Mat3 = mat3(), blendMode = bmNormal a, b: Image, transform = mat3(), blendMode = bmNormal
) {.inline.} = ) {.inline.} =
## Draws one image onto another using matrix with color blending. ## Draws one image onto another using matrix with color blending.
when type(transform) is Vec2: when type(transform) is Vec2:
@ -824,7 +824,7 @@ proc draw*(
a.drawUber(b, transform, blendMode) a.drawUber(b, transform, blendMode)
proc draw*( proc draw*(
a, b: Mask, transform: Mat3 = mat3(), blendMode = bmMask a, b: Mask, transform = mat3(), blendMode = bmMask
) {.inline.} = ) {.inline.} =
## Draws a mask onto a mask using a matrix with color blending. ## Draws a mask onto a mask using a matrix with color blending.
when type(transform) is Vec2: when type(transform) is Vec2:
@ -833,7 +833,7 @@ proc draw*(
a.drawUber(b, transform, blendMode) a.drawUber(b, transform, blendMode)
proc draw*( proc draw*(
image: Image, mask: Mask, transform: Mat3 = mat3(), blendMode = bmMask image: Image, mask: Mask, transform = mat3(), blendMode = bmMask
) {.inline.} = ) {.inline.} =
## Draws a mask onto an image using a matrix with color blending. ## Draws a mask onto an image using a matrix with color blending.
when type(transform) is Vec2: when type(transform) is Vec2:
@ -842,7 +842,7 @@ proc draw*(
image.drawUber(mask, transform, blendMode) image.drawUber(mask, transform, blendMode)
proc draw*( proc draw*(
mask: Mask, image: Image, transform: Mat3 = mat3(), blendMode = bmMask mask: Mask, image: Image, transform = mat3(), blendMode = bmMask
) {.inline.} = ) {.inline.} =
## Draws a image onto a mask using a matrix with color blending. ## Draws a image onto a mask using a matrix with color blending.
when type(transform) is Vec2: when type(transform) is Vec2:

View file

@ -17,13 +17,13 @@ type
## Line join type for strokes. ## Line join type for strokes.
ljMiter, ljRound, ljBevel ljMiter, ljRound, ljBevel
PathCommandKind* = enum PathCommandKind = enum
## Type of path commands ## Type of path commands
Close, Close,
Move, Line, HLine, VLine, Cubic, SCubic, Quad, TQuad, Arc, Move, Line, HLine, VLine, Cubic, SCubic, Quad, TQuad, Arc,
RMove, RLine, RHLine, RVLine, RCubic, RSCubic, RQuad, RTQuad, RArc RMove, RLine, RHLine, RVLine, RCubic, RSCubic, RQuad, RTQuad, RArc
PathCommand* = object PathCommand = object
## Binary version of an SVG command. ## Binary version of an SVG command.
kind: PathCommandKind kind: PathCommandKind
numbers: seq[float32] numbers: seq[float32]
@ -50,15 +50,12 @@ proc newPath*(): Path =
## Create a new Path. ## Create a new Path.
Path() Path()
proc pixelScale(transform: Vec2 | Mat3): float32 = proc pixelScale(transform: Mat3): float32 =
## What is the largest scale factor of this transform? ## What is the largest scale factor of this transform?
when type(transform) is Vec2: max(
return 1.0 vec2(transform[0, 0], transform[0, 1]).length,
else: vec2(transform[1, 0], transform[1, 1]).length
max( )
vec2(transform[0, 0], transform[0, 1]).length,
vec2(transform[1, 0], transform[1, 1]).length
)
proc isRelative(kind: PathCommandKind): bool = proc isRelative(kind: PathCommandKind): bool =
kind in { kind in {
@ -507,12 +504,6 @@ proc rect*(path: Path, x, y, w, h: float32, clockwise = true) =
path.lineTo(x + w, y) path.lineTo(x + w, y)
path.closePath() path.closePath()
proc rect*(path: Path, pos: Vec2, wh: Vec2, clockwise = true) {.inline.} =
## Adds a rectangle.
## Clockwise param can be used to subtract a rect from a path when using
## even-odd winding rule.
path.rect(pos.x, pos.y, wh.x, wh.y, clockwise)
proc rect*(path: Path, rect: Rect, clockwise = true) {.inline.} = proc rect*(path: Path, rect: Rect, clockwise = true) {.inline.} =
## Adds a rectangle. ## Adds a rectangle.
## Clockwise param can be used to subtract a rect from a path when using ## Clockwise param can be used to subtract a rect from a path when using
@ -590,14 +581,6 @@ proc roundedRect*(
path.closePath() path.closePath()
proc roundedRect*(
path: Path, pos, wh: Vec2, nw, ne, se, sw: float32, clockwise = true
) {.inline.} =
## Adds a rounded rectangle.
## Clockwise param can be used to subtract a rect from a path when using
## even-odd winding rule.
path.roundedRect(pos.x, pos.y, wh.x, wh.y, nw, ne, se, sw, clockwise)
proc roundedRect*( proc roundedRect*(
path: Path, rect: Rect, nw, ne, se, sw: float32, clockwise = true path: Path, rect: Rect, nw, ne, se, sw: float32, clockwise = true
) {.inline.} = ) {.inline.} =
@ -627,10 +610,6 @@ proc circle*(path: Path, cx, cy, r: float32) {.inline.} =
## Adds a circle. ## Adds a circle.
path.ellipse(cx, cy, r, r) path.ellipse(cx, cy, r, r)
proc circle*(path: Path, center: Vec2, r: float32) {.inline.} =
## Adds a circle.
path.ellipse(center.x, center.y, r, r)
proc circle*(path: Path, circle: Circle) {.inline.} = proc circle*(path: Path, circle: Circle) {.inline.} =
## Adds a circle. ## Adds a circle.
path.ellipse(circle.pos.x, circle.pos.y, circle.radius, circle.radius) path.ellipse(circle.pos.x, circle.pos.y, circle.radius, circle.radius)
@ -648,7 +627,7 @@ proc polygon*(path: Path, pos: Vec2, size: float32, sides: int) {.inline.} =
## Adds a n-sided regular polygon at (x, y) with the parameter size. ## Adds a n-sided regular polygon at (x, y) with the parameter size.
path.polygon(pos.x, pos.y, size, sides) path.polygon(pos.x, pos.y, size, sides)
proc commandsToShapes*( proc commandsToShapes(
path: Path, closeSubpaths = false, pixelScale: float32 = 1.0 path: Path, closeSubpaths = false, pixelScale: float32 = 1.0
): seq[seq[Vec2]] = ): seq[seq[Vec2]] =
## Converts SVG-like commands to sequences of vectors. ## Converts SVG-like commands to sequences of vectors.
@ -1750,22 +1729,16 @@ proc parseSomePath(
elif type(path) is Path: elif type(path) is Path:
path.commandsToShapes(closeSubpaths, pixelScale) path.commandsToShapes(closeSubpaths, pixelScale)
proc transform(shapes: var seq[seq[Vec2]], transform: Vec2 | Mat3) = proc transform(shapes: var seq[seq[Vec2]], transform: Mat3) =
when type(transform) is Vec2: if transform != mat3():
if transform != vec2(): for shape in shapes.mitems:
for shape in shapes.mitems: for segment in shape.mitems:
for segment in shape.mitems: segment = transform * segment
segment += transform
else:
if transform != mat3():
for shape in shapes.mitems:
for segment in shape.mitems:
segment = transform * segment
proc fillPath*( proc fillPath*(
mask: Mask, mask: Mask,
path: SomePath, path: SomePath,
transform: Vec2 | Mat3 = vec2(), transform = mat3(),
windingRule = wrNonZero, windingRule = wrNonZero,
blendMode = bmNormal blendMode = bmNormal
) = ) =
@ -1778,7 +1751,7 @@ proc fillPath*(
image: Image, image: Image,
path: SomePath, path: SomePath,
paint: Paint, paint: Paint,
transform: Vec2 | Mat3 = vec2(), transform = mat3(),
windingRule = wrNonZero windingRule = wrNonZero
) = ) =
## Fills a path. ## Fills a path.
@ -1827,7 +1800,7 @@ proc fillPath*(
proc strokePath*( proc strokePath*(
mask: Mask, mask: Mask,
path: SomePath, path: SomePath,
transform: Vec2 | Mat3 = vec2(), transform = mat3(),
strokeWidth = 1.0, strokeWidth = 1.0,
lineCap = lcButt, lineCap = lcButt,
lineJoin = ljMiter, lineJoin = ljMiter,
@ -1851,7 +1824,7 @@ proc strokePath*(
image: Image, image: Image,
path: SomePath, path: SomePath,
paint: Paint, paint: Paint,
transform: Vec2 | Mat3 = vec2(), transform = mat3(),
strokeWidth = 1.0, strokeWidth = 1.0,
lineCap = lcButt, lineCap = lcButt,
lineJoin = ljMiter, lineJoin = ljMiter,
@ -1948,7 +1921,7 @@ proc overlaps(
proc fillOverlaps*( proc fillOverlaps*(
path: Path, path: Path,
test: Vec2, test: Vec2,
transform: Vec2 | Mat3 = vec2(), ## Applied to the path, not the test point. transform = mat3(), ## Applied to the path, not the test point.
windingRule = wrNonZero windingRule = wrNonZero
): bool = ): bool =
## Returns whether or not the specified point is contained in the current path. ## Returns whether or not the specified point is contained in the current path.
@ -1959,7 +1932,7 @@ proc fillOverlaps*(
proc strokeOverlaps*( proc strokeOverlaps*(
path: Path, path: Path,
test: Vec2, test: Vec2,
transform: Vec2 | Mat3 = vec2(), ## Applied to the path, not the test point. transform = mat3(), ## Applied to the path, not the test point.
strokeWidth = 1.0, strokeWidth = 1.0,
lineCap = lcButt, lineCap = lcButt,
lineJoin = ljMiter, lineJoin = ljMiter,

View file

@ -154,7 +154,7 @@ block:
let image = newImage(200, 100) let image = newImage(200, 100)
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.fillText(font, "First line") image.fillText(font, "First line")
image.fillText(font, "Second line", vec2(0, font.defaultLineHeight)) image.fillText(font, "Second line", translate(vec2(0, font.defaultLineHeight)))
doDiff(image, "basic7") doDiff(image, "basic7")
@ -826,7 +826,7 @@ block:
let arrangement = typeset(spans, bounds = vec2(360, 360)) let arrangement = typeset(spans, bounds = vec2(360, 360))
image.fillText(arrangement, vec2(20, 20)) image.fillText(arrangement, translate(vec2(20, 20)))
doDiff(image, "spans5") doDiff(image, "spans5")
@ -965,7 +965,7 @@ block:
let arrangement = typeset(spans, bounds = vec2(360, 360)) let arrangement = typeset(spans, bounds = vec2(360, 360))
image.fillText(arrangement, vec2(20, 20)) image.fillText(arrangement, translate(vec2(20, 20)))
doDiff(image, "spans6") doDiff(image, "spans6")

View file

@ -213,7 +213,9 @@ block:
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20 Z") path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20 Z")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcRound, ljRound) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcRound, ljRound
)
image.writeFile("tests/images/paths/boxRound.png") image.writeFile("tests/images/paths/boxRound.png")
@ -222,7 +224,9 @@ block:
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20 Z") path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20 Z")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcRound, ljBevel) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcRound, ljBevel
)
image.writeFile("tests/images/paths/boxBevel.png") image.writeFile("tests/images/paths/boxBevel.png")
@ -231,7 +235,9 @@ block:
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20 Z") path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20 Z")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcRound, ljMiter) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcRound, ljMiter
)
image.writeFile("tests/images/paths/boxMiter.png") image.writeFile("tests/images/paths/boxMiter.png")
@ -240,7 +246,9 @@ block:
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20") path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcButt, ljBevel) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcButt, ljBevel
)
image.writeFile("tests/images/paths/lcButt.png") image.writeFile("tests/images/paths/lcButt.png")
@ -249,7 +257,9 @@ block:
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20") path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcRound, ljBevel) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcRound, ljBevel
)
image.writeFile("tests/images/paths/lcRound.png") image.writeFile("tests/images/paths/lcRound.png")
@ -258,7 +268,9 @@ block:
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20") path = parsePath("M 3 3 L 20 3 L 20 20 L 3 20")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcSquare, ljBevel) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcSquare, ljBevel
)
image.writeFile("tests/images/paths/lcSquare.png") image.writeFile("tests/images/paths/lcSquare.png")
@ -269,31 +281,31 @@ block:
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath( image.strokePath(
path, rgba(0, 0, 0, 255), vec2(5, 5), 10, lcButt, ljBevel, path, rgba(0, 0, 0, 255), translate(vec2(5, 5)), 10, lcButt, ljBevel,
) )
image.strokePath( image.strokePath(
path, rgba(0, 0, 0, 255), vec2(5, 25), 10, lcButt, ljBevel, path, rgba(0, 0, 0, 255), translate(vec2(5, 25)), 10, lcButt, ljBevel,
dashes = @[2.float32, 2] dashes = @[2.float32, 2]
) )
image.strokePath( image.strokePath(
path, rgba(0, 0, 0, 255), vec2(5, 45), 10, lcButt, ljBevel, path, rgba(0, 0, 0, 255), translate(vec2(5, 45)), 10, lcButt, ljBevel,
dashes = @[4.float32, 4] dashes = @[4.float32, 4]
) )
image.strokePath( image.strokePath(
path, rgba(0, 0, 0, 255), vec2(5, 65), 10, lcButt, ljBevel, path, rgba(0, 0, 0, 255), translate(vec2(5, 65)), 10, lcButt, ljBevel,
dashes = @[2.float32, 4, 6, 2] dashes = @[2.float32, 4, 6, 2]
) )
image.strokePath( image.strokePath(
path, rgba(0, 0, 0, 255), vec2(5, 85), 10, lcButt, ljBevel, path, rgba(0, 0, 0, 255), translate(vec2(5, 85)), 10, lcButt, ljBevel,
dashes = @[1.float32] dashes = @[1.float32]
) )
image.strokePath( image.strokePath(
path, rgba(0, 0, 0, 255), vec2(5, 105), 10, lcButt, ljBevel, path, rgba(0, 0, 0, 255), translate(vec2(5, 105)), 10, lcButt, ljBevel,
dashes = @[1.float32, 2, 3, 4, 5, 6, 7, 8, 9] dashes = @[1.float32, 2, 3, 4, 5, 6, 7, 8, 9]
) )
@ -311,7 +323,7 @@ block:
path.lineTo(sin(th)*20, cos(th)*20) path.lineTo(sin(th)*20, cos(th)*20)
image.strokePath( image.strokePath(
path, rgba(0, 0, 0, 255), vec2(30, 30), 8, lcButt, ljMiter, path, rgba(0, 0, 0, 255), translate(vec2(30, 30)), 8, lcButt, ljMiter,
miterLimit = limit miterLimit = limit
) )
image.writeFile(&"tests/images/paths/miterLimit_{angle.int}deg_{limit:0.2f}num.png") image.writeFile(&"tests/images/paths/miterLimit_{angle.int}deg_{limit:0.2f}num.png")
@ -340,28 +352,36 @@ block:
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("M 3 3 L 3 3 L 3 3") path = parsePath("M 3 3 L 3 3 L 3 3")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcSquare, ljMiter) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcSquare, ljMiter
)
block: block:
let let
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("L 0 0 L 0 0") path = parsePath("L 0 0 L 0 0")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcSquare, ljMiter) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcSquare, ljMiter
)
block: block:
let let
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("L 1 1") path = parsePath("L 1 1")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcSquare, ljMiter) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcSquare, ljMiter
)
block: block:
let let
image = newImage(60, 60) image = newImage(60, 60)
path = parsePath("L 0 0") path = parsePath("L 0 0")
image.fill(rgba(255, 255, 255, 255)) image.fill(rgba(255, 255, 255, 255))
image.strokePath(path, rgba(0, 0, 0, 255), vec2(10, 10), 10, lcSquare, ljMiter) image.strokePath(
path, rgba(0, 0, 0, 255), translate(vec2(10, 10)), 10, lcSquare, ljMiter
)
block: block:
let image = newImage(100, 100) let image = newImage(100, 100)