diff --git a/src/app/commands/cmd_merge_down_layer.cpp b/src/app/commands/cmd_merge_down_layer.cpp index 768481e86..7902026b7 100644 --- a/src/app/commands/cmd_merge_down_layer.cpp +++ b/src/app/commands/cmd_merge_down_layer.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2020 Igara Studio S.A. +// Copyright (C) 2019-2020 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -26,7 +26,7 @@ #include "doc/layer.h" #include "doc/primitives.h" #include "doc/sprite.h" -#include "render/render.h" +#include "render/rasterize.h" #include "ui/ui.h" namespace app { @@ -103,7 +103,8 @@ void MergeDownLayerCommand::onExecute(Context* context) // Copy this cel to the destination layer... // Creating a copy of the image - dst_image.reset(Image::createCopy(src_image)); + dst_image.reset( + render::rasterize_with_cel_bounds(src_cel)); // Creating a copy of the cell dst_cel = new Cel(frpos, dst_image); @@ -133,14 +134,10 @@ void MergeDownLayerCommand::onExecute(Context* context) bounds.y-dst_cel->y(), bounds.w, bounds.h, bgcolor)); - // Merge src_image in new_image - render::composite_image( - new_image.get(), src_image, - sprite->palette(src_cel->frame()), - src_cel->x()-bounds.x, - src_cel->y()-bounds.y, - opacity, - src_layer->blendMode()); + // Draw src_cel on new_image + render::rasterize( + new_image.get(), src_cel, + -bounds.x, -bounds.y, false); // First unlink the dst_cel if (dst_cel->links()) diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp index b24547104..a17a353ac 100644 --- a/src/app/ui/editor/tool_loop_impl.cpp +++ b/src/app/ui/editor/tool_loop_impl.cpp @@ -53,6 +53,7 @@ #include "doc/sprite.h" #include "fmt/format.h" #include "render/dithering.h" +#include "render/rasterize.h" #include "render/render.h" #include "ui/ui.h" @@ -430,26 +431,8 @@ public: } else { Cel* cel = m_layer->cel(m_frame); - if (cel && (cel->x() != 0 || cel->y() != 0)) { - m_floodfillSrcImage = Image::create(m_sprite->spec()); - m_floodfillSrcImage->clear(m_sprite->transparentColor()); - if (cel->image()->pixelFormat() == IMAGE_TILEMAP) { - render::Render render; - render.setNewBlend(Preferences::instance().experimental.newBlend()); - render.renderCel( - m_floodfillSrcImage, - m_sprite, - cel->image(), - m_layer, - m_sprite->palette(m_frame), - gfx::RectF(cel->bounds()), - gfx::Clip(m_sprite->bounds()), - 255, BlendMode::NORMAL); - } - else { - copy_image(m_floodfillSrcImage, cel->image(), cel->x(), cel->y()); - } - } + if (cel && (cel->x() != 0 || cel->y() != 0)) + m_floodfillSrcImage = render::rasterize_with_sprite_bounds(cel); } } diff --git a/src/render/CMakeLists.txt b/src/render/CMakeLists.txt index a9c86e79f..748f08e71 100644 --- a/src/render/CMakeLists.txt +++ b/src/render/CMakeLists.txt @@ -1,5 +1,6 @@ # Aseprite Render Library -# Copyright (C) 2001-2017 David Capello +# Copyright (C) 2019 Igara Studio S.A. +# Copyright (C) 2001-2018 David Capello add_library(render-lib error_diffusion.cpp @@ -7,6 +8,7 @@ add_library(render-lib gradient.cpp ordered_dither.cpp quantization.cpp + rasterize.cpp render.cpp zoom.cpp) diff --git a/src/render/README.md b/src/render/README.md index 1ec9f7ce7..e6574d085 100644 --- a/src/render/README.md +++ b/src/render/README.md @@ -1,4 +1,5 @@ # Aseprite Render Library -*Copyright (C) 2001-2017 David Capello* > Distributed under [MIT license](LICENSE.txt) + +Functions to render a [`doc::Sprite`](../doc/sprite.h). diff --git a/src/render/rasterize.cpp b/src/render/rasterize.cpp new file mode 100644 index 000000000..648476e2c --- /dev/null +++ b/src/render/rasterize.cpp @@ -0,0 +1,111 @@ +// Aseprite Render Library +// Copyright (C) 2019 Igara Studio S.A. +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "render/rasterize.h" + +#include "base/debug.h" +#include "doc/blend_internals.h" +#include "doc/cel.h" +#include "doc/sprite.h" +#include "render/render.h" + +namespace render { + +void rasterize( + doc::Image* dst, + const doc::Cel* cel, + const int x, + const int y, + const bool clear) +{ + ASSERT(cel); + + const doc::Sprite* sprite = cel->sprite(); + ASSERT(sprite); + + if (clear) + dst->clear(sprite->transparentColor()); + + int t; + int opacity; + opacity = MUL_UN8(cel->opacity(), cel->layer()->opacity(), t); + + if (cel->image()->pixelFormat() == IMAGE_TILEMAP) { + render::Render render; + render.renderCel( + dst, + sprite, + cel->image(), + cel->layer(), + sprite->palette(cel->frame()), + gfx::RectF(cel->bounds()), + gfx::Clip(x, y, 0, 0, dst->width(), dst->height()), + clear ? 255: opacity, + clear ? BlendMode::NORMAL: cel->layer()->blendMode()); + } + else { + if (clear) + copy_image(dst, cel->image(), x+cel->x(), y+cel->y()); + else + composite_image( + dst, cel->image(), + sprite->palette(cel->frame()), + x+cel->x(), + y+cel->y(), + opacity, + cel->layer()->blendMode()); + } +} + +void rasterize_with_cel_bounds( + doc::Image* dst, + const doc::Cel* cel) +{ + rasterize(dst, cel, -cel->x(), -cel->y(), true); +} + +void rasterize_with_sprite_bounds( + doc::Image* dst, + const doc::Cel* cel) +{ + rasterize(dst, cel, 0, 0, true); +} + +doc::Image* rasterize_with_cel_bounds( + const doc::Cel* cel) +{ + ASSERT(cel); + + const doc::Sprite* sprite = cel->sprite(); + ASSERT(sprite); + + doc::ImageSpec spec = sprite->spec(); + spec.setWidth(cel->bounds().w); + spec.setHeight(cel->bounds().h); + + std::unique_ptr dst(doc::Image::create(spec)); + rasterize_with_cel_bounds(dst.get(), cel); + return dst.release(); +} + +doc::Image* rasterize_with_sprite_bounds( + const doc::Cel* cel) +{ + ASSERT(cel); + + const doc::Sprite* sprite = cel->sprite(); + ASSERT(sprite); + + std::unique_ptr dst(doc::Image::create(sprite->spec())); + rasterize_with_sprite_bounds(dst.get(), cel); + return dst.release(); +} + +} // namespace render diff --git a/src/render/rasterize.h b/src/render/rasterize.h new file mode 100644 index 000000000..59a05d3be --- /dev/null +++ b/src/render/rasterize.h @@ -0,0 +1,41 @@ +// Aseprite Render Library +// Copyright (C) 2019 Igara Studio S.A. +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef RENDER_RASTERIZE_H_INCLUDED +#define RENDER_RASTERIZE_H_INCLUDED +#pragma once + +namespace doc { + class Cel; + class Image; +} + +namespace render { + + void rasterize( + doc::Image* dst, + const doc::Cel* cel, + const int x, + const int y, + const bool clear); + + void rasterize_with_cel_bounds( + doc::Image* dst, + const doc::Cel* cel); + + void rasterize_with_sprite_bounds( + doc::Image* dst, + const doc::Cel* cel); + + doc::Image* rasterize_with_cel_bounds( + const doc::Cel* cel); + + doc::Image* rasterize_with_sprite_bounds( + const doc::Cel* cel); + +} // namespace render + +#endif