aseprite/tests/scripts/inks.lua
2024-09-03 19:11:14 -03:00

518 lines
15 KiB
Lua

-- Copyright (C) 2020-2023 Igara Studio S.A.
--
-- This file is released under the terms of the MIT license.
-- Read LICENSE.txt for more information.
dofile('./test_utils.lua')
local colorModes = { ColorMode.RGB,
ColorMode.GRAY,
ColorMode.INDEXED }
local pencil = "pencil"
local pc = app.pixelColor
local function gray(g)
return pc.graya(g, 255)
end
function test_inks(colorMode)
-- Test ink over a transparent sprite
local s = Sprite(3, 3, colorMode)
local p, a, b, c, d
if colorMode == ColorMode.GRAY then
p = s.palettes[1]
a, b, c, d = gray(0), gray(64), gray(128), gray(255)
else
p = Palette()
p:resize(4)
p:setColor(0, Color(0, 0, 0))
p:setColor(1, Color(64, 64, 64))
p:setColor(2, Color(128, 128, 128))
p:setColor(3, Color(255, 255, 255))
s:setPalette(p)
a, b, c, d = 0, 1, 2, 3
if colorMode == ColorMode.RGB then
a = p:getColor(a).rgbaPixel
b = p:getColor(b).rgbaPixel
c = p:getColor(c).rgbaPixel
d = p:getColor(d).rgbaPixel
end
end
-- With simple ink opacity doesn't have affect (always the color)
local opacities = { 0, 128, 255 }
for i = 1,#opacities do
expect_img(app.activeImage,
{ 0, 0, 0,
0, 0, 0,
0, 0, 0 })
app.useTool{ tool=pencil, color=d, points={ Point(0, 0), Point(2, 2) },
ink=Ink.SIMPLE, opacity=opacities[i] }
expect_img(app.activeImage,
{ d, 0, 0,
0, d, 0,
0, 0, d })
if i < #opacities then app.undo() end
end
-- Check that painting with transparent index (color) on a
-- transparent layer (using any value of opacity) with alpha
-- compositing doesn't modify pixels
for i = 1,#opacities do
app.useTool{ tool=pencil, color=0, points={ Point(1, 1) },
ink=Ink.ALPHA_COMPOSITING, opacity=opacities[i] }
expect_img(app.activeImage,
{ d, 0, 0,
0, d, 0,
0, 0, d })
end
-- Convert to background layer
app.bgColor = Color{ index=0 }
app.command.BackgroundFromLayer()
app.useTool{ tool=pencil, color=d, points={ Point(0, 1), Point(2, 1) },
ink=Ink.ALPHA_COMPOSITING, opacity=64 }
expect_img(app.activeImage,
{ d, a, a,
b, d, b,
a, a, d })
app.useTool{ tool=pencil, color=d, points={ Point(0, 1) },
ink=Ink.ALPHA_COMPOSITING, opacity=86 }
expect_img(app.activeImage,
{ d, a, a,
c, d, b,
a, a, d })
----------------------------------------------------------------------
-- Inks with custom brushes
function test_custom_brush_inks(brushColorMode)
-- Colors in the brush image (ba, bb, bc, bd)
local ba, bb, bc, bd
if brushColorMode == ColorMode.RGB then
ba = Color(0, 0, 0)
bb = Color(64, 64, 64)
bc = Color(128, 128, 128)
bd = Color(255, 255, 255)
elseif brushColorMode == ColorMode.GRAY then
ba, bb, bc, bd = gray(0), gray(64), gray(128), gray(255)
else
ba, bb, bc, bd = 0, 1, 2, 3
end
local brushImage = Image(2, 2, brushColorMode)
array_to_pixels({ 0, bd,
bc, 0 }, brushImage)
local brush = Brush(brushImage)
-- da, db, dc, dd are the final result after painting the custom
-- brush in the sprite
local ra, rb, rc, rd
if s.colorMode ~= ColorMode.INDEXED and
brushColorMode == ColorMode.INDEXED then
-- For indexed images we take the index of the brush and use the
-- sprite palette, we are not sure if this in the future might
-- change, e.g. having the original palette that was used to
-- create the brush integrated to the brush itself, in that case
-- we should convert the brush index using the same brush
-- palette (instead of the sprite palette).
--
-- TODO check BrushInkProcessingBase comment for more information
if s.colorMode == ColorMode.RGB then
ra, rb, rc, rd =
p:getColor(ba).rgbaPixel,
p:getColor(bb).rgbaPixel,
p:getColor(bc).rgbaPixel,
p:getColor(bd).rgbaPixel
else
ra, rb, rc, rd =
p:getColor(ba).grayPixel,
p:getColor(bb).grayPixel,
p:getColor(bc).grayPixel,
p:getColor(bd).grayPixel
end
else
ra, rb, rc, rd = a, b, c, d
end
array_to_pixels({ a, a, a,
a, a, a,
a, a, a }, app.activeImage)
-- Simple
expect_img(app.activeImage,
{ a, a, a,
a, a, a,
a, a, a })
app.useTool{ tool=pencil, brush=brush, points={ Point(2, 2) },
ink=Ink.SIMPLE }
expect_img(app.activeImage,
{ a, a, a,
a, a, rd,
a, rc, a })
-- Alpha Compositing
app.useTool{ tool=pencil, brush=brush, points={ Point(1, 1) },
ink=Ink.ALPHA_COMPOSITING, opacity=255 }
expect_img(app.activeImage,
{ a, rd, a,
rc, a, rd,
a, rc, a })
local qc, qd
if s.colorMode == ColorMode.GRAY and
brushColorMode == ColorMode.INDEXED then
qc = gray(pc.grayaV(rc)/2)
qd = gray(pc.grayaV(rd)/2)
else
qc, qd = rb, rc
end
app.useTool{ tool=pencil, brush=brush, points={ Point(1, 2) },
ink=Ink.ALPHA_COMPOSITING, opacity=128 }
expect_img(app.activeImage,
{ a, rd, a,
rc, qd, rd,
qc, rc, a })
-- TODO test Lock Alpha, Copy Color+Alpha, Shading...
end
for j = 1,#colorModes do
test_custom_brush_inks(colorModes[j])
end
end
function test_alpha_compositing_on_indexed_with_full_opacity_and_repeated_colors_in_palette()
local s = Sprite(1, 1, ColorMode.INDEXED)
local p = Palette()
p:resize(5)
p:setColor(0, Color(0, 0, 0))
p:setColor(1, Color(64, 64, 64))
p:setColor(2, Color(128, 128, 128))
p:setColor(3, Color(128, 128, 128))
p:setColor(4, Color(255, 255, 255))
s:setPalette(p)
local inks = { Ink.SIMPLE, Ink.ALPHA_COMPOSITING }
-- k=1 -> transparent layer
-- k=2 -> background layer
for k=1,2 do
if k == 2 then app.command.BackgroundFromLayer() end
-- i=1 -> simple ink
-- i=2 -> alpha compositing ink
for i = 1,2 do
-- j=color index
for j = 0,4 do
expect_img(app.activeImage, { 0 })
app.useTool{ tool="pencil", color=j, points={ Point(0, 0) },
ink=inks[i], opacity=255 }
expect_img(app.activeImage, { j })
app.undo()
end
end
end
end
for i = 1,#colorModes do
test_inks(colorModes[i])
end
test_alpha_compositing_on_indexed_with_full_opacity_and_repeated_colors_in_palette()
----------------------------------------------------------------------
-- Test painting with transparent color on indexed
----------------------------------------------------------------------
do
local s = Sprite(2, 2, ColorMode.INDEXED)
s.transparentColor = 0
app.bgColor = 0
app.command.BackgroundFromLayer()
assert(app.activeLayer.isBackground)
expect_img(app.activeImage, { 0, 0,
0, 0 })
app.useTool{ tool="pencil", color=Color{r=0,g=0,b=0},
points={ Point(0, 0) },
ink=Ink.SIMPLE }
expect_img(app.activeImage, { 0, 0,
0, 0 })
-- Test that painting in the background layer with transparent color
-- with alpha compositing and all opacity=255, will use the transparent
-- index anyway. Reported here: https://github.com/aseprite/aseprite/issues/3047
app.useTool{ tool="pencil", color=0,
points={ Point(0, 0) },
ink=Ink.ALPHA_COMPOSITING,
opacity=255 }
expect_img(app.activeImage, { 0, 0,
0, 0 })
-- Other cases should keep working
local p = s.palettes[1]
-- palette with only 3 colors: white, gray (50%), black
p:setColor(0, Color{ r=255, g=255, b=255 })
p:setColor(1, Color{ r=128, g=128, b=128 })
p:setColor(2, Color{ r=0, g=0, b=0 })
app.useTool{ tool="paint_bucket", color=2,
points={ Point(0, 0) },
ink=Ink.SIMPLE }
expect_img(app.activeImage, { 2, 2,
2, 2 })
-- White over black w/opacity=50% => gray
app.useTool{ tool="pencil", color=0,
points={ Point(0, 0) },
ink=Ink.ALPHA_COMPOSITING,
opacity=128 }
expect_img(app.activeImage, { 1, 2,
2, 2 })
-- White over gray w/opacity=51% => white
app.useTool{ tool="pencil", color=0,
points={ Point(0, 0) },
ink=Ink.ALPHA_COMPOSITING,
opacity=129 }
expect_img(app.activeImage, { 0, 2,
2, 2 })
end
----------------------------------------------------------------------
-- Tests for Paint Bucket Tool with image brush and
-- pattern alignment SRC (ORIGIN) vs DST (TARGET)
----------------------------------------------------------------------
do
local s = Sprite(3, 3, ColorMode.INDEXED)
array_to_pixels({ 0, 0, 0,
0, 0, 0,
0, 0, 0 }, app.activeImage)
local brushImage = Image(2, 2, ColorMode.INDEXED)
array_to_pixels({ 0, 1,
2, 0 }, brushImage)
brush = Brush{
image=brushImage,
pattern=BrushPattern.ORIGIN
}
app.useTool{ tool="paint_bucket", brush=brush, points={ Point(0, 0) } }
expect_img(app.activeImage,
{ 0, 1, 0,
2, 0, 2,
0, 1, 0 })
app.undo()
app.useTool{ tool="paint_bucket", brush=brush, points={ Point(1, 0) } }
expect_img(app.activeImage,
{ 0, 1, 0,
2, 0, 2,
0, 1, 0 })
app.undo()
brush = Brush{
image=brushImage,
pattern=BrushPattern.TARGET
}
app.useTool{ tool="paint_bucket", brush=brush, points={ Point(1, 1) } }
expect_img(app.activeImage,
{ 0, 1, 0,
2, 0, 2,
0, 1, 0 })
app.undo()
app.useTool{ tool="paint_bucket", brush=brush, points={ Point(2, 1) } }
expect_img(app.activeImage,
{ 1, 0, 1,
0, 2, 0,
1, 0, 1})
end
----------------------------------------------------------------------
-- Tests for Eraser Tool, normal erase and replace color erasing
----------------------------------------------------------------------
do
-- Indexed image + background layer +
-- the mask color is in the palette and it's defined as
-- transparent color
local s = Sprite(3, 3, ColorMode.INDEXED)
local p = s.palettes[1]
p:setColor(0, Color{ r=0 , g=0 , b=0 , a=255 })
p:setColor(1, Color{ r=255, g=0 , b=0 , a=255 })
p:setColor(2, Color{ r=0 , g=255, b=0 , a=255 })
p:setColor(3, Color{ r=0 , g=0 , b=255, a=255 })
p:setColor(4, Color{ r=255, g=255, b=0 , a=255 })
p:setColor(5, Color{ r=255, g=255, b=255, a=255 })
p:setColor(6, Color{ r=0 , g=0 , b=0 , a=0 })
p:resize(7)
app.fgColor = 0
app.bgColor = 0
app.command.BackgroundFromLayer()
expect_img(app.activeImage,
{ 0, 0, 0,
0, 0, 0,
0, 0, 0 })
s.transparentColor = 6 -- mask color as transparent color
app.fgColor = 1
app.bgColor = 3
app.useTool{ tool='pencil',
points={ Point(0, 0), Point(2, 0)} }
app.useTool{ tool='pencil',
color=2,
points={ Point(0, 1), Point(2, 1)} }
app.useTool{ tool='pencil',
button=MouseButton.RIGHT,
points={ Point(0, 2), Point(2, 2)} }
expect_img(app.activeImage,
{ 1, 1, 1,
2, 2, 2,
3, 3, 3 })
app.fgColor = 2
app.bgColor = 6 -- (mask color)
app.useTool{ tool='eraser',
button=MouseButton.LEFT,
points={ Point(0, 0), Point(0, 2) } }
expect_img(app.activeImage,
{ 6, 1, 1,
6, 2, 2,
6, 3, 3 })
app.useTool{ tool='eraser',
button=MouseButton.RIGHT,
points={ Point(1, 0), Point(1, 2) } }
expect_img(app.activeImage,
{ 6, 1, 1,
6, 6, 2,
6, 3, 3 })
end
-- Tests for Eraser Tool with RGBA image + background layer
do
local s = Sprite(3, 3, ColorMode.RGB)
local p = s.palettes[1]
local c0 = pc.rgba(0 , 0, 0, 255)
local c1 = pc.rgba(255, 0, 0, 255)
local c2 = pc.rgba(0 , 255, 0, 255)
local c3 = pc.rgba(0 , 0, 255, 255)
local c4 = pc.rgba(255, 255, 0, 255)
local c5 = pc.rgba(255, 255, 255, 255)
local c6 = pc.rgba(0 , 0, 0, 0)
p:setColor(0, c0)
p:setColor(1, c1)
p:setColor(2, c2)
p:setColor(3, c3)
p:setColor(4, c4)
p:setColor(5, c5)
p:setColor(6, c6)
p:resize(7)
app.fgColor = c0
app.bgColor = c0
app.command.BackgroundFromLayer()
expect_img(app.activeImage,
{ c0, c0, c0,
c0, c0, c0,
c0, c0, c0 })
app.fgColor = c1
app.bgColor = c3
app.useTool{ tool='pencil',
points={ Point(0, 0), Point(2, 0)} }
app.useTool{ tool='pencil',
color=c2,
points={ Point(0, 1), Point(2, 1)} }
app.useTool{ tool='pencil',
button=MouseButton.RIGHT,
points={ Point(0, 2), Point(2, 2)} }
expect_img(app.activeImage,
{ c1, c1, c1,
c2, c2, c2,
c3, c3, c3 })
app.fgColor = c2
app.bgColor = c6
app.useTool{ tool='eraser',
button=MouseButton.LEFT,
points={ Point(0, 0), Point(0, 2) } }
expect_img(app.activeImage,
{ c0, c1, c1,
c0, c2, c2,
c0, c3, c3 })
app.useTool{ tool='eraser',
button=MouseButton.RIGHT,
points={ Point(1, 0), Point(1, 2) } }
expect_img(app.activeImage,
{ c0, c1, c1,
c0, c0, c2,
c0, c3, c3 })
end
-- Tests for Eraser Tool with GRAYSCALE image + background layer
do
local s = Sprite(3, 3, ColorMode.GRAYSCALE)
local p = s.palettes[1]
local c0 = pc.graya( 0, 255)
local c1 = pc.graya( 63, 255)
local c2 = pc.graya(127, 255)
local c3 = pc.graya(191, 255)
local c4 = pc.graya(255, 255)
local c5 = pc.graya( 0, 0)
p:setColor(0, c0)
p:setColor(1, c1)
p:setColor(2, c2)
p:setColor(3, c3)
p:setColor(4, c4)
p:setColor(5, c5)
p:resize(6)
app.fgColor = c0
app.bgColor = c0
app.command.BackgroundFromLayer()
expect_img(app.activeImage,
{ c0, c0, c0,
c0, c0, c0,
c0, c0, c0 })
app.fgColor = c1
app.bgColor = c3
app.useTool{ tool='pencil',
points={ Point(0, 0), Point(2, 0)} }
app.useTool{ tool='pencil',
color=c2,
points={ Point(0, 1), Point(2, 1)} }
app.useTool{ tool='pencil',
button=MouseButton.RIGHT,
points={ Point(0, 2), Point(2, 2)} }
expect_img(app.activeImage,
{ c1, c1, c1,
c2, c2, c2,
c3, c3, c3 })
app.fgColor = c2
app.bgColor = c5
app.useTool{ tool='eraser',
button=MouseButton.LEFT,
points={ Point(0, 0), Point(0, 2) } }
expect_img(app.activeImage,
{ c0, c1, c1,
c0, c2, c2,
c0, c3, c3 })
app.useTool{ tool='eraser',
button=MouseButton.RIGHT,
points={ Point(1, 0), Point(1, 2) } }
expect_img(app.activeImage,
{ c0, c1, c1,
c0, c0, c2,
c0, c3, c3 })
end