Merge pull request #299 from treeform/fixsmooth

Fixsmooth
This commit is contained in:
treeform 2021-10-04 12:39:27 -07:00 committed by GitHub
commit 74cac6af11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 125 additions and 39 deletions

View file

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 B

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 763 B

After

Width:  |  Height:  |  Size: 699 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 896 B

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 B

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
tests/images/turtle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
tests/images/turtle@10x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

View file

@ -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")