diff --git a/README.md b/README.md index 547d1bb..163224b 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,42 @@ This library is being actively developed and is not yet ready for use. Since you ## Testing `nimble test` + +## Examples + +### examples/rounded_rectangle.nim +```nim +var path = newPath() +let + x = 50.0 + y = 50.0 + w = 100.0 + h = 100.0 + nw = 25.0 + ne = 25.0 + se = 25.0 + sw = 25.0 +path.moveTo(x+nw, y) +path.arcTo(x+w, y, x+w, y+h, ne) +path.arcTo(x+w, y+h, x, y+h, se) +path.arcTo(x, y+h, x, y, sw) +path.arcTo(x, y, x+w, y, nw) +path.closePath() +path.closePath() +image.fillPath(path, rgba(255, 0, 0, 255)) +#image.strokePath(path, rgba(0, 0, 0, 255), strokeWidth = 5.0) +``` +![example output](examples/rounded_rectangle.png) + +### examples/square.nim +```nim +var p = newPath() +p.moveTo(50, 50) +p.lineTo(50, 150) +p.lineTo(150, 150) +p.lineTo(150, 50) +p.closePath() +image.fillPath(p, rgba(255, 0, 0, 255)) +#image.strokePath(p, rgba(0, 0, 0, 255), strokeWidth = 5.0) +``` +![example output](examples/square.png) diff --git a/examples/example.nim b/examples/example.nim deleted file mode 100644 index 0262224..0000000 --- a/examples/example.nim +++ /dev/null @@ -1 +0,0 @@ -## Include an example on how to use your library diff --git a/examples/rounded_rectangle.nim b/examples/rounded_rectangle.nim new file mode 100644 index 0000000..28f5896 --- /dev/null +++ b/examples/rounded_rectangle.nim @@ -0,0 +1,25 @@ +import pixie, chroma + +var image = newImageFill(200, 200, rgba(255, 255, 255, 255)) + +var path = newPath() +let + x = 50.0 + y = 50.0 + w = 100.0 + h = 100.0 + nw = 25.0 + ne = 25.0 + se = 25.0 + sw = 25.0 +path.moveTo(x+nw, y) +path.arcTo(x+w, y, x+w, y+h, ne) +path.arcTo(x+w, y+h, x, y+h, se) +path.arcTo(x, y+h, x, y, sw) +path.arcTo(x, y, x+w, y, nw) +path.closePath() +path.closePath() +image.fillPath(path, rgba(255, 0, 0, 255)) +#image.strokePath(path, rgba(0, 0, 0, 255), strokeWidth = 5.0) + +image.writeFile("examples/rounded_rectangle.png") diff --git a/examples/rounded_rectangle.png b/examples/rounded_rectangle.png new file mode 100644 index 0000000..996594e Binary files /dev/null and b/examples/rounded_rectangle.png differ diff --git a/examples/square.nim b/examples/square.nim new file mode 100644 index 0000000..446b6ea --- /dev/null +++ b/examples/square.nim @@ -0,0 +1,14 @@ +import pixie, chroma + +var image = newImageFill(200, 200, rgba(255, 255, 255, 255)) + +var p = newPath() +p.moveTo(50, 50) +p.lineTo(50, 150) +p.lineTo(150, 150) +p.lineTo(150, 50) +p.closePath() +image.fillPath(p, rgba(255, 0, 0, 255)) +#image.strokePath(p, rgba(0, 0, 0, 255), strokeWidth = 5.0) + +image.writeFile("examples/square.png") diff --git a/examples/square.png b/examples/square.png new file mode 100644 index 0000000..1f0a431 Binary files /dev/null and b/examples/square.png differ diff --git a/src/pixie/images.nim b/src/pixie/images.nim index 0eae386..9925d8f 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -32,6 +32,10 @@ proc newImageNoInit*(width, height: int): Image = result.height = height result.data = newSeq[ColorRGBA](width * height) +proc wh*(image: Image): Vec2 {.inline.} = + ## Return with and height as a size vector. + vec2(image.width.float32, image.height.float32) + proc copy*(image: Image): Image = ## Copies an image creating a new image. result = newImage(image.width, image.height) diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index c493832..621f567 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -554,14 +554,14 @@ proc strokePolygons*(ps: seq[seq[Vec2]], strokeWidthR, strokeWidthL: float32): s {.push checks: off, stacktrace: off.} proc fillPolygons*( - image: Image, + size: Vec2, polys: seq[seq[Vec2]], color: ColorRGBA, quality = 4, ): Image = const ep = 0.0001 * PI - result = newImage(image.width, image.height) + result = newImage(size.x.int, size.y.int) proc scanLineHits( polys: seq[seq[Vec2]], @@ -579,7 +579,7 @@ proc fillPolygons*( var at: Vec2 if line.intersects(scan, at): let winding = line.at.y > line.to.y - let x = at.x.clamp(0, image.width.float32) + let x = at.x.clamp(0, size.x) hits.add((x, winding)) hits.sort(proc(a, b: (float32, bool)): int = cmp(a[0], b[0])) @@ -623,103 +623,91 @@ proc fillPolygons*( {.pop.} proc fillPath*( - image: Image, - path: Path, - color: ColorRGBA - ): Image = - let polys = commandsToPolygons(path.commands) - image.fillPolygons(polys, color) + image: Image, + path: Path, + color: ColorRGBA +) = + let + polys = commandsToPolygons(path.commands) + tmp = fillPolygons(image.wh, polys, color) + image.draw(tmp) proc fillPath*( - image: Image, - path: string, - color: ColorRGBA - ): Image = - image.fillPath(parsePath(path), color) - -proc fillPath*( - image: Image, - path: string, - color: ColorRGBA, - pos: Vec2 - ): Image = - var polys = commandsToPolygons(parsePath(path).commands) - for poly in polys.mitems: - for i, p in poly.mpairs: - poly[i] = p + pos - image.fillPolygons(polys, color) - -proc fillPath*( - image: Image, - path: Path, - color: ColorRGBA, - mat: Mat3 - ): Image = + image: Image, + path: Path, + color: ColorRGBA, + mat: Mat3 +) = var polys = commandsToPolygons(path.commands) for poly in polys.mitems: for i, p in poly.mpairs: poly[i] = mat * p - image.fillPolygons(polys, color) + let tmp = fillPolygons(image.wh, polys, color) + image.draw(tmp) proc fillPath*( - image: Image, - path: string, - color: ColorRGBA, - mat: Mat3 - ): Image = + image: Image, + path: string, + color: ColorRGBA, + mat: Mat3 +) = image.fillPath(parsePath(path), color, mat) proc strokePath*( - image: Image, - path: Path, - color: ColorRGBA, - strokeWidth: float32, - # strokeLocation: StrokeLocation, - # strokeCap: StorkeCap, - # strokeJoin: StorkeJoin - ): Image = - let polys = commandsToPolygons(path.commands) - let (strokeL, strokeR) = (strokeWidth/2, strokeWidth/2) - let polys2 = strokePolygons(polys, strokeL, strokeR) - image.fillPolygons(polys2, color) + image: Image, + path: Path, + color: ColorRGBA, + strokeWidth: float32 = 1.0, + # strokeLocation: StrokeLocation, + # strokeCap: StorkeCap, + # strokeJoin: StorkeJoin +) = + let + polys = commandsToPolygons(path.commands) + (strokeL, strokeR) = (strokeWidth/2, strokeWidth/2) + polys2 = strokePolygons(polys, strokeL, strokeR) + tmp = fillPolygons(image.wh, polys2, color) + image.draw(tmp) proc strokePath*( - image: Image, - path: string, - color: ColorRGBA, - strokeWidth: float32 - ): Image = + image: Image, + path: string, + color: ColorRGBA, + strokeWidth: float32 +) = image.strokePath(parsePath(path), color, strokeWidth) proc strokePath*( - image: Image, - path: string, - color: ColorRGBA, - strokeWidth: float32, - pos: Vec2 - ): Image = + image: Image, + path: string, + color: ColorRGBA, + strokeWidth: float32, + pos: Vec2 +) = var polys = commandsToPolygons(parsePath(path).commands) let (strokeL, strokeR) = (strokeWidth/2, strokeWidth/2) var polys2 = strokePolygons(polys, strokeL, strokeR) for poly in polys2.mitems: for i, p in poly.mpairs: poly[i] = p + pos - image.fillPolygons(polys2, color) + let tmp = fillPolygons(image.wh, polys2, color) + image.draw(tmp) proc strokePath*( - image: Image, - path: string, - color: ColorRGBA, - strokeWidth: float32, - mat: Mat3 - ): Image = + image: Image, + path: string, + color: ColorRGBA, + strokeWidth: float32, + mat: Mat3 +) = var polys = commandsToPolygons(parsePath(path).commands) let (strokeL, strokeR) = (strokeWidth/2, strokeWidth/2) var polys2 = strokePolygons(polys, strokeL, strokeR) for poly in polys2.mitems: for i, p in poly.mpairs: poly[i] = mat * p - image.fillPolygons(polys2, color) + let tmp = fillPolygons(image.wh, polys2, color) + image.draw(tmp) proc addPath*(path: Path, other: Path) = ## Adds a path to the current path. diff --git a/tools/gen_readme.nim b/tools/gen_readme.nim new file mode 100644 index 0000000..960b51f --- /dev/null +++ b/tools/gen_readme.nim @@ -0,0 +1,34 @@ +import os, strutils, osproc + +proc cutBetween(str, a, b: string): string = + let + cutA = str.find(a) + cutB = str.find(b) + if cutA == -1 or cutB == -1: + return "" + return str[cutA + a.len..