1 | // Aseprite |
2 | // Copyright (C) 2019-2021 Igara Studio S.A. |
3 | // Copyright (C) 2001-2018 David Capello |
4 | // |
5 | // This program is distributed under the terms of |
6 | // the End-User License Agreement for Aseprite. |
7 | |
8 | #ifndef APP_UTIL_EXPAND_CEL_CANVAS_H_INCLUDED |
9 | #define APP_UTIL_EXPAND_CEL_CANVAS_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "app/tilemap_mode.h" |
13 | #include "app/tileset_mode.h" |
14 | #include "doc/frame.h" |
15 | #include "doc/grid.h" |
16 | #include "doc/image_ref.h" |
17 | #include "doc/layer.h" |
18 | #include "filters/tiled_mode.h" |
19 | #include "gfx/point.h" |
20 | #include "gfx/rect.h" |
21 | #include "gfx/region.h" |
22 | #include "gfx/size.h" |
23 | |
24 | namespace doc { |
25 | class Cel; |
26 | class Image; |
27 | class Layer; |
28 | class Sprite; |
29 | class Tileset; |
30 | } |
31 | |
32 | namespace app { |
33 | class CmdSequence; |
34 | class Doc; |
35 | class Site; |
36 | |
37 | using namespace filters; |
38 | using namespace doc; |
39 | |
40 | // This class can be used to expand the canvas of the current cel to |
41 | // the visible portion of sprite. If the user cancels the operation, |
42 | // you've a rollback() method to restore the cel to its original |
43 | // state. If all changes are committed, some undo information is |
44 | // stored in the document's UndoHistory to go back to the original |
45 | // state using "Undo" command. |
46 | class ExpandCelCanvas { |
47 | public: |
48 | enum Flags { |
49 | None = 0, |
50 | NeedsSource = 1, |
51 | // Use tiles mode but with pixels bounds in dst image (e.g. for |
52 | // selection preview) |
53 | PixelsBounds = 2, |
54 | // True if you want to preview the changes in the tileset. Only |
55 | // useful in TilesetMode::Manual mode when editing tiles in a |
56 | // tilemap. See getDestTileset() for details. |
57 | TilesetPreview = 4, |
58 | // Enable when we are going to use the expanded cel canvas for |
59 | // preview purposes of a selection tools. |
60 | SelectionPreview = 8, |
61 | }; |
62 | |
63 | ExpandCelCanvas(Site site, Layer* layer, |
64 | const TiledMode tiledMode, |
65 | CmdSequence* cmds, |
66 | const Flags flags); |
67 | ~ExpandCelCanvas(); |
68 | |
69 | // Commit changes made in getDestCanvas() in the cel's image. Adds |
70 | // information in the undo history so the user can undo the |
71 | // modifications in the canvas. |
72 | void commit(); |
73 | |
74 | // Restore the cel as its original state as when ExpandCelCanvas() |
75 | // was created. |
76 | void rollback(); |
77 | |
78 | gfx::Point getCelOrigin() const; |
79 | |
80 | Image* getSourceCanvas(); // You can read pixels from here |
81 | Image* getDestCanvas(); // You can write pixels right here |
82 | |
83 | Tileset* getDestTileset(); // You can use this as a preview-tileset |
84 | // when the user is editing in "Manual" mode |
85 | |
86 | void validateSourceCanvas(const gfx::Region& rgn); |
87 | void validateDestCanvas(const gfx::Region& rgn); |
88 | void validateDestTileset(const gfx::Region& rgn, const gfx::Region& forceRgn); |
89 | void invalidateDestCanvas(); |
90 | void invalidateDestCanvas(const gfx::Region& rgn); |
91 | void copyValidDestToSourceCanvas(const gfx::Region& rgn); |
92 | |
93 | const Cel* getCel() const { return m_cel; } |
94 | const doc::Grid& getGrid() const { return m_grid; } |
95 | |
96 | private: |
97 | gfx::Rect getTrimDstImageBounds() const; |
98 | ImageRef trimDstImage(const gfx::Rect& bounds) const; |
99 | void copySourceTilestToDestTileset(); |
100 | |
101 | bool isTilesetPreview() const { |
102 | return ((m_flags & TilesetPreview) == TilesetPreview); |
103 | } |
104 | |
105 | bool isSelectionPreview() const { |
106 | return ((m_flags & SelectionPreview) == SelectionPreview); |
107 | } |
108 | |
109 | // This is the common case where we want to preview a change in |
110 | // the given layer of ExpandCelCanvas ctor. |
111 | bool previewSpecificLayerChanges() const { |
112 | return (m_layer && |
113 | m_layer->isImage() && |
114 | !isSelectionPreview()); |
115 | } |
116 | |
117 | Doc* m_document; |
118 | Sprite* m_sprite; |
119 | Layer* m_layer; |
120 | frame_t m_frame; |
121 | Cel* m_cel; |
122 | ImageRef m_celImage; |
123 | bool m_celCreated; |
124 | gfx::Point m_origCelPos; |
125 | Flags m_flags; |
126 | gfx::Rect m_bounds; |
127 | ImageRef m_srcImage; |
128 | ImageRef m_dstImage; |
129 | std::unique_ptr<Tileset> m_dstTileset; |
130 | bool m_closed; |
131 | bool m_committed; |
132 | CmdSequence* m_cmds; |
133 | gfx::Region m_validSrcRegion; |
134 | gfx::Region m_validDstRegion; |
135 | |
136 | // True if we can compare src image with dst image to patch the |
137 | // cel. This is false when dst is copied to the src, so we cannot |
138 | // reduce the patched region because both images will be the same. |
139 | bool m_canCompareSrcVsDst; |
140 | |
141 | doc::Grid m_grid; |
142 | TilemapMode m_tilemapMode; |
143 | TilesetMode m_tilesetMode; |
144 | }; |
145 | |
146 | } // namespace app |
147 | |
148 | #endif |
149 | |