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
24namespace doc {
25 class Cel;
26 class Image;
27 class Layer;
28 class Sprite;
29 class Tileset;
30}
31
32namespace 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