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
17namespace app {
18namespace cmd {
19
20CopyRect::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
44void CopyRect::onExecute()
45{
46 swap();
47}
48
49void CopyRect::onUndo()
50{
51 swap();
52}
53
54void CopyRect::onRedo()
55{
56 swap();
57}
58
59void 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
83int CopyRect::lineSize()
84{
85 return image()->getRowStrideSize(m_clip.size.w);
86}
87
88} // namespace cmd
89} // namespace app
90