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_BLGRADIENT_H
8#define BLEND2D_BLGRADIENT_H
9
10#include "./blgeometry.h"
11#include "./blmatrix.h"
12#include "./blrgba.h"
13#include "./blvariant.h"
14
15BL_DIAGNOSTIC_PUSH(BL_DIAGNOSTIC_NO_SHADOW)
16
17//! \addtogroup blend2d_api_styling
18//! \{
19
20// ============================================================================
21// [Constants]
22// ============================================================================
23
24//! Gradient type.
25BL_DEFINE_ENUM(BLGradientType) {
26 //! Linear gradient type.
27 BL_GRADIENT_TYPE_LINEAR = 0,
28 //! Radial gradient type.
29 BL_GRADIENT_TYPE_RADIAL = 1,
30 //! Conical gradient type.
31 BL_GRADIENT_TYPE_CONICAL = 2,
32
33 //! Count of gradient types.
34 BL_GRADIENT_TYPE_COUNT = 3
35};
36
37//! Gradient data index.
38BL_DEFINE_ENUM(BLGradientValue) {
39 //! x0 - start 'x' for Linear/Radial and center 'x' for Conical.
40 BL_GRADIENT_VALUE_COMMON_X0 = 0,
41 //! y0 - start 'y' for Linear/Radial and center 'y' for Conical.
42 BL_GRADIENT_VALUE_COMMON_Y0 = 1,
43 //! x1 - end 'x' for Linear/Radial.
44 BL_GRADIENT_VALUE_COMMON_X1 = 2,
45 //! y1 - end 'y' for Linear/Radial.
46 BL_GRADIENT_VALUE_COMMON_Y1 = 3,
47 //! Radial gradient r0 radius.
48 BL_GRADIENT_VALUE_RADIAL_R0 = 4,
49 //! Conical gradient angle.
50 BL_GRADIENT_VALUE_CONICAL_ANGLE = 2,
51
52 //! Count of gradient values.
53 BL_GRADIENT_VALUE_COUNT = 6
54};
55
56// ============================================================================
57// [BLGradientStop]
58// ============================================================================
59
60//! Defines an `offset` and `rgba` color that us used by `BLGradient` to define
61//! a linear transition between colors.
62struct BLGradientStop {
63 double offset;
64 BLRgba64 rgba;
65
66 // --------------------------------------------------------------------------
67 #ifdef __cplusplus
68 //! \name Construction & Destruction
69 //! \{
70
71 BL_INLINE BLGradientStop() noexcept = default;
72 BL_INLINE BLGradientStop(const BLGradientStop& other) noexcept = default;
73
74 BL_INLINE BLGradientStop(double offset, const BLRgba32& rgba32) noexcept
75 : offset(offset),
76 rgba(rgba32) {}
77
78 BL_INLINE BLGradientStop(double offset, const BLRgba64& rgba64) noexcept
79 : offset(offset),
80 rgba(rgba64) {}
81
82 //! \}
83
84 //! \name Overloaded Operators
85 //! \{
86
87 BL_INLINE bool operator==(const BLGradientStop& other) const noexcept { return equals(other); }
88 BL_INLINE bool operator!=(const BLGradientStop& other) const noexcept { return !equals(other); }
89
90 //! \}
91
92 //! \name Common Functionality
93 //! \{
94
95 BL_INLINE void reset() noexcept {
96 this->offset = 0.0;
97 this->rgba.reset();
98 }
99
100 BL_INLINE void reset(double offset, const BLRgba32& rgba32) noexcept {
101 this->offset = offset;
102 this->rgba.reset(rgba32);
103 }
104
105 BL_INLINE void reset(double offset, const BLRgba64& rgba64) noexcept {
106 this->offset = offset;
107 this->rgba.reset(rgba64);
108 }
109
110 BL_INLINE bool equals(const BLGradientStop& other) const noexcept {
111 return blEquals(this->offset, other.offset) &
112 blEquals(this->rgba , other.rgba ) ;
113 }
114
115 //! \}
116 #endif
117 // --------------------------------------------------------------------------
118};
119
120// ============================================================================
121// [BLLinearGradientValues]
122// ============================================================================
123
124//! Linear gradient values packed into a structure.
125struct BLLinearGradientValues {
126 double x0;
127 double y0;
128 double x1;
129 double y1;
130
131 // --------------------------------------------------------------------------
132 #ifdef __cplusplus
133 //! \name Construction & Destruction
134 //! \{
135
136 BL_INLINE BLLinearGradientValues() noexcept = default;
137 BL_INLINE BLLinearGradientValues(const BLLinearGradientValues& other) noexcept = default;
138
139 BL_INLINE BLLinearGradientValues(double x0, double y0, double x1, double y1) noexcept
140 : x0(x0),
141 y0(y0),
142 x1(x1),
143 y1(y1) {}
144
145 //! \}
146
147 //! \name Common Functionality
148 //! \{
149
150 BL_INLINE void reset() noexcept { memset(this, 0, sizeof(*this)); }
151
152 //! \}
153 #endif
154 // --------------------------------------------------------------------------
155};
156
157// ============================================================================
158// [BLRadialGradientValues]
159// ============================================================================
160
161//! Radial gradient values packed into a structure.
162struct BLRadialGradientValues {
163 double x0;
164 double y0;
165 double x1;
166 double y1;
167 double r0;
168
169 // --------------------------------------------------------------------------
170 #ifdef __cplusplus
171 //! \name Construction & Destruction
172 //! \{
173
174 BL_INLINE BLRadialGradientValues() noexcept = default;
175 BL_INLINE BLRadialGradientValues(const BLRadialGradientValues& other) noexcept = default;
176
177 BL_INLINE BLRadialGradientValues(double x0, double y0, double x1, double y1, double r0) noexcept
178 : x0(x0),
179 y0(y0),
180 x1(x1),
181 y1(y1),
182 r0(r0) {}
183
184 //! \}
185
186 //! \name Common Functionality
187 //! \{
188
189 BL_INLINE void reset() noexcept { memset(this, 0, sizeof(*this)); }
190
191 //! \}
192 #endif
193 // --------------------------------------------------------------------------
194};
195
196// ============================================================================
197// [BLConicalGradientValues]
198// ============================================================================
199
200//! Conical gradient values packed into a structure.
201struct BLConicalGradientValues {
202 double x0;
203 double y0;
204 double angle;
205
206 // --------------------------------------------------------------------------
207 #ifdef __cplusplus
208 //! \name Construction & Destruction
209 //! \{
210
211 BL_INLINE BLConicalGradientValues() noexcept = default;
212 BL_INLINE BLConicalGradientValues(const BLConicalGradientValues& other) noexcept = default;
213
214 BL_INLINE BLConicalGradientValues(double x0, double y0, double angle) noexcept
215 : x0(x0),
216 y0(y0),
217 angle(angle) {}
218
219 //! \}
220
221 //! \name Common Functionality
222 //! \{
223
224 BL_INLINE void reset() noexcept { memset(this, 0, sizeof(*this)); }
225
226 //! \}
227 #endif
228 // --------------------------------------------------------------------------
229};
230
231// ============================================================================
232// [BLGradient - Core]
233// ============================================================================
234
235//! Gradient [C Interface - Impl].
236struct BLGradientImpl {
237 //! Union of either raw `stops` & `size` members or their `view`.
238 union {
239 struct {
240 //! Gradient stop data.
241 BLGradientStop* stops;
242 //! Gradient stop count.
243 size_t size;
244 };
245 #ifdef __cplusplus
246 //! Gradient stop view (C++ only).
247 BLArrayView<BLGradientStop> view;
248 #endif
249 };
250
251 //! Stop capacity.
252 size_t capacity;
253
254 //! Reference count.
255 volatile size_t refCount;
256 //! Impl type.
257 uint8_t implType;
258 //! Impl traits.
259 uint8_t implTraits;
260 //! Memory pool data.
261 uint16_t memPoolData;
262
263 //! Gradient type, see `BLGradientType`.
264 uint8_t gradientType;
265 //! Gradient extend mode, see `BLExtendMode`.
266 uint8_t extendMode;
267 //! Type of the transformation matrix.
268 uint8_t matrixType;
269 //! Reserved, must be zero.
270 uint8_t reserved[1];
271
272 //! Gradient transformation matrix.
273 BLMatrix2D matrix;
274
275 union {
276 //! Gradient values (coordinates, radius, angle).
277 double values[BL_GRADIENT_VALUE_COUNT];
278 //! Linear parameters.
279 BLLinearGradientValues linear;
280 //! Radial parameters.
281 BLRadialGradientValues radial;
282 //! Conical parameters.
283 BLConicalGradientValues conical;
284 };
285};
286
287//! Gradient [C Interface - Core].
288struct BLGradientCore {
289 BLGradientImpl* impl;
290};
291
292// ============================================================================
293// [BLGradient - C++]
294// ============================================================================
295
296#ifdef __cplusplus
297//! Gradient [C++ API].
298class BLGradient : public BLGradientCore {
299public:
300 //! \cond INTERNAL
301 static constexpr const uint32_t kImplType = BL_IMPL_TYPE_GRADIENT;
302 //! \endcond
303
304 //! \name Construction & Destruction
305 //! \{
306
307 BL_INLINE BLGradient() noexcept { this->impl = none().impl; }
308 BL_INLINE BLGradient(BLGradient&& other) noexcept { blVariantInitMove(this, &other); }
309 BL_INLINE BLGradient(const BLGradient& other) noexcept { blVariantInitWeak(this, &other); }
310 BL_INLINE explicit BLGradient(BLGradientImpl* impl) noexcept { this->impl = impl; }
311
312 BL_INLINE explicit BLGradient(uint32_t type, const double* values = nullptr) noexcept {
313 blGradientInitAs(this, type, values, BL_EXTEND_MODE_PAD, nullptr, 0, nullptr);
314 }
315
316 BL_INLINE explicit BLGradient(const BLLinearGradientValues& values, uint32_t extendMode = BL_EXTEND_MODE_PAD) noexcept {
317 blGradientInitAs(this, BL_GRADIENT_TYPE_LINEAR, &values, extendMode, nullptr, 0, nullptr);
318 }
319
320 BL_INLINE explicit BLGradient(const BLRadialGradientValues& values, uint32_t extendMode = BL_EXTEND_MODE_PAD) noexcept {
321 blGradientInitAs(this, BL_GRADIENT_TYPE_RADIAL, &values, extendMode, nullptr, 0, nullptr);
322 }
323
324 BL_INLINE explicit BLGradient(const BLConicalGradientValues& values, uint32_t extendMode = BL_EXTEND_MODE_PAD) noexcept {
325 blGradientInitAs(this, BL_GRADIENT_TYPE_CONICAL, &values, extendMode, nullptr, 0, nullptr);
326 }
327
328 BL_INLINE BLGradient(const BLLinearGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n) noexcept {
329 blGradientInitAs(this, BL_GRADIENT_TYPE_LINEAR, &values, extendMode, stops, n, nullptr);
330 }
331
332 BL_INLINE BLGradient(const BLRadialGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n) noexcept {
333 blGradientInitAs(this, BL_GRADIENT_TYPE_RADIAL, &values, extendMode, stops, n, nullptr);
334 }
335
336 BL_INLINE BLGradient(const BLConicalGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n) noexcept {
337 blGradientInitAs(this, BL_GRADIENT_TYPE_CONICAL, &values, extendMode, stops, n, nullptr);
338 }
339
340 BL_INLINE BLGradient(const BLLinearGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n, const BLMatrix2D& m) noexcept {
341 blGradientInitAs(this, BL_GRADIENT_TYPE_LINEAR, &values, extendMode, stops, n, &m);
342 }
343
344 BL_INLINE BLGradient(const BLRadialGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n, const BLMatrix2D& m) noexcept {
345 blGradientInitAs(this, BL_GRADIENT_TYPE_RADIAL, &values, extendMode, stops, n, &m);
346 }
347
348 BL_INLINE BLGradient(const BLConicalGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n, const BLMatrix2D& m) noexcept {
349 blGradientInitAs(this, BL_GRADIENT_TYPE_CONICAL, &values, extendMode, stops, n, &m);
350 }
351
352 BL_INLINE ~BLGradient() noexcept { blGradientReset(this); }
353
354 //! \}
355
356 //! \name Overloaded Operators
357 //! \{
358
359 BL_INLINE BLGradient& operator=(BLGradient&& other) noexcept { blGradientAssignMove(this, &other); return *this; }
360 BL_INLINE BLGradient& operator=(const BLGradient& other) noexcept { blGradientAssignWeak(this, &other); return *this; }
361
362 BL_INLINE bool operator==(const BLGradient& other) const noexcept { return blGradientEquals(this, &other); }
363 BL_INLINE bool operator!=(const BLGradient& other) const noexcept { return !blGradientEquals(this, &other); }
364
365 //! \}
366
367 //! \name Common Functionality
368 //! \{
369
370 BL_INLINE BLResult reset() noexcept { return blGradientReset(this); }
371 BL_INLINE void swap(BLGradient& other) noexcept { std::swap(this->impl, other.impl); }
372
373 BL_INLINE BLResult assign(BLGradient&& other) noexcept { return blGradientAssignMove(this, &other); }
374 BL_INLINE BLResult assign(const BLGradient& other) noexcept { return blGradientAssignWeak(this, &other); }
375
376 //! Tests whether the gradient is a built-in null instance.
377 BL_INLINE bool isNone() const noexcept { return (impl->implTraits & BL_IMPL_TRAIT_NULL) != 0; }
378
379 BL_INLINE bool equals(const BLGradient& other) const noexcept { return blGradientEquals(this, &other); }
380
381 //! \}
382
383 //! \name Create Gradient
384 //! \{
385
386 BL_INLINE BLResult create(const BLLinearGradientValues& values, uint32_t extendMode = BL_EXTEND_MODE_PAD) noexcept {
387 return blGradientCreate(this, BL_GRADIENT_TYPE_LINEAR, &values, extendMode, nullptr, 0, nullptr);
388 }
389
390 BL_INLINE BLResult create(const BLRadialGradientValues& values, uint32_t extendMode = BL_EXTEND_MODE_PAD) noexcept {
391 return blGradientCreate(this, BL_GRADIENT_TYPE_RADIAL, &values, extendMode, nullptr, 0, nullptr);
392 }
393
394 BL_INLINE BLResult create(const BLConicalGradientValues& values, uint32_t extendMode = BL_EXTEND_MODE_PAD) noexcept {
395 return blGradientCreate(this, BL_GRADIENT_TYPE_CONICAL, &values, extendMode, nullptr, 0, nullptr);
396 }
397
398 BL_INLINE BLResult create(const BLLinearGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n) noexcept {
399 return blGradientCreate(this, BL_GRADIENT_TYPE_LINEAR, &values, extendMode, stops, n, nullptr);
400 }
401
402 BL_INLINE BLResult create(const BLRadialGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n) noexcept {
403 return blGradientCreate(this, BL_GRADIENT_TYPE_RADIAL, &values, extendMode, stops, n, nullptr);
404 }
405
406 BL_INLINE BLResult create(const BLConicalGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n) noexcept {
407 return blGradientCreate(this, BL_GRADIENT_TYPE_CONICAL, &values, extendMode, stops, n, nullptr);
408 }
409
410 BL_INLINE BLResult create(const BLLinearGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n, const BLMatrix2D& m) noexcept {
411 return blGradientCreate(this, BL_GRADIENT_TYPE_LINEAR, &values, extendMode, stops, n, &m);
412 }
413
414 BL_INLINE BLResult create(const BLRadialGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n, const BLMatrix2D& m) noexcept {
415 return blGradientCreate(this, BL_GRADIENT_TYPE_RADIAL, &values, extendMode, stops, n, &m);
416 }
417
418 BL_INLINE BLResult create(const BLConicalGradientValues& values, uint32_t extendMode, const BLGradientStop* stops, size_t n, const BLMatrix2D& m) noexcept {
419 return blGradientCreate(this, BL_GRADIENT_TYPE_CONICAL, &values, extendMode, stops, n, &m);
420 }
421
422 //! \}
423
424 //! \name Gradient Options
425 //! \{
426
427 //! Returns the type of the gradient, see `BLGradientType`.
428 BL_INLINE uint32_t type() const noexcept { return impl->gradientType; }
429 //! Sets the gradient type, see `BLGradientType`.
430 BL_INLINE BLResult setType(uint32_t type) noexcept { return blGradientSetType(this, type); }
431
432 //! Returns the gradient extend mode, see `BLExtendMode`.
433 BL_INLINE uint32_t extendMode() const noexcept { return impl->extendMode; }
434 //! Set the gradient extend mode, see `BLExtendMode`.
435 BL_INLINE BLResult setExtendMode(uint32_t extendMode) noexcept { return blGradientSetExtendMode(this, extendMode); }
436 //! Resets the gradient extend mode to `BL_EXTEND_MODE_PAD`.
437 BL_INLINE BLResult resetExtendMode() noexcept { return blGradientSetExtendMode(this, BL_EXTEND_MODE_PAD); }
438
439 BL_INLINE double value(size_t index) const noexcept {
440 BL_ASSERT(index < BL_GRADIENT_VALUE_COUNT);
441 return impl->values[index];
442 }
443
444 BL_INLINE const BLLinearGradientValues& linear() const noexcept { return impl->linear; }
445 BL_INLINE const BLRadialGradientValues& radial() const noexcept { return impl->radial; }
446 BL_INLINE const BLConicalGradientValues& conical() const noexcept { return impl->conical; }
447
448 BL_INLINE BLResult setValue(size_t index, double value) noexcept { return blGradientSetValue(this, index, value); }
449 BL_INLINE BLResult setValues(size_t index, const double* values, size_t n) noexcept { return blGradientSetValues(this, index, values, n); }
450
451 BL_INLINE BLResult setValues(const BLLinearGradientValues& values) noexcept { return setValues(0, (const double*)&values, sizeof(BLLinearGradientValues) / sizeof(double)); }
452 BL_INLINE BLResult setValues(const BLRadialGradientValues& values) noexcept { return setValues(0, (const double*)&values, sizeof(BLRadialGradientValues) / sizeof(double)); }
453 BL_INLINE BLResult setValues(const BLConicalGradientValues& values) noexcept { return setValues(0, (const double*)&values, sizeof(BLConicalGradientValues) / sizeof(double)); }
454
455 BL_INLINE double x0() const noexcept { return impl->values[BL_GRADIENT_VALUE_COMMON_X0]; }
456 BL_INLINE double y0() const noexcept { return impl->values[BL_GRADIENT_VALUE_COMMON_Y0]; }
457 BL_INLINE double x1() const noexcept { return impl->values[BL_GRADIENT_VALUE_COMMON_X1]; }
458 BL_INLINE double y1() const noexcept { return impl->values[BL_GRADIENT_VALUE_COMMON_Y1]; }
459 BL_INLINE double r0() const noexcept { return impl->values[BL_GRADIENT_VALUE_RADIAL_R0]; }
460 BL_INLINE double angle() const noexcept { return impl->values[BL_GRADIENT_VALUE_CONICAL_ANGLE]; }
461
462 BL_INLINE BLResult setX0(double value) noexcept { return setValue(BL_GRADIENT_VALUE_COMMON_X0, value); }
463 BL_INLINE BLResult setY0(double value) noexcept { return setValue(BL_GRADIENT_VALUE_COMMON_Y0, value); }
464 BL_INLINE BLResult setX1(double value) noexcept { return setValue(BL_GRADIENT_VALUE_COMMON_X1, value); }
465 BL_INLINE BLResult setY1(double value) noexcept { return setValue(BL_GRADIENT_VALUE_COMMON_Y1, value); }
466 BL_INLINE BLResult setR0(double value) noexcept { return setValue(BL_GRADIENT_VALUE_RADIAL_R0, value); }
467 BL_INLINE BLResult setAngle(double value) noexcept { return setValue(BL_GRADIENT_VALUE_CONICAL_ANGLE, value); }
468
469 //! \}
470
471 //! \name Gradient Stops
472 //! \{
473
474 BL_INLINE bool empty() const noexcept { return impl->size == 0; }
475 BL_INLINE size_t size() const noexcept { return impl->size; }
476 BL_INLINE size_t capacity() const noexcept { return impl->capacity; }
477
478 //! Reserve the capacity of gradient stops for at least `n` stops.
479 BL_INLINE BLResult reserve(size_t n) noexcept { return blGradientReserve(this, n); }
480 //! Shrink the capacity of gradient stops to fit the current usage.
481 BL_INLINE BLResult shrink() noexcept { return blGradientShrink(this); }
482
483 BL_INLINE const BLGradientStop* stops() const noexcept { return impl->stops; }
484
485 BL_INLINE const BLGradientStop& stopAt(size_t i) const noexcept {
486 BL_ASSERT(i < impl->size);
487 return impl->stops[i];
488 }
489
490 BL_INLINE BLResult resetStops() noexcept { return blGradientResetStops(this); }
491 BL_INLINE BLResult assignStops(const BLGradientStop* stops, size_t n) noexcept { return blGradientAssignStops(this, stops, n); }
492 BL_INLINE BLResult addStop(double offset, const BLRgba32& rgba32) noexcept { return blGradientAddStopRgba32(this, offset, rgba32.value); }
493 BL_INLINE BLResult addStop(double offset, const BLRgba64& rgba64) noexcept { return blGradientAddStopRgba64(this, offset, rgba64.value); }
494 BL_INLINE BLResult removeStop(size_t index) noexcept { return blGradientRemoveStop(this, index); }
495 BL_INLINE BLResult removeStopByOffset(double offset, bool all = true) noexcept { return blGradientRemoveStopByOffset(this, offset, all); }
496 BL_INLINE BLResult removeStops(const BLRange& range) noexcept { return blGradientRemoveStops(this, range.start, range.end); }
497 BL_INLINE BLResult removeStopsByOffset(double offsetMin, double offsetMax) noexcept { return blGradientRemoveStopsFromTo(this, offsetMin, offsetMax); }
498 BL_INLINE BLResult replaceStop(size_t index, double offset, const BLRgba32& rgba32) noexcept { return blGradientReplaceStopRgba32(this, index, offset, rgba32.value); }
499 BL_INLINE BLResult replaceStop(size_t index, double offset, const BLRgba64& rgba64) noexcept { return blGradientReplaceStopRgba64(this, index, offset, rgba64.value); }
500 BL_INLINE size_t indexOfStop(double offset) const noexcept { return blGradientIndexOfStop(this, offset) ;}
501
502 //! \}
503
504 //! \name Transformations
505 //! \{
506
507 BL_INLINE bool hasMatrix() const noexcept { return impl->matrixType != BL_MATRIX2D_TYPE_IDENTITY; }
508 BL_INLINE uint32_t matrixType() const noexcept { return impl->matrixType; }
509 BL_INLINE const BLMatrix2D& matrix() const noexcept { return impl->matrix; }
510
511 //! Applies a matrix operation to the current transformation matrix (internal).
512 BL_INLINE BLResult _applyMatrixOp(uint32_t opType, const void* opData) noexcept {
513 return blGradientApplyMatrixOp(this, opType, opData);
514 }
515
516 //! \cond INTERNAL
517 //! Applies a matrix operation to the current transformation matrix (internal).
518 template<typename... Args>
519 BL_INLINE BLResult _applyMatrixOpV(uint32_t opType, Args&&... args) noexcept {
520 double opData[] = { double(args)... };
521 return blGradientApplyMatrixOp(this, opType, opData);
522 }
523 //! \endcond
524
525 BL_INLINE BLResult setMatrix(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_ASSIGN, &m); }
526 BL_INLINE BLResult resetMatrix() noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_RESET, nullptr); }
527
528 BL_INLINE BLResult translate(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_TRANSLATE, x, y); }
529 BL_INLINE BLResult translate(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_TRANSLATE, p.x, p.y); }
530 BL_INLINE BLResult translate(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_TRANSLATE, &p); }
531 BL_INLINE BLResult scale(double xy) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, xy, xy); }
532 BL_INLINE BLResult scale(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, x, y); }
533 BL_INLINE BLResult scale(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, p.x, p.y); }
534 BL_INLINE BLResult scale(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_SCALE, &p); }
535 BL_INLINE BLResult skew(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SKEW, x, y); }
536 BL_INLINE BLResult skew(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_SKEW, &p); }
537 BL_INLINE BLResult rotate(double angle) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_ROTATE, &angle); }
538 BL_INLINE BLResult rotate(double angle, double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, x, y); }
539 BL_INLINE BLResult rotate(double angle, const BLPoint& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, p.x, p.y); }
540 BL_INLINE BLResult rotate(double angle, const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, p.x, p.y); }
541 BL_INLINE BLResult transform(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_TRANSFORM, &m); }
542
543 BL_INLINE BLResult postTranslate(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_TRANSLATE, x, y); }
544 BL_INLINE BLResult postTranslate(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_TRANSLATE, p.x, p.y); }
545 BL_INLINE BLResult postTranslate(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_TRANSLATE, &p); }
546 BL_INLINE BLResult postScale(double xy) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, xy, xy); }
547 BL_INLINE BLResult postScale(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, x, y); }
548 BL_INLINE BLResult postScale(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, p.x, p.y); }
549 BL_INLINE BLResult postScale(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_SCALE, &p); }
550 BL_INLINE BLResult postSkew(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SKEW, x, y); }
551 BL_INLINE BLResult postSkew(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_SKEW, &p); }
552 BL_INLINE BLResult postRotate(double angle) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_ROTATE, &angle); }
553 BL_INLINE BLResult postRotate(double angle, double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, x, y); }
554 BL_INLINE BLResult postRotate(double angle, const BLPoint& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, p.x, p.y); }
555 BL_INLINE BLResult postRotate(double angle, const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, p.x, p.y); }
556 BL_INLINE BLResult postTransform(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_TRANSFORM, &m); }
557
558 //! \}
559
560 static BL_INLINE const BLGradient& none() noexcept { return reinterpret_cast<const BLGradient*>(blNone)[kImplType]; }
561};
562#endif
563
564//! \}
565
566BL_DIAGNOSTIC_POP
567
568#endif // BLEND2D_BLGRADIENT_H
569