Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/blur.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let
trees = readImage("examples/data/trees.png")
Expand All @@ -19,4 +19,4 @@ blur.draw(mask, blendMode = MaskBlend)
image.draw(trees)
image.draw(blur)

image.writeFile("examples/blur.png")
image.writeFile(outputPath("blur.png"))
12 changes: 12 additions & 0 deletions examples/common.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import os

proc outputPath*(fileName: string): string =
if paramCount() >= 1:
result =
if paramStr(1) == "--" and paramCount() >= 2:
paramStr(2)
else:
paramStr(1)
createDir(parentDir(result))
else:
result = "examples" / fileName
1 change: 1 addition & 0 deletions examples/config.nims
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--path:"../src"
4 changes: 2 additions & 2 deletions examples/gradient.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand Down Expand Up @@ -26,4 +26,4 @@ image.fillPath(
paint
)

image.writeFile("examples/gradient.png")
image.writeFile(outputPath("gradient.png"))
4 changes: 2 additions & 2 deletions examples/heart.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -15,4 +15,4 @@ image.fillPath(
parseHtmlColor("#FC427B").rgba
)

image.writeFile("examples/heart.png")
image.writeFile(outputPath("heart.png"))
4 changes: 2 additions & 2 deletions examples/image_tiled.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -15,4 +15,4 @@ paint.image = readImage("examples/data/mandrill.png")
paint.imageMat = scale(vec2(0.08, 0.08))

image.fillPath(path, paint)
image.writeFile("examples/image_tiled.png")
image.writeFile(outputPath("image_tiled.png"))
4 changes: 2 additions & 2 deletions examples/line.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -13,4 +13,4 @@ let

ctx.strokeSegment(segment(start, stop))

image.writeFile("examples/line.png")
image.writeFile(outputPath("line.png"))
4 changes: 2 additions & 2 deletions examples/masking.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let
image = newImage(200, 200)
Expand Down Expand Up @@ -29,4 +29,4 @@ mask.fillPath(
lines.draw(mask, blendMode = MaskBlend)
image.draw(lines)

image.writeFile("examples/masking.png")
image.writeFile(outputPath("masking.png"))
4 changes: 2 additions & 2 deletions examples/rounded_rectangle.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -13,4 +13,4 @@ let

ctx.fillRoundedRect(rect(pos, wh), r)

image.writeFile("examples/rounded_rectangle.png")
image.writeFile(outputPath("rounded_rectangle.png"))
4 changes: 2 additions & 2 deletions examples/shadow.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -19,4 +19,4 @@ let shadow = polygonImage.shadow(
image.draw(shadow)
image.draw(polygonImage)

image.writeFile("examples/shadow.png")
image.writeFile(outputPath("shadow.png"))
4 changes: 2 additions & 2 deletions examples/square.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -12,4 +12,4 @@ let

ctx.fillRect(rect(pos, wh))

image.writeFile("examples/square.png")
image.writeFile(outputPath("square.png"))
4 changes: 2 additions & 2 deletions examples/text.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -10,4 +10,4 @@ font.paint.color = color(1, 0, 0)
let text = "Typesetting is the arrangement and composition of text in graphic design and publishing in both digital and traditional medias."

image.fillText(font.typeset(text, vec2(180, 180)), translate(vec2(10, 10)))
image.writeFile("examples/text.png")
image.writeFile(outputPath("text.png"))
Binary file modified examples/text.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions examples/text_spans.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -20,4 +20,4 @@ let spans = @[
]

image.fillText(typeset(spans, vec2(180, 180)), translate(vec2(10, 10)))
image.writeFile("examples/text_spans.png")
image.writeFile(outputPath("text_spans.png"))
4 changes: 2 additions & 2 deletions examples/tiger.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pixie
import pixie, common

let image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))
Expand All @@ -12,4 +12,4 @@ image.draw(
translate(vec2(-450, -450))
)

image.writeFile("examples/tiger.png")
image.writeFile(outputPath("tiger.png"))
2 changes: 1 addition & 1 deletion src/pixie/contexts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ proc scale*(ctx: Context, x, y: float32) {.inline, raises: [].} =

proc rotate*(ctx: Context, angle: float32) {.inline, raises: [].} =
## Adds a rotation to the transformation matrix.
ctx.mat = ctx.mat * rotate(-angle)
ctx.mat = ctx.mat * rotate(angle)

