Avoid duplicated code to flip the image.

- Added raster::algorithm::FlipType enum and flip_image function.
- Added gfx/fwd.h for forward declarations.
This commit is contained in:
David Capello 2012-02-19 16:25:07 -03:00
parent 95cb043601
commit 95a9524ec2
10 changed files with 194 additions and 62 deletions

View File

@ -226,8 +226,9 @@ add_library(aseprite-library
modules/palettes.cpp
modules/rootmenu.cpp
raster/algo.cpp
raster/algofill.cpp
raster/algo_polygon.cpp
raster/algofill.cpp
raster/algorithm/flip_image.cpp
raster/blend.cpp
raster/cel.cpp
raster/cel_io.cpp

View File

@ -37,10 +37,6 @@
class FlipCommand : public Command
{
bool m_flip_mask;
bool m_flip_horizontal;
bool m_flip_vertical;
public:
FlipCommand();
Command* clone() const { return new FlipCommand(*this); }
@ -52,6 +48,9 @@ protected:
private:
static char* read_authors_txt(const char *filename);
bool m_flipMask;
raster::algorithm::FlipType m_flipType;
};
FlipCommand::FlipCommand()
@ -59,19 +58,18 @@ FlipCommand::FlipCommand()
"Flip",
CmdRecordableFlag)
{
m_flip_mask = false;
m_flip_horizontal = false;
m_flip_vertical = false;
m_flipMask = false;
m_flipType = raster::algorithm::FlipHorizontal;
}
void FlipCommand::onLoadParams(Params* params)
{
std::string target = params->get("target");
m_flip_mask = (target == "mask");
m_flipMask = (target == "mask");
std::string orientation = params->get("orientation");
m_flip_horizontal = (orientation == "horizontal");
m_flip_vertical = (orientation == "vertical");
m_flipType = (orientation == "vertical" ? raster::algorithm::FlipVertical:
raster::algorithm::FlipHorizontal);
}
bool FlipCommand::onEnabled(Context* context)
@ -86,13 +84,15 @@ void FlipCommand::onExecute(Context* context)
{
UndoTransaction undoTransaction(document,
m_flip_mask ?
(m_flip_horizontal ? "Flip Horizontal":
"Flip Vertical"):
(m_flip_horizontal ? "Flip Canvas Horizontal":
"Flip Canvas Vertical"));
m_flipMask ?
(m_flipType == raster::algorithm::FlipHorizontal ?
"Flip Horizontal":
"Flip Vertical"):
(m_flipType == raster::algorithm::FlipHorizontal ?
"Flip Canvas Horizontal":
"Flip Canvas Vertical"));
if (m_flip_mask) {
if (m_flipMask) {
Image* image;
int x1, y1, x2, y2;
int x, y;
@ -125,8 +125,9 @@ void FlipCommand::onExecute(Context* context)
y2 = MID(0, y2, image->h-1);
}
undoTransaction.flipImage(image, x1, y1, x2, y2,
m_flip_horizontal, m_flip_vertical);
undoTransaction.flipImage(image,
gfx::Rect(x1, y1,
x2-x1+1, y2-y1+1), m_flipType);
}
else {
// get all sprite cels
@ -140,11 +141,14 @@ void FlipCommand::onExecute(Context* context)
undoTransaction.setCelPosition
(cel,
m_flip_horizontal ? sprite->getWidth() - image->w - cel->getX(): cel->getX(),
m_flip_vertical ? sprite->getHeight() - image->h - cel->getY(): cel->getY());
(m_flipType == raster::algorithm::FlipHorizontal ?
sprite->getWidth() - image->w - cel->getX():
cel->getX()),
(m_flipType == raster::algorithm::FlipVertical ?
sprite->getHeight() - image->h - cel->getY():
cel->getY()));
undoTransaction.flipImage(image, 0, 0, image->w-1, image->h-1,
m_flip_horizontal, m_flip_vertical);
undoTransaction.flipImage(image, gfx::Rect(0, 0, image->w, image->h), m_flipType);
}
}

24
src/gfx/fwd.h Normal file
View File

