1// Aseprite
2// Copyright (C) 2019-2020 Igara Studio S.A.
3// Copyright (C) 2001-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/copy_region.h"
13
14#include "app/doc.h"
15#include "app/util/buffer_region.h"
16#include "doc/image.h"
17#include "doc/sprite.h"
18#include "doc/tileset.h"
19
20namespace app {
21namespace cmd {
22
23CopyRegion::CopyRegion(Image* dst, const Image* src,
24 const gfx::Region& region,
25 const gfx::Point& dstPos,
26 bool alreadyCopied)
27 : WithImage(dst)
28 , m_alreadyCopied(alreadyCopied)
29{
30 ASSERT(!region.isEmpty());
31
32 gfx::Rect rc = region.bounds();
33 gfx::Clip clip(
34 rc.x+dstPos.x, rc.y+dstPos.y,
35 rc.x, rc.y, rc.w, rc.h);
36 if (clip.clip(
37 dst->width(), dst->height(),
38 src->width(), src->height())) {
39 // Create region to save/swap later
40 m_region = region;
41 m_region.offset(dstPos);
42 m_region &= gfx::Region(clip.dstBounds());
43 }
44
45 save_image_region_in_buffer(m_region, src, dstPos, m_buffer);
46}
47
48CopyTileRegion::CopyTileRegion(Image* dst, const Image* src,
49 const gfx::Region& region,
50 const gfx::Point& dstPos,
51 bool alreadyCopied,
52 const doc::tile_index tileIndex,
53 const doc::Tileset* tileset)
54 : CopyRegion(dst, src, region, dstPos, alreadyCopied)
55 , m_tileIndex(tileIndex)
56 , m_tilesetId(tileset ? tileset->id(): NullId)
57{
58}
59
60void CopyRegion::onExecute()
61{
62 if (!m_alreadyCopied)
63 swap();
64}
65
66void CopyRegion::onUndo()
67{
68 swap();
69}
70
71void CopyRegion::onRedo()
72{
73 swap();
74}
75
76void CopyRegion::swap()
77{
78 Image* image = this->image();
79 ASSERT(image);
80
81 swap_image_region_with_buffer(m_region, image, m_buffer);
82 image->incrementVersion();
83
84 rehash();
85}
86
87void CopyTileRegion::rehash()
88{
89 ASSERT(m_tileIndex != notile);
90 ASSERT(m_tilesetId != NullId);
91 if (m_tilesetId != NullId) {
92 auto tileset = get<Tileset>(m_tilesetId);
93 ASSERT(tileset);
94 if (tileset) {
95 tileset->incrementVersion();
96 tileset->notifyTileContentChange(m_tileIndex);
97
98 // Notify that the tileset changed
99 static_cast<Doc*>(tileset->sprite()->document())
100 ->notifyTilesetChanged(tileset);
101 }
102 }
103}
104
105} // namespace cmd
106} // namespace app
107