proc resetTransform*(ctx: Context) {.inline, raises: [].} =
## Resets the current transform to the identity matrix.
Expand Down
4 changes: 2 additions & 2 deletions src/pixie/fileformats/svg.nim
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ proc parseSvgProperties(node: XmlNode, inherited: SvgProperties): SvgProperties
m[0, 1] = parseFloat(arr[1])
m[1, 0] = parseFloat(arr[2])
m[1, 1] = parseFloat(arr[3])
m[2, 0] = parseFloat(arr[4])
m[2, 1] = parseFloat(arr[5])
m[0, 2] = parseFloat(arr[4])
m[1, 2] = parseFloat(arr[5])
result.transform = result.transform * m
elif f.startsWith("translate("):
let
Expand Down
6 changes: 3 additions & 3 deletions src/pixie/fontformats/opentype.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2404,9 +2404,9 @@ proc parseCompositeGlyph(opentype: OpenType, offset: int): Path =

var subPath = opentype.parseGlyfGlyph(component.glyphId)
subPath.transform(mat3(
component.xScale, component.scale10, 0.0,
component.scale01, component.yScale, 0.0,
component.dx, component.dy, 1.0
component.xScale, component.scale10, component.dx,
component.scale01, component.yScale, component.dy,
0.0, 0.0, 1.0
))