@ -0,0 +1,24 @@
// ASEPRITE gfx library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef GFX_FWD_H_INCLUDED
#define GFX_FWD_H_INCLUDED
namespace gfx {
template<typename T> class BorderT;
template<typename T> class PointT;
template<typename T> class RectT;
template<typename T> class SizeT;
typedef BorderT<int> Border;
typedef PointT<int> Point;
typedef RectT<int> Rect;
typedef SizeT<int> Size;
} // namespace gfx
#endif

View File

@ -0,0 +1,44 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "raster/algorithm/flip_image.h"
#include "base/unique_ptr.h"
#include "gfx/rect.h"
#include "raster/image.h"
namespace raster { namespace algorithm {
void flip_image(Image* image, const gfx::Rect& bounds, FlipType flipType)
{
UniquePtr<Image> area(image_crop(image, bounds.x, bounds.y, bounds.w, bounds.h, 0));
int x2 = bounds.x+bounds.w-1;
int y2 = bounds.y+bounds.h-1;
int x, y;
for (y=0; y<bounds.h; ++y)
for (x=0; x<bounds.w; ++x)
image_putpixel(image,
(flipType == FlipHorizontal ? x2-x: bounds.x+x),
(flipType == FlipVertical ? y2-y: bounds.y+y),
image_getpixel(area, x, y));
}
} }

View File

@ -0,0 +1,35 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef RASTER_ALGORITHM_FLIP_IMAGE_H_INCLUDED
#define RASTER_ALGORITHM_FLIP_IMAGE_H_INCLUDED
#include "gfx/fwd.h"
#include "raster/algorithm/flip_type.h"
class Image;
namespace raster {
namespace algorithm {
void flip_image(Image* image, const gfx::Rect& bounds, FlipType flipType);
}
}
#endif

View File

@ -0,0 +1,33 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef RASTER_ALGORITHM_FLIP_TYPE_H_INCLUDED
#define RASTER_ALGORITHM_FLIP_TYPE_H_INCLUDED
namespace raster {
namespace algorithm {
enum FlipType {
FlipHorizontal,
FlipVertical,
};
}
}
#endif

View File

@ -22,6 +22,7 @@
#include "base/unique_ptr.h"
#include "document.h"
#include "raster/algorithm/flip_image.h"
#include "raster/blend.h"
#include "raster/cel.h"
#include "raster/dirty.h"
@ -1049,30 +1050,19 @@ void UndoTransaction::clearMask(int bgcolor)
}
}
void UndoTransaction::flipImage(Image* image, int x1, int y1, int x2, int y2,
bool flip_horizontal, bool flip_vertical)
void UndoTransaction::flipImage(Image* image,
const gfx::Rect& bounds,
raster::algorithm::FlipType flipType)
{
// Insert the undo operation.
if (isEnabled()) {
m_undoHistory->pushUndoer
(new undoers::FlipImage
(m_undoHistory->getObjects(), image, x1, y1, x2-x1+1, y2-y1+1,
(flip_horizontal ? undoers::FlipImage::FlipHorizontal: 0) |
(flip_vertical ? undoers::FlipImage::FlipVertical: 0)));
(m_undoHistory->getObjects(), image, bounds, flipType));
}
// Flip the portion of the bitmap.
Image* area = image_crop(image, x1, y1, x2-x1+1, y2-y1+1, 0);
int x, y;
for (y=0; y<(y2-y1+1); y++)
for (x=0; x<(x2-x1+1); x++)
image_putpixel(image,
flip_horizontal ? x2-x: x1+x,
flip_vertical ? y2-y: y1+y,
image_getpixel(area, x, y));
image_free(area);
raster::algorithm::flip_image(image, bounds, flipType);
}
void UndoTransaction::pasteImage(const Image* src_image, int x, int y, int opacity)

View File

@ -20,6 +20,7 @@
#define UNDO_TRANSACTION_H_INCLUDED
#include "gfx/rect.h"
#include "raster/algorithm/flip_type.h"
#include "raster/dithering_method.h"
#include "raster/pixel_format.h"
#include "undo/modification.h"
@ -118,8 +119,7 @@ public:
// for image
Image* getCelImage(Cel* cel);
void clearMask(int bgcolor);
void flipImage(Image* image, int x1, int y1, int x2, int y2,
bool flip_horizontal, bool flip_vertical);
void flipImage(Image* image, const gfx::Rect& bounds, raster::algorithm::FlipType flipType);
void pasteImage(const Image* src_image, int x, int y, int opacity);
// for mask

