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