Fix issue 337: Vertical flip and Horizontal flips functions affect more than selected area

This commit is contained in:
David Capello 2014-02-17 00:41:28 -03:00
parent 3b8926b7d1
commit 2462767aac
3 changed files with 15 additions and 23 deletions

View File

@ -96,22 +96,20 @@ void FlipCommand::onExecute(Context* context)
// whole image.
if (document->isMaskVisible()) {
mask = document->getMask();
gfx::Rect maskBounds = mask->getBounds();
// Adjust the mask depending on the cel position.
maskBounds.offset(-x, -y);
// Intersect the full area of the image with the mask's
// bounds, so we don't request to flip an area outside the
// image's bounds.
bounds = bounds.createIntersect(maskBounds);
bounds = bounds.createIntersect(gfx::Rect(mask->getBounds()).offset(-x, -y));
// If the mask isn't a rectangular area, we've to flip the mask too.
if (mask->getBitmap() != NULL && !mask->isRectangular()) {
int bgcolor = app_get_color_to_clear_layer(writer.layer());
// Flip the portion of image specified by the mask.
mask->offsetOrigin(-x, -y);
api.flipImageWithMask(image, mask, m_flipType, bgcolor);
mask->offsetOrigin(x, y);
alreadyFlipped = true;
// Flip the mask.
@ -121,8 +119,7 @@ void FlipCommand::onExecute(Context* context)
base::UniquePtr<Mask> newMask(new Mask(*mask));
newMask->freeze();
raster::algorithm::flip_image(newMask->getBitmap(),
maskBitmap->getBounds(),
m_flipType);
maskBitmap->getBounds(), m_flipType);
newMask->unfreeze();
// Change the current mask and generate the new boundaries.

View File

@ -990,9 +990,8 @@ void DocumentApi::clearMask(Layer* layer, Cel* cel, int bgcolor)
}
}
void DocumentApi::flipImage(Image* image,
const gfx::Rect& bounds,
raster::algorithm::FlipType flipType)
void DocumentApi::flipImage(Image* image, const gfx::Rect& bounds,
raster::algorithm::FlipType flipType)
{
// Insert the undo operation.
if (undoEnabled()) {

View File

@ -50,18 +50,14 @@ void flip_image(Image* image, const gfx::Rect& bounds, FlipType flipType)
break;
case FlipVertical: {
int section_size = image->getRowStrideSize(bounds.w);
std::vector<uint8_t> tmpline(section_size);
int v = bounds.y+bounds.h-1;
for (int y=bounds.y; y<bounds.y+bounds.h/2; ++y, --v) {
uint8_t* address1 = image->getPixelAddress(bounds.x, y);
uint8_t* address2 = image->getPixelAddress(bounds.x, v);
// Swap lines.
std::copy(address1, address1+section_size, tmpline.begin());
std::copy(address2, address2+section_size, address1);
std::copy(tmpline.begin(), tmpline.end(), address2);
for (int x=bounds.x; x<bounds.x+bounds.w; ++x) {
uint32_t c1 = get_pixel(image, x, y);
uint32_t c2 = get_pixel(image, x, v);
put_pixel(image, x, y, c2);
put_pixel(image, x, v, c1);
}
}
break;
}
@ -75,7 +71,7 @@ void flip_image_with_mask(Image* image, const Mask* mask, FlipType flipType, int
switch (flipType) {
case FlipHorizontal: {
base::UniquePtr<Image> originalRow(Image::create(image->getPixelFormat(), mask->getBounds().w, 1));
base::UniquePtr<Image> originalRow(Image::create(image->getPixelFormat(), bounds.w, 1));
for (int y=bounds.y; y<bounds.y+bounds.h; ++y) {
// Copy the current row.
@ -93,8 +89,8 @@ void flip_image_with_mask(Image* image, const Mask* mask, FlipType flipType, int
break;
}
case FlipVertical:{
base::UniquePtr<Image> originalCol(Image::create(image->getPixelFormat(), 1, mask->getBounds().h));
case FlipVertical: {
base::UniquePtr<Image> originalCol(Image::create(image->getPixelFormat(), 1, bounds.h));
for (int x=bounds.x; x<bounds.x+bounds.w; ++x) {
// Copy the current column.