View File

@ -21,6 +21,10 @@
#include "undoers/flip_image.h"
#include "base/unique_ptr.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "gfx/size.h"
#include "raster/algorithm/flip_image.h"
#include "raster/image.h"
#include "undo/objects_container.h"
#include "undo/undo_exception.h"
@ -29,14 +33,17 @@
using namespace undo;
using namespace undoers;
FlipImage::FlipImage(ObjectsContainer* objects, Image* image, int x, int y, int w, int h, int flipFlags)
FlipImage::FlipImage(ObjectsContainer* objects, Image* image,
const gfx::Rect& bounds,
raster::algorithm::FlipType flipType)
: m_imageId(objects->addObject(image))
, m_format(image->getPixelFormat())
, m_x(x), m_y(y), m_w(w), m_h(h)
, m_flipFlags(flipFlags)
, m_x(bounds.x), m_y(bounds.y)
, m_w(bounds.w), m_h(bounds.h)
, m_flipType(flipType)
{
ASSERT(w >= 1 && h >= 1);
ASSERT(x >= 0 && y >= 0 && x+w <= image->w && y+h <= image->h);
ASSERT(m_w >= 1 && m_h >= 1);
ASSERT(m_x >= 0 && m_y >= 0 && m_x+m_w <= image->w && m_y+m_h <= image->h);
}
void FlipImage::dispose()
@ -47,21 +54,13 @@ void FlipImage::dispose()
void FlipImage::revert(ObjectsContainer* objects, UndoersCollector* redoers)
{
Image* image = objects->getObjectT<Image>(m_imageId);
raster::algorithm::FlipType flipType = static_cast<raster::algorithm::FlipType>(m_flipType);
gfx::Rect bounds(gfx::Point(m_x, m_y), gfx::Size(m_w, m_h));
if (image->getPixelFormat() != m_format)
throw UndoException("Image type does not match");
redoers->pushUndoer(new FlipImage(objects, image, m_x, m_y, m_w, m_h, m_flipFlags));
redoers->pushUndoer(new FlipImage(objects, image, bounds, flipType));
UniquePtr<Image> area(image_crop(image, m_x, m_y, m_w, m_h, 0));
int x, y;
int x2 = m_x+m_w-1;
int y2 = m_y+m_h-1;
for (y=0; y<m_h; ++y)
for (x=0; x<m_w; ++x)
image_putpixel(image,
((m_flipFlags & FlipHorizontal) == FlipHorizontal ? x2-x: m_x+x),
((m_flipFlags & FlipVertical) == FlipVertical ? y2-y: m_y+y),
image_getpixel(area, x, y));
raster::algorithm::flip_image(image, bounds, flipType);
}

View File

@ -19,6 +19,8 @@
#ifndef UNDOERS_FLIP_IMAGE_H_INCLUDED
#define UNDOERS_FLIP_IMAGE_H_INCLUDED
#include "gfx/fwd.h"
#include "raster/algorithm/flip_type.h"
#include "undo/object_id.h"
#include "undoers/undoer_base.h"
@ -29,9 +31,9 @@ namespace undoers {
class FlipImage : public UndoerBase
{
public:
enum FlipFlags { FlipHorizontal = 1, FlipVertical = 2 };
FlipImage(undo::ObjectsContainer* objects, Image* image, int x, int y, int w, int h, int flipFlags);
FlipImage(undo::ObjectsContainer* objects, Image* image,
const gfx::Rect& bounds,
raster::algorithm::FlipType flipType);
void dispose() OVERRIDE;
int getMemSize() const OVERRIDE { return sizeof(*this); }
@ -41,7 +43,7 @@ private:
undo::ObjectId m_imageId;
uint8_t m_format;
uint16_t m_x, m_y, m_w, m_h;
uint8_t m_flipFlags;
uint8_t m_flipType;
};
} // namespace undoers