diff --git a/src/pixie/images.nim b/src/pixie/images.nim index 1eb81a7..54b3543 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -22,6 +22,12 @@ proc `$`*(image: Image): string = ## Display the image size and channels. "" +proc fraction(v: float32): float32 = + ## Returns unsigned fraction part of the float. + ## -13.7868723 -> 0.7868723 + result = abs(v) + result = result - floor(result) + proc inside*(image: Image, x, y: int): bool {.inline.} = ## Returns true if (x, y) is inside the image. x >= 0 and x < image.width and @@ -29,8 +35,9 @@ proc inside*(image: Image, x, y: int): bool {.inline.} = proc inside1px*(image: Image, x, y: float): bool {.inline.} = ## Returns true if (x, y) is inside the image. - x >= -1 and x < (image.width.float32 + 1) and - y >= -1 and y < (image.height.float32 + 1) + const px = 1 + x >= -px and x < (image.width.float32 + px) and + y >= -px and y < (image.height.float32 + px) proc getRgbaUnsafe*(image: Image, x, y: int): ColorRGBA {.inline.} = ## Gets a color from (x, y) coordinates. @@ -116,22 +123,39 @@ func lerp(a, b: Color, v: float): Color {.inline.} = proc getRgbaSmooth*(image: Image, x, y: float64): ColorRGBA {.inline.} = ## Gets a pixel as (x, y) floats. - let - minX = floor(x).int - difX = (x - minX.float32) - minY = floor(y).int - difY = (y - minY.float32) - vX0Y0 = image[minX, minY].color() - vX1Y0 = image[minX + 1, minY].color() - vX0Y1 = image[minX, minY + 1].color() - vX1Y1 = image[minX + 1, minY + 1].color() + proc toAlphy(c: Color): Color = + result.r = c.r * c.a + result.g = c.g * c.a + result.b = c.b * c.a + result.a = c.a + + proc fromAlphy(c: Color): Color = + if c.a == 0: + return + result.r = c.r / c.a + result.g = c.g / c.a + result.b = c.b / c.a + result.a = c.a + + var + x = x # TODO: look at maybe +0.5 + y = y # TODO: look at maybe +0.5 + minX = x.floor.int + difX = x - x.floor + minY = y.floor.int + difY = y - y.floor + + vX0Y0 = image[minX, minY].color().toAlphy() + vX1Y0 = image[minX + 1, minY].color().toAlphy() + vX0Y1 = image[minX, minY + 1].color().toAlphy() + vX1Y1 = image[minX + 1, minY + 1].color().toAlphy() bottomMix = lerp(vX0Y0, vX1Y0, difX) topMix = lerp(vX0Y1, vX1Y1, difX) finalMix = lerp(bottomMix, topMix, difY) - return finalMix.rgba() + return finalMix.fromAlphy().rgba() proc hasEffect*(blendMode: BlendMode, rgba: ColorRGBA): bool = ## Returns true if applying rgba with current blend mode has effect. @@ -143,10 +167,6 @@ proc hasEffect*(blendMode: BlendMode, rgba: ColorRGBA): bool = else: rgba.a > 0 -proc fraction(v: float32): float32 = - result = abs(v) - result = result - floor(result) - proc drawFast1*(a: Image, b: Image, mat: Mat3): Image = ## Draws one image onto another using integer x,y offset with COPY. result = newImage(a.width, a.height) diff --git a/tests/images/centerRotation.master.png b/tests/images/centerRotation.master.png new file mode 100644 index 0000000..70cf775 Binary files /dev/null and b/tests/images/centerRotation.master.png differ diff --git a/tests/images/centerRotation.png b/tests/images/centerRotation.png new file mode 100644 index 0000000..52b891b Binary files /dev/null and b/tests/images/centerRotation.png differ diff --git a/tests/images/centerRotationWhite.master.png b/tests/images/centerRotationWhite.master.png new file mode 100644 index 0000000..2723c55 Binary files /dev/null and b/tests/images/centerRotationWhite.master.png differ diff --git a/tests/images/centerRotationWhite.png b/tests/images/centerRotationWhite.png new file mode 100644 index 0000000..1e1144e Binary files /dev/null and b/tests/images/centerRotationWhite.png differ diff --git a/tests/images/drawFast1Rot.png b/tests/images/drawFast1Rot.png index d67e4bd..35cedb3 100644 Binary files a/tests/images/drawFast1Rot.png and b/tests/images/drawFast1Rot.png differ diff --git a/tests/images/drawFast3.png b/tests/images/drawFast3.png index bef6ff3..df7a048 100644 Binary files a/tests/images/drawFast3.png and b/tests/images/drawFast3.png differ diff --git a/tests/images/transCompose.c.png b/tests/images/transCompose.c.png new file mode 100644 index 0000000..52b891b Binary files /dev/null and b/tests/images/transCompose.c.png differ diff --git a/tests/images/transCompose.png b/tests/images/transCompose.png new file mode 100644 index 0000000..5fd4195 Binary files /dev/null and b/tests/images/transCompose.png differ diff --git a/tests/test_images.nim b/tests/test_images.nim index 9b7c34a..77bef73 100644 --- a/tests/test_images.nim +++ b/tests/test_images.nim @@ -11,6 +11,47 @@ proc writeAndCheck(image: Image, fileName: string) = assert image.height == master.height assert image.data == master.data +block: + var a = newImage(100, 100) + a.fill(rgba(0, 0, 0, 0)) + var b = newImage(50, 50) + b.fill(rgba(255, 92, 0, 255)) + var c = a.drawFast3( + b, + translate(vec2(50, 50)) * rotationMat3(0.2789281382) * translate(vec2(-25, -25)), + bmNormal + ) + c.writeAndCheck("tests/images/centerRotation.png") + +block: + var a = newImage(100, 100) + a.fill(rgba(255, 255, 255, 255)) + var b = newImage(50, 50) + b.fill(rgba(255, 92, 0, 255)) + var c = a.drawFast3( + b, + translate(vec2(50, 50)) * rotationMat3(0.2789281382) * translate(vec2(-25, -25)), + bmNormal + ) + c.writeAndCheck("tests/images/centerRotationWhite.png") + + +block: + var a = newImage(100, 100) + a.fill(rgba(0, 0, 0, 0)) + var b = newImage(50, 50) + b.fill(rgba(255, 92, 0, 255)) + var c = a.drawFast3( + b, + translate(vec2(50, 50)) * rotationMat3(0.2789281382) * translate(vec2(-25, -25)), + bmNormal + ) + c.writeAndCheck("tests/images/transCompose.c.png") + var d = newImage(100, 100) + d.fill(rgba(255, 255, 255, 255)) + var e = d.draw(c) + e.writeAndCheck("tests/images/transCompose.png") + block: var image = newImage(10, 10) image[0, 0] = rgba(255, 255, 255, 255)