1 // Aseprite
2 // Copyright (C) 2001-2015 David Capello
3 //
4 // This program is distributed under the terms of
5 // the End-User License Agreement for Aseprite.
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include "app/cmd/copy_rect.h"
12
13 #include "doc/image.h"
14
15 #include <algorithm>
16
17 namespace app {
18 namespace cmd {
19
CopyRect(Image * dst,const Image * src,const gfx::Clip & clip)20 CopyRect::CopyRect(Image* dst, const Image* src, const gfx::Clip& clip)
21 : WithImage(dst)
22 , m_clip(clip)
23 {
24 if (!m_clip.clip(
25 dst->width(), dst->height(),
26 src->width(), src->height()))
27 return;
28
29 // Fill m_data with "src" data
30
31 int lineSize = src->getRowStrideSize(m_clip.size.w);
32 m_data.resize(lineSize * m_clip.size.h);
33
34 auto it = m_data.begin();
35 for (int v=0; v<m_clip.size.h; ++v) {
36 uint8_t* addr = src->getPixelAddress(
37 m_clip.dst.x, m_clip.dst.y+v);
38
39 std::copy(addr, addr+lineSize, it);
40 it += lineSize;
41 }
42 }
43
onExecute()44 void CopyRect::onExecute()
45 {
46 swap();
47 }
48
onUndo()49 void CopyRect::onUndo()
50 {
51 swap();
52 }
53
onRedo()54 void CopyRect::onRedo()
55 {
56 swap();
57 }
58
swap()59 void CopyRect::swap()
60 {
61 if (m_clip.size.w < 1 || m_clip.size.h < 1)
62 return;
63
64 Image* image = this->image();
65 int lineSize = this->lineSize();
66 std::vector<uint8_t> tmp(lineSize);
67
68 auto it = m_data.begin();
69 for (int v=0; v<m_clip.size.h; ++v) {
70 uint8_t* addr = image->getPixelAddress(
71 m_clip.dst.x, m_clip.dst.y+v);
72
73 std::copy(addr, addr+lineSize, tmp.begin());
74 std::copy(it, it+lineSize, addr);
75 std::copy(tmp.begin(), tmp.end(), it);
76
77 it += lineSize;
78 }
79
80 image->incrementVersion();
81 }
82
lineSize()83 int CopyRect::lineSize()
84 {
85 return image()->getRowStrideSize(m_clip.size.w);
86 }
87
88 } // namespace cmd
89 } // namespace app
90