mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-16 13:14:44 +00:00
Minor changes in FilterManagerImpl
This commit is contained in:
parent
1c984696c1
commit
c1f8c98ca8
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -12,6 +12,7 @@
|
||||
#include "app/commands/filters/filter_manager_impl.h"
|
||||
|
||||
#include "app/cmd/copy_rect.h"
|
||||
#include "app/cmd/patch_cel.h"
|
||||
#include "app/cmd/unlink_cel.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/document.h"
|
||||
@ -44,25 +45,24 @@ FilterManagerImpl::FilterManagerImpl(Context* context, Filter* filter)
|
||||
: m_context(context)
|
||||
, m_site(context->activeSite())
|
||||
, m_filter(filter)
|
||||
, m_dst(NULL)
|
||||
, m_preview_mask(NULL)
|
||||
, m_src(nullptr)
|
||||
, m_dst(nullptr)
|
||||
, m_previewMask(nullptr)
|
||||
, m_progressDelegate(NULL)
|
||||
{
|
||||
int offset_x, offset_y;
|
||||
|
||||
m_src = NULL;
|
||||
m_row = 0;
|
||||
m_offset_x = 0;
|
||||
m_offset_y = 0;
|
||||
m_celX = 0;
|
||||
m_celY = 0;
|
||||
m_mask = NULL;
|
||||
m_targetOrig = TARGET_ALL_CHANNELS;
|
||||
m_target = TARGET_ALL_CHANNELS;
|
||||
|
||||
Image* image = m_site.image(&offset_x, &offset_y);
|
||||
if (image == NULL)
|
||||
int x, y;
|
||||
Image* image = m_site.image(&x, &y);
|
||||
if (!image)
|
||||
throw NoImageException();
|
||||
|
||||
init(m_site.layer(), image, offset_x, offset_y);
|
||||
init(m_site.layer(), image, x, y);
|
||||
}
|
||||
|
||||
FilterManagerImpl::~FilterManagerImpl()
|
||||
@ -102,7 +102,7 @@ void FilterManagerImpl::begin()
|
||||
m_row = 0;
|
||||
m_mask = (document->isMaskVisible() ? document->mask(): NULL);
|
||||
|
||||
updateMask(m_mask, m_src);
|
||||
updateBounds(m_mask, m_src);
|
||||
}
|
||||
|
||||
void FilterManagerImpl::beginForPreview()
|
||||
@ -110,17 +110,18 @@ void FilterManagerImpl::beginForPreview()
|
||||
Document* document = static_cast<app::Document*>(m_site.document());
|
||||
|
||||
if (document->isMaskVisible())
|
||||
m_preview_mask.reset(new Mask(*document->mask()));
|
||||
m_previewMask.reset(new Mask(*document->mask()));
|
||||
else {
|
||||
m_preview_mask.reset(new Mask());
|
||||
m_preview_mask->replace(
|
||||
gfx::Rect(m_offset_x, m_offset_y,
|
||||
m_previewMask.reset(new Mask());
|
||||
m_previewMask->replace(
|
||||
gfx::Rect(
|
||||
m_celX, m_celY,
|
||||
m_src->width(),
|
||||
m_src->height()));
|
||||
}
|
||||
|
||||
m_row = 0;
|
||||
m_mask = m_preview_mask;
|
||||
m_mask = m_previewMask;
|
||||
|
||||
{
|
||||
Editor* editor = current_editor;
|
||||
@ -130,16 +131,16 @@ void FilterManagerImpl::beginForPreview()
|
||||
vp = vp.createIntersection(sprite->bounds());
|
||||
|
||||
if (vp.isEmpty()) {
|
||||
m_preview_mask.reset(NULL);
|
||||
m_previewMask.reset(nullptr);
|
||||
m_row = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
m_preview_mask->intersect(vp);
|
||||
m_previewMask->intersect(vp);
|
||||
}
|
||||
|
||||
if (!updateMask(m_mask, m_src)) {
|
||||
m_preview_mask.reset(NULL);
|
||||
if (!updateBounds(m_mask, m_src)) {
|
||||
m_previewMask.reset(nullptr);
|
||||
m_row = -1;
|
||||
return;
|
||||
}
|
||||
@ -152,19 +153,20 @@ void FilterManagerImpl::end()
|
||||
|
||||
bool FilterManagerImpl::applyStep()
|
||||
{
|
||||
if (m_row < 0 || m_row >= m_h)
|
||||
if (m_row < 0 || m_row >= m_bounds.h)
|
||||
return false;
|
||||
|
||||
if ((m_mask) && (m_mask->bitmap())) {
|
||||
int x = m_x - m_mask->bounds().x + m_offset_x;
|
||||
int y = m_y - m_mask->bounds().y + m_offset_y + m_row;
|
||||
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_w - x < 1) || (m_h - y < 1))
|
||||
if ((m_bounds.w - x < 1) ||
|
||||
(m_bounds.h - y < 1))
|
||||
return false;
|
||||
|
||||
m_maskBits = m_mask->bitmap()
|
||||
->lockBits<BitmapTraits>(Image::ReadLock,
|
||||
gfx::Rect(x, y, m_w - x, m_h - y));
|
||||
gfx::Rect(x, y, m_bounds.w - x, m_bounds.h - y));
|
||||
|
||||
m_maskIterator = m_maskBits.begin();
|
||||
}
|
||||
@ -187,7 +189,7 @@ void FilterManagerImpl::apply(Transaction& transaction)
|
||||
while (!cancelled && applyStep()) {
|
||||
if (m_progressDelegate) {
|
||||
// Report progress.
|
||||
m_progressDelegate->reportProgress(m_progressBase + m_progressWidth * (m_row+1) / m_h);
|
||||
m_progressDelegate->reportProgress(m_progressBase + m_progressWidth * (m_row+1) / m_bounds.h);
|
||||
|
||||
// Does the user cancelled the whole process?
|
||||
cancelled = m_progressDelegate->isCancelled();
|
||||
@ -196,8 +198,12 @@ void FilterManagerImpl::apply(Transaction& transaction)
|
||||
|
||||
if (!cancelled) {
|
||||
// Copy "dst" to "src"
|
||||
transaction.execute(new cmd::CopyRect(
|
||||
m_src, m_dst, gfx::Clip(m_x, m_y, m_x, m_y, m_w, m_h)));
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +239,8 @@ 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(),
|
||||
applyToImage(
|
||||
transaction, it->layer(),
|
||||
image, it->cel()->x(), it->cel()->y());
|
||||
}
|
||||
|
||||
@ -255,10 +262,10 @@ void FilterManagerImpl::flush()
|
||||
gfx::Rect rect(
|
||||
editor->editorToScreen(
|
||||
gfx::Point(
|
||||
m_x+m_offset_x,
|
||||
m_y+m_offset_y+m_row-1)),
|
||||
m_bounds.x+m_celX,
|
||||
m_bounds.y+m_celY+m_row-1)),
|
||||
gfx::Size(
|
||||
editor->zoom().apply(m_w),
|
||||
editor->zoom().apply(m_bounds.w),
|
||||
(editor->zoom().scale() >= 1 ? editor->zoom().apply(1):
|
||||
editor->zoom().remove(1))));
|
||||
|
||||
@ -273,12 +280,12 @@ void FilterManagerImpl::flush()
|
||||
|
||||
const void* FilterManagerImpl::getSourceAddress()
|
||||
{
|
||||
return m_src->getPixelAddress(m_x, m_row+m_y);
|
||||
return m_src->getPixelAddress(m_bounds.x, m_row+m_bounds.y);
|
||||
}
|
||||
|
||||
void* FilterManagerImpl::getDestinationAddress()
|
||||
{
|
||||
return m_dst->getPixelAddress(m_x, m_row+m_y);
|
||||
return m_dst->getPixelAddress(m_bounds.x, m_row+m_bounds.y);
|
||||
}
|
||||
|
||||
bool FilterManagerImpl::skipPixel()
|
||||
@ -305,19 +312,20 @@ RgbMap* FilterManagerImpl::getRgbMap()
|
||||
return m_site.sprite()->rgbMap(m_site.frame());
|
||||
}
|
||||
|
||||
void FilterManagerImpl::init(const Layer* layer, Image* image, int offset_x, int offset_y)
|
||||
void FilterManagerImpl::init(const Layer* layer, Image* image, int x, int y)
|
||||
{
|
||||
m_offset_x = offset_x;
|
||||
m_offset_y = offset_y;
|
||||
m_celX = x;
|
||||
m_celY = y;
|
||||
|
||||
if (!updateMask(static_cast<app::Document*>(m_site.document())->mask(), image))
|
||||
if (!updateBounds(static_cast<app::Document*>(m_site.document())->mask(), image))
|
||||
throw InvalidAreaException();
|
||||
|
||||
m_src = image;
|
||||
m_dst.reset(crop_image(image, 0, 0, image->width(), image->height(), 0));
|
||||
m_dst.reset(Image::createCopy(m_src));
|
||||
|
||||
m_row = -1;
|
||||
m_mask = NULL;
|
||||
m_preview_mask.reset(NULL);
|
||||
m_previewMask.reset(nullptr);
|
||||
|
||||
m_target = m_targetOrig;
|
||||
|
||||
@ -332,51 +340,25 @@ void FilterManagerImpl::applyToImage(Transaction& transaction, Layer* layer, Ima
|
||||
apply(transaction);
|
||||
}
|
||||
|
||||
bool FilterManagerImpl::updateMask(Mask* mask, const Image* image)
|
||||
bool FilterManagerImpl::updateBounds(Mask* mask, const Image* image)
|
||||
{
|
||||
int x, y, w, h;
|
||||
gfx::Rect bounds;
|
||||
|
||||
if (mask && mask->bitmap()) {
|
||||
x = mask->bounds().x - m_offset_x;
|
||||
y = mask->bounds().y - m_offset_y;
|
||||
w = mask->bounds().w;
|
||||
h = mask->bounds().h;
|
||||
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (x+w-1 >= image->width()-1)
|
||||
w = image->width()-x;
|
||||
|
||||
if (y+h-1 >= image->height()-1)
|
||||
h = image->height()-y;
|
||||
bounds = mask->bounds();
|
||||
bounds.offset(-m_celX, -m_celY);
|
||||
bounds &= image->bounds();
|
||||
}
|
||||
else {
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = image->width();
|
||||
h = image->height();
|
||||
bounds = image->bounds();
|
||||
}
|
||||
|
||||
if ((w < 1) || (h < 1)) {
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_w = 0;
|
||||
m_h = 0;
|
||||
if (bounds.isEmpty()) {
|
||||
m_bounds = gfx::Rect(0, 0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_w = w;
|
||||
m_h = h;
|
||||
m_bounds = bounds;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -12,6 +12,7 @@
|
||||
#include "base/exception.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "doc/image_impl.h"
|
||||
#include "doc/image_ref.h"
|
||||
#include "doc/pixel_format.h"
|
||||
#include "doc/site.h"
|
||||
#include "filters/filter_indexed_data.h"
|
||||
@ -85,42 +86,42 @@ namespace app {
|
||||
doc::Sprite* sprite() { return m_site.sprite(); }
|
||||
doc::Layer* layer() { return m_site.layer(); }
|
||||
doc::frame_t frame() { return m_site.frame(); }
|
||||
doc::Image* destinationImage() const { return m_dst; }
|
||||
doc::Image* destinationImage() const { return m_dst.get(); }
|
||||
|
||||
// Updates the current editor to show the progress of the preview.
|
||||
void flush();
|
||||
|
||||
// FilterManager implementation
|
||||
const void* getSourceAddress();
|
||||
void* getDestinationAddress();
|
||||
int getWidth() { return m_w; }
|
||||
Target getTarget() { return m_target; }
|
||||
FilterIndexedData* getIndexedData() { return this; }
|
||||
bool skipPixel();
|
||||
const doc::Image* getSourceImage() { return m_src; }
|
||||
int x() { return m_x; }
|
||||
int y() { return m_y+m_row; }
|
||||
const void* getSourceAddress() override;
|
||||
void* getDestinationAddress() override;
|
||||
int getWidth() override { return m_bounds.w; }
|
||||
Target getTarget() override { return m_target; }
|
||||
FilterIndexedData* getIndexedData() override { return this; }
|
||||
bool skipPixel() override;
|
||||
const doc::Image* getSourceImage() override { return m_src; }
|
||||
int x() override { return m_bounds.x; }
|
||||
int y() override { return m_bounds.y+m_row; }
|
||||
|
||||
// FilterIndexedData implementation
|
||||
doc::Palette* getPalette();
|
||||
doc::RgbMap* getRgbMap();
|
||||
doc::Palette* getPalette() override;
|
||||
doc::RgbMap* getRgbMap() override;
|
||||
|
||||
private:
|
||||
void init(const doc::Layer* layer, doc::Image* image, int offset_x, int offset_y);
|
||||
void init(const doc::Layer* layer, doc::Image* image, int x, int y);
|
||||
void apply(Transaction& transaction);
|
||||
void applyToImage(Transaction& transaction, doc::Layer* layer, doc::Image* image, int x, int y);
|
||||
bool updateMask(doc::Mask* mask, const doc::Image* image);
|
||||
bool updateBounds(doc::Mask* mask, const doc::Image* image);
|
||||
|
||||
Context* m_context;
|
||||
doc::Site m_site;
|
||||
Filter* m_filter;
|
||||
doc::Image* m_src;
|
||||
base::UniquePtr<doc::Image> m_dst;
|
||||
doc::ImageRef m_dst;
|
||||
int m_row;
|
||||
int m_x, m_y, m_w, m_h;
|
||||
int m_offset_x, m_offset_y;
|
||||
gfx::Rect m_bounds;
|
||||
int m_celX, m_celY;
|
||||
doc::Mask* m_mask;
|
||||
base::UniquePtr<doc::Mask> m_preview_mask;
|
||||
base::UniquePtr<doc::Mask> m_previewMask;
|
||||
doc::ImageBits<doc::BitmapTraits> m_maskBits;
|
||||
doc::ImageBits<doc::BitmapTraits>::iterator m_maskIterator;
|
||||
Target m_targetOrig; // Original targets
|
||||
|
Loading…
Reference in New Issue
Block a user