[aseprite] 36/51: Fix several bugs applying filters to cels smaller than the sprite bounds
Tobias Hansen
thansen at moszumanska.debian.org
Mon Jul 11 21:35:18 UTC 2016
This is an automated email from the git hooks/post-receive script.
thansen pushed a commit to branch master
in repository aseprite.
commit d56660420515a49a966361a1c8671ef35818b9b2
Author: David Capello <davidcapello at gmail.com>
Date: Fri Jul 1 18:49:58 2016 -0300
Fix several bugs applying filters to cels smaller than the sprite bounds
Now if we apply a 3x3 (or bigger) convolution matrix to a cel, the cel
will be expanded to so new pixels are included in the new cel content.
---
src/app/commands/filters/filter_manager_impl.cpp | 112 ++++++++++-------------
src/app/commands/filters/filter_manager_impl.h | 16 ++--
src/app/commands/filters/filter_preview.cpp | 1 +
src/app/ui/editor/drawing_state.cpp | 1 +
src/render/render.cpp | 46 ++++++----
src/render/render.h | 14 ++-
6 files changed, 95 insertions(+), 95 deletions(-)
diff --git a/src/app/commands/filters/filter_manager_impl.cpp b/src/app/commands/filters/filter_manager_impl.cpp
index 61a2fc5..9ad408e 100644
--- a/src/app/commands/filters/filter_manager_impl.cpp
+++ b/src/app/commands/filters/filter_manager_impl.cpp
@@ -20,6 +20,7 @@
#include "app/modules/editors.h"
#include "app/transaction.h"
#include "app/ui/editor/editor.h"
+#include "doc/algorithm/shrink_bounds.h"
#include "doc/cel.h"
#include "doc/image.h"
#include "doc/images_collector.h"
@@ -45,15 +46,14 @@ FilterManagerImpl::FilterManagerImpl(Context* context, Filter* filter)
: m_context(context)
, m_site(context->activeSite())
, m_filter(filter)
+ , m_cel(nullptr)
, m_src(nullptr)
, m_dst(nullptr)
+ , m_mask(nullptr)
, m_previewMask(nullptr)
, m_progressDelegate(NULL)
{
m_row = 0;
- m_celX = 0;
- m_celY = 0;
- m_mask = NULL;
m_targetOrig = TARGET_ALL_CHANNELS;
m_target = TARGET_ALL_CHANNELS;
@@ -62,11 +62,7 @@ FilterManagerImpl::FilterManagerImpl(Context* context, Filter* filter)
if (!image)
throw NoImageException();
- init(m_site.layer(), image, x, y);
-}
-
-FilterManagerImpl::~FilterManagerImpl()
-{
+ init(m_site.cel());
}
app::Document* FilterManagerImpl::document()
@@ -100,9 +96,8 @@ void FilterManagerImpl::begin()
Document* document = static_cast<app::Document*>(m_site.document());
m_row = 0;
- m_mask = (document->isMaskVisible() ? document->mask(): NULL);
-
- updateBounds(m_mask, m_src);
+ m_mask = (document->isMaskVisible() ? document->mask(): nullptr);
+ updateBounds(m_mask);
}
void FilterManagerImpl::beginForPreview()
@@ -113,11 +108,7 @@ void FilterManagerImpl::beginForPreview()
m_previewMask.reset(new Mask(*document->mask()));
else {
m_previewMask.reset(new Mask());
- m_previewMask->replace(
- gfx::Rect(
- m_celX, m_celY,
- m_src->width(),
- m_src->height()));
+ m_previewMask->replace(m_site.sprite()->bounds());
}
m_row = 0;
@@ -139,7 +130,7 @@ void FilterManagerImpl::beginForPreview()
m_previewMask->intersect(vp);
}
- if (!updateBounds(m_mask, m_src)) {
+ if (!updateBounds(m_mask)) {
m_previewMask.reset(nullptr);
m_row = -1;
return;
@@ -156,12 +147,11 @@ bool FilterManagerImpl::applyStep()
if (m_row < 0 || m_row >= m_bounds.h)
return false;
- if ((m_mask) && (m_mask->bitmap())) {
- int x = m_bounds.x - m_mask->bounds().x + m_celX;
- int y = m_bounds.y - m_mask->bounds().y + m_celY + m_row;
-
- if ((m_bounds.w - x < 1) ||
- (m_bounds.h - y < 1))
+ if (m_mask && m_mask->bitmap()) {
+ int x = m_bounds.x - m_mask->bounds().x;
+ int y = m_bounds.y - m_mask->bounds().y + m_row;
+ if ((x >= m_bounds.w) ||
+ (y >= m_bounds.h))
return false;
m_maskBits = m_mask->bitmap()
@@ -197,13 +187,16 @@ void FilterManagerImpl::apply(Transaction& transaction)
}
if (!cancelled) {
- // Copy "dst" to "src"
- transaction.execute(
- new cmd::CopyRect(
- m_src, m_dst.get(),
- gfx::Clip(m_bounds.x, m_bounds.y,
- m_bounds.x, m_bounds.y,
- m_bounds.w, m_bounds.h)));
+ gfx::Rect output;
+ if (algorithm::shrink_bounds2(m_src.get(), m_dst.get(),
+ m_bounds, output)) {
+ // Patch "m_cel"
+ transaction.execute(
+ new cmd::PatchCel(
+ m_cel, m_dst.get(),
+ gfx::Region(output),
+ position()));
+ }
}
}
@@ -239,9 +232,7 @@ void FilterManagerImpl::applyToTarget()
// Avoid applying the filter two times to the same image
if (visited.find(image->id()) == visited.end()) {
visited.insert(image->id());
- applyToImage(
- transaction, it->layer(),
- image, it->cel()->x(), it->cel()->y());
+ applyToCel(transaction, it->cel());
}
// Is there a delegate to know if the process was cancelled by the user?
@@ -262,8 +253,8 @@ void FilterManagerImpl::flush()
gfx::Rect rect(
editor->editorToScreen(
gfx::Point(
- m_bounds.x+m_celX,
- m_bounds.y+m_celY+m_row-1)),
+ m_bounds.x,
+ m_bounds.y+m_row-1)),
gfx::Size(
editor->zoom().apply(m_bounds.w),
(editor->zoom().scale() >= 1 ? editor->zoom().apply(1):
@@ -280,12 +271,12 @@ void FilterManagerImpl::flush()
const void* FilterManagerImpl::getSourceAddress()
{
- return m_src->getPixelAddress(m_bounds.x, m_row+m_bounds.y);
+ return m_src->getPixelAddress(m_bounds.x, m_bounds.y+m_row);
}
void* FilterManagerImpl::getDestinationAddress()
{
- return m_dst->getPixelAddress(m_bounds.x, m_row+m_bounds.y);
+ return m_dst->getPixelAddress(m_bounds.x, m_bounds.y+m_row);
}
bool FilterManagerImpl::skipPixel()
@@ -312,55 +303,48 @@ RgbMap* FilterManagerImpl::getRgbMap()
return m_site.sprite()->rgbMap(m_site.frame());
}
-void FilterManagerImpl::init(const Layer* layer, Image* image, int x, int y)
+void FilterManagerImpl::init(Cel* cel)
{
- m_celX = x;
- m_celY = y;
-
- if (!updateBounds(static_cast<app::Document*>(m_site.document())->mask(), image))
+ ASSERT(cel);
+ if (!updateBounds(static_cast<app::Document*>(m_site.document())->mask()))
throw InvalidAreaException();
- m_src = image;
- m_dst.reset(Image::createCopy(m_src));
+ m_cel = cel;
+ m_src.reset(
+ crop_image(
+ cel->image(),
+ gfx::Rect(m_site.sprite()->bounds()).offset(-cel->position()), 0));
+ m_dst.reset(Image::createCopy(m_src.get()));
m_row = -1;
- m_mask = NULL;
+ m_mask = nullptr;
m_previewMask.reset(nullptr);
m_target = m_targetOrig;
- /* the alpha channel of the background layer can't be modified */
- if (layer->isBackground())
+ // The alpha channel of the background layer can't be modified
+ if (cel->layer()->isBackground())
m_target &= ~TARGET_ALPHA_CHANNEL;
}
-void FilterManagerImpl::applyToImage(Transaction& transaction, Layer* layer, Image* image, int x, int y)
+void FilterManagerImpl::applyToCel(Transaction& transaction, Cel* cel)
{
- init(layer, image, x, y);
+ init(cel);
apply(transaction);
}
-bool FilterManagerImpl::updateBounds(Mask* mask, const Image* image)
+bool FilterManagerImpl::updateBounds(doc::Mask* mask)
{
gfx::Rect bounds;
-
- if (mask && mask->bitmap()) {
+ if (mask && mask->bitmap() && !mask->bounds().isEmpty()) {
bounds = mask->bounds();
- bounds.offset(-m_celX, -m_celY);
- bounds &= image->bounds();
- }
- else {
- bounds = image->bounds();
- }
-
- if (bounds.isEmpty()) {
- m_bounds = gfx::Rect(0, 0, 0, 0);
- return false;
+ bounds &= m_site.sprite()->bounds();
}
else {
- m_bounds = bounds;
- return true;
+ bounds = m_site.sprite()->bounds();
}
+ m_bounds = bounds;
+ return !m_bounds.isEmpty();
}
} // namespace app
diff --git a/src/app/commands/filters/filter_manager_impl.h b/src/app/commands/filters/filter_manager_impl.h
index 3bf3685..47e4d31 100644
--- a/src/app/commands/filters/filter_manager_impl.h
+++ b/src/app/commands/filters/filter_manager_impl.h
@@ -17,10 +17,12 @@
#include "doc/site.h"
#include "filters/filter_indexed_data.h"
#include "filters/filter_manager.h"
+#include "gfx/rect.h"
#include <cstring>
namespace doc {
+ class Cel;
class Image;
class Layer;
class Mask;
@@ -68,7 +70,6 @@ namespace app {
};
FilterManagerImpl(Context* context, Filter* filter);
- ~FilterManagerImpl();
void setProgressDelegate(IProgressDelegate* progressDelegate);
@@ -87,6 +88,7 @@ namespace app {
doc::Layer* layer() { return m_site.layer(); }
doc::frame_t frame() { return m_site.frame(); }
doc::Image* destinationImage() const { return m_dst.get(); }
+ gfx::Point position() const { return gfx::Point(0, 0); }
// Updates the current editor to show the progress of the preview.
void flush();
@@ -98,7 +100,7 @@ namespace app {
Target getTarget() override { return m_target; }
FilterIndexedData* getIndexedData() override { return this; }
bool skipPixel() override;
- const doc::Image* getSourceImage() override { return m_src; }
+ const doc::Image* getSourceImage() override { return m_src.get(); }
int x() override { return m_bounds.x; }
int y() override { return m_bounds.y+m_row; }
@@ -107,19 +109,19 @@ namespace app {
doc::RgbMap* getRgbMap() override;
private:
- void init(const doc::Layer* layer, doc::Image* image, int x, int y);
+ void init(doc::Cel* cel);
void apply(Transaction& transaction);
- void applyToImage(Transaction& transaction, doc::Layer* layer, doc::Image* image, int x, int y);
- bool updateBounds(doc::Mask* mask, const doc::Image* image);
+ void applyToCel(Transaction& transaction, doc::Cel* cel);
+ bool updateBounds(doc::Mask* mask);
Context* m_context;
doc::Site m_site;
Filter* m_filter;
- doc::Image* m_src;
+ doc::Cel* m_cel;
+ doc::ImageRef m_src;
doc::ImageRef m_dst;
int m_row;
gfx::Rect m_bounds;
- int m_celX, m_celY;
doc::Mask* m_mask;
base::UniquePtr<doc::Mask> m_previewMask;
doc::ImageBits<doc::BitmapTraits> m_maskBits;
diff --git a/src/app/commands/filters/filter_preview.cpp b/src/app/commands/filters/filter_preview.cpp
index 41fc463..2e6e8ad 100644
--- a/src/app/commands/filters/filter_preview.cpp
+++ b/src/app/commands/filters/filter_preview.cpp
@@ -70,6 +70,7 @@ bool FilterPreview::onProcessMessage(Message* msg)
m_filterMgr->layer(),
m_filterMgr->frame(),
m_filterMgr->destinationImage(),
+ m_filterMgr->position(),
static_cast<doc::LayerImage*>(m_filterMgr->layer())->blendMode());
break;
diff --git a/src/app/ui/editor/drawing_state.cpp b/src/app/ui/editor/drawing_state.cpp
index d8a75dd..775079e 100644
--- a/src/app/ui/editor/drawing_state.cpp
+++ b/src/app/ui/editor/drawing_state.cpp
@@ -63,6 +63,7 @@ void DrawingState::initToolLoop(Editor* editor, MouseMessage* msg)
m_toolLoop->getLayer(),
m_toolLoop->getFrame(),
m_toolLoop->getDstImage(),
+ m_toolLoop->getCelOrigin(),
(m_toolLoop->getLayer() &&
m_toolLoop->getLayer()->isImage() ?
static_cast<LayerImage*>(m_toolLoop->getLayer())->blendMode():
diff --git a/src/render/render.cpp b/src/render/render.cpp
index 0b98198..6ec6d7d 100644
--- a/src/render/render.cpp
+++ b/src/render/render.cpp
@@ -478,12 +478,16 @@ void Render::setBgCheckedSize(const gfx::Size& size)
m_bgCheckedSize = size;
}
-void Render::setPreviewImage(const Layer* layer, frame_t frame,
- Image* image, BlendMode blendMode)
+void Render::setPreviewImage(const Layer* layer,
+ const frame_t frame,
+ const Image* image,
+ const gfx::Point& pos,
+ const BlendMode blendMode)
{
m_selectedLayer = layer;
m_selectedFrame = frame;
m_previewImage = image;
+ m_previewPos = pos;
m_previewBlendMode = blendMode;
}
@@ -660,7 +664,8 @@ void Render::renderSprite(
dstImage,
m_previewImage,
m_sprite->palette(frame),
- 0, 0,
+ m_previewPos.x,
+ m_previewPos.y,
area,
compositeImage,
255,
@@ -843,24 +848,27 @@ void Render::renderLayer(
const Cel* cel = layer->cel(frame);
if (cel) {
Palette* pal = m_sprite->palette(frame);
- Image* src_image;
+ const Image* celImage;
+ gfx::Point celPos;
// Is the 'm_previewImage' set to be used with this layer?
if ((m_previewImage) &&
(m_selectedLayer == layer) &&
(m_selectedFrame == frame)) {
- src_image = m_previewImage;
+ celImage = m_previewImage;
+ celPos = m_previewPos;
- ASSERT(src_image->pixelFormat() == cel->image()->pixelFormat());
+ ASSERT(celImage->pixelFormat() == cel->image()->pixelFormat());
}
// If not, we use the original cel-image from the images' stock
else {
- src_image = cel->image();
+ celImage = cel->image();
+ celPos = cel->position();
}
- if (src_image) {
+ if (celImage) {
const LayerImage* imgLayer = static_cast<const LayerImage*>(layer);
- BlendMode layerBlendMode =
+ const BlendMode layerBlendMode =
(blendMode == BlendMode::UNSPECIFIED ?
imgLayer->blendMode():
blendMode);
@@ -876,7 +884,7 @@ void Render::renderLayer(
opacity = MUL_UN8(opacity, imgLayer->opacity(), t);
opacity = MUL_UN8(opacity, m_globalOpacity, t);
- ASSERT(src_image->maskColor() == m_sprite->transparentColor());
+ ASSERT(celImage->maskColor() == m_sprite->transparentColor());
// Draw parts outside the "m_extraCel" area
if (drawExtra && m_extraType == ExtraType::PATCH) {
@@ -886,17 +894,17 @@ void Render::renderLayer(
for (auto rc : originalAreas) {
renderCel(
- image, src_image, pal,
- cel, gfx::Clip(area.dst.x+rc.x-area.src.x,
- area.dst.y+rc.y-area.src.y, rc), compositeImage,
+ image, celImage, pal, celPos,
+ gfx::Clip(area.dst.x+rc.x-area.src.x,
+ area.dst.y+rc.y-area.src.y, rc), compositeImage,
opacity, layerBlendMode, zoom);
}
}
// Draw the whole cel
else {
renderCel(
- image, src_image, pal,
- cel, area, compositeImage,
+ image, celImage, pal,
+ celPos, area, compositeImage,
opacity, layerBlendMode, zoom);
}
}
@@ -926,7 +934,7 @@ void Render::renderLayer(
renderCel(
image, m_extraImage,
m_sprite->palette(frame),
- m_extraCel,
+ m_extraCel->position(),
gfx::Clip(area.dst.x+extraArea.x-area.src.x,
area.dst.y+extraArea.y-area.src.y,
extraArea),
@@ -941,7 +949,7 @@ void Render::renderCel(
Image* dst_image,
const Image* cel_image,
const Palette* pal,
- const Cel* cel,
+ const gfx::Point& celPos,
const gfx::Clip& area,
CompositeImageFunc compositeImage,
int opacity, BlendMode blendMode, Zoom zoom)
@@ -949,8 +957,8 @@ void Render::renderCel(
renderImage(dst_image,
cel_image,
pal,
- cel->x(),
- cel->y(),
+ celPos.x,
+ celPos.y,
area,
compositeImage,
opacity,
diff --git a/src/render/render.h b/src/render/render.h
index 9c57447..936de70 100644
--- a/src/render/render.h
+++ b/src/render/render.h
@@ -13,7 +13,7 @@
#include "doc/color.h"
#include "doc/frame.h"
#include "doc/pixel_format.h"
-#include "gfx/fwd.h"
+#include "gfx/point.h"
#include "gfx/size.h"
#include "render/extra_type.h"
#include "render/onionskin_position.h"
@@ -111,8 +111,11 @@ namespace render {
// Sets the preview image. This preview image is an alternative
// image to be used for the given layer/frame.
- void setPreviewImage(const Layer* layer, frame_t frame,
- Image* image, BlendMode blendMode);
+ void setPreviewImage(const Layer* layer,
+ const frame_t frame,
+ const Image* image,
+ const gfx::Point& pos,
+ const BlendMode blendMode);
void removePreviewImage();
// Sets an extra cel/image to be drawn after the current
@@ -190,7 +193,7 @@ namespace render {
Image* dst_image,
const Image* cel_image,
const Palette* pal,
- const Cel* cel,
+ const gfx::Point& celPos,
const gfx::Clip& area,
CompositeImageFunc compositeImage,
int opacity, BlendMode blendMode, Zoom zoom);
@@ -221,7 +224,8 @@ namespace render {
int m_globalOpacity;
const Layer* m_selectedLayer;
frame_t m_selectedFrame;
- Image* m_previewImage;
+ const Image* m_previewImage;
+ gfx::Point m_previewPos;
BlendMode m_previewBlendMode;
OnionskinOptions m_onionskin;
};
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git
More information about the Pkg-games-commits
mailing list