1// Aseprite
2// Copyright (C) 2019-2020 Igara Studio S.A.
3// Copyright (C) 2016 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "app/cmd/crop_cel.h"
13
14#include "doc/cel.h"
15#include "doc/layer.h"
16#include "doc/layer_tilemap.h"
17#include "doc/primitives.h"
18
19namespace app {
20namespace cmd {
21
22using namespace doc;
23
24CropCel::CropCel(Cel* cel, const gfx::Rect& newBounds)
25 : WithCel(cel)
26 , m_oldOrigin(cel->position())
27 , m_newOrigin(newBounds.origin())
28 , m_oldBounds(cel->bounds())
29 , m_newBounds(newBounds)
30{
31 m_oldBounds.offset(-m_newOrigin);
32 m_newBounds.offset(-m_oldOrigin);
33
34 ASSERT(m_newBounds != m_oldBounds);
35}
36
37void CropCel::onExecute()
38{
39 cropImage(m_newOrigin, m_newBounds);
40}
41
42void CropCel::onUndo()
43{
44 cropImage(m_oldOrigin, m_oldBounds);
45}
46
47// Crops the cel image leaving the same ID in the image.
48void CropCel::cropImage(const gfx::Point& origin,
49 const gfx::Rect& bounds)
50{
51 Cel* cel = this->cel();
52
53 gfx::Rect localBounds(bounds);
54 if (cel->layer()->isTilemap()) {
55 doc::Tileset* tileset = static_cast<LayerTilemap*>(cel->layer())->tileset();
56 if (tileset) {
57 doc::Grid grid = tileset->grid();
58 localBounds = grid.canvasToTile(bounds);
59 }
60 }
61 if (bounds != cel->image()->bounds()) {
62 ImageRef image(crop_image(cel->image(),
63 localBounds.x, localBounds.y,
64 localBounds.w, localBounds.h,
65 cel->image()->maskColor()));
66 ObjectId id = cel->image()->id();
67 ObjectVersion ver = cel->image()->version();
68
69 cel->image()->setId(NullId);
70 image->setId(id);
71 image->setVersion(ver);
72 image->incrementVersion();
73 cel->data()->setImage(image, cel->layer());
74 cel->data()->incrementVersion();
75 }
76
77 if (cel->data()->position() != origin) {
78 cel->data()->setPosition(origin);
79 cel->data()->incrementVersion();
80 }
81}
82
83} // namespace cmd
84} // namespace app
85