[lua] Replace Paint() class with GraphicsContext.blendMode/opacity properties

In some way we prefer to simplify the GraphicsContext class instead of
exposing a new Paint() class (which might be confusing with the
app.useTool() too).

Now BlendMode can be used for GraphicsContext.blendMode and
Layer.blendMode (not all modes are available in both cases).

This reverts commit 3d7c05c8f1.
This commit is contained in:
David Capello 2023-03-13 21:17:51 -03:00
parent 3d7c05c8f1
commit 17c66181ae
6 changed files with 95 additions and 166 deletions

View File

@ -187,7 +187,6 @@ if(ENABLE_SCRIPTING)
script/layer_class.cpp
script/layers_class.cpp
script/luacpp.cpp
script/paint_class.cpp
script/palette_class.cpp
script/palettes_class.cpp
script/pixel_color_object.cpp

View File

@ -16,6 +16,7 @@
#include "app/doc_exporter.h"
#include "app/doc_range.h"
#include "app/pref/preferences.h"
#include "app/script/blend_mode.h"
#include "app/script/luacpp.h"
#include "app/script/security.h"
#include "app/sprite_sheet_type.h"
@ -27,7 +28,6 @@
#include "base/fs.h"
#include "base/fstream_path.h"
#include "doc/anidir.h"
#include "doc/blend_mode.h"
#include "doc/color_mode.h"
#include "filters/target.h"
#include "ui/cursor_type.h"
@ -161,7 +161,6 @@ void register_color_space_class(lua_State* L);
#ifdef ENABLE_UI
void register_dialog_class(lua_State* L);
void register_graphics_context_class(lua_State* L);
void register_paint_class(lua_State* L);
#endif
void register_events_class(lua_State* L);
void register_frame_class(lua_State* L);
@ -288,25 +287,44 @@ Engine::Engine()
lua_newtable(L);
lua_pushvalue(L, -1);
lua_setglobal(L, "BlendMode");
setfield_integer(L, "NORMAL", doc::BlendMode::NORMAL);
setfield_integer(L, "MULTIPLY", doc::BlendMode::MULTIPLY);
setfield_integer(L, "SCREEN", doc::BlendMode::SCREEN);
setfield_integer(L, "OVERLAY", doc::BlendMode::OVERLAY);
setfield_integer(L, "DARKEN", doc::BlendMode::DARKEN);
setfield_integer(L, "LIGHTEN", doc::BlendMode::LIGHTEN);
setfield_integer(L, "COLOR_DODGE", doc::BlendMode::COLOR_DODGE);
setfield_integer(L, "COLOR_BURN", doc::BlendMode::COLOR_BURN);
setfield_integer(L, "HARD_LIGHT", doc::BlendMode::HARD_LIGHT);
setfield_integer(L, "SOFT_LIGHT", doc::BlendMode::SOFT_LIGHT);
setfield_integer(L, "DIFFERENCE", doc::BlendMode::DIFFERENCE);
setfield_integer(L, "EXCLUSION", doc::BlendMode::EXCLUSION);
setfield_integer(L, "HSL_HUE", doc::BlendMode::HSL_HUE);
setfield_integer(L, "HSL_SATURATION", doc::BlendMode::HSL_SATURATION);
setfield_integer(L, "HSL_COLOR", doc::BlendMode::HSL_COLOR);
setfield_integer(L, "HSL_LUMINOSITY", doc::BlendMode::HSL_LUMINOSITY);
setfield_integer(L, "ADDITION", doc::BlendMode::ADDITION);
setfield_integer(L, "SUBTRACT", doc::BlendMode::SUBTRACT);
setfield_integer(L, "DIVIDE", doc::BlendMode::DIVIDE);
setfield_integer(L, "CLEAR", app::script::BlendMode::CLEAR);
setfield_integer(L, "SRC", app::script::BlendMode::SRC);
setfield_integer(L, "DST", app::script::BlendMode::DST);
setfield_integer(L, "SRC_OVER", app::script::BlendMode::SRC_OVER);
setfield_integer(L, "DST_OVER", app::script::BlendMode::DST_OVER);
setfield_integer(L, "SRC_IN", app::script::BlendMode::SRC_IN);
setfield_integer(L, "DST_IN", app::script::BlendMode::DST_IN);
setfield_integer(L, "SRC_OUT", app::script::BlendMode::SRC_OUT);
setfield_integer(L, "DST_OUT", app::script::BlendMode::DST_OUT);
setfield_integer(L, "SRC_ATOP", app::script::BlendMode::SRC_ATOP);
setfield_integer(L, "DST_ATOP", app::script::BlendMode::DST_ATOP);
setfield_integer(L, "XOR", app::script::BlendMode::XOR);
setfield_integer(L, "PLUS", app::script::BlendMode::PLUS);
setfield_integer(L, "MODULATE", app::script::BlendMode::MODULATE);
setfield_integer(L, "MULTIPLY", app::script::BlendMode::MULTIPLY);
setfield_integer(L, "SCREEN", app::script::BlendMode::SCREEN);
setfield_integer(L, "OVERLAY", app::script::BlendMode::OVERLAY);
setfield_integer(L, "DARKEN", app::script::BlendMode::DARKEN);
setfield_integer(L, "LIGHTEN", app::script::BlendMode::LIGHTEN);
setfield_integer(L, "COLOR_DODGE", app::script::BlendMode::COLOR_DODGE);
setfield_integer(L, "COLOR_BURN", app::script::BlendMode::COLOR_BURN);
setfield_integer(L, "HARD_LIGHT", app::script::BlendMode::HARD_LIGHT);
setfield_integer(L, "SOFT_LIGHT", app::script::BlendMode::SOFT_LIGHT);
setfield_integer(L, "DIFFERENCE", app::script::BlendMode::DIFFERENCE);
setfield_integer(L, "EXCLUSION", app::script::BlendMode::EXCLUSION);
setfield_integer(L, "HUE", app::script::BlendMode::HUE);
setfield_integer(L, "SATURATION", app::script::BlendMode::SATURATION);
setfield_integer(L, "COLOR", app::script::BlendMode::COLOR);
setfield_integer(L, "LUMINOSITY", app::script::BlendMode::LUMINOSITY);
setfield_integer(L, "ADDITION", app::script::BlendMode::ADDITION);
setfield_integer(L, "SUBTRACT", app::script::BlendMode::SUBTRACT);
setfield_integer(L, "DIVIDE", app::script::BlendMode::DIVIDE);
// Backward compatibility
setfield_integer(L, "NORMAL", app::script::BlendMode::SRC_OVER);
setfield_integer(L, "HSL_HUE", app::script::BlendMode::HUE);
setfield_integer(L, "HSL_SATURATION", app::script::BlendMode::SATURATION);
setfield_integer(L, "HSL_COLOR", app::script::BlendMode::COLOR);
setfield_integer(L, "HSL_LUMINOSITY", app::script::BlendMode::LUMINOSITY);
lua_pop(L, 1);
lua_newtable(L);
@ -443,7 +461,6 @@ Engine::Engine()
#ifdef ENABLE_UI
register_dialog_class(L);
register_graphics_context_class(L);
register_paint_class(L);
#endif
register_events_class(L);
register_frame_class(L);

View File

@ -13,6 +13,7 @@
#include "app/color.h"
#include "app/color_utils.h"
#include "app/modules/palettes.h"
#include "app/script/blend_mode.h"
#include "app/script/engine.h"
#include "app/script/luacpp.h"
#include "app/ui/skin/skin_theme.h"
@ -51,8 +52,7 @@ void GraphicsContext::drawImage(const doc::Image* img, int x, int y)
void GraphicsContext::drawImage(const doc::Image* img,
const gfx::Rect& srcRc,
const gfx::Rect& dstRc,
const os::Paint* paint)
const gfx::Rect& dstRc)
{
if (srcRc.isEmpty() || dstRc.isEmpty())
return; // Do nothing for empty rectangles
@ -75,7 +75,7 @@ void GraphicsContext::drawImage(const doc::Image* img,
srcRc.w, srcRc.h);
m_surface->drawSurface(tmpSurface.get(), gfx::Rect(0, 0, srcRc.w, srcRc.h),
dstRc, os::Sampling(), paint);
dstRc, os::Sampling(), &m_paint);
}
}
@ -219,15 +219,13 @@ int GraphicsContext_drawImage(lua_State* L)
int dy = lua_tointeger(L, 8);
int dw = lua_tointeger(L, 9);
int dh = lua_tointeger(L, 10);
auto p = may_get_obj<os::Paint>(L, 11);
gc->drawImage(img, gfx::Rect(x, y, w, h), gfx::Rect(dx, dy, dw, dh), p);
gc->drawImage(img, gfx::Rect(x, y, w, h), gfx::Rect(dx, dy, dw, dh));
}
else if (lua_gettop(L) >= 3) {
const auto srcRect = may_get_obj<gfx::Rect>(L, 3);
const auto dstRect = may_get_obj<gfx::Rect>(L, 4);
auto p = may_get_obj<os::Paint>(L, 5);
if (srcRect && dstRect)
gc->drawImage(img, *srcRect, *dstRect, p);
gc->drawImage(img, *srcRect, *dstRect);
else {
gc->drawImage(img, x, y);
}
@ -399,6 +397,37 @@ int GraphicsContext_set_strokeWidth(lua_State* L)
return 1;
}
int GraphicsContext_get_blendMode(lua_State* L)
{
auto gc = get_obj<GraphicsContext>(L, 1);
lua_pushinteger(
L, int(base::convert_to<app::script::BlendMode>(gc->blendMode())));
return 0;
}
int GraphicsContext_set_blendMode(lua_State* L)
{
auto gc = get_obj<GraphicsContext>(L, 1);
gc->blendMode(base::convert_to<os::BlendMode>(
app::script::BlendMode(lua_tointeger(L, 2))));
return 0;
}
int GraphicsContext_get_opacity(lua_State* L)
{
auto gc = get_obj<GraphicsContext>(L, 1);
lua_pushnumber(L, gc->opacity());
return 1;
}
int GraphicsContext_set_opacity(lua_State* L)
{
auto gc = get_obj<GraphicsContext>(L, 1);
const float opacity = lua_tonumber(L, 2);
gc->opacity(opacity);
return 0;
}
const luaL_Reg GraphicsContext_methods[] = {
{ "__gc", GraphicsContext_gc },
{ "save", GraphicsContext_save },
@ -429,6 +458,8 @@ const Property GraphicsContext_properties[] = {
{ "antialias", GraphicsContext_get_antialias, GraphicsContext_set_antialias },
{ "color", GraphicsContext_get_color, GraphicsContext_set_color },
{ "strokeWidth", GraphicsContext_get_strokeWidth, GraphicsContext_set_strokeWidth },
{ "blendMode", GraphicsContext_get_blendMode, GraphicsContext_set_blendMode },
{ "opacity", GraphicsContext_get_opacity, GraphicsContext_set_opacity },
{ nullptr, nullptr, nullptr }
};

View File

@ -62,6 +62,17 @@ public:
float strokeWidth() const { return m_paint.strokeWidth(); }
void strokeWidth(float value) { m_paint.strokeWidth(value); }
#if LAF_SKIA
float opacity() const { return m_paint.skPaint().getAlphaf(); }
void opacity(float value) { m_paint.skPaint().setAlphaf(value); }
#else
float opacity() const { return 1.0f; }
void opacity(float) { }
#endif
os::BlendMode blendMode() const { return m_paint.blendMode(); }
void blendMode(const os::BlendMode bm) { m_paint.blendMode(bm); }
void strokeRect(const gfx::Rect& rc) {
m_paint.style(os::Paint::Stroke);
m_surface->drawRect(rc, m_paint);
@ -78,8 +89,7 @@ public:
void drawImage(const doc::Image* img, int x, int y);
void drawImage(const doc::Image* img,
const gfx::Rect& srcRc,
const gfx::Rect& dstRc,
const os::Paint* paint);
const gfx::Rect& dstRc);
void drawThemeImage(const std::string& partId, const gfx::Point& pt);
void drawThemeRect(const std::string& partId, const gfx::Rect& rc);

View File

@ -15,6 +15,7 @@
#include "app/cmd/set_layer_tileset.h"
#include "app/doc.h"
#include "app/doc_api.h"
#include "app/script/blend_mode.h"
#include "app/script/docobj.h"
#include "app/script/engine.h"
#include "app/script/luacpp.h"
@ -141,7 +142,9 @@ int Layer_get_blendMode(lua_State* L)
{
auto layer = get_docobj<Layer>(L, 1);
if (layer->isImage()) {
lua_pushinteger(L, (int)static_cast<LayerImage*>(layer)->blendMode());
lua_pushinteger(
L, int(base::convert_to<app::script::BlendMode>(
static_cast<LayerImage*>(layer)->blendMode())));
return 1;
}
else
@ -269,11 +272,11 @@ int Layer_set_opacity(lua_State* L)
int Layer_set_blendMode(lua_State* L)
{
auto layer = get_docobj<Layer>(L, 1);
const int blendMode = lua_tointeger(L, 2);
auto blendMode = app::script::BlendMode(lua_tointeger(L, 2));
if (layer->isImage()) {
Tx tx;
tx(new cmd::SetLayerBlendMode(static_cast<LayerImage*>(layer),
(doc::BlendMode)blendMode));
base::convert_to<doc::BlendMode>(blendMode)));
tx.commit();
}
return 0;

View File

@ -1,131 +0,0 @@
// Aseprite
// Copyright (C) 2023 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/script/engine.h"
#include "app/script/luacpp.h"
#include "base/string.h"
#include "os/paint.h"
#ifdef ENABLE_UI
namespace app {
namespace script {
using Paint = os::Paint;
namespace {
static std::map<std::string, os::BlendMode> stringToBlendMode = {
{ "clear", os::BlendMode::Clear },
{ "src", os::BlendMode::Src },
{ "dst", os::BlendMode::Dst },
{ "srcover", os::BlendMode::SrcOver },
{ "dstover", os::BlendMode::DstOver },
{ "srcin", os::BlendMode::SrcIn },
{ "dstin", os::BlendMode::DstIn },
{ "srcout", os::BlendMode::SrcOut },
{ "dstout", os::BlendMode::DstOut },
{ "srcatop", os::BlendMode::SrcATop },
{ "dstatop", os::BlendMode::DstATop },
{ "xor", os::BlendMode::Xor },
{ "plus", os::BlendMode::Plus },
{ "modulate", os::BlendMode::Modulate },
{ "screen", os::BlendMode::Screen },
{ "overlay", os::BlendMode::Overlay },
{ "darken", os::BlendMode::Darken },
{ "lighten", os::BlendMode::Lighten },
{ "colordodge", os::BlendMode::ColorDodge },
{ "colorburn", os::BlendMode::ColorBurn },
{ "hardlight", os::BlendMode::HardLight },
{ "softlight", os::BlendMode::SoftLight },
{ "difference", os::BlendMode::Difference },
{ "exclusion", os::BlendMode::Exclusion },
{ "multiply", os::BlendMode::Multiply },
{ "hue", os::BlendMode::Hue },
{ "saturation", os::BlendMode::Saturation },
{ "color", os::BlendMode::Color },
{ "luminosity", os::BlendMode::Luminosity },
};
int Paint_gc(lua_State* L)
{
auto p = get_obj<Paint>(L, 1);
p->~Paint();
return 0;
}
int Paint_new(lua_State* L)
{
push_new<Paint>(L);
return 1;
}
int Paint_get_blendMode(lua_State* L)
{
auto p = get_obj<Paint>(L, 1);
auto bm = p->blendMode();
for (const auto& kv : stringToBlendMode) {
if (kv.second == bm) {
lua_pushstring(L, kv.first.c_str());
return 1;
}
}
return 0;
}
int Paint_set_blendMode(lua_State* L)
{
auto p = get_obj<Paint>(L, 1);
if (auto str = lua_tostring(L, 2))
p->blendMode(stringToBlendMode[base::string_to_lower(str)]);
return 0;
}
int Paint_get_alpha(lua_State* L)
{
auto p = get_obj<Paint>(L, 1);
lua_pushnumber(L, p->skPaint().getAlphaf());
return 1;
}
int Paint_set_alpha(lua_State* L)
{
auto p = get_obj<Paint>(L, 1);
const float alpha = lua_tonumber(L, 2);
p->skPaint().setAlphaf(alpha);
return 0;
}
const luaL_Reg Paint_methods[] = {
{ "__gc", Paint_gc },
{ nullptr, nullptr }
};
const Property Paint_properties[] = {
{ "blendMode", Paint_get_blendMode, Paint_set_blendMode },
{ "alpha", Paint_get_alpha, Paint_set_alpha },
{ nullptr, nullptr, nullptr }
};
} // anonymous namespace
DEF_MTNAME(Paint);
void register_paint_class(lua_State* L)
{
REG_CLASS(L, Paint);
REG_CLASS_NEW(L, Paint);
REG_CLASS_PROPERTIES(L, Paint);
}
} // namespace script
} // namespace app
#endif // ENABLE_UI