1 // Aseprite
2 // Copyright (C) 2001-2018  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/clear_mask.h"
12 
13 #include "app/cmd/clear_cel.h"
14 #include "app/doc.h"
15 #include "doc/algorithm/fill_selection.h"
16 #include "doc/cel.h"
17 #include "doc/image_impl.h"
18 #include "doc/layer.h"
19 #include "doc/mask.h"
20 #include "doc/primitives.h"
21 
22 namespace app {
23 namespace cmd {
24 
25 using namespace doc;
26 
ClearMask(Cel * cel)27 ClearMask::ClearMask(Cel* cel)
28   : WithCel(cel)
29 {
30   Doc* doc = static_cast<Doc*>(cel->document());
31 
32   // If the mask is empty or is not visible then we have to clear the
33   // entire image in the cel.
34   if (!doc->isMaskVisible()) {
35     m_seq.add(new cmd::ClearCel(cel));
36     return;
37   }
38 
39   Image* image = cel->image();
40   assert(image);
41   if (!image)
42     return;
43 
44   Mask* mask = doc->mask();
45   m_offset = mask->bounds().origin() - cel->position();
46 
47   gfx::Rect bounds =
48     image->bounds().createIntersection(
49       gfx::Rect(
50         m_offset.x, m_offset.y,
51         mask->bounds().w, mask->bounds().h));
52   if (bounds.isEmpty())
53     return;
54 
55   m_dstImage.reset(new WithImage(image));
56   m_bgcolor = doc->bgColor(cel->layer());
57   m_boundsX = bounds.x;
58   m_boundsY = bounds.y;
59 
60   m_copy.reset(crop_image(image,
61       bounds.x, bounds.y, bounds.w, bounds.h, m_bgcolor));
62 }
63 
onExecute()64 void ClearMask::onExecute()
65 {
66   m_seq.execute(context());
67   if (m_dstImage)
68     clear();
69 }
70 
onUndo()71 void ClearMask::onUndo()
72 {
73   if (m_dstImage)
74     restore();
75   m_seq.undo();
76 }
77 
onRedo()78 void ClearMask::onRedo()
79 {
80   m_seq.redo();
81   if (m_dstImage)
82     clear();
83 }
84 
clear()85 void ClearMask::clear()
86 {
87   Cel* cel = this->cel();
88   Image* image = m_dstImage->image();
89   Doc* doc = static_cast<Doc*>(cel->document());
90   Mask* mask = doc->mask();
91 
92   doc::algorithm::fill_selection(image, m_offset, mask, m_bgcolor);
93 }
94 
restore()95 void ClearMask::restore()
96 {
97   copy_image(m_dstImage->image(), m_copy.get(), m_boundsX, m_boundsY);
98 }
99 
100 } // namespace cmd
101 } // namespace app
102