mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-29 03:32:48 +00:00
Improve creation of Dirty() instance (fix issue #239)
Now Dirty() ctor receives the bounds, so we don't need to iterate over the whole image to find/shrink the modified region.
This commit is contained in:
parent
ba4937ab07
commit
13946b310c
@ -850,7 +850,7 @@ void DocumentApi::flattenLayers(Sprite* sprite, int bgcolor)
|
||||
|
||||
// We have to save the current state of `cel_image' in the undo.
|
||||
if (undo->isEnabled()) {
|
||||
Dirty* dirty = new Dirty(cel_image, image);
|
||||
Dirty* dirty = new Dirty(cel_image, image, image->getBounds());
|
||||
dirty->saveImagePixels(cel_image);
|
||||
m_undoers->pushUndoer(new undoers::DirtyArea(
|
||||
getObjects(), cel_image, dirty));
|
||||
@ -1033,7 +1033,7 @@ void DocumentApi::flipImageWithMask(Image* image, const Mask* mask, raster::algo
|
||||
// Insert the undo operation.
|
||||
DocumentUndo* undo = m_document->getUndo();
|
||||
if (undo->isEnabled()) {
|
||||
base::UniquePtr<Dirty> dirty((new Dirty(image, flippedImage)));
|
||||
base::UniquePtr<Dirty> dirty((new Dirty(image, flippedImage, image->getBounds())));
|
||||
dirty->saveImagePixels(image);
|
||||
|
||||
m_undoers->pushUndoer(new undoers::DirtyArea(getObjects(), image, dirty));
|
||||
|
@ -86,6 +86,7 @@ class ToolLoopImpl : public tools::ToolLoop,
|
||||
UndoTransaction m_undoTransaction;
|
||||
ExpandCelCanvas m_expandCelCanvas;
|
||||
gfx::Region m_dirtyArea;
|
||||
gfx::Rect m_dirtyBounds;
|
||||
tools::ShadeTable8* m_shadeTable;
|
||||
|
||||
public:
|
||||
@ -175,7 +176,7 @@ public:
|
||||
if (!m_canceled) {
|
||||
// Paint ink
|
||||
if (getInk()->isPaint()) {
|
||||
m_expandCelCanvas.commit();
|
||||
m_expandCelCanvas.commit(m_dirtyBounds);
|
||||
}
|
||||
// Selection ink
|
||||
else if (getInk()->isSelection()) {
|
||||
@ -247,6 +248,7 @@ public:
|
||||
|
||||
void updateDirtyArea() OVERRIDE
|
||||
{
|
||||
m_dirtyBounds = m_dirtyBounds.createUnion(m_dirtyArea.getBounds());
|
||||
m_document->notifySpritePixelsModified(m_sprite, m_dirtyArea);
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ ExpandCelCanvas::~ExpandCelCanvas()
|
||||
delete m_dstImage;
|
||||
}
|
||||
|
||||
void ExpandCelCanvas::commit()
|
||||
void ExpandCelCanvas::commit(const gfx::Rect& bounds)
|
||||
{
|
||||
ASSERT(!m_closed);
|
||||
ASSERT(!m_committed);
|
||||
@ -192,7 +192,10 @@ void ExpandCelCanvas::commit()
|
||||
else {
|
||||
// Add to the undo history the differences between m_celImage and m_dstImage
|
||||
if (m_undo.isEnabled()) {
|
||||
base::UniquePtr<Dirty> dirty(new Dirty(m_celImage, m_dstImage));
|
||||
base::UniquePtr<Dirty> dirty
|
||||
(new Dirty(m_celImage, m_dstImage,
|
||||
(bounds.isEmpty() ? m_celImage->getBounds():
|
||||
bounds)));
|
||||
|
||||
dirty->saveImagePixels(m_celImage);
|
||||
if (dirty != NULL)
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define APP_UTIL_EXPAND_CEL_CANVAS_H_INCLUDED
|
||||
|
||||
#include "filters/tiled_mode.h"
|
||||
#include "gfx/rect.h"
|
||||
|
||||
namespace raster {
|
||||
class Cel;
|
||||
@ -50,7 +51,7 @@ namespace app {
|
||||
// Commit changes made in getDestCanvas() in the cel's image. Adds
|
||||
// information in the undo history so the user can undo the
|
||||
// modifications in the canvas.
|
||||
void commit();
|
||||
void commit(const gfx::Rect& bounds = gfx::Rect());
|
||||
|
||||
// Restore the cel as its original state as when ExpandCelCanvas()
|
||||
// was created.
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "raster/image.h"
|
||||
#include "raster/primitives.h"
|
||||
#include "raster/primitives_fast.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -58,29 +59,59 @@ Dirty::Dirty(const Dirty& src)
|
||||
}
|
||||
}
|
||||
|
||||
Dirty::Dirty(Image* image, Image* image_diff)
|
||||
: m_format(image->getPixelFormat())
|
||||
, m_x1(0), m_y1(0)
|
||||
, m_x2(image->getWidth()-1), m_y2(image->getHeight()-1)
|
||||
template<typename ImageTraits>
|
||||
inline bool shrink_row(const Image* image, const Image* image_diff, int& x1, int y, int& x2)
|
||||
{
|
||||
int x, y, x1, x2;
|
||||
for (; x1<=x2; ++x1) {
|
||||
if (get_pixel_fast<ImageTraits>(image, x1, y) !=
|
||||
get_pixel_fast<ImageTraits>(image_diff, x1, y))
|
||||
break;
|
||||
}
|
||||
|
||||
for (y=0; y<image->getHeight(); y++) {
|
||||
x1 = -1;
|
||||
for (x=0; x<image->getWidth(); x++) {
|
||||
if (get_pixel(image, x, y) != get_pixel(image_diff, x, y)) {
|
||||
x1 = x;
|
||||
if (x1 > x2)
|
||||
return false;
|
||||
|
||||
for (; x2>x1; x2--) {
|
||||
if (get_pixel_fast<ImageTraits>(image, x2, y) !=
|
||||
get_pixel_fast<ImageTraits>(image_diff, x2, y))
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Dirty::Dirty(Image* image, Image* image_diff, const gfx::Rect& bounds)
|
||||
: m_format(image->getPixelFormat())
|
||||
, m_x1(bounds.x), m_y1(bounds.y)
|
||||
, m_x2(bounds.x2()-1), m_y2(bounds.y2()-1)
|
||||
{
|
||||
int y, x1, x2;
|
||||
|
||||
for (y=m_y1; y<=m_y2; y++) {
|
||||
x1 = m_x1;
|
||||
x2 = m_x2;
|
||||
|
||||
bool res;
|
||||
switch (image->getPixelFormat()) {
|
||||
case IMAGE_RGB:
|
||||
res = shrink_row<RgbTraits>(image, image_diff, x1, y, x2);
|
||||
break;
|
||||
}
|
||||
|
||||
case IMAGE_GRAYSCALE:
|
||||
res = shrink_row<GrayscaleTraits>(image, image_diff, x1, y, x2);
|
||||
break;
|
||||
|
||||
case IMAGE_INDEXED:
|
||||
res = shrink_row<IndexedTraits>(image, image_diff, x1, y, x2);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(false && "Not implemented for bitmaps");
|
||||
return;
|
||||
}
|
||||
if (x1 < 0)
|
||||
if (!res)
|
||||
continue;
|
||||
|
||||
for (x2=image->getWidth()-1; x2>x1; x2--) {
|
||||
if (get_pixel(image, x2, y) != get_pixel(image_diff, x2, y))
|
||||
break;
|
||||
}
|
||||
|
||||
Col* col = new Col(x1, x2-x1+1);
|
||||
col->data.resize(getLineSize(col->w));
|
||||
|
||||
|
@ -54,9 +54,10 @@ namespace raster {
|
||||
Row(int y) : y(y) { }
|
||||
};
|
||||
|
||||
public:
|
||||
Dirty(PixelFormat format, int x1, int y1, int x2, int y2);
|
||||
Dirty(const Dirty& src);
|
||||
Dirty(Image* image1, Image* image2);
|
||||
Dirty(Image* image1, Image* image2, const gfx::Rect& bounds);
|
||||
~Dirty();
|
||||
|
||||
int getMemSize() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user