commit
a5b3f6a5a6
44 changed files with 178 additions and 147 deletions
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma, vmath
|
import chroma, pixie, vmath
|
||||||
|
|
||||||
let
|
let
|
||||||
trees = readImage("examples/data/trees.png")
|
trees = readImage("examples/data/trees.png")
|
||||||
|
@ -8,7 +8,7 @@ let
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
||||||
var p: Path
|
var p: Path
|
||||||
p.polygon(100, 100, 70, sides=6)
|
p.polygon(100, 100, 70, sides = 6)
|
||||||
p.closePath()
|
p.closePath()
|
||||||
|
|
||||||
let mask = newMask(200, 200)
|
let mask = newMask(200, 200)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma, vmath
|
import chroma, pixie, vmath
|
||||||
|
|
||||||
let
|
let
|
||||||
image = newImage(200, 200)
|
image = newImage(200, 200)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma, vmath
|
import chroma, pixie, vmath
|
||||||
|
|
||||||
let image = newImage(200, 200)
|
let image = newImage(200, 200)
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma, vmath
|
import chroma, pixie, vmath
|
||||||
|
|
||||||
let
|
let
|
||||||
trees = readImage("examples/data/trees.png")
|
trees = readImage("examples/data/trees.png")
|
||||||
|
@ -7,7 +7,7 @@ let
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
||||||
var p: Path
|
var p: Path
|
||||||
p.polygon(100, 100, 70, sides=8)
|
p.polygon(100, 100, 70, sides = 8)
|
||||||
p.closePath()
|
p.closePath()
|
||||||
|
|
||||||
var polyImage = newImage(200, 200)
|
var polyImage = newImage(200, 200)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma
|
import chroma, pixie
|
||||||
|
|
||||||
var image = newImage(200, 200)
|
var image = newImage(200, 200)
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma, vmath
|
import chroma, pixie, vmath
|
||||||
|
|
||||||
let image = newImage(200, 200)
|
let image = newImage(200, 200)
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import cairo, math, benchy, pixie, chroma
|
import benchy, cairo, chroma, math, pixie
|
||||||
|
|
||||||
var
|
var
|
||||||
surface = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000)
|
surface = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import svg_cairo, benchy
|
import benchy, svg_cairo
|
||||||
|
|
||||||
let data = readFile("tests/images/svg/Ghostscript_Tiger.svg")
|
let data = readFile("tests/images/svg/Ghostscript_Tiger.svg")
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## Load and Save SVG files.
|
## Load and Save SVG files.
|
||||||
|
|
||||||
import chroma, pixie/images, pixie/common, pixie/paths, vmath, xmlparser,
|
import cairo, chroma, pixie/common, pixie/images, pixie/paths, strutils, vmath,
|
||||||
xmltree, strutils, strutils, cairo
|
xmlparser, xmltree
|
||||||
|
|
||||||
type Path = paths.Path
|
type Path = paths.Path
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import svg_cairo, pixie, strformat
|
import pixie, strformat, svg_cairo
|
||||||
|
|
||||||
const files = [
|
const files = [
|
||||||
"line01",
|
"line01",
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
|
||||||
|
import algorithm, bumpy, chroma, pixie, pixie/images, pixie/paths, print,
|
||||||
import pixie, pixie/paths, pixie/images, chroma, print, vmath, algorithm, sequtils, bumpy
|
sequtils, vmath
|
||||||
|
|
||||||
printColors = false
|
printColors = false
|
||||||
|
|
||||||
|
|
||||||
proc intersectsInner*(a, b: Segment, at: var Vec2): bool {.inline.} =
|
proc intersectsInner*(a, b: Segment, at: var Vec2): bool {.inline.} =
|
||||||
## Checks if the a segment intersects b segment.
|
## Checks if the a segment intersects b segment.
|
||||||
## If it returns true, at will have point of intersection
|
## If it returns true, at will have point of intersection
|
||||||
|
@ -28,7 +27,7 @@ proc roundBy*(v: Vec2, n: float32): Vec2 {.inline.} =
|
||||||
|
|
||||||
proc pathToTrapezoids(p: Path): seq[Trapezoid] =
|
proc pathToTrapezoids(p: Path): seq[Trapezoid] =
|
||||||
|
|
||||||
var polygons = p.commands.commandsToPolygons()
|
var polygons = p.commandsToShapes()
|
||||||
|
|
||||||
const q = 1/256.0
|
const q = 1/256.0
|
||||||
|
|
||||||
|
@ -73,7 +72,7 @@ proc pathToTrapezoids(p: Path): seq[Trapezoid] =
|
||||||
var collision = false
|
var collision = false
|
||||||
for y in yScanLines:
|
for y in yScanLines:
|
||||||
var at: Vec2
|
var at: Vec2
|
||||||
if intersects(line(vec2(0,y), vec2(1,y)), s, at):
|
if intersects(line(vec2(0, y), vec2(1, y)), s, at):
|
||||||
at = at.roundBy(q)
|
at = at.roundBy(q)
|
||||||
at.y = y
|
at.y = y
|
||||||
if s.at.y != at.y and s.to.y != at.y:
|
if s.at.y != at.y and s.to.y != at.y:
|
||||||
|
@ -136,9 +135,9 @@ proc pathToTrapezoids(p: Path): seq[Trapezoid] =
|
||||||
Trapezoid(
|
Trapezoid(
|
||||||
nw: a.at,
|
nw: a.at,
|
||||||
ne: b.at,
|
ne: b.at,
|
||||||
se: b.to,# + vec2(0,0.7),
|
se: b.to, # + vec2(0,0.7),
|
||||||
sw: a.to# + vec2(0,0.7)
|
sw: a.to # + vec2(0,0.7)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
proc trapFill(image: Image, t: Trapezoid, color: ColorRGBA) =
|
proc trapFill(image: Image, t: Trapezoid, color: ColorRGBA) =
|
||||||
|
@ -180,7 +179,7 @@ block:
|
||||||
var image = newImage(200, 200)
|
var image = newImage(200, 200)
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
||||||
var p = newPath()
|
var p: Path
|
||||||
p.moveTo(50, 50)
|
p.moveTo(50, 50)
|
||||||
p.lineTo(50, 150)
|
p.lineTo(50, 150)
|
||||||
p.lineTo(150, 150)
|
p.lineTo(150, 150)
|
||||||
|
@ -190,7 +189,7 @@ block:
|
||||||
var trapezoids = p.pathToTrapezoids()
|
var trapezoids = p.pathToTrapezoids()
|
||||||
image.drawTrapezoids(trapezoids)
|
image.drawTrapezoids(trapezoids)
|
||||||
|
|
||||||
image.writeFile("trapezoids/rect.png")
|
image.writeFile("experiments/trapezoids/rect.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
# Rhombus
|
# Rhombus
|
||||||
|
@ -198,7 +197,7 @@ block:
|
||||||
var image = newImage(200, 200)
|
var image = newImage(200, 200)
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
|
||||||
var p = newPath()
|
var p: Path
|
||||||
p.moveTo(100, 50)
|
p.moveTo(100, 50)
|
||||||
p.lineTo(150, 100)
|
p.lineTo(150, 100)
|
||||||
p.lineTo(100, 150)
|
p.lineTo(100, 150)
|
||||||
|
@ -208,7 +207,7 @@ block:
|
||||||
var trapezoids = p.pathToTrapezoids()
|
var trapezoids = p.pathToTrapezoids()
|
||||||
image.drawTrapezoids(trapezoids)
|
image.drawTrapezoids(trapezoids)
|
||||||
|
|
||||||
image.writeFile("trapezoids/rhombus.png")
|
image.writeFile("experiments/trapezoids/rhombus.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
# heart
|
# heart
|
||||||
|
@ -224,7 +223,7 @@ block:
|
||||||
var trapezoids = p.pathToTrapezoids()
|
var trapezoids = p.pathToTrapezoids()
|
||||||
image.drawTrapezoids(trapezoids)
|
image.drawTrapezoids(trapezoids)
|
||||||
|
|
||||||
image.writeFile("trapezoids/heart.png")
|
image.writeFile("experiments/trapezoids/heart.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
# l
|
# l
|
||||||
|
@ -241,7 +240,7 @@ block:
|
||||||
var trapezoids = p.pathToTrapezoids()
|
var trapezoids = p.pathToTrapezoids()
|
||||||
image.drawTrapezoids(trapezoids)
|
image.drawTrapezoids(trapezoids)
|
||||||
|
|
||||||
image.writeFile("trapezoids/l.png")
|
image.writeFile("experiments/trapezoids/l.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
# g
|
# g
|
||||||
|
@ -258,4 +257,4 @@ block:
|
||||||
var trapezoids = p.pathToTrapezoids()
|
var trapezoids = p.pathToTrapezoids()
|
||||||
image.drawTrapezoids(trapezoids)
|
image.drawTrapezoids(trapezoids)
|
||||||
|
|
||||||
image.writeFile("trapezoids/g.png")
|
image.writeFile("experiments/trapezoids/g.png")
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
|
@ -11,4 +11,4 @@ requires "chroma >= 0.2.1"
|
||||||
requires "zippy >= 0.3.5"
|
requires "zippy >= 0.3.5"
|
||||||
requires "flatty >= 0.1.3"
|
requires "flatty >= 0.1.3"
|
||||||
requires "nimsimd >= 1.0.0"
|
requires "nimsimd >= 1.0.0"
|
||||||
requires "bumpy >= 1.0.1"
|
requires "bumpy >= 1.0.2"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import pixie/images, pixie/masks, pixie/paths, pixie/common, pixie/blends,
|
import flatty/binny, os, pixie/blends, pixie/common, pixie/fileformats/bmp,
|
||||||
pixie/fileformats/bmp, pixie/fileformats/png, pixie/fileformats/jpg,
|
pixie/fileformats/jpg, pixie/fileformats/png, pixie/fileformats/svg,
|
||||||
pixie/fileformats/svg, flatty/binny, os, pixie/gradients
|
pixie/images, pixie/masks, pixie/paths
|
||||||
|
|
||||||
export images, masks, paths, common, blends, gradients
|
export blends, common, images, masks, paths
|
||||||
|
|
||||||
type
|
type
|
||||||
FileFormat* = enum
|
FileFormat* = enum
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
## Blending modes.
|
## Blending modes.
|
||||||
import chroma, math, common
|
|
||||||
|
import chroma, common, math
|
||||||
|
|
||||||
when defined(amd64) and not defined(pixieNoSimd):
|
when defined(amd64) and not defined(pixieNoSimd):
|
||||||
import nimsimd/sse2
|
import nimsimd/sse2
|
||||||
|
@ -28,8 +29,8 @@ type
|
||||||
bmColor
|
bmColor
|
||||||
bmLuminosity
|
bmLuminosity
|
||||||
|
|
||||||
bmMask ## Special blend mode that is used for masking
|
bmMask ## Special blend mode that is used for masking
|
||||||
bmOverwrite ## Special blend mode that just copies pixels
|
bmOverwrite ## Special blend mode that just copies pixels
|
||||||
bmSubtractMask ## Inverse mask
|
bmSubtractMask ## Inverse mask
|
||||||
bmIntersectMask
|
bmIntersectMask
|
||||||
bmExcludeMask
|
bmExcludeMask
|
||||||
|
@ -141,9 +142,9 @@ proc ClipColor(C: var Color) {.inline.} =
|
||||||
n = min([C.r, C.g, C.b])
|
n = min([C.r, C.g, C.b])
|
||||||
x = max([C.r, C.g, C.b])
|
x = max([C.r, C.g, C.b])
|
||||||
if n < 0:
|
if n < 0:
|
||||||
C = L + (((C - L) * L) / (L - n))
|
C = L + (((C - L) * L) / (L - n))
|
||||||
if x > 1:
|
if x > 1:
|
||||||
C = L + (((C - L) * (1 - L)) / (x - L))
|
C = L + (((C - L) * (1 - L)) / (x - L))
|
||||||
|
|
||||||
proc SetLum(C: Color, l: float32): Color {.inline.} =
|
proc SetLum(C: Color, l: float32): Color {.inline.} =
|
||||||
let d = l - Lum(C)
|
let d = l - Lum(C)
|
||||||
|
@ -297,7 +298,12 @@ proc blendSoftLight(backdrop, source: ColorRGBA): ColorRGBA =
|
||||||
|
|
||||||
when defined(amd64) and not defined(pixieNoSimd):
|
when defined(amd64) and not defined(pixieNoSimd):
|
||||||
let
|
let
|
||||||
vb = mm_setr_ps(backdrop.r.float32, backdrop.g.float32, backdrop.b.float32, 0)
|
vb = mm_setr_ps(
|
||||||
|
backdrop.r.float32,
|
||||||
|
backdrop.g.float32,
|
||||||
|
backdrop.b.float32,
|
||||||
|
0
|
||||||
|
)
|
||||||
vs = mm_setr_ps(source.r.float32, source.g.float32, source.b.float32, 0)
|
vs = mm_setr_ps(source.r.float32, source.g.float32, source.b.float32, 0)
|
||||||
v2 = mm_set1_ps(2)
|
v2 = mm_set1_ps(2)
|
||||||
v255 = mm_set1_ps(255)
|
v255 = mm_set1_ps(255)
|
||||||
|
@ -519,8 +525,8 @@ when defined(amd64) and not defined(pixieNoSimd):
|
||||||
proc unpackAlphaValues*(v: M128i): M128i {.inline.} =
|
proc unpackAlphaValues*(v: M128i): M128i {.inline.} =
|
||||||
## Unpack the first 32 bits into 4 rgba(0, 0, 0, value)
|
## Unpack the first 32 bits into 4 rgba(0, 0, 0, value)
|
||||||
let
|
let
|
||||||
first32 = cast[M128i]([uint32.high, 0, 0, 0]) # First 32 bits
|
first32 = cast[M128i]([uint32.high, 0, 0, 0]) # First 32 bits
|
||||||
alphaMask = mm_set1_epi32(cast[int32](0xff000000)) # Only `a`
|
alphaMask = mm_set1_epi32(cast[int32](0xff000000)) # Only `a`
|
||||||
|
|
||||||
result = mm_shuffle_epi32(v, MM_SHUFFLE(0, 0, 0, 0))
|
result = mm_shuffle_epi32(v, MM_SHUFFLE(0, 0, 0, 0))
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import flatty/binny, chroma, pixie/common, pixie/images
|
import chroma, flatty/binny, pixie/common, pixie/images
|
||||||
|
|
||||||
# See: https://en.wikipedia.org/wiki/BMP_file_format
|
# See: https://en.wikipedia.org/wiki/BMP_file_format
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie/images, pixie/common
|
import pixie/common, pixie/images
|
||||||
|
|
||||||
when defined(pixieUseStb):
|
when defined(pixieUseStb):
|
||||||
import pixie/fileformats/stb_image/stb_image
|
import pixie/fileformats/stb_image/stb_image
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import chroma, pixie/common, math, zippy, zippy/crc, flatty/binny,
|
import chroma, flatty/binny, math, pixie/common, pixie/images, pixie/masks,
|
||||||
pixie/images, pixie/masks
|
zippy, zippy/crc
|
||||||
|
|
||||||
# See http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html
|
# See http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## Load and Save SVG files.
|
## Load and Save SVG files.
|
||||||
|
|
||||||
import chroma, pixie/images, pixie/common, pixie/paths, vmath, xmlparser,
|
import chroma, pixie/common, pixie/images, pixie/paths, strutils, vmath,
|
||||||
xmltree, strutils, strutils
|
xmlparser, xmltree
|
||||||
|
|
||||||
const svgSignature* = "<?xml"
|
const svgSignature* = "<?xml"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import chroma, blends, bumpy, vmath, common, system/memory, masks
|
import blends, bumpy, chroma, common, masks, system/memory, vmath
|
||||||
|
|
||||||
when defined(amd64) and not defined(pixieNoSimd):
|
when defined(amd64) and not defined(pixieNoSimd):
|
||||||
import nimsimd/sse2
|
import nimsimd/sse2
|
||||||
|
@ -68,7 +68,7 @@ proc `[]=`*(image: Image, x, y: int, rgba: ColorRGBA) {.inline.} =
|
||||||
if image.inside(x, y):
|
if image.inside(x, y):
|
||||||
image.setRgbaUnsafe(x, y, rgba)
|
image.setRgbaUnsafe(x, y, rgba)
|
||||||
|
|
||||||
proc fillUnsafe(data: var seq[ColorRGBA], rgba: ColorRGBA, start, len: int) =
|
proc fillUnsafe*(data: var seq[ColorRGBA], rgba: ColorRGBA, start, len: int) =
|
||||||
## Fills the image data with the parameter color starting at index start and
|
## Fills the image data with the parameter color starting at index start and
|
||||||
## continuing for len indices.
|
## continuing for len indices.
|
||||||
|
|
||||||
|
@ -571,7 +571,7 @@ proc drawCorrect(a, b: Image | Mask, mat = mat3(), blendMode = bmNormal) =
|
||||||
else: # b is a Mask
|
else: # b is a Mask
|
||||||
let
|
let
|
||||||
sample = b.getValueSmooth(xFloat, yFloat)
|
sample = b.getValueSmooth(xFloat, yFloat)
|
||||||
blended = blender(backdrop, rgba(0, 0, 0, sample))
|
blended = blender(backdrop, rgba(0, 0, 0, sample))
|
||||||
a.setRgbaUnsafe(x, y, blended)
|
a.setRgbaUnsafe(x, y, blended)
|
||||||
else: # a is a Mask
|
else: # a is a Mask
|
||||||
let backdrop = a.getValueUnsafe(x, y)
|
let backdrop = a.getValueUnsafe(x, y)
|
||||||
|
@ -678,7 +678,7 @@ proc drawUber(a, b: Image | Mask, mat = mat3(), blendMode = bmNormal) =
|
||||||
else: # b is a Mask
|
else: # b is a Mask
|
||||||
let
|
let
|
||||||
sample = b.getValueSmooth(xFloat, yFloat)
|
sample = b.getValueSmooth(xFloat, yFloat)
|
||||||
blended = blender(backdrop, rgba(0, 0, 0, sample))
|
blended = blender(backdrop, rgba(0, 0, 0, sample))
|
||||||
a.setRgbaUnsafe(x, y, blended)
|
a.setRgbaUnsafe(x, y, blended)
|
||||||
else: # a is a Mask
|
else: # a is a Mask
|
||||||
let backdrop = a.getValueUnsafe(x, y)
|
let backdrop = a.getValueUnsafe(x, y)
|
||||||
|
@ -765,7 +765,7 @@ proc drawUber(a, b: Image | Mask, mat = mat3(), blendMode = bmNormal) =
|
||||||
else: # b is a Mask
|
else: # b is a Mask
|
||||||
let
|
let
|
||||||
sample = b.getValueUnsafe(xFloat.int, yFloat.int)
|
sample = b.getValueUnsafe(xFloat.int, yFloat.int)
|
||||||
blended = blender(backdrop, rgba(0, 0, 0, sample))
|
blended = blender(backdrop, rgba(0, 0, 0, sample))
|
||||||
a.setRgbaUnsafe(x, y, blended)
|
a.setRgbaUnsafe(x, y, blended)
|
||||||
else: # a is a Mask
|
else: # a is a Mask
|
||||||
let backdrop = a.getValueUnsafe(x, y)
|
let backdrop = a.getValueUnsafe(x, y)
|
||||||
|
@ -827,11 +827,13 @@ proc shift*(target: Image | Mask, offset: Vec2) =
|
||||||
## Shifts the target by offset.
|
## Shifts the target by offset.
|
||||||
if offset != vec2(0, 0):
|
if offset != vec2(0, 0):
|
||||||
let copy = target.copy() # Copy to read from
|
let copy = target.copy() # Copy to read from
|
||||||
|
|
||||||
# Reset target for being drawn to
|
# Reset target for being drawn to
|
||||||
when type(target) is Image:
|
when type(target) is Image:
|
||||||
target.fill(rgba(0, 0, 0, 0))
|
target.fill(rgba(0, 0, 0, 0))
|
||||||
else:
|
else:
|
||||||
target.fill(0)
|
target.fill(0)
|
||||||
|
|
||||||
target.draw(copy, offset, bmOverwrite) # Draw copy at offset
|
target.draw(copy, offset, bmOverwrite) # Draw copy at offset
|
||||||
|
|
||||||
proc shadow*(
|
proc shadow*(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import common, vmath, system/memory
|
import common, system/memory, vmath
|
||||||
|
|
||||||
when defined(amd64) and not defined(pixieNoSimd):
|
when defined(amd64) and not defined(pixieNoSimd):
|
||||||
import nimsimd/sse2
|
import nimsimd/sse2
|
||||||
|
@ -84,7 +84,7 @@ proc minifyBy2*(mask: Mask, power = 1): Mask =
|
||||||
mask.getValueUnsafe(x * 2 + 0, y * 2 + 1)
|
mask.getValueUnsafe(x * 2 + 0, y * 2 + 1)
|
||||||
result.setValueUnsafe(x, y, (value div 4).uint8)
|
result.setValueUnsafe(x, y, (value div 4).uint8)
|
||||||
|
|
||||||
proc fillUnsafe(data: var seq[uint8], value: uint8, start, len: int) =
|
proc fillUnsafe*(data: var seq[uint8], value: uint8, start, len: int) =
|
||||||
## Fills the mask data with the parameter value starting at index start and
|
## Fills the mask data with the parameter value starting at index start and
|
||||||
## continuing for len indices.
|
## continuing for len indices.
|
||||||
nimSetMem(data[start].addr, value.cint, len)
|
nimSetMem(data[start].addr, value.cint, len)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import common, strutils, vmath, images, masks, chroma, bumpy, blends
|
import blends, bumpy, chroma, common, images, masks, strutils, vmath
|
||||||
|
|
||||||
when defined(amd64) and not defined(pixieNoSimd):
|
when defined(amd64) and not defined(pixieNoSimd):
|
||||||
import nimsimd/sse2
|
import nimsimd/sse2
|
||||||
|
@ -382,7 +382,7 @@ proc roundedRect*(
|
||||||
h = wh.y
|
h = wh.y
|
||||||
s = splineCircleK
|
s = splineCircleK
|
||||||
|
|
||||||
maxRadius = min(w/2, h/2)
|
maxRadius = min(w / 2, h / 2)
|
||||||
nw = min(nw, maxRadius)
|
nw = min(nw, maxRadius)
|
||||||
ne = min(ne, maxRadius)
|
ne = min(ne, maxRadius)
|
||||||
se = min(se, maxRadius)
|
se = min(se, maxRadius)
|
||||||
|
@ -397,14 +397,14 @@ proc roundedRect*(
|
||||||
l1 = vec2(x, y + h - sw)
|
l1 = vec2(x, y + h - sw)
|
||||||
l2 = vec2(x, y + nw)
|
l2 = vec2(x, y + nw)
|
||||||
|
|
||||||
t1h = t1 + vec2(-nw*s, 0)
|
t1h = t1 + vec2(-nw * s, 0)
|
||||||
t2h = t2 + vec2(+ne*s, 0)
|
t2h = t2 + vec2(+ne * s, 0)
|
||||||
r1h = r1 + vec2(0, -ne*s)
|
r1h = r1 + vec2(0, -ne * s)
|
||||||
r2h = r2 + vec2(0, +se*s)
|
r2h = r2 + vec2(0, +se * s)
|
||||||
b1h = b1 + vec2(+se*s, 0)
|
b1h = b1 + vec2(+se * s, 0)
|
||||||
b2h = b2 + vec2(-sw*s, 0)
|
b2h = b2 + vec2(-sw * s, 0)
|
||||||
l1h = l1 + vec2(0, +sw*s)
|
l1h = l1 + vec2(0, +sw * s)
|
||||||
l2h = l2 + vec2(0, -nw*s)
|
l2h = l2 + vec2(0, -nw * s)
|
||||||
|
|
||||||
if clockwise:
|
if clockwise:
|
||||||
path.moveTo(t1)
|
path.moveTo(t1)
|
||||||
|
@ -571,15 +571,15 @@ proc commandsToShapes*(path: Path): seq[seq[Vec2]] =
|
||||||
|
|
||||||
var q = sqrt(max(0, pq))
|
var q = sqrt(max(0, pq))
|
||||||
if large == sweep:
|
if large == sweep:
|
||||||
q = -q
|
q = -q
|
||||||
|
|
||||||
proc svgAngle(u, v: Vec2): float32 =
|
proc svgAngle(u, v: Vec2): float32 =
|
||||||
let
|
let
|
||||||
dot = dot(u,v)
|
dot = dot(u, v)
|
||||||
len = length(u) * length(v)
|
len = length(u) * length(v)
|
||||||
result = arccos(clamp(dot / len, -1, 1))
|
result = arccos(clamp(dot / len, -1, 1))
|
||||||
if (u.x * v.y - u.y * v.x) < 0:
|
if (u.x * v.y - u.y * v.x) < 0:
|
||||||
result = -result
|
result = -result
|
||||||
|
|
||||||
let
|
let
|
||||||
cp = vec2(q * radii.x * p.y / radii.y, -q * radii.y * p.x / radii.x)
|
cp = vec2(q * radii.x * p.y / radii.y, -q * radii.y * p.x / radii.x)
|
||||||
|
@ -865,13 +865,11 @@ proc partitionSegments(
|
||||||
segmentCount += shape.len - 1
|
segmentCount += shape.len - 1
|
||||||
|
|
||||||
let
|
let
|
||||||
maxPartitions = max(1, height div 10)
|
maxPartitions = max(1, height div 10).uint32
|
||||||
numPartitions = min(maxPartitions, max(1, segmentCount div 10))
|
numPartitions = min(maxPartitions, max(1, segmentCount div 10).uint32)
|
||||||
|
partitionHeight = (height.uint32 div numPartitions)
|
||||||
result.setLen(numPartitions)
|
|
||||||
|
|
||||||
let partitionHeight = height div numPartitions
|
|
||||||
|
|
||||||
|
var partitions = newSeq[seq[(Segment, int16)]](numPartitions)
|
||||||
for shape in shapes:
|
for shape in shapes:
|
||||||
for segment in shape.segments:
|
for segment in shape.segments:
|
||||||
if segment.at.y == segment.to.y: # Skip horizontal
|
if segment.at.y == segment.to.y: # Skip horizontal
|
||||||
|
@ -884,41 +882,46 @@ proc partitionSegments(
|
||||||
winding = -1
|
winding = -1
|
||||||
|
|
||||||
if partitionHeight == 0:
|
if partitionHeight == 0:
|
||||||
result[0].add((segment, winding))
|
partitions[0].add((segment, winding))
|
||||||
else:
|
else:
|
||||||
let
|
var
|
||||||
atPartition = max(0, segment.at.y).int div partitionHeight
|
atPartition = max(0, segment.at.y).uint32 div partitionHeight
|
||||||
toPartition = max(0, ceil(segment.to.y)).int div partitionHeight
|
toPartition = max(0, ceil(segment.to.y)).uint32 div partitionHeight
|
||||||
for i in min(atPartition, result.high) .. min(toPartition, result.high):
|
atPartition = clamp(atPartition, 0, partitions.high.uint32)
|
||||||
result[i].add((segment, winding))
|
toPartition = clamp(toPartition, 0, partitions.high.uint32)
|
||||||
|
for i in atPartition .. toPartition:
|
||||||
|
partitions[i].add((segment, winding))
|
||||||
|
|
||||||
|
partitions
|
||||||
|
|
||||||
proc computeCoverages(
|
proc computeCoverages(
|
||||||
coverages: var seq[uint8],
|
coverages: var seq[uint8],
|
||||||
hits: var seq[(float32, int16)],
|
hits: var seq[(float32, int16)],
|
||||||
|
numHits: var int,
|
||||||
size: Vec2,
|
size: Vec2,
|
||||||
y: int,
|
y: int,
|
||||||
partitions: seq[seq[(Segment, int16)]],
|
partitions: seq[seq[(Segment, int16)]],
|
||||||
|
partitionHeight: uint32,
|
||||||
windingRule: WindingRule
|
windingRule: WindingRule
|
||||||
) =
|
) {.inline.} =
|
||||||
const
|
const
|
||||||
quality = 5 # Must divide 255 cleanly (1, 3, 5, 15, 17, 51, 85)
|
quality = 5 # Must divide 255 cleanly (1, 3, 5, 15, 17, 51, 85)
|
||||||
sampleCoverage = 255.uint8 div quality
|
sampleCoverage = (255 div quality).uint8
|
||||||
ep = 0.0001 * PI
|
|
||||||
offset = 1 / quality.float32
|
offset = 1 / quality.float32
|
||||||
initialOffset = offset / 2
|
initialOffset = offset / 2
|
||||||
|
|
||||||
var numHits: int
|
|
||||||
|
|
||||||
let
|
let
|
||||||
partitionHeight = size.y.int div partitions.len
|
|
||||||
partition =
|
partition =
|
||||||
if partitionHeight == 0:
|
if partitionHeight == 0:
|
||||||
0
|
0.uint32
|
||||||
else:
|
else:
|
||||||
min(y div partitionHeight, partitions.high)
|
min(y.uint32 div partitionHeight, partitions.high.uint32)
|
||||||
|
|
||||||
|
zeroMem(coverages[0].addr, coverages.len)
|
||||||
|
|
||||||
# Do scanlines for this row
|
# Do scanlines for this row
|
||||||
for m in 0 ..< quality:
|
for m in 0 ..< quality:
|
||||||
|
const ep = 0.0001 * PI
|
||||||
let
|
let
|
||||||
yLine = y.float32 + initialOffset + offset * m.float32 + ep
|
yLine = y.float32 + initialOffset + offset * m.float32 + ep
|
||||||
scanline = Line(a: vec2(0, yLine), b: vec2(size.x, yLine))
|
scanline = Line(a: vec2(0, yLine), b: vec2(size.x, yLine))
|
||||||
|
@ -926,7 +929,7 @@ proc computeCoverages(
|
||||||
for (segment, winding) in partitions[partition]:
|
for (segment, winding) in partitions[partition]:
|
||||||
if segment.at.y <= scanline.a.y and segment.to.y >= scanline.a.y:
|
if segment.at.y <= scanline.a.y and segment.to.y >= scanline.a.y:
|
||||||
var at: Vec2
|
var at: Vec2
|
||||||
if scanline.intersects(segment, at):# and segment.to != at:
|
if scanline.intersects(segment, at): # and segment.to != at:
|
||||||
if numHits == hits.len:
|
if numHits == hits.len:
|
||||||
hits.setLen(hits.len * 2)
|
hits.setLen(hits.len * 2)
|
||||||
hits[numHits] = (at.x.clamp(0, scanline.b.x), winding)
|
hits[numHits] = (at.x.clamp(0, scanline.b.x), winding)
|
||||||
|
@ -940,9 +943,9 @@ proc computeCoverages(
|
||||||
for i in 0 ..< numHits:
|
for i in 0 ..< numHits:
|
||||||
let (at, winding) = hits[i]
|
let (at, winding) = hits[i]
|
||||||
|
|
||||||
var
|
var fillStart = x.int
|
||||||
fillStart = x.int
|
|
||||||
leftCover = if at.int - x.int > 0: trunc(x) + 1 - x else: at - x
|
let leftCover = if at.int - x.int > 0: trunc(x) + 1 - x else: at - x
|
||||||
if leftCover != 0:
|
if leftCover != 0:
|
||||||
inc fillStart
|
inc fillStart
|
||||||
if shouldFill(windingRule, count):
|
if shouldFill(windingRule, count):
|
||||||
|
@ -978,7 +981,9 @@ proc fillShapes(
|
||||||
windingRule: WindingRule,
|
windingRule: WindingRule,
|
||||||
blendMode: BlendMode
|
blendMode: BlendMode
|
||||||
) =
|
) =
|
||||||
let partitions = partitionSegments(shapes, image.height)
|
let
|
||||||
|
partitions = partitionSegments(shapes, image.height)
|
||||||
|
partitionHeight = image.height.uint32 div partitions.len.uint32
|
||||||
|
|
||||||
# Figure out the total bounds of all the shapes,
|
# Figure out the total bounds of all the shapes,
|
||||||
# rasterize only within the total bounds
|
# rasterize only within the total bounds
|
||||||
|
@ -995,17 +1000,17 @@ proc fillShapes(
|
||||||
var
|
var
|
||||||
coverages = newSeq[uint8](image.width)
|
coverages = newSeq[uint8](image.width)
|
||||||
hits = newSeq[(float32, int16)](4)
|
hits = newSeq[(float32, int16)](4)
|
||||||
|
numHits: int
|
||||||
|
|
||||||
for y in startY ..< stopY:
|
for y in startY ..< stopY:
|
||||||
# Reset buffer for this row
|
|
||||||
zeroMem(coverages[0].addr, coverages.len)
|
|
||||||
|
|
||||||
computeCoverages(
|
computeCoverages(
|
||||||
coverages,
|
coverages,
|
||||||
hits,
|
hits,
|
||||||
|
numHits,
|
||||||
image.wh,
|
image.wh,
|
||||||
y,
|
y,
|
||||||
partitions,
|
partitions,
|
||||||
|
partitionHeight,
|
||||||
windingRule
|
windingRule
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1023,34 +1028,45 @@ proc fillShapes(
|
||||||
var coverage = mm_loadu_si128(coverages[x].addr)
|
var coverage = mm_loadu_si128(coverages[x].addr)
|
||||||
coverage = mm_and_si128(coverage, first32)
|
coverage = mm_and_si128(coverage, first32)
|
||||||
|
|
||||||
let eqZero = mm_cmpeq_epi16(coverage, mm_setzero_si128())
|
let
|
||||||
|
index = image.dataIndex(x, y)
|
||||||
|
eqZero = mm_cmpeq_epi16(coverage, mm_setzero_si128())
|
||||||
if mm_movemask_epi8(eqZero) != 0xffff:
|
if mm_movemask_epi8(eqZero) != 0xffff:
|
||||||
# If the coverages are not all zero
|
# If the coverages are not all zero
|
||||||
var source = vColor
|
if mm_movemask_epi8(mm_cmpeq_epi32(coverage, first32)) == 0xffff:
|
||||||
|
# Coverages are all 255
|
||||||
if mm_movemask_epi8(mm_cmpeq_epi32(coverage, first32)) != 0xffff:
|
if color.a == 255 and blendMode == bmNormal:
|
||||||
# If the coverages are not all 255
|
mm_storeu_si128(image.data[index].addr, vColor)
|
||||||
|
else:
|
||||||
|
let backdrop = mm_loadu_si128(image.data[index].addr)
|
||||||
|
mm_storeu_si128(
|
||||||
|
image.data[index].addr,
|
||||||
|
blenderSimd(backdrop, vColor)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Coverages are not all 255
|
||||||
coverage = unpackAlphaValues(coverage)
|
coverage = unpackAlphaValues(coverage)
|
||||||
# Shift the coverages from `a` to `g` and `a` for multiplying
|
# Shift the coverages from `a` to `g` and `a` for multiplying
|
||||||
coverage = mm_or_si128(coverage, mm_srli_epi32(coverage, 16))
|
coverage = mm_or_si128(coverage, mm_srli_epi32(coverage, 16))
|
||||||
|
|
||||||
var
|
var
|
||||||
colorEven = mm_slli_epi16(source, 8)
|
source = vColor
|
||||||
colorOdd = mm_and_si128(source, oddMask)
|
sourceEven = mm_slli_epi16(source, 8)
|
||||||
|
sourceOdd = mm_and_si128(source, oddMask)
|
||||||
|
|
||||||
colorEven = mm_mulhi_epu16(colorEven, coverage)
|
sourceEven = mm_mulhi_epu16(sourceEven, coverage)
|
||||||
colorOdd = mm_mulhi_epu16(colorOdd, coverage)
|
sourceOdd = mm_mulhi_epu16(sourceOdd, coverage)
|
||||||
|
|
||||||
colorEven = mm_srli_epi16(mm_mulhi_epu16(colorEven, div255), 7)
|
sourceEven = mm_srli_epi16(mm_mulhi_epu16(sourceEven, div255), 7)
|
||||||
colorOdd = mm_srli_epi16(mm_mulhi_epu16(colorOdd, div255), 7)
|
sourceOdd = mm_srli_epi16(mm_mulhi_epu16(sourceOdd, div255), 7)
|
||||||
|
|
||||||
source = mm_or_si128(colorEven, mm_slli_epi16(colorOdd, 8))
|
source = mm_or_si128(sourceEven, mm_slli_epi16(sourceOdd, 8))
|
||||||
|
|
||||||
let
|
|
||||||
index = image.dataIndex(x, y)
|
|
||||||
backdrop = mm_loadu_si128(image.data[index].addr)
|
|
||||||
mm_storeu_si128(image.data[index].addr, blenderSimd(backdrop, source))
|
|
||||||
|
|
||||||
|
let backdrop = mm_loadu_si128(image.data[index].addr)
|
||||||
|
mm_storeu_si128(
|
||||||
|
image.data[index].addr,
|
||||||
|
blenderSimd(backdrop, source)
|
||||||
|
)
|
||||||
x += 4
|
x += 4
|
||||||
|
|
||||||
while x < image.width:
|
while x < image.width:
|
||||||
|
@ -1069,8 +1085,12 @@ proc fillShapes(
|
||||||
source.b = ((color.b.uint16 * coverage) div 255).uint8
|
source.b = ((color.b.uint16 * coverage) div 255).uint8
|
||||||
source.a = ((color.a.uint16 * coverage) div 255).uint8
|
source.a = ((color.a.uint16 * coverage) div 255).uint8
|
||||||
|
|
||||||
let backdrop = image.getRgbaUnsafe(x, y)
|
if source.a == 255 and blendMode == bmNormal:
|
||||||
image.setRgbaUnsafe(x, y, blender(backdrop, source))
|
# Skip blending
|
||||||
|
image.setRgbaUnsafe(x, y, source)
|
||||||
|
else:
|
||||||
|
let backdrop = image.getRgbaUnsafe(x, y)
|
||||||
|
image.setRgbaUnsafe(x, y, blender(backdrop, source))
|
||||||
inc x
|
inc x
|
||||||
|
|
||||||
proc fillShapes(
|
proc fillShapes(
|
||||||
|
@ -1078,7 +1098,9 @@ proc fillShapes(
|
||||||
shapes: seq[seq[Vec2]],
|
shapes: seq[seq[Vec2]],
|
||||||
windingRule: WindingRule
|
windingRule: WindingRule
|
||||||
) =
|
) =
|
||||||
let partitions = partitionSegments(shapes, mask.height)
|
let
|
||||||
|
partitions = partitionSegments(shapes, mask.height)
|
||||||
|
partitionHeight = mask.height.uint32 div partitions.len.uint32
|
||||||
|
|
||||||
# Figure out the total bounds of all the shapes,
|
# Figure out the total bounds of all the shapes,
|
||||||
# rasterize only within the total bounds
|
# rasterize only within the total bounds
|
||||||
|
@ -1088,24 +1110,23 @@ proc fillShapes(
|
||||||
startY = max(0, bounds.y.int)
|
startY = max(0, bounds.y.int)
|
||||||
stopY = min(mask.height, (bounds.y + bounds.h).int)
|
stopY = min(mask.height, (bounds.y + bounds.h).int)
|
||||||
|
|
||||||
var
|
|
||||||
coverages = newSeq[uint8](mask.width)
|
|
||||||
hits = newSeq[(float32, int16)](4)
|
|
||||||
|
|
||||||
|
|
||||||
when defined(amd64) and not defined(pixieNoSimd):
|
when defined(amd64) and not defined(pixieNoSimd):
|
||||||
let maskerSimd = bmNormal.maskerSimd()
|
let maskerSimd = bmNormal.maskerSimd()
|
||||||
|
|
||||||
for y in startY ..< stopY:
|
var
|
||||||
# Reset buffer for this row
|
coverages = newSeq[uint8](mask.width)
|
||||||
zeroMem(coverages[0].addr, coverages.len)
|
hits = newSeq[(float32, int16)](4)
|
||||||
|
numHits: int
|
||||||
|
|
||||||
|
for y in startY ..< stopY:
|
||||||
computeCoverages(
|
computeCoverages(
|
||||||
coverages,
|
coverages,
|
||||||
hits,
|
hits,
|
||||||
|
numHits,
|
||||||
mask.wh,
|
mask.wh,
|
||||||
y,
|
y,
|
||||||
partitions,
|
partitions,
|
||||||
|
partitionHeight,
|
||||||
windingRule
|
windingRule
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1132,6 +1153,7 @@ proc fillShapes(
|
||||||
if peeked == 0:
|
if peeked == 0:
|
||||||
x += 8
|
x += 8
|
||||||
continue
|
continue
|
||||||
|
|
||||||
let coverage = coverages[x]
|
let coverage = coverages[x]
|
||||||
if coverage != 0:
|
if coverage != 0:
|
||||||
let
|
let
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import benchy, chroma, vmath, pixie/images
|
import benchy, chroma, pixie/images, vmath
|
||||||
|
|
||||||
include pixie/blends
|
include pixie/blends
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import chroma, vmath, benchy
|
import benchy, chroma, vmath
|
||||||
|
|
||||||
include pixie/images
|
include pixie/images
|
||||||
|
|
||||||
block:
|
block:
|
||||||
|
@ -23,7 +24,6 @@ block:
|
||||||
a.drawUber(b, translate(vec2(25, 25)), bmNormal)
|
a.drawUber(b, translate(vec2(25, 25)), bmNormal)
|
||||||
keep(b)
|
keep(b)
|
||||||
|
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let
|
let
|
||||||
a = newImage(1000, 1000)
|
a = newImage(1000, 1000)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import chroma, pixie, benchy
|
import benchy, chroma, pixie
|
||||||
|
|
||||||
let image = newImage(2560, 1440)
|
let image = newImage(2560, 1440)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma, vmath, benchy
|
import benchy, chroma, pixie, vmath
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let
|
let
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie/fileformats/jpg, benchy
|
import benchy, pixie/fileformats/jpg
|
||||||
|
|
||||||
let data = readFile("tests/images/jpg/jpeg420exif.jpg")
|
let data = readFile("tests/images/jpg/jpeg420exif.jpg")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import chroma, pixie, benchy
|
import benchy, chroma, pixie
|
||||||
|
|
||||||
let mask = newMask(2560, 1440)
|
let mask = newMask(2560, 1440)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie/paths, benchy
|
import benchy, pixie/paths
|
||||||
|
|
||||||
let pathStr = "m57.611-8.591c-1.487,1.851-4.899,4.42-1.982,6.348,0.194,0.129,0.564,0.133,0.737-0.001,2.021-1.565,4.024-2.468,6.46-3.05,0.124-0.029,0.398,0.438,0.767,0.277,1.613-0.703,3.623-0.645,4.807-1.983,3.767,0.224,7.332-0.892,10.723-2.2,1.161-0.448,2.431-1.007,3.632-1.509,1.376-0.576,2.58-1.504,3.692-2.645,0.133-0.136,0.487-0.046,0.754-0.046-0.04-0.863,0.922-0.99,1.169-1.612,0.092-0.232-0.058-0.628,0.075-0.73,2.138-1.63,3.058-3.648,1.889-6.025-0.285-0.578-0.534-1.196-1.1-1.672-1.085-0.911-2.187-0.057-3.234-0.361-0.159,0.628-0.888,0.456-1.274,0.654-0.859,0.439-2.192-0.146-3.051,0.292-1.362,0.695-2.603,0.864-4.025,1.241-0.312,0.082-1.09-0.014-1.25,0.613-0.134-0.134-0.282-0.368-0.388-0.346-1.908,0.396-3.168,0.61-4.469,2.302-0.103,0.133-0.545-0.046-0.704,0.089-0.957,0.808-1.362,2.042-2.463,2.714-0.201,0.123-0.553-0.045-0.747,0.084-0.646,0.431-1.013,1.072-1.655,1.519-0.329,0.229-0.729-0.096-0.697-0.352,0.245-1.947,0.898-3.734,0.323-5.61,2.077-2.52,4.594-4.469,6.4-7.2,0.015-2.166,0.707-4.312,0.594-6.389-0.01-0.193-0.298-0.926-0.424-1.273-0.312-0.854,0.594-1.92-0.25-2.644-1.404-1.203-2.696-0.327-3.52,1.106-1.838,0.39-3.904,1.083-5.482-0.151-1.007-0.787-1.585-1.693-2.384-2.749-0.985-1.302-0.65-2.738-0.58-4.302,0.006-0.128-0.309-0.264-0.309-0.398,0.001-0.135,0.221-0.266,0.355-0.4-0.706-0.626-0.981-1.684-2-2,0.305-1.092-0.371-1.976-1.242-2.278-1.995-0.691-3.672,1.221-5.564,1.294-0.514,0.019-0.981-1.019-1.63-1.344-0.432-0.216-1.136-0.249-1.498,0.017-0.688,0.504-1.277,0.618-2.035,0.823-1.617,0.436-2.895,1.53-4.375,2.385-1.485,0.857-2.44,2.294-3.52,3.614-0.941,1.152-1.077,3.566,0.343,4.066,1.843,0.65,3.147-2.053,5.113-1.727,0.312,0.051,0.518,0.362,0.408,0.75,0.389,0.109,0.607-0.12,0.8-0.4,0.858,1.019,2.022,1.356,2.96,2.229,0.97,0.904,2.716,0.486,3.731,1.483,1.529,1.502,0.97,4.183,2.909,5.488-0.586,1.313-1.193,2.59-1.528,4.017-0.282,1.206,0.712,2.403,1.923,2.312,1.258-0.094,1.52-0.853,2.005-1.929,0.267,0.267,0.736,0.564,0.695,0.78-0.457,2.387-1.484,4.38-1.942,6.811-0.059,0.317-0.364,0.519-0.753,0.409-0.468,4.149-4.52,6.543-7.065,9.708-0.403,0.502-0.407,1.751,0.002,2.154,1.403,1.387,3.363-0.159,5.063-0.662,0.213-1.206,1.072-2.148,2.404-2.092,0.256,0.01,0.491-0.532,0.815-0.662,0.348-0.138,0.85,0.086,1.136-0.112,1.729-1.195,3.137-2.301,4.875-3.49,0.192-0.131,0.536,0.028,0.752-0.08,0.325-0.162,0.512-0.549,0.835-0.734,0.348-0.2,0.59,0.09,0.783,0.37-0.646,0.349-0.65,1.306-1.232,1.508-0.775,0.268-1.336,0.781-2.01,1.228-0.292,0.193-0.951-0.055-1.055,0.124-0.598,1.028-1.782,1.466-2.492,2.349z"
|
let pathStr = "m57.611-8.591c-1.487,1.851-4.899,4.42-1.982,6.348,0.194,0.129,0.564,0.133,0.737-0.001,2.021-1.565,4.024-2.468,6.46-3.05,0.124-0.029,0.398,0.438,0.767,0.277,1.613-0.703,3.623-0.645,4.807-1.983,3.767,0.224,7.332-0.892,10.723-2.2,1.161-0.448,2.431-1.007,3.632-1.509,1.376-0.576,2.58-1.504,3.692-2.645,0.133-0.136,0.487-0.046,0.754-0.046-0.04-0.863,0.922-0.99,1.169-1.612,0.092-0.232-0.058-0.628,0.075-0.73,2.138-1.63,3.058-3.648,1.889-6.025-0.285-0.578-0.534-1.196-1.1-1.672-1.085-0.911-2.187-0.057-3.234-0.361-0.159,0.628-0.888,0.456-1.274,0.654-0.859,0.439-2.192-0.146-3.051,0.292-1.362,0.695-2.603,0.864-4.025,1.241-0.312,0.082-1.09-0.014-1.25,0.613-0.134-0.134-0.282-0.368-0.388-0.346-1.908,0.396-3.168,0.61-4.469,2.302-0.103,0.133-0.545-0.046-0.704,0.089-0.957,0.808-1.362,2.042-2.463,2.714-0.201,0.123-0.553-0.045-0.747,0.084-0.646,0.431-1.013,1.072-1.655,1.519-0.329,0.229-0.729-0.096-0.697-0.352,0.245-1.947,0.898-3.734,0.323-5.61,2.077-2.52,4.594-4.469,6.4-7.2,0.015-2.166,0.707-4.312,0.594-6.389-0.01-0.193-0.298-0.926-0.424-1.273-0.312-0.854,0.594-1.92-0.25-2.644-1.404-1.203-2.696-0.327-3.52,1.106-1.838,0.39-3.904,1.083-5.482-0.151-1.007-0.787-1.585-1.693-2.384-2.749-0.985-1.302-0.65-2.738-0.58-4.302,0.006-0.128-0.309-0.264-0.309-0.398,0.001-0.135,0.221-0.266,0.355-0.4-0.706-0.626-0.981-1.684-2-2,0.305-1.092-0.371-1.976-1.242-2.278-1.995-0.691-3.672,1.221-5.564,1.294-0.514,0.019-0.981-1.019-1.63-1.344-0.432-0.216-1.136-0.249-1.498,0.017-0.688,0.504-1.277,0.618-2.035,0.823-1.617,0.436-2.895,1.53-4.375,2.385-1.485,0.857-2.44,2.294-3.52,3.614-0.941,1.152-1.077,3.566,0.343,4.066,1.843,0.65,3.147-2.053,5.113-1.727,0.312,0.051,0.518,0.362,0.408,0.75,0.389,0.109,0.607-0.12,0.8-0.4,0.858,1.019,2.022,1.356,2.96,2.229,0.97,0.904,2.716,0.486,3.731,1.483,1.529,1.502,0.97,4.183,2.909,5.488-0.586,1.313-1.193,2.59-1.528,4.017-0.282,1.206,0.712,2.403,1.923,2.312,1.258-0.094,1.52-0.853,2.005-1.929,0.267,0.267,0.736,0.564,0.695,0.78-0.457,2.387-1.484,4.38-1.942,6.811-0.059,0.317-0.364,0.519-0.753,0.409-0.468,4.149-4.52,6.543-7.065,9.708-0.403,0.502-0.407,1.751,0.002,2.154,1.403,1.387,3.363-0.159,5.063-0.662,0.213-1.206,1.072-2.148,2.404-2.092,0.256,0.01,0.491-0.532,0.815-0.662,0.348-0.138,0.85,0.086,1.136-0.112,1.729-1.195,3.137-2.301,4.875-3.49,0.192-0.131,0.536,0.028,0.752-0.08,0.325-0.162,0.512-0.549,0.835-0.734,0.348-0.2,0.59,0.09,0.783,0.37-0.646,0.349-0.65,1.306-1.232,1.508-0.775,0.268-1.336,0.781-2.01,1.228-0.292,0.193-0.951-0.055-1.055,0.124-0.598,1.028-1.782,1.466-2.492,2.349z"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import pixie/fileformats/png, stb_image/read as stbi, stb_image/write as stbr,
|
import benchy, nimPNG, pixie/fileformats/png, stb_image/read as stbi,
|
||||||
benchy, nimPNG
|
stb_image/write as stbr
|
||||||
|
|
||||||
let data = readFile("tests/images/png/lenna.png")
|
let data = readFile("tests/images/png/lenna.png")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie/fileformats/svg, benchy
|
import benchy, pixie/fileformats/svg
|
||||||
|
|
||||||
let data = readFile("tests/images/svg/Ghostscript_Tiger.svg")
|
let data = readFile("tests/images/svg/Ghostscript_Tiger.svg")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import random, strformat, pixie/fileformats/jpg, pixie/common
|
import pixie/common, pixie/fileformats/jpg, random, strformat
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import random, strformat, pixie/paths, pixie/common, strformat
|
import pixie/common, pixie/paths, random, strformat
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import random, strformat, pixie/fileformats/png, pixie/common, pngsuite
|
import pixie/common, pixie/fileformats/png, pngsuite, random, strformat
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import random, strformat, pixie/fileformats/svg, pixie/common
|
import pixie/common, pixie/fileformats/svg, random, strformat
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, pixie/fileformats/bmp, chroma
|
import chroma, pixie, pixie/fileformats/bmp
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var image = newImage(4, 2)
|
var image = newImage(4, 2)
|
||||||
|
@ -32,5 +32,6 @@ block:
|
||||||
|
|
||||||
block:
|
block:
|
||||||
for bits in [32, 24]:
|
for bits in [32, 24]:
|
||||||
var image = decodeBmp(readFile("tests/images/bmp/knight." & $bits & ".master.bmp"))
|
let image =
|
||||||
|
decodeBmp(readFile("tests/images/bmp/knight." & $bits & ".master.bmp"))
|
||||||
writeFile("tests/images/bmp/knight." & $bits & ".bmp", encodeBmp(image))
|
writeFile("tests/images/bmp/knight." & $bits & ".bmp", encodeBmp(image))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma, vmath
|
import chroma, pixie, vmath
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let image = newImage(10, 10)
|
let image = newImage(10, 10)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie, chroma, pixie/fileformats/png
|
import chroma, pixie, pixie/fileformats/png
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let pathStr = """
|
let pathStr = """
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie/fileformats/png, strformat, pngsuite, pixie/common
|
import pixie/common, pixie/fileformats/png, pngsuite, strformat
|
||||||
|
|
||||||
for file in pngSuiteFiles:
|
for file in pngSuiteFiles:
|
||||||
let
|
let
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import pixie/fileformats/svg, pixie, strformat
|
import pixie, pixie/fileformats/svg, strformat
|
||||||
|
|
||||||
const files = [
|
const files = [
|
||||||
"line01",
|
"line01",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import chroma, pixie/fileformats/png, stb_image/read as stbi, strformat, pngsuite
|
import chroma, pixie/fileformats/png, pngsuite, stb_image/read as stbi, strformat
|
||||||
|
|
||||||
for file in pngSuiteFiles:
|
for file in pngSuiteFiles:
|
||||||
let
|
let
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import os, strutils, osproc, sequtils, algorithm
|
import algorithm, os, osproc, sequtils, strutils
|
||||||
|
|
||||||
proc cutBetween(str, a, b: string): string =
|
proc cutBetween(str, a, b: string): string =
|
||||||
let
|
let
|
||||||
|
@ -30,7 +30,8 @@ for path in exampleFiles:
|
||||||
md.add "```nim"
|
md.add "```nim"
|
||||||
md.add innerCode.strip()
|
md.add innerCode.strip()
|
||||||
md.add "```"
|
md.add "```"
|
||||||
md.add ".replace("\\", "/") & ")"
|
md.add ".replace("\\",
|
||||||
|
"/") & ")"
|
||||||
md.add ""
|
md.add ""
|
||||||
|
|
||||||
var readme = readFile("README.md")
|
var readme = readFile("README.md")
|
||||||
|
|
Loading…
Reference in a new issue