tiled draw path + removed 2 exported procs from paints.nim (#132)

This commit is contained in:
Ryan Oldenburg 2021-02-25 11:05:20 -06:00 committed by GitHub
parent 84b8410cef
commit 34b5f07f1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 78 deletions

View file

@ -510,7 +510,7 @@ proc newMask*(image: Image): Mask =
for j in i ..< image.data.len:
result.data[j] = image.data[j].a
proc getRgbaSmooth*(image: Image, x, y: float32): ColorRGBA =
proc getRgbaSmooth*(image: Image, x, y: float32, wrapped = false): ColorRGBA =
## Gets a interpolated color with float point coordinates.
## Pixes outside the image are transparent.
let
@ -520,39 +520,30 @@ proc getRgbaSmooth*(image: Image, x, y: float32): ColorRGBA =
diffY = y - minY
x = minX.int
y = minY.int
x0 = (x + 0)
y0 = (y + 0)
x1 = (x + 1)
y1 = (y + 1)
x0y0 = image[x + 0, y + 0]
x1y0 = image[x + 1, y + 0]
x0y1 = image[x + 0, y + 1]
x1y1 = image[x + 1, y + 1]
var x0y0, x1y0, x0y1, x1y1: ColorRGBA
if wrapped:
x0y0 = image.getRgbaUnsafe(x0 mod image.width, y0 mod image.height)
x1y0 = image.getRgbaUnsafe(x1 mod image.width, y0 mod image.height)
x0y1 = image.getRgbaUnsafe(x0 mod image.width, y1 mod image.height)
x1y1 = image.getRgbaUnsafe(x1 mod image.width, y1 mod image.height)
else:
x0y0 = image[x0, y0]
x1y0 = image[x1, y0]
x0y1 = image[x0, y1]
x1y1 = image[x1, y1]
bottomMix = lerp(x0y0, x1y0, diffX)
topMix = lerp(x0y1, x1y1, diffX)
lerp(bottomMix, topMix, diffY)
proc getRgbaSmoothWrapped*(image: Image, x, y: float32): ColorRGBA =
## Gets a interpolated color with float point coordinates.
## Pixes outside the image are repeated.
let
minX = floor(x)
minY = floor(y)
diffX = x - minX
diffY = y - minY
x = minX.int
y = minY.int
x0y0 = image[(x + 0) mod image.width, (y + 0) mod image.height]
x1y0 = image[(x + 1) mod image.width, (y + 0) mod image.height]
x0y1 = image[(x + 0) mod image.width, (y + 1) mod image.height]
x1y1 = image[(x + 1) mod image.width, (y + 1) mod image.height]
bottomMix = lerp(x0y0, x1y0, diffX)
topMix = lerp(x0y1, x1y1, diffX)
lerp(bottomMix, topMix, diffY)
proc drawCorrect(a, b: Image | Mask, mat = mat3(), blendMode = bmNormal) =
proc drawCorrect(a, b: Image | Mask, mat = mat3(), tiled = false, blendMode = bmNormal) =
## Draws one image onto another using matrix with color blending.
when type(a) is Image:
@ -589,7 +580,7 @@ proc drawCorrect(a, b: Image | Mask, mat = mat3(), blendMode = bmNormal) =
let backdrop = a.getRgbaUnsafe(x, y)
when type(b) is Image:
let
sample = b.getRgbaSmooth(xFloat, yFloat)
sample = b.getRgbaSmooth(xFloat, yFloat, tiled)
blended = blender(backdrop, sample)
else: # b is a Mask
let
@ -599,7 +590,7 @@ proc drawCorrect(a, b: Image | Mask, mat = mat3(), blendMode = bmNormal) =
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(xFloat, yFloat, tiled).a
else: # b is a Mask
let sample = b.getValueSmooth(xFloat, yFloat)
a.setValueUnsafe(x, y, masker(backdrop, sample))
@ -839,6 +830,9 @@ proc draw*(
## Draws a image onto a mask using a position offset with color blending.
mask.draw(image, translate(pos), blendMode)
proc drawTiled*(dest, src: Image, mat: Mat3, blendMode = bmNormal) =
dest.drawCorrect(src, mat, true, blendMode)
proc resize*(srcImage: Image, width, height: int): Image =
## Resize an image to a given hight and width.
if width == srcImage.width and height == srcImage.height:

View file

@ -27,48 +27,6 @@ type
color*: Color ## Color of the stop
position*: float32 ## Gradient Stop position 0..1.
proc fillImage*(
dest: Image,
src: Image,
mat: Mat3
) =
## Draws and basic image fill.
dest.draw(
src,
mat
)
proc fillImageTiled*(
dest: Image,
src: Image,
mat: Mat3
) =
## Draws a tiled image fill.
var
matInv = mat.inverse()
src = src
block: # Shrink by 2 as needed
const h = 0.5.float32
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 minFilterBy2 > 2:
src = src.minifyBy2()
dx /= 2
dy /= 2
minFilterBy2 /= 2
matInv = matInv * scale(vec2(0.5, 0.5))
for y in 0 ..< dest.height:
for x in 0 ..< dest.width:
var srcPos = matInv * vec2(x.float32, y.float32)
let rgba = src.getRgbaSmoothWrapped(srcPos.x, srcPos.y)
dest.setRgbaUnsafe(x,y, rgba)
proc toLineSpace(at, to, point: Vec2): float32 =
## Convert position on to where it would fall on a line between at and to.
let

View file

@ -1481,15 +1481,9 @@ proc fillPath*(
of pkSolid:
fill.fill(paint.color.toPremultipliedAlpha())
of pkImage:
fill.fillImage(
paint.image,
paint.imageMat
)
fill.draw(paint.image, paint.imageMat)
of pkImageTiled:
fill.fillImageTiled(
paint.image,
paint.imageMat
)
fill.drawTiled(paint.image, paint.imageMat)
of pkGradientLinear:
fill.fillLinearGradient(
paint.gradientHandlePositions[0],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB