diff --git a/src/app/script/blend_mode.h b/src/app/script/blend_mode.h new file mode 100644 index 000000000..0a2688f27 --- /dev/null +++ b/src/app/script/blend_mode.h @@ -0,0 +1,204 @@ +// Aseprite +// Copyright (c) 2023 Igara Studio S.A. +// +// This program is distributed under the terms of +// the End-User License Agreement for Aseprite. + +#ifndef APP_SCRIPT_BLEND_MODE_H_INCLUDED +#define APP_SCRIPT_BLEND_MODE_H_INCLUDED +#pragma once + +#include "base/convert_to.h" +#include "doc/blend_mode.h" +#include "os/paint.h" + +namespace app { +namespace script { + +// Blend modes for doc::BlendMode and os::BlendMode, used in +// Layer.blendMode and GraphicsContext.blendMode. +enum class BlendMode : int { + CLEAR, + SRC, + DST, + SRC_OVER, + DST_OVER, + SRC_IN, + DST_IN, + SRC_OUT, + DST_OUT, + SRC_ATOP, + DST_ATOP, + XOR, + PLUS, + MODULATE, + MULTIPLY, + SCREEN, + OVERLAY, + DARKEN, + LIGHTEN, + COLOR_DODGE, + COLOR_BURN, + HARD_LIGHT, + SOFT_LIGHT, + DIFFERENCE, + EXCLUSION, + HUE, + SATURATION, + COLOR, + LUMINOSITY, + ADDITION, + SUBTRACT, + DIVIDE, +}; + +} // namespace script +} // namespace app + +namespace base { + +template<> +inline os::BlendMode convert_to(const app::script::BlendMode& from) { + switch (from) { + case app::script::BlendMode::CLEAR: return os::BlendMode::Clear; + case app::script::BlendMode::SRC: return os::BlendMode::Src; + case app::script::BlendMode::DST: return os::BlendMode::Dst; + case app::script::BlendMode::SRC_OVER: return os::BlendMode::SrcOver; + case app::script::BlendMode::DST_OVER: return os::BlendMode::DstOver; + case app::script::BlendMode::SRC_IN: return os::BlendMode::SrcIn; + case app::script::BlendMode::DST_IN: return os::BlendMode::DstIn; + case app::script::BlendMode::SRC_OUT: return os::BlendMode::SrcOut; + case app::script::BlendMode::DST_OUT: return os::BlendMode::DstOut; + case app::script::BlendMode::SRC_ATOP: return os::BlendMode::SrcATop; + case app::script::BlendMode::DST_ATOP: return os::BlendMode::DstATop; + case app::script::BlendMode::XOR: return os::BlendMode::Xor; + case app::script::BlendMode::PLUS: return os::BlendMode::Plus; + case app::script::BlendMode::MODULATE: return os::BlendMode::Modulate; + case app::script::BlendMode::MULTIPLY: return os::BlendMode::Multiply; + case app::script::BlendMode::SCREEN: return os::BlendMode::Screen; + case app::script::BlendMode::OVERLAY: return os::BlendMode::Overlay; + case app::script::BlendMode::DARKEN: return os::BlendMode::Darken; + case app::script::BlendMode::LIGHTEN: return os::BlendMode::Lighten; + case app::script::BlendMode::COLOR_DODGE: return os::BlendMode::ColorDodge; + case app::script::BlendMode::COLOR_BURN: return os::BlendMode::ColorBurn; + case app::script::BlendMode::HARD_LIGHT: return os::BlendMode::HardLight; + case app::script::BlendMode::SOFT_LIGHT: return os::BlendMode::SoftLight; + case app::script::BlendMode::DIFFERENCE: return os::BlendMode::Difference; + case app::script::BlendMode::EXCLUSION: return os::BlendMode::Exclusion; + case app::script::BlendMode::HUE: return os::BlendMode::Hue; + case app::script::BlendMode::SATURATION: return os::BlendMode::Saturation; + case app::script::BlendMode::COLOR: return os::BlendMode::Color; + case app::script::BlendMode::LUMINOSITY: return os::BlendMode::Luminosity; + case app::script::BlendMode::ADDITION: return os::BlendMode::Plus; + // Default value + case app::script::BlendMode::SUBTRACT: + case app::script::BlendMode::DIVIDE: + return os::BlendMode::SrcOver; + } +} + +template<> +inline app::script::BlendMode convert_to(const os::BlendMode& from) { + switch (from) { + case os::BlendMode::Clear: return app::script::BlendMode::CLEAR; + case os::BlendMode::Src: return app::script::BlendMode::SRC; + case os::BlendMode::Dst: return app::script::BlendMode::DST; + case os::BlendMode::SrcOver: return app::script::BlendMode::SRC_OVER; + case os::BlendMode::DstOver: return app::script::BlendMode::DST_OVER; + case os::BlendMode::SrcIn: return app::script::BlendMode::SRC_IN; + case os::BlendMode::DstIn: return app::script::BlendMode::DST_IN; + case os::BlendMode::SrcOut: return app::script::BlendMode::SRC_OUT; + case os::BlendMode::DstOut: return app::script::BlendMode::DST_OUT; + case os::BlendMode::SrcATop: return app::script::BlendMode::SRC_ATOP; + case os::BlendMode::DstATop: return app::script::BlendMode::DST_ATOP; + case os::BlendMode::Xor: return app::script::BlendMode::XOR; + case os::BlendMode::Plus: return app::script::BlendMode::PLUS; + case os::BlendMode::Modulate: return app::script::BlendMode::MODULATE; + case os::BlendMode::Screen: return app::script::BlendMode::SCREEN; + case os::BlendMode::Overlay: return app::script::BlendMode::OVERLAY; + case os::BlendMode::Darken: return app::script::BlendMode::DARKEN; + case os::BlendMode::Lighten: return app::script::BlendMode::LIGHTEN; + case os::BlendMode::ColorDodge: return app::script::BlendMode::COLOR_DODGE; + case os::BlendMode::ColorBurn: return app::script::BlendMode::COLOR_BURN; + case os::BlendMode::HardLight: return app::script::BlendMode::HARD_LIGHT; + case os::BlendMode::SoftLight: return app::script::BlendMode::SOFT_LIGHT; + case os::BlendMode::Difference: return app::script::BlendMode::DIFFERENCE; + case os::BlendMode::Exclusion: return app::script::BlendMode::EXCLUSION; + case os::BlendMode::Multiply: return app::script::BlendMode::MULTIPLY; + case os::BlendMode::Hue: return app::script::BlendMode::HUE; + case os::BlendMode::Saturation: return app::script::BlendMode::SATURATION; + case os::BlendMode::Color: return app::script::BlendMode::COLOR; + case os::BlendMode::Luminosity: return app::script::BlendMode::LUMINOSITY; + } +} + +template<> +inline doc::BlendMode convert_to(const app::script::BlendMode& from) { + switch (from) { + case app::script::BlendMode::SRC_OVER: return doc::BlendMode::NORMAL; + case app::script::BlendMode::PLUS: return doc::BlendMode::ADDITION; + case app::script::BlendMode::MULTIPLY: return doc::BlendMode::MULTIPLY; + case app::script::BlendMode::SCREEN: return doc::BlendMode::SCREEN; + case app::script::BlendMode::OVERLAY: return doc::BlendMode::OVERLAY; + case app::script::BlendMode::DARKEN: return doc::BlendMode::DARKEN; + case app::script::BlendMode::LIGHTEN: return doc::BlendMode::LIGHTEN; + case app::script::BlendMode::COLOR_DODGE: return doc::BlendMode::COLOR_DODGE; + case app::script::BlendMode::COLOR_BURN: return doc::BlendMode::COLOR_BURN; + case app::script::BlendMode::HARD_LIGHT: return doc::BlendMode::HARD_LIGHT; + case app::script::BlendMode::SOFT_LIGHT: return doc::BlendMode::SOFT_LIGHT; + case app::script::BlendMode::DIFFERENCE: return doc::BlendMode::DIFFERENCE; + case app::script::BlendMode::EXCLUSION: return doc::BlendMode::EXCLUSION; + case app::script::BlendMode::HUE: return doc::BlendMode::HSL_HUE; + case app::script::BlendMode::SATURATION: return doc::BlendMode::HSL_SATURATION; + case app::script::BlendMode::COLOR: return doc::BlendMode::HSL_COLOR; + case app::script::BlendMode::LUMINOSITY: return doc::BlendMode::HSL_LUMINOSITY; + case app::script::BlendMode::ADDITION: return doc::BlendMode::ADDITION; + case app::script::BlendMode::SUBTRACT: return doc::BlendMode::SUBTRACT; + case app::script::BlendMode::DIVIDE: return doc::BlendMode::DIVIDE; + // Default value + case app::script::BlendMode::CLEAR: + case app::script::BlendMode::SRC: + case app::script::BlendMode::DST: + case app::script::BlendMode::DST_OVER: + case app::script::BlendMode::SRC_IN: + case app::script::BlendMode::DST_IN: + case app::script::BlendMode::SRC_OUT: + case app::script::BlendMode::DST_OUT: + case app::script::BlendMode::SRC_ATOP: + case app::script::BlendMode::DST_ATOP: + case app::script::BlendMode::XOR: + case app::script::BlendMode::MODULATE: + return doc::BlendMode::NORMAL; + } +} + +template<> +inline app::script::BlendMode convert_to(const doc::BlendMode& from) { + switch (from) { + case doc::BlendMode::NORMAL: return app::script::BlendMode::SRC_OVER; + case doc::BlendMode::MULTIPLY: return app::script::BlendMode::MULTIPLY; + case doc::BlendMode::SCREEN: return app::script::BlendMode::SCREEN; + case doc::BlendMode::OVERLAY: return app::script::BlendMode::OVERLAY; + case doc::BlendMode::DARKEN: return app::script::BlendMode::DARKEN; + case doc::BlendMode::LIGHTEN: return app::script::BlendMode::LIGHTEN; + case doc::BlendMode::COLOR_DODGE: return app::script::BlendMode::COLOR_DODGE; + case doc::BlendMode::COLOR_BURN: return app::script::BlendMode::COLOR_BURN; + case doc::BlendMode::HARD_LIGHT: return app::script::BlendMode::HARD_LIGHT; + case doc::BlendMode::SOFT_LIGHT: return app::script::BlendMode::SOFT_LIGHT; + case doc::BlendMode::DIFFERENCE: return app::script::BlendMode::DIFFERENCE; + case doc::BlendMode::EXCLUSION: return app::script::BlendMode::EXCLUSION; + case doc::BlendMode::HSL_HUE: return app::script::BlendMode::HUE; + case doc::BlendMode::HSL_SATURATION: return app::script::BlendMode::SATURATION; + case doc::BlendMode::HSL_COLOR: return app::script::BlendMode::COLOR; + case doc::BlendMode::HSL_LUMINOSITY: return app::script::BlendMode::LUMINOSITY; + case doc::BlendMode::ADDITION: return app::script::BlendMode::ADDITION; + case doc::BlendMode::SUBTRACT: return app::script::BlendMode::SUBTRACT; + case doc::BlendMode::DIVIDE: return app::script::BlendMode::DIVIDE; + default: + return app::script::BlendMode::SRC_OVER; + } +} + +} + +#endif