Add cmd::CropCel and implement cmd::TrimCel using it

This commit is contained in:
David Capello 2016-05-10 10:37:16 -03:00
parent 3369d902d9
commit 1e0fd35413
5 changed files with 138 additions and 63 deletions

View File

@ -111,6 +111,7 @@ add_library(app-lib
cmd/copy_frame.cpp
cmd/copy_rect.cpp
cmd/copy_region.cpp
cmd/crop_cel.cpp
cmd/deselect_mask.cpp
cmd/flatten_layers.cpp
cmd/flip_image.cpp

72
src/app/cmd/crop_cel.cpp Normal file
View File

@ -0,0 +1,72 @@
// Aseprite
// Copyright (C) 2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/crop_cel.h"
#include "doc/cel.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
using namespace doc;
CropCel::CropCel(Cel* cel, const gfx::Rect& newBounds)
: WithCel(cel)
, m_oldOrigin(cel->position())
, m_newOrigin(newBounds.origin())
, m_oldBounds(cel->bounds())
, m_newBounds(newBounds)
{
m_oldBounds.offset(-m_newOrigin);
m_newBounds.offset(-m_oldOrigin);
}
void CropCel::onExecute()
{
cropImage(m_newOrigin, m_newBounds);
}
void CropCel::onUndo()
{
cropImage(m_oldOrigin, m_oldBounds);
}
// Crops the cel image leaving the same ID in the image.
void CropCel::cropImage(const gfx::Point& origin,
const gfx::Rect& bounds)
{
Cel* cel = this->cel();
if (bounds != cel->image()->bounds()) {
ImageRef image(crop_image(cel->image(),
bounds.x, bounds.y,
bounds.w, bounds.h,
cel->image()->maskColor()));
ObjectId id = cel->image()->id();
ObjectVersion ver = cel->image()->version();
cel->image()->setId(NullId);
image->setId(id);
image->setVersion(ver);
image->incrementVersion();
cel->data()->setImage(image);
cel->incrementVersion();
}
if (cel->data()->position() != origin) {
cel->data()->setPosition(origin);
cel->incrementVersion();
}
}
} // namespace cmd
} // namespace app

45
src/app/cmd/crop_cel.h Normal file
View File

@ -0,0 +1,45 @@
// Aseprite
// Copyright (C) 2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
#ifndef APP_CMD_CROP_CEL_H_INCLUDED
#define APP_CMD_CROP_CEL_H_INCLUDED
#pragma once
#include "app/cmd.h"
#include "app/cmd/with_cel.h"
#include "gfx/point.h"
#include "gfx/rect.h"
namespace app {
namespace cmd {
class CropCel : public Cmd
, public WithCel {
public:
CropCel(doc::Cel* cel, const gfx::Rect& newBounds);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this);
}
private:
void cropImage(const gfx::Point& origin,
const gfx::Rect& bounds);
gfx::Point m_oldOrigin;
gfx::Point m_newOrigin;
gfx::Rect m_oldBounds;
gfx::Rect m_newBounds;
};
} // namespace cmd
} // namespace app
#endif

View File

@ -11,9 +11,10 @@
#include "app/cmd/trim_cel.h"
#include "app/cmd/crop_cel.h"
#include "app/cmd/remove_cel.h"
#include "doc/algorithm/shrink_bounds.h"
#include "doc/cel.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
@ -21,68 +22,31 @@ namespace cmd {
using namespace doc;
TrimCel::TrimCel(Cel* cel)
: WithCel(cel)
, m_originalBounds(cel->image()->bounds())
, m_color(cel->image()->maskColor())
, m_removeCel(nullptr)
{
if (algorithm::shrink_bounds(cel->image(), m_bounds, m_color)) {
m_originalBounds.x = -m_bounds.x;
m_originalBounds.y = -m_bounds.y;
gfx::Rect newBounds;
if (algorithm::shrink_bounds(cel->image(), newBounds,
cel->image()->maskColor())) {
newBounds.offset(cel->position());
m_subCmd = new cmd::CropCel(cel, newBounds);
}
else {
m_subCmd = new cmd::RemoveCel(cel);
}
else
m_removeCel = new cmd::RemoveCel(cel);
}
void TrimCel::onExecute()
{
if (m_removeCel)
m_removeCel->execute(context());
else
cropImage(m_bounds);
m_subCmd->execute(context());
}
void TrimCel::onUndo()
{
if (m_removeCel)
m_removeCel->undo();
else
cropImage(m_originalBounds);
m_subCmd->undo();
}
void TrimCel::onRedo()
{
if (m_removeCel)
m_removeCel->redo();
else
cropImage(m_bounds);
}
// Crops the cel image leaving the same ID in the image.
void TrimCel::cropImage(const gfx::Rect& bounds)
{
Cel* cel = this->cel();
if (bounds == cel->image()->bounds())
return;
ImageRef image(crop_image(cel->image(),
bounds.x, bounds.y,
bounds.w, bounds.h,
m_color));
ObjectId id = cel->image()->id();
ObjectVersion ver = cel->image()->version();
gfx::Point newPos = cel->position() + bounds.origin();
cel->image()->setId(NullId);
image->setId(id);
image->setVersion(ver);
image->incrementVersion();
cel->data()->setImage(image);
cel->data()->setPosition(newPos);
cel->incrementVersion();
m_subCmd->redo();
}
} // namespace cmd

View File

@ -10,16 +10,15 @@
#pragma once
#include "app/cmd.h"
#include "app/cmd/remove_cel.h"
#include "app/cmd/with_cel.h"
#include "doc/color.h"
#include "gfx/rect.h"
namespace doc {
class Cel;
}
namespace app {
namespace cmd {
class TrimCel : public Cmd
, public WithCel {
class TrimCel : public Cmd {
public:
TrimCel(doc::Cel* cel);
@ -28,17 +27,11 @@ namespace cmd {
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) +
(m_removeCel ? m_removeCel->memSize() : 0);
return sizeof(*this) + m_subCmd->memSize();
}
private:
void cropImage(const gfx::Rect& bounds);
gfx::Rect m_bounds;
gfx::Rect m_originalBounds;
doc::color_t m_color;
RemoveCel* m_removeCel;
Cmd* m_subCmd;
};
} // namespace cmd