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].
23struct BLPatternImpl {
24 //! Image used by the pattern.
25 BL_TYPED_MEMBER(BLImageCore, BLImage, image);
26 //! Reserved, must be null.
27 void* reservedHeader[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].
56struct BLPatternCore {
57 BLPatternImpl* impl;
58};
59
60// ============================================================================
61// [BLPattern - C++]
62// ============================================================================
63
64#ifdef __cplusplus
65//! Pattern [C++ API].
66class BLPattern : public BLPatternCore {
67public:
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