1// Aseprite
2// Copyright (C) 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/patch_cel.h"
13
14#include "app/cmd/copy_region.h"
15#include "app/cmd/crop_cel.h"
16#include "app/cmd/trim_cel.h"
17#include "doc/cel.h"
18#include "doc/layer_tilemap.h"
19
20namespace app {
21namespace cmd {
22
23using namespace doc;
24
25PatchCel::PatchCel(doc::Cel* dstCel,
26 const doc::Image* patch,
27 const gfx::Region& patchedRegion,
28 const gfx::Point& patchPos)
29 : WithCel(dstCel)
30 , m_patch(patch)
31 , m_region(patchedRegion)
32 , m_pos(patchPos)
33{
34 ASSERT(!patchedRegion.isEmpty());
35}
36
37void PatchCel::onExecute()
38{
39 Cel* cel = this->cel();
40
41 gfx::Rect newBounds;
42 gfx::Region regionInTiles;
43 doc::Grid grid;
44 if (cel->image()->pixelFormat() == IMAGE_TILEMAP) {
45 newBounds = cel->bounds() | m_region.bounds();
46 auto tileset = static_cast<LayerTilemap*>(cel->layer())->tileset();
47 grid = tileset->grid();
48 grid.origin(m_pos);
49 regionInTiles = grid.canvasToTile(m_region);
50 }
51 else {
52 newBounds = cel->bounds() | gfx::Rect(m_region.bounds()).offset(m_pos);
53 }
54
55 if (cel->bounds() != newBounds)
56 executeAndAdd(new CropCel(cel, newBounds));
57
58 if (cel->image()->pixelFormat() == IMAGE_TILEMAP) {
59 executeAndAdd(
60 new CopyRegion(cel->image(),
61 m_patch,
62 regionInTiles,
63 -grid.canvasToTile(cel->position())));
64 }
65 else {
66 executeAndAdd(
67 new CopyRegion(cel->image(),
68 m_patch,
69 m_region,
70 m_pos - cel->position()));
71 }
72
73 executeAndAdd(new TrimCel(cel));
74
75 m_patch = nullptr;
76}
77
78} // namespace cmd
79} // namespace app
80