diff --git a/src/pixie/images.nim b/src/pixie/images.nim index 9b98612..e263dba 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -544,12 +544,12 @@ proc getRgbaSmooth*( ## Gets a interpolated color with float point coordinates. ## Pixes outside the image are transparent. let - x0 = x.int - y0 = y.int + x0 = x.floor.int + y0 = y.floor.int x1 = x0 + 1 y1 = y0 + 1 - xFractional = x.fractional - yFractional = y.fractional + xFractional = x - x.floor + yFractional = y - y.floor var x0y0, x1y0, x0y1, x1y1: ColorRGBX if wrapped: @@ -588,21 +588,28 @@ proc drawCorrect( var matInv = mat.inverse() + # Compute movement vectors + p = matInv * vec2(0 + h, 0 + h) + dx = matInv * vec2(1 + h, 0 + h) - p + dy = matInv * vec2(0 + h, 1 + h) - p + filterBy2 = max(dx.length, dy.length) b = b - block: # Shrink by 2 as needed - var - p = matInv * vec2(0 + h, 0 + h) - dx = matInv * vec2(1 + h, 0 + h) - p - dy = matInv * vec2(0 + h, 1 + h) - p - minFilterBy2 = max(dx.length, dy.length) + while filterBy2 >= 2.0: + b = b.minifyBy2() + p /= 2 + dx /= 2 + dy /= 2 + filterBy2 /= 2 + matInv = scale(vec2(1/2, 1/2)) * matInv - while minFilterBy2 >= 2: - b = b.minifyBy2() - dx /= 2 - dy /= 2 - minFilterBy2 /= 2 - matInv = matInv * scale(vec2(0.5, 0.5)) + while filterBy2 <= 0.5: + b = b.magnifyBy2() + p *= 2 + dx *= 2 + dy *= 2 + filterBy2 *= 2 + matInv = scale(vec2(2, 2)) * matInv for y in 0 ..< a.height: for x in 0 ..< a.width: @@ -653,16 +660,22 @@ proc drawUber( p = matInv * vec2(0 + h, 0 + h) dx = matInv * vec2(1 + h, 0 + h) - p dy = matInv * vec2(0 + h, 1 + h) - p - minFilterBy2 = max(dx.length, dy.length) + filterBy2 = max(dx.length, dy.length) b = b - while minFilterBy2 >= 2.0: + while filterBy2 >= 2.0: b = b.minifyBy2() p /= 2 dx /= 2 dy /= 2 - minFilterBy2 /= 2 - matInv = matInv * scale(vec2(0.5, 0.5)) + filterBy2 /= 2 + + while filterBy2 <= 0.5: + b = b.magnifyBy2() + p *= 2 + dx *= 2 + dy *= 2 + filterBy2 *= 2 let smooth = not( dx.length == 1.0 and @@ -716,29 +729,26 @@ proc drawUber( if smooth: var srcPos = p + dx * xMin.float32 + dy * y.float32 - srcPos = vec2(max(0, srcPos.x), max(0, srcPos.y)) + srcPos = vec2(srcPos.x - h, srcPos.y - h) for x in xMin ..< xMax: - let - xFloat = srcPos.x - h - yFloat = srcPos.y - h when type(a) is Image: let backdrop = a.getRgbaUnsafe(x, y) when type(b) is Image: let - sample = b.getRgbaSmooth(xFloat, yFloat) + sample = b.getRgbaSmooth(srcPos.x, srcPos.y) blended = blender(backdrop, sample) else: # b is a Mask let - sample = b.getValueSmooth(xFloat, yFloat) + sample = b.getValueSmooth(srcPos.x, srcPos.y) blended = blender(backdrop, rgbx(0, 0, 0, sample)) a.setRgbaUnsafe(x, y, blended) else: # a is a Mask let backdrop = a.getValueUnsafe(x, y) when type(b) is Image: - let sample = b.getRgbaSmooth(xFloat, yFloat).a + let sample = b.getRgbaSmooth(srcPos.x, srcPos.y).a else: # b is a Mask - let sample = b.getValueSmooth(xFloat, yFloat) + let sample = b.getValueSmooth(srcPos.x, srcPos.y) a.setValueUnsafe(x, y, masker(backdrop, sample)) srcPos += dx diff --git a/tests/images/diffs/smooth1.png b/tests/images/diffs/smooth1.png index 9a5edb0..7115484 100644 Binary files a/tests/images/diffs/smooth1.png and b/tests/images/diffs/smooth1.png differ diff --git a/tests/images/diffs/smooth10.png b/tests/images/diffs/smooth10.png new file mode 100644 index 0000000..0a145cb Binary files /dev/null and b/tests/images/diffs/smooth10.png differ diff --git a/tests/images/diffs/smooth11.png b/tests/images/diffs/smooth11.png new file mode 100644 index 0000000..c318c4a Binary files /dev/null and b/tests/images/diffs/smooth11.png differ diff --git a/tests/images/diffs/smooth12.png b/tests/images/diffs/smooth12.png new file mode 100644 index 0000000..6ce686e Binary files /dev/null and b/tests/images/diffs/smooth12.png differ diff --git a/tests/images/diffs/smooth2.png b/tests/images/diffs/smooth2.png index 08fc36e..477dd12 100644 Binary files a/tests/images/diffs/smooth2.png and b/tests/images/diffs/smooth2.png differ diff --git a/tests/images/diffs/smooth3.png b/tests/images/diffs/smooth3.png index 59ca693..d7b9945 100644 Binary files a/tests/images/diffs/smooth3.png and b/tests/images/diffs/smooth3.png differ diff --git a/tests/images/diffs/smooth4.png b/tests/images/diffs/smooth4.png index 78aa339..51320c9 100644 Binary files a/tests/images/diffs/smooth4.png and b/tests/images/diffs/smooth4.png differ diff --git a/tests/images/diffs/smooth5.png b/tests/images/diffs/smooth5.png new file mode 100644 index 0000000..ffe5bfb Binary files /dev/null and b/tests/images/diffs/smooth5.png differ diff --git a/tests/images/diffs/smooth6.png b/tests/images/diffs/smooth6.png new file mode 100644 index 0000000..6e54dff Binary files /dev/null and b/tests/images/diffs/smooth6.png differ diff --git a/tests/images/diffs/smooth7.png b/tests/images/diffs/smooth7.png new file mode 100644 index 0000000..53b2f2e Binary files /dev/null and b/tests/images/diffs/smooth7.png differ diff --git a/tests/images/diffs/smooth8.png b/tests/images/diffs/smooth8.png new file mode 100644 index 0000000..a37198b Binary files /dev/null and b/tests/images/diffs/smooth8.png differ diff --git a/tests/images/diffs/smooth9.png b/tests/images/diffs/smooth9.png new file mode 100644 index 0000000..a37198b Binary files /dev/null and b/tests/images/diffs/smooth9.png differ diff --git a/tests/images/masters/smooth10.png b/tests/images/masters/smooth10.png new file mode 100644 index 0000000..83ec23d Binary files /dev/null and b/tests/images/masters/smooth10.png differ diff --git a/tests/images/masters/smooth11.png b/tests/images/masters/smooth11.png new file mode 100644 index 0000000..25faa14 Binary files /dev/null and b/tests/images/masters/smooth11.png differ diff --git a/tests/images/masters/smooth12.png b/tests/images/masters/smooth12.png new file mode 100644 index 0000000..6a1ce12 Binary files /dev/null and b/tests/images/masters/smooth12.png differ diff --git a/tests/images/masters/smooth2.png b/tests/images/masters/smooth2.png index de657ea..10f9ec6 100644 Binary files a/tests/images/masters/smooth2.png and b/tests/images/masters/smooth2.png differ diff --git a/tests/images/masters/smooth5.png b/tests/images/masters/smooth5.png new file mode 100644 index 0000000..8a4f927 Binary files /dev/null and b/tests/images/masters/smooth5.png differ diff --git a/tests/images/masters/smooth6.png b/tests/images/masters/smooth6.png new file mode 100644 index 0000000..97d3482 Binary files /dev/null and b/tests/images/masters/smooth6.png differ diff --git a/tests/images/masters/smooth7.png b/tests/images/masters/smooth7.png new file mode 100644 index 0000000..97d3482 Binary files /dev/null and b/tests/images/masters/smooth7.png differ diff --git a/tests/images/masters/smooth8.png b/tests/images/masters/smooth8.png new file mode 100644 index 0000000..c75da7b Binary files /dev/null and b/tests/images/masters/smooth8.png differ diff --git a/tests/images/masters/smooth9.png b/tests/images/masters/smooth9.png new file mode 100644 index 0000000..bce9689 Binary files /dev/null and b/tests/images/masters/smooth9.png differ diff --git a/tests/images/rendered/smooth1.png b/tests/images/rendered/smooth1.png index c83aeca..08ee941 100644 Binary files a/tests/images/rendered/smooth1.png and b/tests/images/rendered/smooth1.png differ diff --git a/tests/images/rendered/smooth10.png b/tests/images/rendered/smooth10.png new file mode 100644 index 0000000..8ada96e Binary files /dev/null and b/tests/images/rendered/smooth10.png differ diff --git a/tests/images/rendered/smooth11.png b/tests/images/rendered/smooth11.png new file mode 100644 index 0000000..5fc8850 Binary files /dev/null and b/tests/images/rendered/smooth11.png differ diff --git a/tests/images/rendered/smooth12.png b/tests/images/rendered/smooth12.png new file mode 100644 index 0000000..688ad7f Binary files /dev/null and b/tests/images/rendered/smooth12.png differ diff --git a/tests/images/rendered/smooth2.png b/tests/images/rendered/smooth2.png index 56d925a..93e2407 100644 Binary files a/tests/images/rendered/smooth2.png and b/tests/images/rendered/smooth2.png differ diff --git a/tests/images/rendered/smooth3.png b/tests/images/rendered/smooth3.png index 59db7c6..8f8c41f 100644 Binary files a/tests/images/rendered/smooth3.png and b/tests/images/rendered/smooth3.png differ diff --git a/tests/images/rendered/smooth4.png b/tests/images/rendered/smooth4.png index d59f752..b4a16ef 100644 Binary files a/tests/images/rendered/smooth4.png and b/tests/images/rendered/smooth4.png differ diff --git a/tests/images/rendered/smooth5.png b/tests/images/rendered/smooth5.png new file mode 100644 index 0000000..8ae1ebe Binary files /dev/null and b/tests/images/rendered/smooth5.png differ diff --git a/tests/images/rendered/smooth6.png b/tests/images/rendered/smooth6.png new file mode 100644 index 0000000..da0ceb1 Binary files /dev/null and b/tests/images/rendered/smooth6.png differ diff --git a/tests/images/rendered/smooth7.png b/tests/images/rendered/smooth7.png new file mode 100644 index 0000000..9d69a8d Binary files /dev/null and b/tests/images/rendered/smooth7.png differ diff --git a/tests/images/rendered/smooth8.png b/tests/images/rendered/smooth8.png new file mode 100644 index 0000000..127a2f4 Binary files /dev/null and b/tests/images/rendered/smooth8.png differ diff --git a/tests/images/rendered/smooth9.png b/tests/images/rendered/smooth9.png new file mode 100644 index 0000000..d56d4e7 Binary files /dev/null and b/tests/images/rendered/smooth9.png differ diff --git a/tests/images/turtle.png b/tests/images/turtle.png new file mode 100644 index 0000000..f813c76 Binary files /dev/null and b/tests/images/turtle.png differ diff --git a/tests/images/turtle@10x.png b/tests/images/turtle@10x.png new file mode 100644 index 0000000..2c371f1 Binary files /dev/null and b/tests/images/turtle@10x.png differ diff --git a/tests/test_images_draw.nim b/tests/test_images_draw.nim index 1932781..ba89f6b 100644 --- a/tests/test_images_draw.nim +++ b/tests/test_images_draw.nim @@ -138,22 +138,20 @@ proc doDiff(rendered: Image, name: string) = block: let - image = newImage(100, 100) - path = newPath() - path.rect(0, 0, 99, 99) - image.fillPath(path, rgba(0, 0, 0, 255), translate(vec2(0.5, 0.5))) - doDiff(image, "smooth1") + a = newImage(100, 100) + b = newImage(99, 99) + a.fill(rgba(255, 255, 255, 255)) + b.fill(rgbx(0, 0, 0, 255)) + a.draw(b, translate(vec2(0.5, 0.5))) + doDiff(a, "smooth1") block: let a = newImage(100, 100) - b = newImage(100, 100) - path = newPath() - path.rect(-25, -25, 50, 50) - path.transform(rotate(45 * PI.float32 / 180)) - b.fillPath(path, rgba(0, 0, 0, 255), translate(vec2(50, 50))) + b = newImage(50, 50) a.fill(rgba(255, 255, 255, 255)) - a.draw(b, translate(vec2(0, 0.4))) + b.fill(rgbx(0, 0, 0, 255)) + a.draw(b, translate(vec2(0, 50)) * rotate(45.toRadians)) doDiff(a, "smooth2") block: @@ -173,3 +171,81 @@ block: b.fill(rgba(0, 0, 0, 255)) a.draw(b, translate(vec2(25.2, 25.6))) doDiff(a, "smooth4") + +block: + let + a = newImage(100, 100) + 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) + a.draw(b, m) + doDiff(a, "smooth5") + +block: + let + 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) + a.draw(b, m) + doDiff(a, "smooth6") + +block: + let + 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)) + a.draw(b, m) + doDiff(a, "smooth7") + +block: + let + a = newImage(100, 100) + b = readImage(&"tests/images/turtle.png") + a.fill(rgba(255, 255, 255, 255)) + let m = scale(vec2(2, 2)) + a.draw(b, m) + doDiff(a, "smooth8") + +block: + let + a = newImage(100, 100) + b = readImage(&"tests/images/turtle.png") + a.fill(rgba(255, 255, 255, 255)) + let m = translate(vec2(1, 1)) * scale(vec2(2, 2)) + a.draw(b, m) + doDiff(a, "smooth9") + +block: + let + a = newImage(100, 100) + b = readImage(&"tests/images/turtle.png") + a.fill(rgba(255, 255, 255, 255)) + let m = translate(vec2(0.5, 0.5)) * scale(vec2(2, 2)) + a.draw(b, m) + doDiff(a, "smooth10") + +block: + let + a = newImage(100, 100) + b = readImage(&"tests/images/turtle.png") + a.fill(rgba(255, 255, 255, 255)) + let m = translate(vec2(-43.29, -103.87)) * + rotate(-15.toRadians) * + scale(vec2(263.86/40, 263.86/40)) + a.draw(b, m) + doDiff(a, "smooth11") + +block: + let + 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) + a.draw(b, m * translate(vec2(0,0))) + a.draw(b, m * translate(vec2(-40,0))) + a.draw(b, m * translate(vec2(-40,-40))) + a.draw(b, m * translate(vec2(0,-40))) + doDiff(a, "smooth12")