mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 06:32:42 +00:00
Reduce the patched region with ExpandCelCanvas when we have the source image to compare with
This commit is contained in:
parent
cee3c246bb
commit
c12100dedb
@ -182,13 +182,26 @@ void ExpandCelCanvas::commit()
|
||||
|
||||
ASSERT(m_cel->image() == m_celImage.get());
|
||||
|
||||
// TODO create a new "dirty dst region" which is the region to be
|
||||
// patched as m_validDstRegion includes more than it's needed.
|
||||
gfx::Region* regionToPatch = &m_validDstRegion;
|
||||
gfx::Region reduced;
|
||||
|
||||
if ((m_flags & NeedsSource) == NeedsSource) {
|
||||
ASSERT(gfx::Region().createSubtraction(m_validDstRegion, m_validSrcRegion).isEmpty());
|
||||
|
||||
for (gfx::Rect rc : m_validDstRegion) {
|
||||
if (algorithm::shrink_bounds2(getSourceCanvas(),
|
||||
getDestCanvas(), rc, rc)) {
|
||||
reduced |= gfx::Region(rc);
|
||||
}
|
||||
}
|
||||
regionToPatch = &reduced;
|
||||
}
|
||||
|
||||
m_transaction.execute(
|
||||
new cmd::PatchCel(
|
||||
m_cel,
|
||||
m_dstImage.get(),
|
||||
m_validDstRegion,
|
||||
*regionToPatch,
|
||||
m_bounds.origin()));
|
||||
}
|
||||
else {
|
||||
|
@ -50,7 +50,7 @@ bool is_same_pixel<BitmapTraits>(color_t pixel1, color_t pixel2)
|
||||
}
|
||||
|
||||
template<typename ImageTraits>
|
||||
bool shrink_bounds_templ(Image* image, gfx::Rect& bounds, color_t refpixel)
|
||||
bool shrink_bounds_templ(const Image* image, gfx::Rect& bounds, color_t refpixel)
|
||||
{
|
||||
bool shrink;
|
||||
int u, v;
|
||||
@ -120,9 +120,80 @@ bool shrink_bounds_templ(Image* image, gfx::Rect& bounds, color_t refpixel)
|
||||
return (!bounds.isEmpty());
|
||||
}
|
||||
|
||||
template<typename ImageTraits>
|
||||
bool shrink_bounds_templ2(const Image* a, const Image* b, gfx::Rect& bounds)
|
||||
{
|
||||
bool shrink;
|
||||
int u, v;
|
||||
|
||||
// Shrink left side
|
||||
for (u=bounds.x; u<bounds.x+bounds.w; ++u) {
|
||||
shrink = true;
|
||||
for (v=bounds.y; v<bounds.y+bounds.h; ++v) {
|
||||
if (get_pixel_fast<ImageTraits>(a, u, v) !=
|
||||
get_pixel_fast<ImageTraits>(b, u, v)) {
|
||||
shrink = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!shrink)
|
||||
break;
|
||||
++bounds.x;
|
||||
--bounds.w;
|
||||
}
|
||||
|
||||
// Shrink right side
|
||||
for (u=bounds.x+bounds.w-1; u>=bounds.x; --u) {
|
||||
shrink = true;
|
||||
for (v=bounds.y; v<bounds.y+bounds.h; ++v) {
|
||||
if (get_pixel_fast<ImageTraits>(a, u, v) !=
|
||||
get_pixel_fast<ImageTraits>(b, u, v)) {
|
||||
shrink = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!shrink)
|
||||
break;
|
||||
--bounds.w;
|
||||
}
|
||||
|
||||
// Shrink top side
|
||||
for (v=bounds.y; v<bounds.y+bounds.h; ++v) {
|
||||
shrink = true;
|
||||
for (u=bounds.x; u<bounds.x+bounds.w; ++u) {
|
||||
if (get_pixel_fast<ImageTraits>(a, u, v) !=
|
||||
get_pixel_fast<ImageTraits>(b, u, v)) {
|
||||
shrink = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!shrink)
|
||||
break;
|
||||
++bounds.y;
|
||||
--bounds.h;
|
||||
}
|
||||
|
||||
// Shrink bottom side
|
||||
for (v=bounds.y+bounds.h-1; v>=bounds.y; --v) {
|
||||
shrink = true;
|
||||
for (u=bounds.x; u<bounds.x+bounds.w; ++u) {
|
||||
if (get_pixel_fast<ImageTraits>(a, u, v) !=
|
||||
get_pixel_fast<ImageTraits>(b, u, v)) {
|
||||
shrink = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!shrink)
|
||||
break;
|
||||
--bounds.h;
|
||||
}
|
||||
|
||||
return (!bounds.isEmpty());
|
||||
}
|
||||
|
||||
bool shrink_bounds(Image* image,
|
||||
}
|
||||
|
||||
bool shrink_bounds(const Image* image,
|
||||
const gfx::Rect& start_bounds,
|
||||
gfx::Rect& bounds,
|
||||
color_t refpixel)
|
||||
@ -138,10 +209,29 @@ bool shrink_bounds(Image* image,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool shrink_bounds(Image *image, gfx::Rect& bounds, color_t refpixel)
|
||||
bool shrink_bounds(const Image* image, gfx::Rect& bounds, color_t refpixel)
|
||||
{
|
||||
return shrink_bounds(image, image->bounds(), bounds, refpixel);
|
||||
}
|
||||
|
||||
bool shrink_bounds2(const Image* a, const Image* b,
|
||||
const gfx::Rect& start_bounds,
|
||||
gfx::Rect& bounds)
|
||||
{
|
||||
ASSERT(a && b);
|
||||
ASSERT(a->bounds() == b->bounds());
|
||||
|
||||
bounds = (start_bounds & a->bounds());
|
||||
|
||||
switch (a->pixelFormat()) {
|
||||
case IMAGE_RGB: return shrink_bounds_templ2<RgbTraits>(a, b, bounds);
|
||||
case IMAGE_GRAYSCALE: return shrink_bounds_templ2<GrayscaleTraits>(a, b, bounds);
|
||||
case IMAGE_INDEXED: return shrink_bounds_templ2<IndexedTraits>(a, b, bounds);
|
||||
case IMAGE_BITMAP: return shrink_bounds_templ2<BitmapTraits>(a, b, bounds);
|
||||
}
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace algorithm
|
||||
} // namespace doc
|
||||
|
@ -17,15 +17,20 @@ namespace doc {
|
||||
|
||||
namespace algorithm {
|
||||
|
||||
bool shrink_bounds(Image* image,
|
||||
bool shrink_bounds(const Image* image,
|
||||
const gfx::Rect& start_bounds,
|
||||
gfx::Rect& bounds,
|
||||
color_t refpixel);
|
||||
|
||||
bool shrink_bounds(Image* image,
|
||||
bool shrink_bounds(const Image* image,
|
||||
gfx::Rect& bounds,
|
||||
color_t refpixel);
|
||||
|
||||
bool shrink_bounds2(const Image* a,
|
||||
const Image* b,
|
||||
const gfx::Rect& start_bounds,
|
||||
gfx::Rect& bounds);
|
||||
|
||||
} // algorithm
|
||||
} // doc
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user