diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp index a16e6934f..34581998b 100644 --- a/src/app/ui/editor/tool_loop_impl.cpp +++ b/src/app/ui/editor/tool_loop_impl.cpp @@ -45,6 +45,7 @@ #include "app/ui_context.h" #include "app/util/expand_cel_canvas.h" #include "app/util/layer_utils.h" +#include "doc/brush.h" #include "doc/cel.h" #include "doc/image.h" #include "doc/layer.h" @@ -189,6 +190,18 @@ public: ASSERT(m_ink); ASSERT(m_controller); + if (m_brush->type() == kImageBrushType && + (m_button == Right || (m_button == Left && m_brush->isMonochromeImage()))) { + m_brush->setImageColor( + Brush::ImageColor::MainColor, + color_utils::color_for_target_mask( + (m_button == Left ? Preferences::instance().colorBar.fgColor() : + Preferences::instance().colorBar.bgColor()), + ColorTarget(ColorTarget::TransparentLayer, + m_brush->image()->pixelFormat(), + -1))); + } + if (m_tilesMode) { // Use FloodFillPointShape or TilePointShape in tiles mode if (!m_pointShape->isFloodFill()) { diff --git a/src/doc/brush.cpp b/src/doc/brush.cpp index 7342f98ef..786bd1a73 100644 --- a/src/doc/brush.cpp +++ b/src/doc/brush.cpp @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (C) 2019-2022 Igara Studio S.A. +// Copyright (C) 2019-2023 Igara Studio S.A. // Copyright (C) 2001-2016 David Capello // // This file is released under the terms of the MIT license. @@ -283,8 +283,11 @@ void Brush::setImageColor(ImageColor imageColor, color_t color) void Brush::resetImageColors() { - if (m_backupImage) + if (m_backupImage) { m_image.reset(Image::createCopy(m_backupImage.get())); + m_mainColor.reset(); + m_bgColor.reset(); + } } void Brush::setCenter(const gfx::Point& center) diff --git a/src/doc/brush.h b/src/doc/brush.h index 47d94de2a..b8b117458 100644 --- a/src/doc/brush.h +++ b/src/doc/brush.h @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (C) 2019-2022 Igara Studio S.A. +// Copyright (C) 2019-2023 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This file is released under the terms of the MIT license. @@ -78,6 +78,10 @@ namespace doc { return m_image.get(); } + const bool isMonochromeImage() const { + return m_mainColor.has_value(); + } + private: void clean(); void regenerate(); diff --git a/tests/scripts/brush.lua b/tests/scripts/brush.lua index 2f9accdeb..736a2c778 100644 --- a/tests/scripts/brush.lua +++ b/tests/scripts/brush.lua @@ -1,4 +1,4 @@ --- Copyright (C) 2019 Igara Studio S.A. +-- Copyright (C) 2019-2023 Igara Studio S.A. -- -- This file is released under the terms of the MIT license. -- Read LICENSE.txt for more information. @@ -72,3 +72,165 @@ do brush:setBgColor(b) expect_img(brush.image, { b, g, g, b }) end + +-- Tests with Image Brushes +-- Brush in a certain pixel format used on different sprites of +-- all available pixel formats. +do + -- RGB sprite + local sprRGB = Sprite(2, 2, ColorMode.RGB) + local cel = sprRGB.cels[1] + expect_img(cel.image, { 0, 0, + 0, 0}) + local pal = Palette(4) + pal:setColor(1, Color{ r=255, g=0, b=0, a=128 }) + pal:setColor(2, Color{ r=0, g=255, b=0, a=128 }) + pal:setColor(3, Color{ r=0, g=0, b=255, a=128 }) + sprRGB:setPalette(pal) + + -- Test Sprite RGB with RGB brush + local brushImg = Image(2, 2, ColorMode.RGB) + array_to_pixels({ pal:getColor(1), pal:getColor(2), + pal:getColor(3), pal:getColor(0) }, brushImg) + local bruRGB = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruRGB, points={ Point(1, 1) } } + expect_img(cel.image, + { pal:getColor(1).rgbaPixel, pal:getColor(2).rgbaPixel, + pal:getColor(3).rgbaPixel, pal:getColor(0).rgbaPixel }) + app.undo() + + -- Test Sprite RGB with INDEXED brush + local brushImg = Image(2, 2, ColorMode.INDEXED) + array_to_pixels({ 1, 2, + 3, 0 }, brushImg) + local bruINDEXED = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruINDEXED, points={ Point(1, 1) } } + expect_img(cel.image, + { pal:getColor(1).rgbaPixel, pal:getColor(2).rgbaPixel, + pal:getColor(3).rgbaPixel, 0 }) + app.undo() + + -- Test Sprite RGB with GRAYSCALE brush + local brushImg = Image(2, 2, ColorMode.GRAYSCALE) + array_to_pixels({ Color{ gray=255, alpha=128 }, Color{ gray=128, alpha=128 }, + Color{ gray=64, alpha=255 }, Color{ gray=0, alpha=255 } }, brushImg) + local bruGRAYSCALE = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruGRAYSCALE, points={ Point(1, 1) } } + expect_img(cel.image, + { Color{ gray=255, alpha=128 }.rgbaPixel, Color{ gray=128, alpha=128 }.rgbaPixel, + Color{ gray=64, alpha=255 }.rgbaPixel, Color{ gray=0, alpha=255 }.rgbaPixel }) + + -- -- -- -- -- -- -- + -- INDEXED sprite + local sprINDEXED = Sprite(2, 2, ColorMode.INDEXED) + local cel = sprINDEXED.cels[1] + expect_img(cel.image, { 0, 0, + 0, 0 }) + local pal = Palette(4) + pal:setColor(1, Color{ r=255, g=0, b=0, a=128 }) + pal:setColor(2, Color{ r=0, g=255, b=0, a=128 }) + pal:setColor(3, Color{ r=0, g=0, b=255, a=128 }) + sprINDEXED:setPalette(pal) + + -- Test Sprite INDEXED with RGB brush + local brushImg = Image(2, 2, ColorMode.RGB) + array_to_pixels({ pal:getColor(1), pal:getColor(2), + pal:getColor(3), app.pixelColor.rgba(0, 0, 0, 0) }, brushImg) + local bruRGB = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruRGB, points={ Point(1, 1) } } + expect_img(cel.image, + { 1, 2, + 3, 3 }) + app.undo() + + -- Test Sprite INDEXED with INDEXED brush + local brushImg = Image(2, 2, ColorMode.INDEXED) + array_to_pixels({ 1, 2, + 3, 0 }, brushImg) + local bruINDEXED = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruINDEXED, points={ Point(1, 1) } } + expect_img(cel.image, + { 1, 2, + 3, 0 }) + app.undo() + + -- Test Sprite INDEXED with INDEXED brush + -- (INDEXED brush with one out of bounds index) + local brushImg = Image(2, 2, ColorMode.INDEXED) + array_to_pixels({ 1, 5, + 3, 0 }, brushImg) + local bruINDEXED = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruINDEXED, points={ Point(1, 1) } } + expect_img(cel.image, + { 1, 3, + 3, 0 }) + app.undo() + + -- Test Sprite INDEXED with GRAYSCALE brush + local brushImg = Image(2, 2, ColorMode.GRAYSCALE) + array_to_pixels({ Color{ gray=255, alpha=128 }, Color{ gray=128, alpha=128 }, + Color{ gray=64, alpha=255 }, Color{ gray=0, alpha=255 } }, brushImg) + local bruGRAYSCALE = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruGRAYSCALE, points={ Point(1, 1) } } + expect_img(cel.image, + { 2, 3, + 3, 3 }) + + -- -- -- -- -- -- -- + -- GRAYSCALE sprite + local sprGRAYSCALE = Sprite(2, 2, ColorMode.GRAYSCALE) + local cel = sprGRAYSCALE.cels[1] + expect_img(cel.image, { 0, 0, + 0, 0 }) + local pal = Palette(4) + pal:setColor(1, Color{ gray=128, alpha=128 }.grayPixel) + pal:setColor(2, Color{ gray=64, alpha=128 }.grayPixel) + pal:setColor(3, Color{ gray=32, alpha=255 }.grayPixel) + print(pal:getColor(1).grayPixel) + print(pal:getColor(2).grayPixel) + print(pal:getColor(3).grayPixel) + sprGRAYSCALE:setPalette(pal) + + -- Test Sprite GRAYSCALE with RGB brush + local brushImg = Image(2, 2, ColorMode.RGB) + array_to_pixels({ Color{ r=255, g=0, b=0, a=128 }, Color{ r=0, g=255, b=0, a=128 }, + Color{ r=0, g=0, b=255, a=128 }, app.pixelColor.rgba(0, 0, 0, 0) }, brushImg) + local bruRGB = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruRGB, points={ Point(1, 1) } } + expect_img(cel.image, + { Color{ gray=54, alpha=128 }.grayPixel, Color{ gray=182, alpha=128 }.grayPixel, + Color{ gray=18, alpha=128 }.grayPixel, 0 }) + app.undo() + + -- Test Sprite GRAYSCALE with INDEXED brush + -- (INDEXED brush with out of bound index) + local brushImg = Image(2, 2, ColorMode.INDEXED) + array_to_pixels({ 1, 5, + 3, 0 }, brushImg) + local bruINDEXED = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruINDEXED, points={ Point(1, 1) } } + expect_img(cel.image, + { Color{ gray=128, alpha=128 }.grayPixel, + Color{ gray=32, alpha=255 }.grayPixel }) + app.undo() + + -- Test Sprite GRAYSCALE with GRAYSCALE brush + local brushImg = Image(2, 2, ColorMode.GRAYSCALE) + array_to_pixels({ Color{ gray=128, alpha=128 }, Color{ gray=222, alpha=222 }, + Color{ gray=32, alpha=255 }, Color{ gray=0, alpha=255 } }, brushImg) + local bruGRAYSCALE = Brush { image=brushImg } + + app.useTool{ tool=pencil, brush=bruGRAYSCALE, points={ Point(1, 1) } } + expect_img(cel.image, + { pal:getColor(1).grayPixel, Color{ gray=222, alpha=222 }.grayPixel, + pal:getColor(3).grayPixel, Color{ gray=0, alpha=255 }.grayPixel }) +end \ No newline at end of file