1 | // [Blend2D] |
2 | // 2D Vector Graphics Powered by a JIT Compiler. |
3 | // |
4 | // [License] |
5 | // Zlib - See LICENSE.md file in the package. |
6 | |
7 | #ifndef BLEND2D_BLPATTERN_H |
8 | #define BLEND2D_BLPATTERN_H |
9 | |
10 | #include "./blgeometry.h" |
11 | #include "./blimage.h" |
12 | #include "./blmatrix.h" |
13 | #include "./blvariant.h" |
14 | |
15 | //! \addtogroup blend2d_api_styling |
16 | //! \{ |
17 | |
18 | // ============================================================================ |
19 | // [BLPattern - Core] |
20 | // ============================================================================ |
21 | |
22 | //! Pattern [C Interface - Impl]. |
23 | struct BLPatternImpl { |
24 | //! Image used by the pattern. |
25 | BL_TYPED_MEMBER(BLImageCore, BLImage, image); |
26 | //! Reserved, must be null. |
27 | void* [2]; |
28 | |
29 | //! Reference count. |
30 | volatile size_t refCount; |
31 | //! Impl type. |
32 | uint8_t implType; |
33 | //! Impl traits. |
34 | uint8_t implTraits; |
35 | //! Memory pool data. |
36 | uint16_t memPoolData; |
37 | |
38 | //! Reserved, must be zero. |
39 | uint8_t patternType; |
40 | //! Pattern extend mode, see `BLExtendMode`. |
41 | uint8_t extendMode; |
42 | //! Type of the transformation matrix. |
43 | uint8_t matrixType; |
44 | //! Reserved, must be zero. |
45 | uint8_t reserved[1]; |
46 | |
47 | //! Pattern transformation matrix. |
48 | BLMatrix2D matrix; |
49 | //! Image area to use. |
50 | BLRectI area; |
51 | |
52 | BL_HAS_TYPED_MEMBERS(BLPatternImpl) |
53 | }; |
54 | |
55 | //! Pattern [C Interface - Core]. |
56 | struct BLPatternCore { |
57 | BLPatternImpl* impl; |
58 | }; |
59 | |
60 | // ============================================================================ |
61 | // [BLPattern - C++] |
62 | // ============================================================================ |
63 | |
64 | #ifdef __cplusplus |
65 | //! Pattern [C++ API]. |
66 | class BLPattern : public BLPatternCore { |
67 | public: |
68 | //! \cond INTERNAL |
69 | static constexpr const uint32_t kImplType = BL_IMPL_TYPE_PATTERN; |
70 | //! \endcond |
71 | |
72 | //! \name Construction & Destruction |
73 | //! \{ |
74 | |
75 | BL_INLINE BLPattern() noexcept { this->impl = none().impl; } |
76 | BL_INLINE BLPattern(BLPattern&& other) noexcept { blVariantInitMove(this, &other); } |
77 | BL_INLINE BLPattern(const BLPattern& other) noexcept { blVariantInitWeak(this, &other); } |
78 | BL_INLINE explicit BLPattern(BLPatternImpl* impl) noexcept { this->impl = impl; } |
79 | |
80 | BL_INLINE explicit BLPattern(const BLImage& image, uint32_t extendMode = BL_EXTEND_MODE_REPEAT) noexcept { |
81 | blPatternInitAs(this, &image, nullptr, extendMode, nullptr); |
82 | } |
83 | |
84 | BL_INLINE BLPattern(const BLImage& image, uint32_t extendMode, const BLMatrix2D& m) noexcept { |
85 | blPatternInitAs(this, &image, nullptr, extendMode, &m); |
86 | } |
87 | |
88 | BL_INLINE BLPattern(const BLImage& image, const BLRectI& area, uint32_t extendMode = BL_EXTEND_MODE_REPEAT) noexcept { |
89 | blPatternInitAs(this, &image, &area, extendMode, nullptr); |
90 | } |
91 | |
92 | BL_INLINE BLPattern(const BLImage& image, const BLRectI& area, uint32_t extendMode, const BLMatrix2D& m) noexcept { |
93 | blPatternInitAs(this, &image, &area, extendMode, &m); |
94 | } |
95 | |
96 | BL_INLINE ~BLPattern() noexcept { blPatternReset(this); } |
97 | |
98 | //! \} |
99 | |
100 | //! \name Overloaded Operators |
101 | //! \{ |
102 | |
103 | BL_INLINE BLPattern& operator=(BLPattern&& other) noexcept { blPatternAssignMove(this, &other); return *this; } |
104 | BL_INLINE BLPattern& operator=(const BLPattern& other) noexcept { blPatternAssignWeak(this, &other); return *this; } |
105 | |
106 | BL_INLINE bool operator==(const BLPattern& other) const noexcept { return equals(other); } |
107 | BL_INLINE bool operator!=(const BLPattern& other) const noexcept { return !equals(other); } |
108 | |
109 | //! \} |
110 | |
111 | //! \name Common Functionality |
112 | //! \{ |
113 | |
114 | BL_INLINE BLResult reset() noexcept { return blPatternReset(this); } |
115 | |
116 | BL_INLINE void swap(BLPattern& other) noexcept { std::swap(this->impl, other.impl); } |
117 | |
118 | BL_INLINE BLResult assign(BLPattern&& other) noexcept { return blPatternAssignMove(this, &other); } |
119 | BL_INLINE BLResult assign(const BLPattern& other) noexcept { return blPatternAssignWeak(this, &other); } |
120 | |
121 | //! Tests whether the pattern is a built-in null instance. |
122 | BL_INLINE bool isNone() const noexcept { return (impl->implTraits & BL_IMPL_TRAIT_NULL) != 0; } |
123 | |
124 | BL_INLINE bool equals(const BLPattern& other) const noexcept { return blPatternEquals(this, &other); } |
125 | |
126 | //! \} |
127 | |
128 | //! \name Create Pattern |
129 | //! \{ |
130 | |
131 | BL_INLINE BLResult create(const BLImage& image, uint32_t extendMode = BL_EXTEND_MODE_REPEAT) noexcept { |
132 | return blPatternCreate(this, &image, nullptr, extendMode, nullptr); |
133 | } |
134 | |
135 | BL_INLINE BLResult create(const BLImage& image, uint32_t extendMode, const BLMatrix2D& m) noexcept { |
136 | return blPatternCreate(this, &image, nullptr, extendMode, &m); |
137 | } |
138 | |
139 | BL_INLINE BLResult create(const BLImage& image, const BLRectI& area, uint32_t extendMode = BL_EXTEND_MODE_REPEAT) noexcept { |
140 | return blPatternCreate(this, &image, &area, extendMode, nullptr); |
141 | } |
142 | |
143 | BL_INLINE BLResult create(const BLImage& image, const BLRectI& area, uint32_t extendMode, const BLMatrix2D& m) noexcept { |
144 | return blPatternCreate(this, &image, &area, extendMode, &m); |
145 | } |
146 | |
147 | //! \} |
148 | |
149 | //! \name Pattern Source |
150 | //! \{ |
151 | |
152 | BL_INLINE const BLImage& image() const noexcept { return impl->image; } |
153 | BL_INLINE BLResult setImage(const BLImage& image) noexcept { return blPatternSetImage(this, &image, nullptr); } |
154 | BL_INLINE BLResult setImage(const BLImage& image, const BLRectI& area) noexcept { return blPatternSetImage(this, &image, &area); } |
155 | BL_INLINE BLResult resetImage() noexcept { return setImage(BLImage::none()); } |
156 | |
157 | BL_INLINE const BLRectI& area() const noexcept { return impl->area; } |
158 | BL_INLINE BLResult setArea(const BLRectI& area) noexcept { return blPatternSetArea(this, &area); } |
159 | BL_INLINE BLResult resetArea() noexcept { return setArea(BLRectI(0, 0, 0, 0)); } |
160 | |
161 | //! \} |
162 | |
163 | //! \name Pattern Options |
164 | //! \{ |
165 | |
166 | BL_INLINE uint32_t extendMode() const noexcept { return impl->extendMode; } |
167 | BL_INLINE BLResult setExtendMode(uint32_t extendMode) noexcept { return blPatternSetExtendMode(this, extendMode); } |
168 | BL_INLINE BLResult resetExtendMode() noexcept { return setExtendMode(BL_EXTEND_MODE_REPEAT); } |
169 | |
170 | //! \} |
171 | |
172 | //! \name Transformations |
173 | //! \{ |
174 | |
175 | BL_INLINE bool hasMatrix() const noexcept { return impl->matrixType != BL_MATRIX2D_TYPE_IDENTITY; } |
176 | BL_INLINE uint32_t matrixType() const noexcept { return impl->matrixType; } |
177 | BL_INLINE const BLMatrix2D& matrix() const noexcept { return impl->matrix; } |
178 | |
179 | //! Applies a matrix operation to the current transformation matrix (internal). |
180 | BL_INLINE BLResult _applyMatrixOp(uint32_t opType, const void* opData) noexcept { |
181 | return blPatternApplyMatrixOp(this, opType, opData); |
182 | } |
183 | |
184 | //! \cond INTERNAL |
185 | //! Applies a matrix operation to the current transformation matrix (internal). |
186 | template<typename... Args> |
187 | BL_INLINE BLResult _applyMatrixOpV(uint32_t opType, Args&&... args) noexcept { |
188 | double opData[] = { double(args)... }; |
189 | return blPatternApplyMatrixOp(this, opType, opData); |
190 | } |
191 | //! \endcond |
192 | |
193 | BL_INLINE BLResult setMatrix(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_ASSIGN, &m); } |
194 | BL_INLINE BLResult resetMatrix() noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_RESET, nullptr); } |
195 | |
196 | BL_INLINE BLResult translate(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_TRANSLATE, x, y); } |
197 | BL_INLINE BLResult translate(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_TRANSLATE, p.x, p.y); } |
198 | BL_INLINE BLResult translate(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_TRANSLATE, &p); } |
199 | BL_INLINE BLResult scale(double xy) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, xy, xy); } |
200 | BL_INLINE BLResult scale(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, x, y); } |
201 | BL_INLINE BLResult scale(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, p.x, p.y); } |
202 | BL_INLINE BLResult scale(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_SCALE, &p); } |
203 | BL_INLINE BLResult skew(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SKEW, x, y); } |
204 | BL_INLINE BLResult skew(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_SKEW, &p); } |
205 | BL_INLINE BLResult rotate(double angle) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_ROTATE, &angle); } |
206 | BL_INLINE BLResult rotate(double angle, double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, x, y); } |
207 | BL_INLINE BLResult rotate(double angle, const BLPoint& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, p.x, p.y); } |
208 | BL_INLINE BLResult rotate(double angle, const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, p.x, p.y); } |
209 | BL_INLINE BLResult transform(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_TRANSFORM, &m); } |
210 | |
211 | BL_INLINE BLResult postTranslate(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_TRANSLATE, x, y); } |
212 | BL_INLINE BLResult postTranslate(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_TRANSLATE, p.x, p.y); } |
213 | BL_INLINE BLResult postTranslate(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_TRANSLATE, &p); } |
214 | BL_INLINE BLResult postScale(double xy) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, xy, xy); } |
215 | BL_INLINE BLResult postScale(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, x, y); } |
216 | BL_INLINE BLResult postScale(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, p.x, p.y); } |
217 | BL_INLINE BLResult postScale(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_SCALE, &p); } |
218 | BL_INLINE BLResult postSkew(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SKEW, x, y); } |
219 | BL_INLINE BLResult postSkew(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_SKEW, &p); } |
220 | BL_INLINE BLResult postRotate(double angle) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_ROTATE, &angle); } |
221 | BL_INLINE BLResult postRotate(double angle, double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, x, y); } |
222 | BL_INLINE BLResult postRotate(double angle, const BLPoint& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, p.x, p.y); } |
223 | BL_INLINE BLResult postRotate(double angle, const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, p.x, p.y); } |
224 | BL_INLINE BLResult postTransform(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_TRANSFORM, &m); } |
225 | |
226 | //! \} |
227 | |
228 | static BL_INLINE const BLPattern& none() noexcept { return reinterpret_cast<const BLPattern*>(blNone)[kImplType]; } |
229 | }; |
230 | #endif |
231 | |
232 | //! \} |
233 | |
234 | #endif // BLEND2D_BLPATTERN_H |
235 | |