mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-11 09:40:42 +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.
|
// We have to save the current state of `cel_image' in the undo.
|
||||||
if (undo->isEnabled()) {
|
if (undo->isEnabled()) {
|
||||||
Dirty* dirty = new Dirty(cel_image, image);
|
Dirty* dirty = new Dirty(cel_image, image, image->getBounds());
|
||||||
dirty->saveImagePixels(cel_image);
|
dirty->saveImagePixels(cel_image);
|
||||||
m_undoers->pushUndoer(new undoers::DirtyArea(
|
m_undoers->pushUndoer(new undoers::DirtyArea(
|
||||||
getObjects(), cel_image, dirty));
|
getObjects(), cel_image, dirty));
|
||||||
@ -1033,7 +1033,7 @@ void DocumentApi::flipImageWithMask(Image* image, const Mask* mask, raster::algo
|
|||||||
// Insert the undo operation.
|
// Insert the undo operation.
|
||||||
DocumentUndo* undo = m_document->getUndo();
|
DocumentUndo* undo = m_document->getUndo();
|
||||||
if (undo->isEnabled()) {
|
if (undo->isEnabled()) {
|
||||||
base::UniquePtr<Dirty> dirty((new Dirty(image, flippedImage)));
|
base::UniquePtr<Dirty> dirty((new Dirty(image, flippedImage, image->getBounds())));
|
||||||
dirty->saveImagePixels(image);
|
dirty->saveImagePixels(image);
|
||||||
|
|
||||||
m_undoers->pushUndoer(new undoers::DirtyArea(getObjects(), image, dirty));
|
m_undoers->pushUndoer(new undoers::DirtyArea(getObjects(), image, dirty));
|
||||||
|
@ -86,6 +86,7 @@ class ToolLoopImpl : public tools::ToolLoop,
|
|||||||
UndoTransaction m_undoTransaction;
|
UndoTransaction m_undoTransaction;
|
||||||
ExpandCelCanvas m_expandCelCanvas;
|
ExpandCelCanvas m_expandCelCanvas;
|
||||||
gfx::Region m_dirtyArea;
|
gfx::Region m_dirtyArea;
|
||||||
|
gfx::Rect m_dirtyBounds;
|
||||||
tools::ShadeTable8* m_shadeTable;
|
tools::ShadeTable8* m_shadeTable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -175,7 +176,7 @@ public:
|
|||||||
if (!m_canceled) {
|
if (!m_canceled) {
|
||||||
// Paint ink
|
// Paint ink
|
||||||
if (getInk()->isPaint()) {
|
if (getInk()->isPaint()) {
|
||||||
m_expandCelCanvas.commit();
|
m_expandCelCanvas.commit(m_dirtyBounds);
|
||||||
}
|
}
|
||||||
// Selection ink
|
// Selection ink
|
||||||
else if (getInk()->isSelection()) {
|
else if (getInk()->isSelection()) {
|
||||||
@ -247,6 +248,7 @@ public:
|
|||||||
|
|
||||||
void updateDirtyArea() OVERRIDE
|
void updateDirtyArea() OVERRIDE
|
||||||
{
|
{
|
||||||
|
m_dirtyBounds = m_dirtyBounds.createUnion(m_dirtyArea.getBounds());
|
||||||
m_document->notifySpritePixelsModified(m_sprite, m_dirtyArea);
|
m_document->notifySpritePixelsModified(m_sprite, m_dirtyArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ ExpandCelCanvas::~ExpandCelCanvas()
|
|||||||
delete m_dstImage;
|
delete m_dstImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpandCelCanvas::commit()
|
void ExpandCelCanvas::commit(const gfx::Rect& bounds)
|
||||||
{
|
{
|
||||||
ASSERT(!m_closed);
|
ASSERT(!m_closed);
|
||||||
ASSERT(!m_committed);
|
ASSERT(!m_committed);
|
||||||
@ -192,7 +192,10 @@ void ExpandCelCanvas::commit()
|
|||||||
else {
|
else {
|
||||||
// Add to the undo history the differences between m_celImage and m_dstImage
|
// Add to the undo history the differences between m_celImage and m_dstImage
|
||||||
if (m_undo.isEnabled()) {
|
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);
|
dirty->saveImagePixels(m_celImage);
|
||||||
if (dirty != NULL)
|
if (dirty != NULL)
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define APP_UTIL_EXPAND_CEL_CANVAS_H_INCLUDED
|
#define APP_UTIL_EXPAND_CEL_CANVAS_H_INCLUDED
|
||||||
|
|
||||||
#include "filters/tiled_mode.h"
|
#include "filters/tiled_mode.h"
|
||||||
|
#include "gfx/rect.h"
|
||||||
|
|
||||||
namespace raster {
|
namespace raster {
|
||||||
class Cel;
|
class Cel;
|
||||||
@ -50,7 +51,7 @@ namespace app {
|
|||||||
// Commit changes made in getDestCanvas() in the cel's image. Adds
|
// Commit changes made in getDestCanvas() in the cel's image. Adds
|
||||||
// information in the undo history so the user can undo the
|
// information in the undo history so the user can undo the
|
||||||
// modifications in the canvas.
|
// modifications in the canvas.
|
||||||
void commit();
|
void commit(const gfx::Rect& bounds = gfx::Rect());
|
||||||
|
|
||||||
// Restore the cel as its original state as when ExpandCelCanvas()
|
// Restore the cel as its original state as when ExpandCelCanvas()
|
||||||
// was created.
|
// was created.
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "raster/image.h"
|
#include "raster/image.h"
|
||||||
#include "raster/primitives.h"
|
#include "raster/primitives.h"
|
||||||
|
#include "raster/primitives_fast.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -58,29 +59,59 @@ Dirty::Dirty(const Dirty& src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dirty::Dirty(Image* image, Image* image_diff)
|
template<typename ImageTraits>
|
||||||
: m_format(image->getPixelFormat())
|
inline bool shrink_row(const Image* image, const Image* image_diff, int& x1, int y, int& x2)
|
||||||
, m_x1(0), m_y1(0)
|
|
||||||
, m_x2(image->getWidth()-1), m_y2(image->getHeight()-1)
|
|
||||||
{
|
{
|
||||||
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++) {
|
if (x1 > x2)
|
||||||
x1 = -1;
|
return false;
|
||||||
for (x=0; x<image->getWidth(); x++) {
|
|
||||||
if (get_pixel(image, x, y) != get_pixel(image_diff, x, y)) {
|
for (; x2>x1; x2--) {
|
||||||
x1 = x;
|
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;
|
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;
|
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* col = new Col(x1, x2-x1+1);
|
||||||
col->data.resize(getLineSize(col->w));
|
col->data.resize(getLineSize(col->w));
|
||||||
|
|
||||||
|
@ -54,9 +54,10 @@ namespace raster {
|
|||||||
Row(int y) : y(y) { }
|
Row(int y) : y(y) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
Dirty(PixelFormat format, int x1, int y1, int x2, int y2);
|
Dirty(PixelFormat format, int x1, int y1, int x2, int y2);
|
||||||
Dirty(const Dirty& src);
|
Dirty(const Dirty& src);
|
||||||
Dirty(Image* image1, Image* image2);
|
Dirty(Image* image1, Image* image2, const gfx::Rect& bounds);
|
||||||
~Dirty();
|
~Dirty();
|
||||||
|
|
||||||
int getMemSize() const;
|
int getMemSize() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user