path as ref object
This commit is contained in:
parent
28067d6979
commit
3f08c2bfa4
|
@ -266,7 +266,7 @@ image.fillPath(
|
|||
### Image tiled
|
||||
[examples/image_tiled.nim](examples/image_tiled.nim)
|
||||
```nim
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.polygon(
|
||||
vec2(100, 100),
|
||||
70,
|
||||
|
|
|
@ -3,7 +3,7 @@ import pixie
|
|||
let image = newImage(200, 200)
|
||||
image.fill(rgba(255, 255, 255, 255))
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.polygon(
|
||||
vec2(100, 100),
|
||||
70,
|
||||
|
|
|
@ -103,7 +103,7 @@ proc fillRect*(
|
|||
transform: Vec2 | Mat3 = vec2(0, 0)
|
||||
) =
|
||||
## Fills a rectangle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(rect)
|
||||
mask.fillPath(path, transform)
|
||||
|
||||
|
@ -114,7 +114,7 @@ proc strokeRect*(
|
|||
strokeWidth = 1.0
|
||||
) =
|
||||
## Strokes a rectangle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(rect)
|
||||
mask.strokePath(path, transform, strokeWidth)
|
||||
|
||||
|
@ -125,7 +125,7 @@ proc fillRoundedRect*(
|
|||
transform: Vec2 | Mat3 = vec2(0, 0)
|
||||
) =
|
||||
## Fills a rounded rectangle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.roundedRect(rect, nw, ne, se, sw)
|
||||
mask.fillPath(path, transform)
|
||||
|
||||
|
@ -136,7 +136,7 @@ proc fillRoundedRect*(
|
|||
transform: Vec2 | Mat3 = vec2(0, 0)
|
||||
) =
|
||||
## Fills a rounded rectangle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.roundedRect(rect, radius, radius, radius, radius)
|
||||
mask.fillPath(path, transform)
|
||||
|
||||
|
@ -148,7 +148,7 @@ proc strokeRoundedRect*(
|
|||
strokeWidth = 1.0
|
||||
) =
|
||||
## Strokes a rounded rectangle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.roundedRect(rect, nw, ne, se, sw)
|
||||
mask.strokePath(path, transform, strokeWidth)
|
||||
|
||||
|
@ -160,7 +160,7 @@ proc strokeRoundedRect*(
|
|||
strokeWidth = 1.0
|
||||
) =
|
||||
## Strokes a rounded rectangle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.roundedRect(rect, radius, radius, radius, radius)
|
||||
mask.strokePath(path, transform, strokeWidth)
|
||||
|
||||
|
@ -171,7 +171,7 @@ proc strokeSegment*(
|
|||
strokeWidth = 1.0
|
||||
) =
|
||||
## Strokes a segment (draws a line from segment.at to segment.to).
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.moveTo(segment.at)
|
||||
path.lineTo(segment.to)
|
||||
mask.strokePath(path, transform, strokeWidth)
|
||||
|
@ -183,7 +183,7 @@ proc fillEllipse*(
|
|||
transform: Vec2 | Mat3 = vec2(0, 0)
|
||||
) =
|
||||
## Fills an ellipse.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(center, rx, ry)
|
||||
mask.fillPath(path, transform)
|
||||
|
||||
|
@ -195,7 +195,7 @@ proc strokeEllipse*(
|
|||
strokeWidth = 1.0
|
||||
) =
|
||||
## Strokes an ellipse.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(center, rx, ry)
|
||||
mask.strokePath(path, transform, strokeWidth)
|
||||
|
||||
|
@ -206,7 +206,7 @@ proc fillCircle*(
|
|||
transform: Vec2 | Mat3 = vec2(0, 0)
|
||||
) =
|
||||
## Fills a circle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(center, radius, radius)
|
||||
mask.fillPath(path, transform)
|
||||
|
||||
|
@ -218,7 +218,7 @@ proc strokeCircle*(
|
|||
strokeWidth = 1.0
|
||||
) =
|
||||
## Strokes a circle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(center, radius, radius)
|
||||
mask.fillPath(path, transform, strokeWidth)
|
||||
|
||||
|
@ -230,7 +230,7 @@ proc fillPolygon*(
|
|||
transform: Vec2 | Mat3 = vec2(0, 0)
|
||||
) =
|
||||
## Fills a polygon.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.polygon(pos, size, sides)
|
||||
mask.fillPath(path, transform)
|
||||
|
||||
|
@ -243,6 +243,6 @@ proc strokePolygon*(
|
|||
strokeWidth = 1.0
|
||||
) =
|
||||
## Strokes a polygon.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.polygon(pos, size, sides)
|
||||
mask.strokePath(path, transform, strokeWidth)
|
||||
|
|
|
@ -49,6 +49,7 @@ proc newContext*(image: Image): Context =
|
|||
result = Context()
|
||||
result.image = image
|
||||
result.mat = mat3()
|
||||
result.path = newPath()
|
||||
result.globalAlpha = 1
|
||||
result.lineWidth = 1
|
||||
result.miterLimit = 10
|
||||
|
@ -233,7 +234,7 @@ proc strokeText(ctx: Context, image: Image, text: string, at: Vec2) =
|
|||
|
||||
proc beginPath*(ctx: Context) {.inline.} =
|
||||
## Starts a new path by emptying the list of sub-paths.
|
||||
ctx.path = Path()
|
||||
ctx.path = newPath()
|
||||
|
||||
proc moveTo*(ctx: Context, v: Vec2) {.inline.} =
|
||||
## Begins a new sub-path at the point (x, y).
|
||||
|
@ -355,7 +356,7 @@ proc stroke*(ctx: Context) {.inline.} =
|
|||
|
||||
proc clearRect*(ctx: Context, rect: Rect) =
|
||||
## Erases the pixels in a rectangular area.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(rect)
|
||||
if ctx.layer != nil:
|
||||
ctx.layer.fillPath(
|
||||
|
@ -376,7 +377,7 @@ proc clearRect*(ctx: Context, x, y, width, height: float32) {.inline.} =
|
|||
|
||||
proc fillRect*(ctx: Context, rect: Rect) =
|
||||
## Draws a rectangle that is filled according to the current fillStyle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(rect)
|
||||
ctx.fill(path)
|
||||
|
||||
|
@ -387,7 +388,7 @@ proc fillRect*(ctx: Context, x, y, width, height: float32) {.inline.} =
|
|||
proc strokeRect*(ctx: Context, rect: Rect) =
|
||||
## Draws a rectangle that is stroked (outlined) according to the current
|
||||
## strokeStyle and other context settings.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(rect)
|
||||
ctx.stroke(path)
|
||||
|
||||
|
@ -520,7 +521,7 @@ proc polygon*(ctx: Context, pos: Vec2, size: float32, sides: int) {.inline.} =
|
|||
|
||||
proc fillRoundedRect*(ctx: Context, rect: Rect, nw, ne, se, sw: float32) =
|
||||
## Draws a rounded rectangle that is filled according to the current fillStyle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.roundedRect(rect, nw, ne, se, sw)
|
||||
ctx.fill(path)
|
||||
|
||||
|
@ -531,7 +532,7 @@ proc fillRoundedRect*(ctx: Context, rect: Rect, radius: float32) {.inline.} =
|
|||
proc strokeRoundedRect*(ctx: Context, rect: Rect, nw, ne, se, sw: float32) =
|
||||
## Draws a rounded rectangle that is stroked (outlined) according to the
|
||||
## current strokeStyle and other context settings.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.roundedRect(rect, nw, ne, se, sw)
|
||||
ctx.stroke(path)
|
||||
|
||||
|
@ -543,61 +544,61 @@ proc strokeRoundedRect*(ctx: Context, rect: Rect, radius: float32) {.inline.} =
|
|||
proc strokeSegment*(ctx: Context, segment: Segment) =
|
||||
## Strokes a segment (draws a line from segment.at to segment.to) according
|
||||
## to the current strokeStyle and other context settings.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.moveTo(segment.at)
|
||||
path.lineTo(segment.to)
|
||||
ctx.stroke(path)
|
||||
|
||||
proc fillEllipse*(ctx: Context, center: Vec2, rx, ry: float32) =
|
||||
## Draws an ellipse that is filled according to the current fillStyle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(center, rx, ry)
|
||||
ctx.fill(path)
|
||||
|
||||
proc strokeEllipse*(ctx: Context, center: Vec2, rx, ry: float32) =
|
||||
## Draws an ellipse that is stroked (outlined) according to the current
|
||||
## strokeStyle and other context settings.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(center, rx, ry)
|
||||
ctx.stroke(path)
|
||||
|
||||
proc fillCircle*(ctx: Context, circle: Circle) =
|
||||
## Draws a circle that is filled according to the current fillStyle
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.circle(circle.pos, circle.radius)
|
||||
ctx.fill(path)
|
||||
|
||||
proc fillCircle*(ctx: Context, center: Vec2, radius: float32) =
|
||||
## Draws a circle that is filled according to the current fillStyle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(center, radius, radius)
|
||||
ctx.fill(path)
|
||||
|
||||
proc strokeCircle*(ctx: Context, circle: Circle) =
|
||||
## Draws a circle that is stroked (outlined) according to the current
|
||||
## strokeStyle and other context settings.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.circle(circle.pos, circle.radius)
|
||||
ctx.stroke(path)
|
||||
|
||||
proc strokeCircle*(ctx: Context, center: Vec2, radius: float32) =
|
||||
## Draws a circle that is stroked (outlined) according to the current
|
||||
## strokeStyle and other context settings.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(center, radius, radius)
|
||||
ctx.stroke(path)
|
||||
|
||||
proc fillPolygon*(ctx: Context, pos: Vec2, size: float32, sides: int) =
|
||||
## Draws an n-sided regular polygon at (x, y) of size that is filled according
|
||||
## to the current fillStyle.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.polygon(pos, size, sides)
|
||||
ctx.fill(path)
|
||||
|
||||
proc strokePolygon*(ctx: Context, pos: Vec2, size: float32, sides: int) =
|
||||
## Draws an n-sided regular polygon at (x, y) of size that is stroked
|
||||
## (outlined) according to the current strokeStyle and other context settings.
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.polygon(pos, size, sides)
|
||||
ctx.stroke(path)
|
||||
|
||||
|
@ -610,7 +611,7 @@ proc drawImage*(ctx: Context, image: Image, dx, dy, dWidth, dHeight: float32) =
|
|||
))
|
||||
savedStyle = ctx.fillStyle
|
||||
ctx.fillStyle = Paint(kind: pkImage, image: image, imageMat: imageMat)
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(rect(dx, dy, dWidth, dHeight))
|
||||
ctx.fill(path)
|
||||
ctx.fillStyle = savedStyle
|
||||
|
|
|
@ -376,7 +376,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
x2 = parseFloat(node.attrOrDefault("x2", "0"))
|
||||
y2 = parseFloat(node.attrOrDefault("y2", "0"))
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.moveTo(x1, y1)
|
||||
path.lineTo(x2, y2)
|
||||
|
||||
|
@ -405,7 +405,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
if vecs.len == 0:
|
||||
failInvalid()
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.moveTo(vecs[0])
|
||||
for i in 1 ..< vecs.len:
|
||||
path.lineTo(vecs[i])
|
||||
|
@ -434,7 +434,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
rx = max(parseFloat(node.attrOrDefault("rx", "0")), 0)
|
||||
ry = max(parseFloat(node.attrOrDefault("ry", "0")), 0)
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
if rx > 0 or ry > 0:
|
||||
if rx == 0:
|
||||
rx = ry
|
||||
|
@ -473,7 +473,7 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
|
|||
rx = parseFloat(node.attrOrDefault("rx", "0"))
|
||||
ry = parseFloat(node.attrOrDefault("ry", "0"))
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(cx, cy, rx, ry)
|
||||
|
||||
img.fill(ctx, path)
|
||||
|
|
|
@ -1229,6 +1229,9 @@ proc parseGlyph(opentype: OpenType, glyphId: uint16): Path
|
|||
proc parseGlyphPath(buf: string, offset, numberOfContours: int): Path =
|
||||
if numberOfContours < 0:
|
||||
raise newException(PixieError, "Glyph numberOfContours must be >= 0")
|
||||
|
||||
result = newPath()
|
||||
|
||||
if numberOfContours == 0:
|
||||
return
|
||||
|
||||
|
@ -1357,6 +1360,8 @@ proc parseGlyphPath(buf: string, offset, numberOfContours: int): Path =
|
|||
result.closePath()
|
||||
|
||||
proc parseCompositeGlyph(opentype: OpenType, offset: int): Path =
|
||||
result = newPath()
|
||||
|
||||
var
|
||||
i = offset
|
||||
moreComponents = true
|
||||
|
@ -1458,7 +1463,7 @@ proc parseGlyph(opentype: OpenType, glyphId: uint16): Path =
|
|||
if glyphId.int + 1 < opentype.glyf.offsets.len and
|
||||
glyphOffset == opentype.glyf.offsets[glyphId + 1]:
|
||||
# Empty glyph
|
||||
return
|
||||
return Path()
|
||||
|
||||
var i = glyphOffset.int
|
||||
opentype.buf.eofCheck(i + 10)
|
||||
|
|
|
@ -94,11 +94,12 @@ proc strikeoutThickness(typeface: Typeface): float32 {.inline.} =
|
|||
|
||||
proc getGlyphPath*(typeface: Typeface, rune: Rune): Path {.inline.} =
|
||||
## The glyph path for the rune.
|
||||
result = newPath()
|
||||
if rune.uint32 > SP.uint32: # Empty paths for control runes (not tofu)
|
||||
if typeface.opentype != nil:
|
||||
result = typeface.opentype.getGlyphPath(rune)
|
||||
result.addPath(typeface.opentype.getGlyphPath(rune))
|
||||
else:
|
||||
result = typeface.svgFont.getGlyphPath(rune)
|
||||
result.addPath(typeface.svgFont.getGlyphPath(rune))
|
||||
|
||||
proc getAdvance*(typeface: Typeface, rune: Rune): float32 {.inline.} =
|
||||
## The advance for the rune in pixels.
|
||||
|
|
|
@ -28,7 +28,7 @@ type
|
|||
kind: PathCommandKind
|
||||
numbers: seq[float32]
|
||||
|
||||
Path* = object
|
||||
Path* = ref object
|
||||
## Used to hold paths and create paths.
|
||||
commands: seq[PathCommand]
|
||||
start, at: Vec2 # Maintained by moveTo, lineTo, etc. Used by arcTo.
|
||||
|
@ -46,6 +46,10 @@ const
|
|||
when defined(release):
|
||||
{.push checks: off.}
|
||||
|
||||
proc newPath*(): Path =
|
||||
## Create a new Path.
|
||||
Path()
|
||||
|
||||
proc pixelScale(transform: Vec2 | Mat3): float32 =
|
||||
## What is the largest scale factor of this transform?
|
||||
when type(transform) is Vec2:
|
||||
|
@ -104,6 +108,7 @@ proc `$`*(path: Path): string =
|
|||
|
||||
proc parsePath*(path: string): Path =
|
||||
## Converts a SVG style path string into seq of commands.
|
||||
result = newPath()
|
||||
|
||||
if path.len == 0:
|
||||
return
|
||||
|
@ -123,7 +128,7 @@ proc parsePath*(path: string): Path =
|
|||
numberStart = 0
|
||||
hitDecimal = false
|
||||
|
||||
proc finishCommand(result: var Path) =
|
||||
proc finishCommand(result: Path) =
|
||||
finishNumber()
|
||||
|
||||
if armed: # The first finishCommand() arms
|
||||
|
@ -247,7 +252,7 @@ proc parsePath*(path: string): Path =
|
|||
|
||||
finishCommand(result)
|
||||
|
||||
proc transform*(path: var Path, mat: Mat3) =
|
||||
proc transform*(path: Path, mat: Mat3) =
|
||||
## Apply a matrix transform to a path.
|
||||
if mat == mat3():
|
||||
return
|
||||
|
@ -312,39 +317,39 @@ proc transform*(path: var Path, mat: Mat3) =
|
|||
command.numbers[5] = to.x
|
||||
command.numbers[6] = to.y
|
||||
|
||||
proc addPath*(path: var Path, other: Path) =
|
||||
proc addPath*(path: Path, other: Path) =
|
||||
## Adds a path to the current path.
|
||||
path.commands.add(other.commands)
|
||||
|
||||
proc closePath*(path: var Path) =
|
||||
proc closePath*(path: Path) =
|
||||
## Attempts to add a straight line from the current point to the start of
|
||||
## the current sub-path. If the shape has already been closed or has only
|
||||
## one point, this function does nothing.
|
||||
path.commands.add(PathCommand(kind: Close))
|
||||
path.at = path.start
|
||||
|
||||
proc moveTo*(path: var Path, x, y: float32) =
|
||||
proc moveTo*(path: Path, x, y: float32) =
|
||||
## Begins a new sub-path at the point (x, y).
|
||||
path.commands.add(PathCommand(kind: Move, numbers: @[x, y]))
|
||||
path.start = vec2(x, y)
|
||||
path.at = path.start
|
||||
|
||||
proc moveTo*(path: var Path, v: Vec2) {.inline.} =
|
||||
proc moveTo*(path: Path, v: Vec2) {.inline.} =
|
||||
## Begins a new sub-path at the point (x, y).
|
||||
path.moveTo(v.x, v.y)
|
||||
|
||||
proc lineTo*(path: var Path, x, y: float32) =
|
||||
proc lineTo*(path: Path, x, y: float32) =
|
||||
## Adds a straight line to the current sub-path by connecting the sub-path's
|
||||
## last point to the specified (x, y) coordinates.
|
||||
path.commands.add(PathCommand(kind: Line, numbers: @[x, y]))
|
||||
path.at = vec2(x, y)
|
||||
|
||||
proc lineTo*(path: var Path, v: Vec2) {.inline.} =
|
||||
proc lineTo*(path: Path, v: Vec2) {.inline.} =
|
||||
## Adds a straight line to the current sub-path by connecting the sub-path's
|
||||
## last point to the specified (x, y) coordinates.
|
||||
path.lineTo(v.x, v.y)
|
||||
|
||||
proc bezierCurveTo*(path: var Path, x1, y1, x2, y2, x3, y3: float32) =
|
||||
proc bezierCurveTo*(path: Path, x1, y1, x2, y2, x3, y3: float32) =
|
||||
## Adds a cubic Bézier curve to the current sub-path. It requires three
|
||||
## points: the first two are control points and the third one is the end
|
||||
## point. The starting point is the latest point in the current path,
|
||||
|
@ -355,14 +360,14 @@ proc bezierCurveTo*(path: var Path, x1, y1, x2, y2, x3, y3: float32) =
|
|||
))
|
||||
path.at = vec2(x3, y3)
|
||||
|
||||
proc bezierCurveTo*(path: var Path, ctrl1, ctrl2, to: Vec2) {.inline.} =
|
||||
proc bezierCurveTo*(path: Path, ctrl1, ctrl2, to: Vec2) {.inline.} =
|
||||
## Adds a cubic Bézier curve to the current sub-path. It requires three
|
||||
## points: the first two are control points and the third one is the end
|
||||
## point. The starting point is the latest point in the current path,
|
||||
## which can be changed using moveTo() before creating the Bézier curve.
|
||||
path.bezierCurveTo(ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, to.x, to.y)
|
||||
|
||||
proc quadraticCurveTo*(path: var Path, x1, y1, x2, y2: float32) =
|
||||
proc quadraticCurveTo*(path: Path, x1, y1, x2, y2: float32) =
|
||||
## Adds a quadratic Bézier curve to the current sub-path. It requires two
|
||||
## points: the first one is a control point and the second one is the end
|
||||
## point. The starting point is the latest point in the current path,
|
||||
|
@ -374,7 +379,7 @@ proc quadraticCurveTo*(path: var Path, x1, y1, x2, y2: float32) =
|
|||
))
|
||||
path.at = vec2(x2, y2)
|
||||
|
||||
proc quadraticCurveTo*(path: var Path, ctrl, to: Vec2) {.inline.} =
|
||||
proc quadraticCurveTo*(path: Path, ctrl, to: Vec2) {.inline.} =
|
||||
## Adds a quadratic Bézier curve to the current sub-path. It requires two
|
||||
## points: the first one is a control point and the second one is the end
|
||||
## point. The starting point is the latest point in the current path,
|
||||
|
@ -383,7 +388,7 @@ proc quadraticCurveTo*(path: var Path, ctrl, to: Vec2) {.inline.} =
|
|||
path.quadraticCurveTo(ctrl.x, ctrl.y, to.x, to.y)
|
||||
|
||||
proc ellipticalArcTo*(
|
||||
path: var Path,
|
||||
path: Path,
|
||||
rx, ry: float32,
|
||||
xAxisRotation: float32,
|
||||
largeArcFlag, sweepFlag: bool,
|
||||
|
@ -399,7 +404,7 @@ proc ellipticalArcTo*(
|
|||
))
|
||||
path.at = vec2(x, y)
|
||||
|
||||
proc arc*(path: var Path, x, y, r, a0, a1: float32, ccw: bool) =
|
||||
proc arc*(path: Path, x, y, r, a0, a1: float32, ccw: bool) =
|
||||
## Adds a circular arc to the current sub-path.
|
||||
if r == 0: # When radius is zero, do nothing.
|
||||
return
|
||||
|
@ -436,11 +441,11 @@ proc arc*(path: var Path, x, y, r, a0, a1: float32, ccw: bool) =
|
|||
path.at.y = y + r * sin(a1)
|
||||
path.ellipticalArcTo(r, r, 0, angle >= PI, cw, path.at.x, path.at.y)
|
||||
|
||||
proc arc*(path: var Path, pos: Vec2, r: float32, a: Vec2, ccw: bool = false) =
|
||||
proc arc*(path: Path, pos: Vec2, r: float32, a: Vec2, ccw: bool = false) =
|
||||
## Adds a circular arc to the current sub-path.
|
||||
path.arc(pos.x, pos.y, r, a.x, a.y, ccw)
|
||||
|
||||
proc arcTo*(path: var Path, x1, y1, x2, y2, r: float32) =
|
||||
proc arcTo*(path: Path, x1, y1, x2, y2, r: float32) =
|
||||
## Adds a circular arc using the given control points and radius.
|
||||
## Commonly used for making rounded corners.
|
||||
if r < 0: # When radius is negative, error.
|
||||
|
@ -481,11 +486,11 @@ proc arcTo*(path: var Path, x1, y1, x2, y2, r: float32) =
|
|||
path.at.y = y1 + t21 * y21
|
||||
path.ellipticalArcTo(r, r, 0, false, y01 * x20 > x01 * y20, path.at.x, path.at.y)
|
||||
|
||||
proc arcTo*(path: var Path, a, b: Vec2, r: float32) =
|
||||
proc arcTo*(path: Path, a, b: Vec2, r: float32) =
|
||||
## Adds a circular arc using the given control points and radius.
|
||||
path.arcTo(a.x, a.y, b.x, b.y, r)
|
||||
|
||||
proc rect*(path: var Path, x, y, w, h: float32, clockwise = true) =
|
||||
proc rect*(path: Path, x, y, w, h: float32, clockwise = true) =
|
||||
## Adds a rectangle.
|
||||
## Clockwise param can be used to subtract a rect from a path when using
|
||||
## even-odd winding rule.
|
||||
|
@ -502,13 +507,13 @@ proc rect*(path: var Path, x, y, w, h: float32, clockwise = true) =
|
|||
path.lineTo(x + w, y)
|
||||
path.closePath()
|
||||
|
||||
proc rect*(path: var Path, pos: Vec2, wh: Vec2, clockwise = true) {.inline.} =
|
||||
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: var Path, rect: Rect, clockwise = true) {.inline.} =
|
||||
proc rect*(path: Path, rect: Rect, clockwise = true) {.inline.} =
|
||||
## Adds a rectangle.
|
||||
## Clockwise param can be used to subtract a rect from a path when using
|
||||
## even-odd winding rule.
|
||||
|
@ -519,7 +524,7 @@ const splineCircleK = 4.0 * (-1.0 + sqrt(2.0)) / 3
|
|||
## https://dl3.pushbulletusercontent.com/a3fLVC8boTzRoxevD1OgCzRzERB9z2EZ/unknown.png
|
||||
|
||||
proc roundedRect*(
|
||||
path: var Path, x, y, w, h, nw, ne, se, sw: float32, clockwise = true
|
||||
path: Path, x, y, w, h, nw, ne, se, sw: float32, clockwise = true
|
||||
) =
|
||||
## Adds a rounded rectangle.
|
||||
## Clockwise param can be used to subtract a rect from a path when using
|
||||
|
@ -586,7 +591,7 @@ proc roundedRect*(
|
|||
path.closePath()
|
||||
|
||||
proc roundedRect*(
|
||||
path: var Path, pos, wh: Vec2, nw, ne, se, sw: float32, clockwise = true
|
||||
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
|
||||
|
@ -594,14 +599,14 @@ proc roundedRect*(
|
|||
path.roundedRect(pos.x, pos.y, wh.x, wh.y, nw, ne, se, sw, clockwise)
|
||||
|
||||
proc roundedRect*(
|
||||
path: var Path, rect: Rect, nw, ne, se, sw: float32, clockwise = true
|
||||
path: Path, rect: Rect, 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(rect.x, rect.y, rect.w, rect.h, nw, ne, se, sw, clockwise)
|
||||
|
||||
proc ellipse*(path: var Path, cx, cy, rx, ry: float32) =
|
||||
proc ellipse*(path: Path, cx, cy, rx, ry: float32) =
|
||||
## Adds a ellipse.
|
||||
let
|
||||
magicX = splineCircleK * rx
|
||||
|
@ -614,23 +619,23 @@ proc ellipse*(path: var Path, cx, cy, rx, ry: float32) =
|
|||
path.bezierCurveTo(cx + magicX, cy - ry, cx + rx, cy - magicY, cx + rx, cy)
|
||||
path.closePath()
|
||||
|
||||
proc ellipse*(path: var Path, center: Vec2, rx, ry: float32) {.inline.} =
|
||||
proc ellipse*(path: Path, center: Vec2, rx, ry: float32) {.inline.} =
|
||||
## Adds a ellipse.
|
||||
path.ellipse(center.x, center.y, rx, ry)
|
||||
|
||||
proc circle*(path: var Path, cx, cy, r: float32) {.inline.} =
|
||||
proc circle*(path: Path, cx, cy, r: float32) {.inline.} =
|
||||
## Adds a circle.
|
||||
path.ellipse(cx, cy, r, r)
|
||||
|
||||
proc circle*(path: var Path, center: Vec2, r: float32) {.inline.} =
|
||||
proc circle*(path: Path, center: Vec2, r: float32) {.inline.} =
|
||||
## Adds a circle.
|
||||
path.ellipse(center.x, center.y, r, r)
|
||||
|
||||
proc circle*(path: var Path, circle: Circle) {.inline.} =
|
||||
proc circle*(path: Path, circle: Circle) {.inline.} =
|
||||
## Adds a circle.
|
||||
path.ellipse(circle.pos.x, circle.pos.y, circle.radius, circle.radius)
|
||||
|
||||
proc polygon*(path: var Path, x, y, size: float32, sides: int) =
|
||||
proc polygon*(path: Path, x, y, size: float32, sides: int) =
|
||||
## Adds an n-sided regular polygon at (x, y) with the parameter size.
|
||||
path.moveTo(x + size * cos(0.0), y + size * sin(0.0))
|
||||
for side in 0 .. sides:
|
||||
|
@ -639,7 +644,7 @@ proc polygon*(path: var Path, x, y, size: float32, sides: int) =
|
|||
y + size * sin(side.float32 * 2.0 * PI / sides.float32)
|
||||
)
|
||||
|
||||
proc polygon*(path: var Path, pos: Vec2, size: float32, sides: int) {.inline.} =
|
||||
proc polygon*(path: 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)
|
||||
|
||||
|
@ -1611,7 +1616,7 @@ proc strokeShapes(
|
|||
miterAngleLimit = miterLimitToAngle(miterLimit)
|
||||
|
||||
proc makeCircle(at: Vec2): seq[Vec2] =
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(at, halfStroke, halfStroke)
|
||||
path.commandsToShapes()[0]
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ block:
|
|||
block:
|
||||
let ctx = newContext(newImage(300, 150))
|
||||
|
||||
var region: Path
|
||||
let region = newPath()
|
||||
region.moveTo(30, 90)
|
||||
region.lineTo(110, 20)
|
||||
region.lineTo(240, 130)
|
||||
|
@ -438,7 +438,7 @@ block:
|
|||
block:
|
||||
let ctx = newContext(newImage(300, 150))
|
||||
|
||||
var region: Path
|
||||
let region = newPath()
|
||||
region.rect(80, 10, 20, 130)
|
||||
region.rect(40, 50, 100, 50)
|
||||
ctx.clip(region, wrEvenOdd)
|
||||
|
@ -453,9 +453,9 @@ block:
|
|||
|
||||
let ctx = newContext(image)
|
||||
|
||||
var circlePath: Path
|
||||
var circlePath = newPath()
|
||||
circlePath.circle(150, 75, 75)
|
||||
var squarePath: Path
|
||||
var squarePath = newPath()
|
||||
squarePath.rect(85, 10, 130, 130)
|
||||
|
||||
ctx.clip(circlePath)
|
||||
|
@ -476,7 +476,7 @@ block:
|
|||
|
||||
ctx.saveLayer()
|
||||
|
||||
var circlePath: Path
|
||||
var circlePath = newPath()
|
||||
circlePath.circle(150, 75, 75)
|
||||
|
||||
ctx.clip(circlePath)
|
||||
|
|
|
@ -144,7 +144,7 @@ block: # Test conversion between image and mask
|
|||
originalImage = newImage(100, 100)
|
||||
originalMask = newMask(100, 100)
|
||||
|
||||
var p: Path
|
||||
let p = newPath()
|
||||
p.rect(10, 10, 80, 80)
|
||||
|
||||
originalImage.fillPath(p, rgba(255, 0, 0, 255))
|
||||
|
@ -157,7 +157,7 @@ block: # Test conversion between image and mask
|
|||
doAssert newImage(newMask(originalImage)).data == newImage(originalMask).data
|
||||
|
||||
block:
|
||||
var p: Path
|
||||
let p = newPath()
|
||||
p.roundedRect(10, 10, 80, 80, 10, 10, 10, 10)
|
||||
|
||||
let image = newImage(100, 100)
|
||||
|
|
|
@ -21,7 +21,7 @@ block:
|
|||
y = 10.0
|
||||
h = 80.0
|
||||
w = 80.0
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.moveTo(x + r, y)
|
||||
# path.arcTo(x + w, y, x + w, y + h, r)
|
||||
# path.arcTo(x + w, y + h, x, y + h, r)
|
||||
|
@ -40,7 +40,7 @@ block:
|
|||
let image = newImage(100, 100)
|
||||
image.fill(rgba(255, 100, 100, 255))
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(image.width / 2, image.height / 2, 25, 25)
|
||||
|
||||
let mask = newMask(image.width, image.height)
|
||||
|
@ -53,7 +53,7 @@ block:
|
|||
let a = newMask(100, 100)
|
||||
a.fill(255)
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(a.width / 2, a.height / 2, 25, 25)
|
||||
|
||||
let b = newMask(a.width, a.height)
|
||||
|
@ -66,7 +66,7 @@ block:
|
|||
let a = newMask(100, 100)
|
||||
a.fill(255)
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(a.width / 2, a.height / 2, 25, 25)
|
||||
|
||||
let b = newImage(a.width, a.height)
|
||||
|
@ -82,7 +82,7 @@ block:
|
|||
writeFile("tests/images/masks/shifted.png", a.encodePng())
|
||||
|
||||
block:
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(40, 40, 20, 20)
|
||||
|
||||
let a = newMask(100, 100)
|
||||
|
@ -95,7 +95,7 @@ block:
|
|||
block:
|
||||
let mask = newMask(100, 100)
|
||||
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(mask.width / 2, mask.height / 2, 25, 25)
|
||||
|
||||
mask.fillPath(path)
|
||||
|
|
|
@ -98,7 +98,7 @@ block:
|
|||
image.writeFile("tests/images/paths/pathYellowRectangle.png")
|
||||
|
||||
block:
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.moveTo(10, 10)
|
||||
path.lineTo(10, 90)
|
||||
path.lineTo(90, 90)
|
||||
|
@ -163,7 +163,7 @@ block:
|
|||
# y = 10.0
|
||||
# h = 80.0
|
||||
# w = 80.0
|
||||
# var path: Path
|
||||
# let path = newPath()
|
||||
# path.moveTo(x + r, y)
|
||||
# path.arcTo(x + w, y, x + w, y + h, r)
|
||||
# path.arcTo(x + w, y + h, x, y + h, r)
|
||||
|
@ -187,7 +187,7 @@ block:
|
|||
# y = 10.0
|
||||
# h = 80.0
|
||||
# w = 80.0
|
||||
# var path: Path
|
||||
# let path = newPath()
|
||||
# path.moveTo(x + r, y)
|
||||
# path.arcTo(x + w, y, x + w, y + h, r)
|
||||
# path.arcTo(x + w, y + h, x, y + h, r)
|
||||
|
@ -304,7 +304,7 @@ block:
|
|||
let
|
||||
image = newImage(60, 60)
|
||||
image.fill(rgba(255, 255, 255, 255))
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.moveTo(-20, 0)
|
||||
path.lineTo(0, 0)
|
||||
let th = angle.float32.degToRad() + PI/2
|
||||
|
@ -532,7 +532,7 @@ block:
|
|||
surface.writeFile("tests/images/paths/arcTo3.png")
|
||||
|
||||
block:
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(0, 0, 10, 10)
|
||||
|
||||
doAssert path.fillOverlaps(vec2(5, 5))
|
||||
|
@ -542,7 +542,7 @@ block:
|
|||
doAssert not path.fillOverlaps(vec2(10, 10))
|
||||
|
||||
block:
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(20, 20, 20, 10)
|
||||
|
||||
doAssert not path.fillOverlaps(vec2(0, 0))
|
||||
|
@ -551,7 +551,7 @@ block:
|
|||
doAssert path.fillOverlaps(vec2(30, 20))
|
||||
|
||||
block:
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.rect(10, 10, 10, 10)
|
||||
|
||||
doAssert path.strokeOverlaps(vec2(10, 10))
|
||||
|
@ -559,7 +559,7 @@ block:
|
|||
doAssert not path.strokeOverlaps(vec2(5, 5))
|
||||
|
||||
block:
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.ellipse(20, 20, 20, 10)
|
||||
|
||||
doAssert not path.strokeOverlaps(vec2(0, 0))
|
||||
|
@ -570,7 +570,7 @@ block:
|
|||
doAssert not path.strokeOverlaps(vec2(19.4, 30.6))
|
||||
|
||||
block:
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.circle(50, 50, 30)
|
||||
|
||||
var paint = Paint(kind: pkSolid, color: rgba(255, 0, 255, 255))
|
||||
|
@ -582,7 +582,7 @@ block:
|
|||
image.writeFile("tests/images/paths/opacityFill.png")
|
||||
|
||||
block:
|
||||
var path: Path
|
||||
let path = newPath()
|
||||
path.circle(50, 50, 30)
|
||||
|
||||
var paint = Paint(kind: pkSolid, color: rgba(255, 0, 255, 255))
|
||||
|
|
Loading…
Reference in a new issue