| 1 | // Aseprite Document Library | 
|---|
| 2 | // Copyright (c) 2020 Igara Studio S.A. | 
|---|
| 3 | // Copyright (c) 2001-2018 David Capello | 
|---|
| 4 | // | 
|---|
| 5 | // This file is released under the terms of the MIT license. | 
|---|
| 6 | // Read LICENSE.txt for more information. | 
|---|
| 7 |  | 
|---|
| 8 | #ifndef DOC_MASK_H_INCLUDED | 
|---|
| 9 | #define DOC_MASK_H_INCLUDED | 
|---|
| 10 | #pragma once | 
|---|
| 11 |  | 
|---|
| 12 | #include "doc/image.h" | 
|---|
| 13 | #include "doc/image_buffer.h" | 
|---|
| 14 | #include "doc/image_ref.h" | 
|---|
| 15 | #include "doc/object.h" | 
|---|
| 16 | #include "doc/primitives.h" | 
|---|
| 17 | #include "gfx/rect.h" | 
|---|
| 18 |  | 
|---|
| 19 | #include <string> | 
|---|
| 20 |  | 
|---|
| 21 | namespace doc { | 
|---|
| 22 |  | 
|---|
| 23 | // Represents the selection (selected pixels, 0/1, 0=non-selected, 1=selected) | 
|---|
| 24 | // | 
|---|
| 25 | // TODO rename Mask -> Selection | 
|---|
| 26 | class Mask : public Object { | 
|---|
| 27 | public: | 
|---|
| 28 | Mask(); | 
|---|
| 29 | Mask(const Mask& mask); | 
|---|
| 30 | virtual ~Mask(); | 
|---|
| 31 |  | 
|---|
| 32 | virtual int getMemSize() const override; | 
|---|
| 33 |  | 
|---|
| 34 | void setName(const char *name); | 
|---|
| 35 | const std::string& name() const { return m_name; } | 
|---|
| 36 |  | 
|---|
| 37 | const Image* bitmap() const { return m_bitmap.get(); } | 
|---|
| 38 | Image* bitmap() { return m_bitmap.get(); } | 
|---|
| 39 |  | 
|---|
| 40 | // Returns true if the mask is completely empty (i.e. nothing | 
|---|
| 41 | // selected) | 
|---|
| 42 | bool isEmpty() const { | 
|---|
| 43 | return (!m_bitmap ? true: false); | 
|---|
| 44 | } | 
|---|
| 45 |  | 
|---|
| 46 | // Returns true if the point is inside the mask | 
|---|
| 47 | bool containsPoint(int u, int v) const { | 
|---|
| 48 | return (m_bitmap.get() && | 
|---|
| 49 | u >= m_bounds.x && u < m_bounds.x+m_bounds.w && | 
|---|
| 50 | v >= m_bounds.y && v < m_bounds.y+m_bounds.h && | 
|---|
| 51 | get_pixel(m_bitmap.get(), u-m_bounds.x, v-m_bounds.y)); | 
|---|
| 52 | } | 
|---|
| 53 |  | 
|---|
| 54 | gfx::Point origin() const { return m_bounds.origin(); } | 
|---|
| 55 | const gfx::Rect& bounds() const { return m_bounds; } | 
|---|
| 56 |  | 
|---|
| 57 | void setOrigin(int x, int y) { | 
|---|
| 58 | m_bounds.x = x; | 
|---|
| 59 | m_bounds.y = y; | 
|---|
| 60 | } | 
|---|
| 61 |  | 
|---|
| 62 | // These functions can be used to disable the automatic call to | 
|---|
| 63 | // "shrink" method (so you can do a lot of modifications without | 
|---|
| 64 | // lossing time shrinking the mask in each little operation). | 
|---|
| 65 | void freeze(); | 
|---|
| 66 | void unfreeze(); | 
|---|
| 67 |  | 
|---|
| 68 | // Returns true if the mask is frozen (See freeze/unfreeze functions). | 
|---|
| 69 | bool isFrozen() const { return m_freeze_count > 0; } | 
|---|
| 70 |  | 
|---|
| 71 | // Returns true if the mask is a rectangular region. | 
|---|
| 72 | bool isRectangular() const; | 
|---|
| 73 |  | 
|---|
| 74 | // Clears the mask. | 
|---|
| 75 | void clear(); | 
|---|
| 76 |  | 
|---|
| 77 | // Copies the data from the given mask. | 
|---|
| 78 | void copyFrom(const Mask* sourceMask); | 
|---|
| 79 |  | 
|---|
| 80 | // Replace the whole mask with the given region. | 
|---|
| 81 | void replace(const gfx::Rect& bounds); | 
|---|
| 82 | void replace(const doc::Mask& sourceMask) { copyFrom(&sourceMask); } | 
|---|
| 83 |  | 
|---|
| 84 | // Inverts the mask. | 
|---|
| 85 | void invert(); | 
|---|
| 86 |  | 
|---|
| 87 | void add(const doc::Mask& mask); | 
|---|
| 88 | void subtract(const doc::Mask& mask); | 
|---|
| 89 | void intersect(const doc::Mask& mask); | 
|---|
| 90 |  | 
|---|
| 91 | void add(const gfx::Rect& bounds); | 
|---|
| 92 | void subtract(const gfx::Rect& bounds); | 
|---|
| 93 | void intersect(const gfx::Rect& bounds); | 
|---|
| 94 |  | 
|---|
| 95 | void byColor(const Image* image, int color, int fuzziness); | 
|---|
| 96 | void crop(const Image* image); | 
|---|
| 97 |  | 
|---|
| 98 | // Reserves a rectangle to draw onto the bitmap (you should call | 
|---|
| 99 | // shrink after you draw in the bitmap) | 
|---|
| 100 | void reserve(const gfx::Rect& bounds); | 
|---|
| 101 |  | 
|---|
| 102 | // Shrinks all sides of the mask to the minimum possible looking at | 
|---|
| 103 | // empty pixels in the bitmap | 
|---|
| 104 | void shrink(); | 
|---|
| 105 |  | 
|---|
| 106 | // Displaces the mask bounds origin point. | 
|---|
| 107 | void offsetOrigin(int dx, int dy); | 
|---|
| 108 |  | 
|---|
| 109 | private: | 
|---|
| 110 | void initialize(); | 
|---|
| 111 |  | 
|---|
| 112 | int m_freeze_count; | 
|---|
| 113 | std::string m_name;           // Mask name | 
|---|
| 114 | gfx::Rect m_bounds;           // Region bounds | 
|---|
| 115 | ImageRef m_bitmap;            // Bitmapped image mask | 
|---|
| 116 | ImageBufferPtr m_buffer;      // Buffer used in m_bitmap | 
|---|
| 117 |  | 
|---|
| 118 | Mask& operator=(const Mask& mask); | 
|---|
| 119 | }; | 
|---|
| 120 |  | 
|---|
| 121 | } // namespace doc | 
|---|
| 122 |  | 
|---|
| 123 | #endif | 
|---|
| 124 |  | 
|---|