result.addPath(subPath)
Expand Down
11 changes: 8 additions & 3 deletions src/pixie/images.nim
Original file line number Diff line number Diff line change
Expand Up @@ -664,18 +664,23 @@ proc draw*(
transform = transform * scale(vec2(1/2, 1/2))

let
translation = transform.pos
hasRotationOrScaling = not(dx == vec2(1, 0) and dy == vec2(0, 1))
smooth = not(
dx.length == 1.0 and
dy.length == 1.0 and
transform[2, 0].fractional == 0.0 and
transform[2, 1].fractional == 0.0
translation.x.fractional == 0.0 and
translation.y.fractional == 0.0
)

if hasRotationOrScaling or smooth:
a.drawSmooth(b, transform, blendMode)
else:
a.blendRect(b, ivec2(transform[2, 0].int32, transform[2, 1].int32), blendMode)
a.blendRect(
b,
ivec2(translation.x.int32, translation.y.int32),
blendMode
)

proc drawTiled*(
dst, src: Image, mat: Mat3, blendMode = NormalBlend
Expand Down
2 changes: 1 addition & 1 deletion src/pixie/paths.nim
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ proc commandsToShapes(

ArcParams(
radii: radii,
rotMat: rotate(-radians),
rotMat: rotate(radians),
center: center,
theta: theta,
delta: delta
Expand Down
13 changes: 1 addition & 12 deletions tests/all.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,4 @@ import
test_ppm,
test_qoi,
test_svg,
../examples/text,
../examples/text_spans,
../examples/square,
../examples/line,
../examples/rounded_rectangle,
../examples/heart,
../examples/masking,
../examples/gradient,
../examples/image_tiled,
../examples/shadow,
../examples/blur,
../examples/tiger
test_examples
Binary file added tests/contexts/setTransform_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions tests/test_contexts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,18 @@ block:
block:
let ctx = newContext(newImage(300, 150))

ctx.setTransform(mat3(1, 0.2, 0, 0.8, 1, 0, 0, 0, 1))
ctx.setTransform(mat3(1, 0.8, 0, 0.2, 1, 0, 0, 0, 1))
ctx.fillRect(0, 0, 100, 100)

ctx.image.xray("tests/contexts/setTransform_1.png")

block:
let ctx = newContext(newImage(300, 150))

ctx.setTransform(mat3(1, 0.2, 0, 0.8, 1, 0, 0, 0, 1))
ctx.setTransform(mat3(1, 0.8, 0, 0.2, 1, 0, 0, 0, 1))
ctx.fillRect(0, 0, 100, 100)

ctx.image.xray("tests/contexts/resetTransform_1.png")
ctx.image.xray("tests/contexts/setTransform_2.png")

block:
let ctx = newContext(newImage(300, 150))
Expand All @@ -225,7 +225,7 @@ block:
block:
let ctx = newContext(newImage(300, 150))

ctx.transform(mat3(1, 0, 0, 1.7, 1, 0, 0, 0, 1))
ctx.transform(mat3(1, 1.7, 0, 0, 1, 0, 0, 0, 1))
ctx.fillStyle = "gray"
ctx.fillRect(40, 40, 50, 20)
ctx.fillRect(40, 90, 50, 20)
Expand Down
51 changes: 51 additions & 0 deletions tests/test_examples.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import os, osproc, strformat, pixie

const examples = [
"text",
"text_spans",
"square",
"line",
"rounded_rectangle",
"heart",
"masking",
"gradient",
"image_tiled",
"shadow",
"blur",
"tiger"
]

const updateThreshold = 1.0

let
generatedDir = "tmp/generated/examples"
xrayDir = "tmp/xray/examples"

createDir(generatedDir)
createDir(xrayDir)

for example in examples:
let
nimFile = &"examples/{example}.nim"
masterPath = &"examples/{example}.png"
generatedPath = generatedDir / &"{example}.png"
xrayPath = xrayDir / &"{example}.png"
run = execCmdEx(
&"nim r -d:release {nimFile} -- {generatedPath}",
workingDir = getCurrentDir()
)

if run.exitCode != 0:
echo run.output
raise newException(PixieError, &"Example {example} failed with exit code {run.exitCode}")

let
generated = readImage(generatedPath)
master = readImage(masterPath)
(score, xray) = diff(generated, master)

xray.writeFile(xrayPath)
echo &"xray {masterPath} -> {score:0.6f}"

if score > updateThreshold:
copyFile(generatedPath, masterPath)
6 changes: 3 additions & 3 deletions tests/test_images.nim
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,9 @@ block:
a.draw(
b,
mat3(
-0.5, -4.371138828673793e-008, 0.0,
-4.371138828673793e-008, 0.5, 0.0,
292.0, 45.0, 1.0
-0.5, -4.371138828673793e-008, 292.0,
-4.371138828673793e-008, 0.5, 45.0,
0.0, 0.0, 1.0
)
)

Expand Down
12 changes: 6 additions & 6 deletions tests/test_images_draw.nim
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ block:
b = newImage(50, 50)
a.fill(rgba(255, 255, 255, 255))
b.fill(rgbx(0, 0, 0, 255))
a.draw(b, translate(vec2(0, 50)) * rotate(45.toRadians))
a.draw(b, translate(vec2(0, 50)) * rotate(-45.toRadians))
a.xray("tests/images/masters/smooth2.png")

block:
Expand All @@ -170,7 +170,7 @@ block:
b = newImage(10, 10)
a.fill(rgba(255, 255, 255, 255))
b.fill(rgbx(255, 0, 0, 255))
let m = translate(vec2(50, 50)) * rotate(30.toRadians)
let m = translate(vec2(50, 50)) * rotate(-30.toRadians)
a.draw(b, m)
a.xray("tests/images/masters/smooth5.png")

Expand All @@ -179,7 +179,7 @@ block:
a = newImage(100, 100)
b = readImage(&"tests/images/turtle.png")
a.fill(rgba(255, 255, 255, 255))
let m = translate(vec2(50, 50)) * rotate(30.toRadians)
let m = translate(vec2(50, 50)) * rotate(-30.toRadians)
a.draw(b, m)
a.xray("tests/images/masters/smooth6.png")

Expand All @@ -188,7 +188,7 @@ block:
a = newImage(100, 100)
b = readImage(&"tests/images/turtle@10x.png")
a.fill(rgba(255, 255, 255, 255))
let m = translate(vec2(50, 50)) * rotate(30.toRadians) * scale(vec2(0.1, 0.1))
let m = translate(vec2(50, 50)) * rotate(-30.toRadians) * scale(vec2(0.1, 0.1))
a.draw(b, m)
a.xray("tests/images/masters/smooth7.png")

Expand Down Expand Up @@ -225,7 +225,7 @@ block:
b = readImage(&"tests/images/turtle.png")
a.fill(rgba(255, 255, 255, 255))
let m = translate(vec2(-43.29, -103.87)) *
rotate(-15.toRadians) *
rotate(15.toRadians) *
scale(vec2(263.86/40, 263.86/40))
a.draw(b, m)
a.xray("tests/images/masters/smooth11.png")
Expand All @@ -235,7 +235,7 @@ block:
a = newImage(100, 100)
b = readImage(&"tests/images/turtle.png")
a.fill(rgba(255, 255, 255, 255))
let m = translate(vec2(50, 50)) * rotate(-5.toRadians)
let m = translate(vec2(50, 50)) * rotate(5.toRadians)
a.draw(b, m * translate(vec2(0, 0)))
a.draw(b, m * translate(vec2(-40, 0)))
a.draw(b, m * translate(vec2(-40, -40)))
Expand Down
Loading