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 <davidcape...@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 _______________________________________________ Pkg-games-commits mailing list Pkg-games-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits