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_BLCONTEXT_H
8#define BLEND2D_BLCONTEXT_H
9
10#include "./blfont.h"
11#include "./blgeometry.h"
12#include "./blimage.h"
13#include "./blmatrix.h"
14#include "./blpath.h"
15#include "./blrgba.h"
16#include "./blregion.h"
17#include "./blvariant.h"
18
19//! \addtogroup blend2d_api_rendering
20//! \{
21
22// ============================================================================
23// [Constants]
24// ============================================================================
25
26//! Rendering context type.
27BL_DEFINE_ENUM(BLContextType) {
28 //! No rendering context.
29 BL_CONTEXT_TYPE_NONE = 0,
30 //! Dummy rendering context.
31 BL_CONTEXT_TYPE_DUMMY = 1,
32
33 /*
34 //! Proxy rendering context.
35 BL_CONTEXT_TYPE_PROXY = 2,
36 */
37
38 //! Software-accelerated rendering context.
39 BL_CONTEXT_TYPE_RASTER = 3,
40
41 //! Count of rendering context types.
42 BL_CONTEXT_TYPE_COUNT = 4
43};
44
45//! Rendering context hint.
46BL_DEFINE_ENUM(BLContextHint) {
47 //! Rendering quality.
48 BL_CONTEXT_HINT_RENDERING_QUALITY = 0,
49 //! Gradient quality.
50 BL_CONTEXT_HINT_GRADIENT_QUALITY = 1,
51 //! Pattern quality.
52 BL_CONTEXT_HINT_PATTERN_QUALITY = 2,
53
54 //! Count of rendering context hints.
55 BL_CONTEXT_HINT_COUNT = 8
56};
57
58//! Describes a rendering operation type - fill or stroke.
59//!
60//! The rendering context allows to get and set fill & stroke options directly
61//! or via "style" functions that take the rendering operation type (`opType`)
62//! and dispatch the call to the right function.
63BL_DEFINE_ENUM(BLContextOpType) {
64 //! Fill operation type.
65 BL_CONTEXT_OP_TYPE_FILL = 0,
66 //! Stroke operation type.
67 BL_CONTEXT_OP_TYPE_STROKE = 1,
68
69 //! Count of rendering operations.
70 BL_CONTEXT_OP_TYPE_COUNT = 2
71};
72
73//! Rendering context flush-flags, use with `BLContext::flush()`.
74BL_DEFINE_ENUM(BLContextFlushFlags) {
75 //! Wait for completion (will block).
76 BL_CONTEXT_FLUSH_SYNC = 0x80000000u
77};
78
79//! Rendering context create-flags.
80BL_DEFINE_ENUM(BLContextCreateFlags) {
81 //! When creating an asynchronous rendering context that uses threads for
82 //! rendering, the rendering context can sometimes allocate less threads
83 //! than specified if the built-in thread-pool doesn't have enough threads
84 //! available. This flag will force the thread-pool to override the thread
85 //! limit temporarily to fulfill the thread count requirement.
86 //!
87 //! \note This flag is ignored if `BLContextCreateInfo::threadCount == 0`.
88 BL_CONTEXT_CREATE_FLAG_FORCE_THREADS = 0x00000001u,
89
90 //! Fallback to synchronous rendering in case that acquiring threads from
91 //! thread-pool failed. This flag only makes sense when asynchronous mode
92 //! was specified by having non-zero thread count. In that case if the
93 //! rendering context fails to acquire at least one thread it would fallback
94 //! to synchronous mode instead.
95 //!
96 //! \note This flag is ignored if `BLContextCreateInfo::threadCount == 0`.
97 BL_CONTEXT_CREATE_FLAG_FALLBACK_TO_SYNC = 0x00000002u,
98
99 //! If this flag is specified and asynchronous rendering is enabled then
100 //! the context would create its own isolated thread-pool, which is useful
101 //! for debugging purposes.
102 //!
103 //! Do not use this flag in production as rendering contexts with isolated
104 //! thread-pool have to create and destroy all threads they use. This flag
105 //! is only useful for testing, debugging, and isolated benchmarking.
106 BL_CONTEXT_CREATE_FLAG_ISOLATED_THREADS = 0x00000010u,
107
108 //! If this flag is specified and JIT pipeline generation enabled then the
109 //! rendering context would create its own isolated JIT runtime. which is
110 //! useful for debugging purposes. This flag will be ignored if JIT pipeline
111 //! generation is either not supported or was disabled by other flags.
112 //!
113 //! Do not use this flag in production as rendering contexts with isolated
114 //! JIT runtime do not use global pipeline cache, that's it, after the
115 //! rendering context is destroyed the JIT runtime is destroyed with it with
116 //! all compiled pipelines. This flag is only useful for testing, debugging,
117 //! and isolated benchmarking.
118 BL_CONTEXT_CREATE_FLAG_ISOLATED_JIT = 0x00000020u,
119
120 //! Override CPU features when creating isolated context.
121 BL_CONTEXT_CREATE_FLAG_OVERRIDE_CPU_FEATURES = 0x00000040u
122};
123
124//! Clip mode.
125BL_DEFINE_ENUM(BLClipMode) {
126 //! Clipping to a rectangle that is aligned to the pixel grid.
127 BL_CLIP_MODE_ALIGNED_RECT = 0,
128 //! Clipping to a rectangle that is not aligned to pixel grid.
129 BL_CLIP_MODE_UNALIGNED_RECT = 1,
130 //! Clipping to a non-rectangular area that is defined by using mask.
131 BL_CLIP_MODE_MASK = 2,
132
133 //! Count of clip modes.
134 BL_CLIP_MODE_COUNT = 3
135};
136
137//! Composition & blending operator.
138BL_DEFINE_ENUM(BLCompOp) {
139 //! Source-over [default].
140 BL_COMP_OP_SRC_OVER = 0,
141 //! Source-copy.
142 BL_COMP_OP_SRC_COPY = 1,
143 //! Source-in.
144 BL_COMP_OP_SRC_IN = 2,
145 //! Source-out.
146 BL_COMP_OP_SRC_OUT = 3,
147 //! Source-atop.
148 BL_COMP_OP_SRC_ATOP = 4,
149 //! Destination-over.
150 BL_COMP_OP_DST_OVER = 5,
151 //! Destination-copy [nop].
152 BL_COMP_OP_DST_COPY = 6,
153 //! Destination-in.
154 BL_COMP_OP_DST_IN = 7,
155 //! Destination-out.
156 BL_COMP_OP_DST_OUT = 8,
157 //! Destination-atop.
158 BL_COMP_OP_DST_ATOP = 9,
159 //! Xor.
160 BL_COMP_OP_XOR = 10,
161 //! Clear.
162 BL_COMP_OP_CLEAR = 11,
163 //! Plus.
164 BL_COMP_OP_PLUS = 12,
165 //! Minus.
166 BL_COMP_OP_MINUS = 13,
167 //! Multiply.
168 BL_COMP_OP_MULTIPLY = 14,
169 //! Screen.
170 BL_COMP_OP_SCREEN = 15,
171 //! Overlay.
172 BL_COMP_OP_OVERLAY = 16,
173 //! Darken.
174 BL_COMP_OP_DARKEN = 17,
175 //! Lighten.
176 BL_COMP_OP_LIGHTEN = 18,
177 //! Color dodge.
178 BL_COMP_OP_COLOR_DODGE = 19,
179 //! Color burn.
180 BL_COMP_OP_COLOR_BURN = 20,
181 //! Linear burn.
182 BL_COMP_OP_LINEAR_BURN = 21,
183 //! Linear light.
184 BL_COMP_OP_LINEAR_LIGHT = 22,
185 //! Pin light.
186 BL_COMP_OP_PIN_LIGHT = 23,
187 //! Hard-light.
188 BL_COMP_OP_HARD_LIGHT = 24,
189 //! Soft-light.
190 BL_COMP_OP_SOFT_LIGHT = 25,
191 //! Difference.
192 BL_COMP_OP_DIFFERENCE = 26,
193 //! Exclusion.
194 BL_COMP_OP_EXCLUSION = 27,
195
196 //! Count of composition & blending operators.
197 BL_COMP_OP_COUNT = 28
198};
199
200//! Gradient rendering quality.
201BL_DEFINE_ENUM(BLGradientQuality) {
202 //! Nearest neighbor.
203 BL_GRADIENT_QUALITY_NEAREST = 0,
204
205 //! Count of gradient quality options.
206 BL_GRADIENT_QUALITY_COUNT = 1
207};
208
209//! Pattern quality.
210BL_DEFINE_ENUM(BLPatternQuality) {
211 //! Nearest neighbor.
212 BL_PATTERN_QUALITY_NEAREST = 0,
213 //! Bilinear.
214 BL_PATTERN_QUALITY_BILINEAR = 1,
215
216 //! Count of pattern quality options.
217 BL_PATTERN_QUALITY_COUNT = 2
218};
219
220//! Rendering quality.
221BL_DEFINE_ENUM(BLRenderingQuality) {
222 //! Render using anti-aliasing.
223 BL_RENDERING_QUALITY_ANTIALIAS = 0,
224
225 //! Count of rendering quality options.
226 BL_RENDERING_QUALITY_COUNT = 1
227};
228
229// ============================================================================
230// [BLContext - CreateInfo]
231// ============================================================================
232
233//! Information that can be used to customize the rendering context.
234struct BLContextCreateInfo {
235 //! Create flags, see `BLContextCreateFlags`.
236 uint32_t flags;
237
238 //! Number of threads to acquire from thread-pool and use for rendering.
239 //!
240 //! If `threadCount` is zero it means to initialize the context for synchronous
241 //! rendering. This means that every operation will take effect immediately.
242 //! If the number is `1` or greater it means to initialize the context for
243 //! asynchronous rendering - in this case `threadCount` specifies how many
244 //! threads can execute in parallel.
245 uint32_t threadCount;
246
247 //! CPU features to use in isolated JIT runtime (if supported), only used
248 //! when `flags` contains `BL_CONTEXT_CREATE_FLAG_OVERRIDE_CPU_FEATURES`.
249 uint32_t cpuFeatures;
250
251 //! Reserved for future use, must be zero.
252 uint32_t reserved[5];
253
254 // --------------------------------------------------------------------------
255 #ifdef __cplusplus
256 BL_INLINE void reset() noexcept { memset(this, 0, sizeof(*this)); }
257 #endif
258 // --------------------------------------------------------------------------
259};
260
261// ============================================================================
262// [BLContext - Cookie]
263// ============================================================================
264
265//! Holds an arbitrary 128-bit value (cookie) that can be used to match other
266//! cookies. Blend2D uses cookies in places where it allows to "lock" some
267//! state that can only be unlocked by a matching cookie. Please don't confuse
268//! cookies with a security of any kind, it's just an arbitrary data that must
269//! match to proceed with a certain operation.
270//!
271//! Cookies can be used with `BLContext::save()` and `BLContext::restore()`
272//! functions
273struct BLContextCookie {
274 uint64_t data[2];
275
276 // --------------------------------------------------------------------------
277 #ifdef __cplusplus
278
279 BL_INLINE bool operator==(const BLContextCookie& other) const noexcept { return equals(other); }
280 BL_INLINE bool operator!=(const BLContextCookie& other) const noexcept { return !equals(other); }
281
282 BL_INLINE bool empty() const noexcept {
283 return this->data[0] == 0 && this->data[1] == 0;
284 }
285
286 BL_INLINE void reset() noexcept { reset(0, 0); }
287 BL_INLINE void reset(const BLContextCookie& other) noexcept { reset(other.data[0], other.data[1]); }
288
289 BL_INLINE void reset(uint64_t data0, uint64_t data1) noexcept {
290 this->data[0] = data0;
291 this->data[1] = data1;
292 }
293
294 BL_INLINE bool equals(const BLContextCookie& other) const noexcept {
295 return blEquals(this->data[0], other.data[0]) &
296 blEquals(this->data[1], other.data[1]);
297 }
298
299 #endif
300 // --------------------------------------------------------------------------
301};
302
303// ============================================================================
304// [BLContext - Hints]
305// ============================================================================
306
307//! Rendering context hints.
308struct BLContextHints {
309 union {
310 struct {
311 uint8_t renderingQuality;
312 uint8_t gradientQuality;
313 uint8_t patternQuality;
314 };
315
316 uint8_t hints[BL_CONTEXT_HINT_COUNT];
317 };
318
319 // --------------------------------------------------------------------------
320 #ifdef __cplusplus
321
322 BL_INLINE void reset() noexcept { memset(this, 0, sizeof(*this)); }
323
324 #endif
325 // --------------------------------------------------------------------------
326};
327
328// ============================================================================
329// [BLContext - State]
330// ============================================================================
331
332//! Rendering context state.
333//!
334//! This state is not meant to be created by users, it's only provided for users
335//! that want to introspect it and for C++ API that accesses it directly.
336struct BLContextState {
337 //! Current context hints.
338 BLContextHints hints;
339 //! Current composition operator.
340 uint8_t compOp;
341 //! Current fill rule.
342 uint8_t fillRule;
343 //! Current type of a style for fill and stroke operations, see `BLContextOpType`.
344 uint8_t styleType[2];
345 //! Reserved for future use, must be zero.
346 uint8_t reserved[4];
347
348 //! Approximation options.
349 BLApproximationOptions approximationOptions;
350
351 //! Current global alpha value [0, 1].
352 double globalAlpha;
353 //! Current fill or stroke alpha, see `BLContextOpType`.
354 double styleAlpha[2];
355
356 //! Current stroke options.
357 BL_TYPED_MEMBER(BLStrokeOptionsCore, BLStrokeOptions, strokeOptions);
358
359 //! Current meta transformation matrix.
360 BLMatrix2D metaMatrix;
361 //! Current user transformation matrix.
362 BLMatrix2D userMatrix;
363
364 //! Count of saved states in the context.
365 size_t savedStateCount;
366
367 BL_HAS_TYPED_MEMBERS(BLContextState)
368};
369
370// ============================================================================
371// [BLContext - Core]
372// ============================================================================
373
374//! Rendering context [C Interface - Virtual Function Table].
375struct BLContextVirt {
376 BLResult (BL_CDECL* destroy )(BLContextImpl* impl) BL_NOEXCEPT;
377 BLResult (BL_CDECL* flush )(BLContextImpl* impl, uint32_t flags) BL_NOEXCEPT;
378
379 BLResult (BL_CDECL* save )(BLContextImpl* impl, BLContextCookie* cookie) BL_NOEXCEPT;
380 BLResult (BL_CDECL* restore )(BLContextImpl* impl, const BLContextCookie* cookie) BL_NOEXCEPT;
381
382 BLResult (BL_CDECL* matrixOp )(BLContextImpl* impl, uint32_t opType, const void* opData) BL_NOEXCEPT;
383 BLResult (BL_CDECL* userToMeta )(BLContextImpl* impl) BL_NOEXCEPT;
384
385 BLResult (BL_CDECL* setHint )(BLContextImpl* impl, uint32_t hintType, uint32_t value) BL_NOEXCEPT;
386 BLResult (BL_CDECL* setHints )(BLContextImpl* impl, const BLContextHints* hints) BL_NOEXCEPT;
387 BLResult (BL_CDECL* setFlattenMode )(BLContextImpl* impl, uint32_t mode) BL_NOEXCEPT;
388 BLResult (BL_CDECL* setFlattenTolerance )(BLContextImpl* impl, double tolerance) BL_NOEXCEPT;
389 BLResult (BL_CDECL* setApproximationOptions)(BLContextImpl* impl, const BLApproximationOptions* options) BL_NOEXCEPT;
390
391 BLResult (BL_CDECL* setCompOp )(BLContextImpl* impl, uint32_t compOp) BL_NOEXCEPT;
392 BLResult (BL_CDECL* setGlobalAlpha )(BLContextImpl* impl, double alpha) BL_NOEXCEPT;
393
394 // Allows to dispatch fill/stroke by `BLContextOpType`.
395 BLResult (BL_CDECL* setStyleAlpha[2] )(BLContextImpl* impl, double alpha) BL_NOEXCEPT;
396 BLResult (BL_CDECL* getStyle[2] )(BLContextImpl* impl, void* object) BL_NOEXCEPT;
397 BLResult (BL_CDECL* getStyleRgba32[2] )(BLContextImpl* impl, uint32_t* rgba32) BL_NOEXCEPT;
398 BLResult (BL_CDECL* getStyleRgba64[2] )(BLContextImpl* impl, uint64_t* rgba64) BL_NOEXCEPT;
399 BLResult (BL_CDECL* setStyle[2] )(BLContextImpl* impl, const void* object) BL_NOEXCEPT;
400 BLResult (BL_CDECL* setStyleRgba32[2] )(BLContextImpl* impl, uint32_t rgba32) BL_NOEXCEPT;
401 BLResult (BL_CDECL* setStyleRgba64[2] )(BLContextImpl* impl, uint64_t rgba64) BL_NOEXCEPT;
402
403 BLResult (BL_CDECL* setFillRule )(BLContextImpl* impl, uint32_t fillRule) BL_NOEXCEPT;
404
405 BLResult (BL_CDECL* setStrokeWidth )(BLContextImpl* impl, double width) BL_NOEXCEPT;
406 BLResult (BL_CDECL* setStrokeMiterLimit )(BLContextImpl* impl, double miterLimit) BL_NOEXCEPT;
407 BLResult (BL_CDECL* setStrokeCap )(BLContextImpl* impl, uint32_t position, uint32_t strokeCap) BL_NOEXCEPT;
408 BLResult (BL_CDECL* setStrokeCaps )(BLContextImpl* impl, uint32_t strokeCap) BL_NOEXCEPT;
409 BLResult (BL_CDECL* setStrokeJoin )(BLContextImpl* impl, uint32_t strokeJoin) BL_NOEXCEPT;
410 BLResult (BL_CDECL* setStrokeDashOffset )(BLContextImpl* impl, double dashOffset) BL_NOEXCEPT;
411 BLResult (BL_CDECL* setStrokeDashArray )(BLContextImpl* impl, const BLArrayCore* dashArray) BL_NOEXCEPT;
412 BLResult (BL_CDECL* setStrokeTransformOrder)(BLContextImpl* impl, uint32_t transformOrder) BL_NOEXCEPT;
413 BLResult (BL_CDECL* setStrokeOptions )(BLContextImpl* impl, const BLStrokeOptionsCore* options) BL_NOEXCEPT;
414
415 BLResult (BL_CDECL* clipToRectI )(BLContextImpl* impl, const BLRectI* rect) BL_NOEXCEPT;
416 BLResult (BL_CDECL* clipToRectD )(BLContextImpl* impl, const BLRect* rect) BL_NOEXCEPT;
417 BLResult (BL_CDECL* restoreClipping )(BLContextImpl* impl) BL_NOEXCEPT;
418
419 BLResult (BL_CDECL* clearAll )(BLContextImpl* impl) BL_NOEXCEPT;
420 BLResult (BL_CDECL* clearRectI )(BLContextImpl* impl, const BLRectI* rect) BL_NOEXCEPT;
421 BLResult (BL_CDECL* clearRectD )(BLContextImpl* impl, const BLRect* rect) BL_NOEXCEPT;
422
423 BLResult (BL_CDECL* fillAll )(BLContextImpl* impl) BL_NOEXCEPT;
424 BLResult (BL_CDECL* fillRectI )(BLContextImpl* impl, const BLRectI* rect) BL_NOEXCEPT;
425 BLResult (BL_CDECL* fillRectD )(BLContextImpl* impl, const BLRect* rect) BL_NOEXCEPT;
426 BLResult (BL_CDECL* fillPathD )(BLContextImpl* impl, const BLPathCore* path) BL_NOEXCEPT;
427 BLResult (BL_CDECL* fillGeometry )(BLContextImpl* impl, uint32_t geometryType, const void* geometryData) BL_NOEXCEPT;
428 BLResult (BL_CDECL* fillTextI )(BLContextImpl* impl, const BLPointI* pt, const BLFontCore* font, const void* text, size_t size, uint32_t encoding) BL_NOEXCEPT;
429 BLResult (BL_CDECL* fillTextD )(BLContextImpl* impl, const BLPoint* pt, const BLFontCore* font, const void* text, size_t size, uint32_t encoding) BL_NOEXCEPT;
430 BLResult (BL_CDECL* fillGlyphRunI )(BLContextImpl* impl, const BLPointI* pt, const BLFontCore* font, const BLGlyphRun* glyphRun) BL_NOEXCEPT;
431 BLResult (BL_CDECL* fillGlyphRunD )(BLContextImpl* impl, const BLPoint* pt, const BLFontCore* font, const BLGlyphRun* glyphRun) BL_NOEXCEPT;
432
433 BLResult (BL_CDECL* strokeRectI )(BLContextImpl* impl, const BLRectI* rect) BL_NOEXCEPT;
434 BLResult (BL_CDECL* strokeRectD )(BLContextImpl* impl, const BLRect* rect) BL_NOEXCEPT;
435 BLResult (BL_CDECL* strokePathD )(BLContextImpl* impl, const BLPathCore* path) BL_NOEXCEPT;
436 BLResult (BL_CDECL* strokeGeometry )(BLContextImpl* impl, uint32_t geometryType, const void* geometryData) BL_NOEXCEPT;
437 BLResult (BL_CDECL* strokeTextI )(BLContextImpl* impl, const BLPointI* pt, const BLFontCore* font, const void* text, size_t size, uint32_t encoding) BL_NOEXCEPT;
438 BLResult (BL_CDECL* strokeTextD )(BLContextImpl* impl, const BLPoint* pt, const BLFontCore* font, const void* text, size_t size, uint32_t encoding) BL_NOEXCEPT;
439 BLResult (BL_CDECL* strokeGlyphRunI )(BLContextImpl* impl, const BLPointI* pt, const BLFontCore* font, const BLGlyphRun* glyphRun) BL_NOEXCEPT;
440 BLResult (BL_CDECL* strokeGlyphRunD )(BLContextImpl* impl, const BLPoint* pt, const BLFontCore* font, const BLGlyphRun* glyphRun) BL_NOEXCEPT;
441
442 BLResult (BL_CDECL* blitImageI )(BLContextImpl* impl, const BLPointI* pt, const BLImageCore* img, const BLRectI* imgArea) BL_NOEXCEPT;
443 BLResult (BL_CDECL* blitImageD )(BLContextImpl* impl, const BLPoint* pt, const BLImageCore* img, const BLRectI* imgArea) BL_NOEXCEPT;
444 BLResult (BL_CDECL* blitScaledImageI )(BLContextImpl* impl, const BLRectI* rect, const BLImageCore* img, const BLRectI* imgArea) BL_NOEXCEPT;
445 BLResult (BL_CDECL* blitScaledImageD )(BLContextImpl* impl, const BLRect* rect, const BLImageCore* img, const BLRectI* imgArea) BL_NOEXCEPT;
446};
447
448//! Rendering context [C Interface - Impl].
449struct BLContextImpl {
450 //! Virtual function table.
451 const BLContextVirt* virt;
452 //! Current state of the context.
453 const BLContextState* state;
454 //! Reserved header for future use.
455 void* reservedHeader;
456
457 //! Reference count.
458 volatile size_t refCount;
459 //! Impl type.
460 uint8_t implType;
461 //! Impl traits.
462 uint8_t implTraits;
463 //! Memory pool data.
464 uint16_t memPoolData;
465 //! Type of the context, see `BLContextType`.
466 uint32_t contextType;
467
468 //! Current size of the target in abstract units, pixels if rendering to `BLImage`.
469 BLSize targetSize;
470};
471
472//! Rendering context [C Interface - Core].
473struct BLContextCore {
474 BLContextImpl* impl;
475};
476
477// ============================================================================
478// [BLContext - C++]
479// ============================================================================
480
481#ifdef __cplusplus
482//! Rendering context [C++ API].
483class BLContext : public BLContextCore {
484public:
485 //! \cond INTERNAL
486 static constexpr const uint32_t kImplType = BL_IMPL_TYPE_CONTEXT;
487
488 // Only used by `BLContext` to make invocation of functions in `BLContextVirt`.
489 enum OpType : uint32_t {
490 kOpFill = BL_CONTEXT_OP_TYPE_FILL,
491 kOpStroke = BL_CONTEXT_OP_TYPE_STROKE
492 };
493 //! \endcond
494
495 //! \name Construction & Destruction
496 //! \{
497
498 //! Creates a default constructed rendering context.
499 //!
500 //! Default constructed means that the instance is valid, but uninitialized,
501 //! which means the rendering context does not have attached any target. Any
502 //! attempt to use uninitialized context results in `BL_ERROR_NOT_INITIALIZED`
503 //! error.
504 BL_INLINE BLContext() noexcept { this->impl = none().impl; }
505
506 //! Move constructor.
507 //!
508 //! Moves the `other` rendering context into this one and resets the `other`.
509 BL_INLINE BLContext(BLContext&& other) noexcept { blVariantInitMove(this, &other); }
510
511 //! Copy constructor.
512 //!
513 //! Creates a weak-copy of the `other` rendering context by increasing it's
514 //! internal reference counter. This context and `other` would point to the
515 //! same data and would be otherwise identical. Any change to `other` would
516 //! also affect this context.
517 //!
518 //! This function is mostly provided for C++ users that may keep a global
519 //! reference to the same rendering context, for example, otherwise sharing
520 //! is not that useful as they also share a state.
521 //!
522 //! Two weak copies of the same rendering context cannot be used by different
523 //! threads simultaneously.
524 BL_INLINE BLContext(const BLContext& other) noexcept { blVariantInitWeak(this, &other); }
525
526 //! Initializes this `BLContext` class with rendering context `impl`.
527 //!
528 //! Mostly for internal purposes and to keep the API consistent.
529 BL_INLINE explicit BLContext(BLContextImpl* impl) noexcept { this->impl = impl; }
530
531 //! Creates a new rendering context for rendering to the image `target`.
532 BL_INLINE explicit BLContext(BLImage& target) noexcept { blContextInitAs(this, &target, nullptr); }
533 //! Creates a new rendering context for rendering to the image `target`.
534 //!
535 //! This overload accepts create options that can be used to change the
536 //! implementation of the rendering context.
537 BL_INLINE BLContext(BLImage& target, const BLContextCreateInfo& options) noexcept { blContextInitAs(this, &target, &options); }
538 //! \overload
539 BL_INLINE BLContext(BLImage& target, const BLContextCreateInfo* options) noexcept { blContextInitAs(this, &target, options); }
540
541 //! Destroys the rendering context.
542 //!
543 //! Waits for all operations, detaches the target from the rendering context
544 //! and then destroys it. Does nothing if the context is not initialized.
545 BL_INLINE ~BLContext() noexcept { blContextReset(this); }
546
547 //! \}
548
549 //! \name Overloaded Operators
550 //! \{
551
552 //! Returns true if the rendering context is initialized (has target attached).
553 //!
554 //! Provided for users that want to use bool idiom in C++ to check for the
555 //! status of the object.
556 //!
557 //! ```
558 //! if (ctx) {
559 //! // Rendering context is initialized.
560 //! }
561 //! ```
562 BL_INLINE explicit operator bool() const noexcept { return !isNone(); }
563
564 BL_INLINE BLContext& operator=(BLContext&& other) noexcept { blContextAssignMove(this, &other); return *this; }
565 BL_INLINE BLContext& operator=(const BLContext& other) noexcept { blContextAssignWeak(this, &other); return *this; }
566
567 //! Returns whether this and `other` point to the same rendering context.
568 BL_INLINE bool operator==(const BLContext& other) const noexcept { return equals(other); }
569 //! Returns whether this and `other` are different rendering contexts.
570 BL_INLINE bool operator!=(const BLContext& other) const noexcept { return !equals(other); }
571
572 //! \}
573
574 //! \name Target Information
575 //! \{
576
577 //! Returns target size in abstract units (pixels in case of `BLImage`).
578 BL_INLINE BLSize targetSize() const noexcept { return impl->targetSize; }
579 //! Returns target width in abstract units (pixels in case of `BLImage`).
580 BL_INLINE double targetWidth() const noexcept { return impl->targetSize.w; }
581 //! Returns target height in abstract units (pixels in case of `BLImage`).
582 BL_INLINE double targetHeight() const noexcept { return impl->targetSize.h; }
583
584 //! \}
585
586 //! \name Context Lifetime and Others
587 //! \{
588
589 //! Returns the type of this context, see `BLContextType`.
590 BL_INLINE uint32_t contextType() const noexcept { return impl->contextType; }
591
592 //! Tests whether the context is a built-in null instance.
593 BL_INLINE bool isNone() const noexcept { return (impl->implTraits & BL_IMPL_TRAIT_NULL) != 0; }
594
595 //! Returns whether this and `other` point to the same rendering context.
596 BL_INLINE bool equals(const BLContext& other) const noexcept { return this->impl == other.impl; }
597
598 //! Resets this rendering context to the default constructed one.
599 //!
600 //! Similar behavior to the destructor, but the context will still be valid
601 //! after `reset()` and would behave like a default constructed context.
602 BL_INLINE BLResult reset() noexcept { return blContextReset(this); }
603
604 BL_INLINE BLResult assign(BLContext&& other) noexcept { return blContextAssignMove(this, &other); }
605 BL_INLINE BLResult assign(const BLContext& other) noexcept { return blContextAssignWeak(this, &other); }
606
607 //! Begins rendering to the given `image`.
608 //!
609 //! If this operation succeeds then the rendering context will have exclusive
610 //! access to the image data. This means that no other renderer can use it
611 //! during rendering.
612 BL_INLINE BLResult begin(BLImage& image) noexcept { return blContextBegin(this, &image, nullptr); }
613 //! \overload
614 BL_INLINE BLResult begin(BLImage& image, const BLContextCreateInfo& options) noexcept { return blContextBegin(this, &image, &options); }
615 //! \overload
616 BL_INLINE BLResult begin(BLImage& image, const BLContextCreateInfo* options) noexcept { return blContextBegin(this, &image, options); }
617
618 //! Waits for completion of all render commands and detaches the rendering
619 //! context from the rendering target. After `end()` completes the rendering
620 //! context implementation would be released and replaced by a built-in null
621 //! instance (no context).
622 BL_INLINE BLResult end() noexcept { return blContextEnd(this); }
623
624 //! Flushes the context, see `BLContextFlushFlags`.
625 BL_INLINE BLResult flush(uint32_t flags) noexcept { return impl->virt->flush(impl, flags); }
626
627 //! \}
628
629 //! \name State Management
630 //! \{
631
632 //! Returns the number of saved states in the context (0 means no saved states).
633 BL_INLINE size_t savedStateCount() const noexcept { return impl->state->savedStateCount; }
634
635 //! Saves the current rendering context state.
636 //!
637 //! Blend2D uses optimizations that make `save()` a cheap operation. Only core
638 //! values are actually saved in `save()`, others will only be saved if they
639 //! are modified. This means that consecutive calls to `save()` and `restore()`
640 //! do almost nothing.
641 BL_INLINE BLResult save() noexcept { return impl->virt->save(impl, nullptr); }
642
643 //! Saves the current rendering context state and creates a restoration `cookie`.
644 //!
645 //! If you use a `cookie` to save a state you have to use the same cookie to
646 //! restore it otherwise the `restore()` would fail. Please note that cookies
647 //! are not a means of security, they are provided for making it easier to
648 //! guarantee that a code that you may not control won't break your context.
649 BL_INLINE BLResult save(BLContextCookie& cookie) noexcept { return impl->virt->save(impl, &cookie); }
650
651 //! Restores the top-most saved context-state.
652 //!
653 //! Possible return conditions:
654 //!
655 //! * `BL_SUCCESS` - State was restored successfully.
656 //! * `BL_ERROR_NO_STATES_TO_RESTORE` - There are no saved states to restore.
657 //! * `BL_ERROR_NO_MATCHING_COOKIE` - Previous state was saved with cookie,
658 //! which was not provided. You would need the correct cookie to restore
659 //! such state.
660 BL_INLINE BLResult restore() noexcept { return impl->virt->restore(impl, nullptr); }
661
662 //! Restores to the point that matches the given `cookie`.
663 //!
664 //! More than one state can be restored in case that the `cookie` points to
665 //! some previous state in the list.
666 //!
667 //! Possible return conditions:
668 //!
669 //! * `BL_SUCCESS` - Matching state was restored successfully.
670 //! * `BL_ERROR_NO_STATES_TO_RESTORE` - There are no saved states to restore.
671 //! * `BL_ERROR_NO_MATCHING_COOKIE` - The cookie did't match any saved state.
672 BL_INLINE BLResult restore(const BLContextCookie& cookie) noexcept { return impl->virt->restore(impl, &cookie); }
673
674 //! \}
675
676 //! \name Transformations
677 //! \{
678
679 //! Returns meta-matrix.
680 //!
681 //! Meta matrix is a core transformation matrix that is normally not changed
682 //! by transformations applied to the context. Instead it acts as a secondary
683 //! matrix used to create the final transformation matrix from meta and user
684 //! matrices.
685 //!
686 //! Meta matrix can be used to scale the whole context for HI-DPI rendering
687 //! or to change the orientation of the image being rendered, however, the
688 //! number of use-cases is unlimited.
689 //!
690 //! To change the meta-matrix you must first change user-matrix and then call
691 //! `userToMeta()`, which would update meta-matrix and clear user-matrix.
692 //!
693 //! See `userMatrix()` and `userToMeta()`.
694 BL_INLINE const BLMatrix2D& metaMatrix() const noexcept { return impl->state->metaMatrix; }
695
696 //! Returns user-matrix.
697 //!
698 //! User matrix contains all transformations that happened to the rendering
699 //! context unless the context was restored or `userToMeta()` was called.
700 BL_INLINE const BLMatrix2D& userMatrix() const noexcept { return impl->state->userMatrix; }
701
702 //! Applies a matrix operation to the current transformation matrix (internal).
703 BL_INLINE BLResult _applyMatrixOp(uint32_t opType, const void* opData) noexcept {
704 return impl->virt->matrixOp(impl, opType, opData);
705 }
706
707 //! \cond INTERNAL
708 //! Applies a matrix operation to the current transformation matrix (internal).
709 template<typename... Args>
710 BL_INLINE BLResult _applyMatrixOpV(uint32_t opType, Args&&... args) noexcept {
711 double opData[] = { double(args)... };
712 return impl->virt->matrixOp(impl, opType, opData);
713 }
714 //! \endcond
715
716 //! Sets user matrix to `m`.
717 BL_INLINE BLResult setMatrix(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_ASSIGN, &m); }
718 //! Resets user matrix to identity.
719 BL_INLINE BLResult resetMatrix() noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_RESET, nullptr); }
720
721 BL_INLINE BLResult translate(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_TRANSLATE, x, y); }
722 BL_INLINE BLResult translate(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_TRANSLATE, p.x, p.y); }
723 BL_INLINE BLResult translate(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_TRANSLATE, &p); }
724 BL_INLINE BLResult scale(double xy) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, xy, xy); }
725 BL_INLINE BLResult scale(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, x, y); }
726 BL_INLINE BLResult scale(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SCALE, p.x, p.y); }
727 BL_INLINE BLResult scale(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_SCALE, &p); }
728 BL_INLINE BLResult skew(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_SKEW, x, y); }
729 BL_INLINE BLResult skew(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_SKEW, &p); }
730 BL_INLINE BLResult rotate(double angle) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_ROTATE, &angle); }
731 BL_INLINE BLResult rotate(double angle, double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, x, y); }
732 BL_INLINE BLResult rotate(double angle, const BLPoint& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, p.x, p.y); }
733 BL_INLINE BLResult rotate(double angle, const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_ROTATE_PT, angle, p.x, p.y); }
734 BL_INLINE BLResult transform(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_TRANSFORM, &m); }
735
736 BL_INLINE BLResult postTranslate(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_TRANSLATE, x, y); }
737 BL_INLINE BLResult postTranslate(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_TRANSLATE, p.x, p.y); }
738 BL_INLINE BLResult postTranslate(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_TRANSLATE, &p); }
739 BL_INLINE BLResult postScale(double xy) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, xy, xy); }
740 BL_INLINE BLResult postScale(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, x, y); }
741 BL_INLINE BLResult postScale(const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SCALE, p.x, p.y); }
742 BL_INLINE BLResult postScale(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_SCALE, &p); }
743 BL_INLINE BLResult postSkew(double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_SKEW, x, y); }
744 BL_INLINE BLResult postSkew(const BLPoint& p) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_SKEW, &p); }
745 BL_INLINE BLResult postRotate(double angle) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_ROTATE, &angle); }
746 BL_INLINE BLResult postRotate(double angle, double x, double y) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, x, y); }
747 BL_INLINE BLResult postRotate(double angle, const BLPoint& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, p.x, p.y); }
748 BL_INLINE BLResult postRotate(double angle, const BLPointI& p) noexcept { return _applyMatrixOpV(BL_MATRIX2D_OP_POST_ROTATE_PT, angle, p.x, p.y); }
749 BL_INLINE BLResult postTransform(const BLMatrix2D& m) noexcept { return _applyMatrixOp(BL_MATRIX2D_OP_POST_TRANSFORM, &m); }
750
751 //! Store the result of combining the current `MetaMatrix` and `UserMatrix`
752 //! to `MetaMatrix` and reset `UserMatrix` to identity as shown below:
753 //!
754 //! ```
755 //! MetaMatrix = MetaMatrix x UserMatrix
756 //! UserMatrix = Identity
757 //! ```
758 //!
759 //! Please note that this operation is irreversible. The only way to restore
760 //! both matrices to the state before the call to `userToMeta()` is to use
761 //! `save()` and `restore()` functions.
762 BL_INLINE BLResult userToMeta() noexcept { return impl->virt->userToMeta(impl); }
763
764 //! \}
765
766 //! \name Rendering Hints
767 //! \{
768
769 //! Returns rendering hints.
770 BL_INLINE const BLContextHints& hints() const noexcept { return impl->state->hints; }
771
772 //! Sets the given rendering hint `hintType` to the `value`.
773 BL_INLINE BLResult setHint(uint32_t hintType, uint32_t value) noexcept { return impl->virt->setHint(impl, hintType, value); }
774 //! Sets all rendering hints of this context to the given `hints`.
775 BL_INLINE BLResult setHints(const BLContextHints& hints) noexcept { return impl->virt->setHints(impl, &hints); }
776
777 BL_INLINE BLResult setRenderingQuality(uint32_t value) noexcept { return setHint(BL_CONTEXT_HINT_RENDERING_QUALITY, value); }
778 BL_INLINE BLResult setGradientQuality(uint32_t value) noexcept { return setHint(BL_CONTEXT_HINT_GRADIENT_QUALITY, value); }
779 BL_INLINE BLResult setPatternQuality(uint32_t value) noexcept { return setHint(BL_CONTEXT_HINT_PATTERN_QUALITY, value); }
780
781 //! \}
782
783 //! \name Approximation Options
784 //! \{
785
786 //! Returns approximation options.
787 BL_INLINE const BLApproximationOptions& approximationOptions() const noexcept { return impl->state->approximationOptions; }
788
789 //! Returns flatten mode (how curves are flattened), see `BLFlattenMmode`.
790 BL_INLINE uint32_t flattenMode() const noexcept { return impl->state->approximationOptions.flattenMode; }
791 //! Sets flatten `mode` (how curves are flattened), see `BLFlattenMmode`.
792 BL_INLINE BLResult setFlattenMode(uint32_t mode) noexcept { return impl->virt->setFlattenMode(impl, mode); }
793
794 //! Returns tolerance used for curve flattening.
795 BL_INLINE double flattenTolerance() const noexcept { return impl->state->approximationOptions.flattenTolerance; }
796 //! Sets tolerance used for curve flattening.
797 BL_INLINE BLResult setFlattenTolerance(double tolerance) noexcept { return impl->virt->setFlattenTolerance(impl, tolerance); }
798
799 //! \}
800
801 //! \name Composition Options
802 //! \{
803
804 //! Returns composition operator.
805 BL_INLINE uint32_t compOp() const noexcept { return impl->state->compOp; }
806 //! Sets composition operator to `compOp`, see `BLCompOp`.
807 BL_INLINE BLResult setCompOp(uint32_t compOp) noexcept { return impl->virt->setCompOp(impl, compOp); }
808
809 //! Returns global alpha value.
810 BL_INLINE double globalAlpha() const noexcept { return impl->state->globalAlpha; }
811 //! Sets global alpha value.
812 BL_INLINE BLResult setGlobalAlpha(double alpha) noexcept { return impl->virt->setGlobalAlpha(impl, alpha); }
813
814 //! \}
815
816 //! \name Style Options
817 //! \{
818
819 BL_INLINE uint32_t styleType(uint32_t opType) const noexcept {
820 return opType <= BL_CONTEXT_OP_TYPE_COUNT ? uint32_t(impl->state->styleType[opType]) : uint32_t(0);
821 }
822
823 //! Returns fill or alpha value dependeing on the rendering operation `opType`.
824 //!
825 //! The function behaves like `fillAlpha()` or `strokeAlpha()` depending on
826 //! `opType` value, see `BLContextOpType`.
827 BL_INLINE double styleAlpha(uint32_t opType) const noexcept {
828 return opType < BL_CONTEXT_OP_TYPE_COUNT ? impl->state->styleAlpha[opType] : 0.0;
829 }
830
831 //! Set fill or stroke `alpha` value depending on the rendering operation `opType`.
832 //!
833 //! The function behaves like `setFillAlpha()` or `setStrokeAlpha()` depending
834 //! on `opType` value, see `BLContextOpType`.
835 BL_INLINE BLResult setStyleAlpha(uint32_t opType, double alpha) noexcept {
836 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
837 return blTraceError(BL_ERROR_INVALID_VALUE);
838 return impl->virt->setStyleAlpha[opType](impl, alpha);
839 }
840
841 BL_INLINE BLResult getStyle(uint32_t opType, BLRgba32& out) const noexcept {
842 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
843 return blTraceError(BL_ERROR_INVALID_VALUE);
844 return impl->virt->getStyleRgba32[opType](impl, &out.value);
845 }
846
847 BL_INLINE BLResult getStyle(uint32_t opType, BLRgba64& out) const noexcept {
848 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
849 return blTraceError(BL_ERROR_INVALID_VALUE);
850 return impl->virt->getStyleRgba64[opType](impl, &out.value);
851 }
852
853 BL_INLINE BLResult getStyle(uint32_t opType, BLPattern& out) const noexcept {
854 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
855 return blTraceError(BL_ERROR_INVALID_VALUE);
856 return impl->virt->getStyle[opType](impl, &out);
857 }
858
859 BL_INLINE BLResult getStyle(uint32_t opType, BLGradient& out) const noexcept {
860 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
861 return blTraceError(BL_ERROR_INVALID_VALUE);
862 return impl->virt->getStyle[opType](impl, &out);
863 }
864
865 BL_INLINE BLResult setStyle(uint32_t opType, const BLGradient& gradient) noexcept {
866 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
867 return blTraceError(BL_ERROR_INVALID_VALUE);
868 return impl->virt->setStyle[opType](impl, &gradient);
869 }
870
871 BL_INLINE BLResult setStyle(uint32_t opType, const BLPattern& pattern) noexcept {
872 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
873 return blTraceError(BL_ERROR_INVALID_VALUE);
874 return impl->virt->setStyle[opType](impl, &pattern);
875 }
876
877 BL_INLINE BLResult setStyle(uint32_t opType, const BLImage& image) noexcept {
878 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
879 return blTraceError(BL_ERROR_INVALID_VALUE);
880 return impl->virt->setStyle[opType](impl, &image);
881 }
882
883 BL_INLINE BLResult setStyle(uint32_t opType, const BLVariant& variant) noexcept {
884 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
885 return blTraceError(BL_ERROR_INVALID_VALUE);
886 return impl->virt->setStyle[opType](impl, &variant);
887 }
888
889 BL_INLINE BLResult setStyle(uint32_t opType, const BLRgba32& rgba32) noexcept {
890 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
891 return blTraceError(BL_ERROR_INVALID_VALUE);
892 return impl->virt->setStyleRgba32[opType](impl, rgba32.value);
893 }
894
895 BL_INLINE BLResult setStyle(uint32_t opType, const BLRgba64& rgba64) noexcept {
896 if (BL_UNLIKELY(opType >= BL_CONTEXT_OP_TYPE_COUNT))
897 return blTraceError(BL_ERROR_INVALID_VALUE);
898 return impl->virt->setStyleRgba64[opType](impl, rgba64.value);
899 }
900
901 //! \}
902
903 //! \name Fill Style & Options
904 //! \{
905
906 //! Returns fill alpha value.
907 BL_INLINE double fillAlpha() const noexcept { return impl->state->styleAlpha[kOpFill]; }
908 //! Sets fill `alpha` value.
909 BL_INLINE BLResult setFillAlpha(double alpha) noexcept { return impl->virt->setStyleAlpha[kOpFill](impl, alpha); }
910
911 BL_INLINE uint32_t fillStyleType() const noexcept { return impl->state->styleType[kOpFill]; }
912 BL_INLINE BLResult getFillStyle(BLRgba32& out) const noexcept { return impl->virt->getStyleRgba32[kOpFill](impl, &out.value); }
913 BL_INLINE BLResult getFillStyle(BLRgba64& out) const noexcept { return impl->virt->getStyleRgba64[kOpFill](impl, &out.value); }
914 BL_INLINE BLResult getFillStyle(BLPattern& out) const noexcept { return impl->virt->getStyle[kOpFill](impl, &out); }
915 BL_INLINE BLResult getFillStyle(BLGradient& out) const noexcept { return impl->virt->getStyle[kOpFill](impl, &out); }
916
917 BL_INLINE BLResult setFillStyle(const BLRgba32& rgba32) noexcept { return impl->virt->setStyleRgba32[kOpFill](impl, rgba32.value); }
918 BL_INLINE BLResult setFillStyle(const BLRgba64& rgba64) noexcept { return impl->virt->setStyleRgba64[kOpFill](impl, rgba64.value); }
919 BL_INLINE BLResult setFillStyle(const BLGradient& gradient) noexcept { return impl->virt->setStyle[kOpFill](impl, &gradient); }
920 BL_INLINE BLResult setFillStyle(const BLPattern& pattern) noexcept { return impl->virt->setStyle[kOpFill](impl, &pattern); }
921 BL_INLINE BLResult setFillStyle(const BLVariant& variant) noexcept { return impl->virt->setStyle[kOpFill](impl, &variant); }
922
923 //! Returns fill-rule, see `BLFillRule`.
924 BL_INLINE uint32_t fillRule() const noexcept { return impl->state->fillRule; }
925 //! Sets fill-rule, see `BLFillRule`.
926 BL_INLINE BLResult setFillRule(uint32_t fillRule) noexcept { return impl->virt->setFillRule(impl, fillRule); }
927
928 //! \}
929
930 //! \name Stroke Style & Options
931 //! \{
932
933 //! Returns stroke alpha value.
934 BL_INLINE double strokeAlpha() const noexcept { return impl->state->styleAlpha[kOpStroke]; }
935 //! Sets stroke alpha value to `alpha`.
936 BL_INLINE BLResult setStrokeAlpha(double alpha) noexcept { return impl->virt->setStyleAlpha[kOpStroke](impl, alpha); }
937
938 BL_INLINE uint32_t strokeStyleType() const noexcept { return impl->state->styleType[kOpStroke]; }
939 BL_INLINE BLResult getStrokeStyle(BLRgba32& out) const noexcept { return impl->virt->getStyleRgba32[kOpStroke](impl, &out.value); }
940 BL_INLINE BLResult getStrokeStyle(BLRgba64& out) const noexcept { return impl->virt->getStyleRgba64[kOpStroke](impl, &out.value); }
941 BL_INLINE BLResult getStrokeStyle(BLPattern& out) const noexcept { return impl->virt->getStyle[kOpStroke](impl, &out); }
942 BL_INLINE BLResult getStrokeStyle(BLGradient& out) const noexcept { return impl->virt->getStyle[kOpStroke](impl, &out); }
943
944 BL_INLINE BLResult setStrokeStyle(const BLRgba32& rgba32) noexcept { return impl->virt->setStyleRgba32[kOpStroke](impl, rgba32.value); }
945 BL_INLINE BLResult setStrokeStyle(const BLRgba64& rgba64) noexcept { return impl->virt->setStyleRgba64[kOpStroke](impl, rgba64.value); }
946 BL_INLINE BLResult setStrokeStyle(const BLPattern& pattern) noexcept { return impl->virt->setStyle[kOpStroke](impl, &pattern); }
947 BL_INLINE BLResult setStrokeStyle(const BLGradient& gradient) noexcept { return impl->virt->setStyle[kOpStroke](impl, &gradient); }
948 BL_INLINE BLResult setStrokeStyle(const BLVariant& variant) noexcept { return impl->virt->setStyle[kOpStroke](impl, &variant); }
949
950 //! Returns stroke width.
951 BL_INLINE double strokeWidth() const noexcept { return impl->state->strokeOptions.width; }
952 //! Returns stroke miter-limit.
953 BL_INLINE double strokeMiterLimit() const noexcept { return impl->state->strokeOptions.miterLimit; }
954 //! Returns stroke join, see `BLStrokeJoin`.
955 BL_INLINE uint32_t strokeJoin() const noexcept { return impl->state->strokeOptions.join; }
956 //! Returns stroke start-cap, see `BLStrokeCap`.
957 BL_INLINE uint32_t strokeStartCap() const noexcept { return impl->state->strokeOptions.startCap; }
958 //! Returns stroke end-cap, see `BLStrokeCap`.
959 BL_INLINE uint32_t strokeEndCap() const noexcept { return impl->state->strokeOptions.endCap; }
960 //! Returns stroke dash-offset.
961 BL_INLINE double strokeDashOffset() const noexcept { return impl->state->strokeOptions.dashOffset; }
962 //! Returns stroke dash-array.
963 BL_INLINE const BLArray<double>& strokeDashArray() const noexcept { return impl->state->strokeOptions.dashArray; }
964 //! Returns stroke transform order, see `BLStrokeTransformOrder`.
965 BL_INLINE uint32_t strokeTransformOrder() const noexcept { return impl->state->strokeOptions.transformOrder; }
966 //! Returns stroke options as a reference to `BLStrokeOptions`.
967 BL_INLINE const BLStrokeOptions& strokeOptions() const noexcept { return impl->state->strokeOptions; }
968
969 //! Sets stroke width to `width`.
970 BL_INLINE BLResult setStrokeWidth(double width) noexcept { return impl->virt->setStrokeWidth(impl, width); }
971 //! Sets miter limit to `miterLimit`.
972 BL_INLINE BLResult setStrokeMiterLimit(double miterLimit) noexcept { return impl->virt->setStrokeMiterLimit(impl, miterLimit); }
973 //! Sets stroke join to `strokeJoin`, see `BLStrokeJoin`.
974 BL_INLINE BLResult setStrokeJoin(uint32_t strokeJoin) noexcept { return impl->virt->setStrokeJoin(impl, strokeJoin); }
975 //! Sets stroke cap of the specified `type` to `strokeCap`, see `BLStrokeCap`.
976 BL_INLINE BLResult setStrokeCap(uint32_t type, uint32_t strokeCap) noexcept { return impl->virt->setStrokeCap(impl, type, strokeCap); }
977 //! Sets stroke start cap to `strokeCap`, see `BLStrokeCap`.
978 BL_INLINE BLResult setStrokeStartCap(uint32_t strokeCap) noexcept { return setStrokeCap(BL_STROKE_CAP_POSITION_START, strokeCap); }
979 //! Sets stroke end cap to `strokeCap`, see `BLStrokeCap`.
980 BL_INLINE BLResult setStrokeEndCap(uint32_t strokeCap) noexcept { return setStrokeCap(BL_STROKE_CAP_POSITION_END, strokeCap); }
981 //! Sets all stroke caps to `strokeCap`, see `BLStrokeCap`.
982 BL_INLINE BLResult setStrokeCaps(uint32_t strokeCap) noexcept { return impl->virt->setStrokeCaps(impl, strokeCap); }
983 //! Sets stroke dash-offset to `dashOffset`.
984 BL_INLINE BLResult setStrokeDashOffset(double dashOffset) noexcept { return impl->virt->setStrokeDashOffset(impl, dashOffset); }
985 //! Sets stroke dash-array to `dashArray`.
986 BL_INLINE BLResult setStrokeDashArray(const BLArray<double>& dashArray) noexcept { return impl->virt->setStrokeDashArray(impl, &dashArray); }
987 //! Sets stroke transformation order to `transformOrder`, see `BLStrokeTransformOrder`.
988 BL_INLINE BLResult setStrokeTransformOrder(uint32_t transformOrder) noexcept { return impl->virt->setStrokeTransformOrder(impl, transformOrder); }
989 //! Sets all stroke `options`.
990 BL_INLINE BLResult setStrokeOptions(const BLStrokeOptions& options) noexcept { return impl->virt->setStrokeOptions(impl, &options); }
991
992 //! \}
993
994 //! \name Clip Operations
995 //! \{
996
997 //! Restores clipping to the last saved state or to the context default
998 //! clipping if there is no saved state.
999 //!
1000 //! If there are no saved states then it resets clipping completely to the
1001 //! initial state that was used when the rendering context was created.
1002 BL_INLINE BLResult restoreClipping() noexcept { return impl->virt->restoreClipping(impl); }
1003
1004 BL_INLINE BLResult clipToRect(const BLRectI& rect) noexcept { return impl->virt->clipToRectI(impl, &rect); }
1005 BL_INLINE BLResult clipToRect(const BLRect& rect) noexcept { return impl->virt->clipToRectD(impl, &rect); }
1006 BL_INLINE BLResult clipToRect(double x, double y, double w, double h) noexcept { return clipToRect(BLRect(x, y, w, h)); }
1007
1008 //! \}
1009
1010 //! \name Clear Operations
1011 //! \{
1012
1013 //! Clear everything.
1014 BL_INLINE BLResult clearAll() noexcept { return impl->virt->clearAll(impl); }
1015
1016 //! Clears a rectangle `rect`.
1017 BL_INLINE BLResult clearRect(const BLRectI& rect) noexcept { return impl->virt->clearRectI(impl, &rect); }
1018 //! Clears a rectangle `rect`.
1019 BL_INLINE BLResult clearRect(const BLRect& rect) noexcept { return impl->virt->clearRectD(impl, &rect); }
1020 //! \overload
1021 BL_INLINE BLResult clearRect(double x, double y, double w, double h) noexcept { return clearRect(BLRect(x, y, w, h)); }
1022
1023 //! \}
1024
1025 //! \name Fill Operations
1026 //! \{
1027
1028 //! Fills the passed geometry specified by `geometryType` and `geometryData` [Internal].
1029 BL_INLINE BLResult fillGeometry(uint32_t geometryType, const void* geometryData) noexcept { return impl->virt->fillGeometry(impl, geometryType, geometryData); }
1030
1031 //! Fills everything.
1032 BL_INLINE BLResult fillAll() noexcept { return impl->virt->fillAll(impl); }
1033
1034 //! Fills a box.
1035 BL_INLINE BLResult fillBox(const BLBox& box) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_BOXD, &box); }
1036 // \overload
1037 BL_INLINE BLResult fillBox(const BLBoxI& box) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_BOXI, &box); }
1038 // \overload
1039 BL_INLINE BLResult fillBox(double x0, double y0, double x1, double y1) noexcept { return fillBox(BLBox(x0, y0, x1, y1)); }
1040
1041 //! Fills a rectangle `rect`.
1042 BL_INLINE BLResult fillRect(const BLRectI& rect) noexcept { return impl->virt->fillRectI(impl, &rect); }
1043 //! Fills a rectangle `rect`.
1044 BL_INLINE BLResult fillRect(const BLRect& rect) noexcept { return impl->virt->fillRectD(impl, &rect); }
1045 //! \overload
1046 BL_INLINE BLResult fillRect(double x, double y, double w, double h) noexcept { return fillRect(BLRect(x, y, w, h)); }
1047
1048 //! Fills a circle.
1049 BL_INLINE BLResult fillCircle(const BLCircle& circle) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_CIRCLE, &circle); }
1050 //! \overload
1051 BL_INLINE BLResult fillCircle(double cx, double cy, double r) noexcept { return fillCircle(BLCircle(cx, cy, r)); }
1052
1053 //! Fills an ellipse.
1054 BL_INLINE BLResult fillEllipse(const BLEllipse& ellipse) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_ELLIPSE, &ellipse); }
1055 //! \overload
1056 BL_INLINE BLResult fillEllipse(double cx, double cy, double rx, double ry) noexcept { return fillEllipse(BLEllipse(cx, cy, rx, ry)); }
1057
1058 //! Fills a rounded rectangle.
1059 BL_INLINE BLResult fillRoundRect(const BLRoundRect& rr) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_ROUND_RECT, &rr); }
1060 //! \overload
1061 BL_INLINE BLResult fillRoundRect(const BLRect& rect, double r) noexcept { return fillRoundRect(BLRoundRect(rect.x, rect.y, rect.w, rect.h, r)); }
1062 //! \overload
1063 BL_INLINE BLResult fillRoundRect(const BLRect& rect, double rx, double ry) noexcept { return fillRoundRect(BLRoundRect(rect.x, rect.y, rect.w, rect.h, rx, ry)); }
1064 //! \overload
1065 BL_INLINE BLResult fillRoundRect(double x, double y, double w, double h, double r) noexcept { return fillRoundRect(BLRoundRect(x, y, w, h, r)); }
1066 //! \overload
1067 BL_INLINE BLResult fillRoundRect(double x, double y, double w, double h, double rx, double ry) noexcept { return fillRoundRect(BLRoundRect(x, y, w, h, rx, ry)); }
1068
1069 //! Fills a chord.
1070 BL_INLINE BLResult fillChord(const BLArc& chord) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_CHORD, &chord); }
1071 //! \overload
1072 BL_INLINE BLResult fillChord(double cx, double cy, double r, double start, double sweep) noexcept { return fillChord(BLArc(cx, cy, r, r, start, sweep)); }
1073 //! \overload
1074 BL_INLINE BLResult fillChord(double cx, double cy, double rx, double ry, double start, double sweep) noexcept { return fillChord(BLArc(cx, cy, rx, ry, start, sweep)); }
1075
1076 //! Fills a pie.
1077 BL_INLINE BLResult fillPie(const BLArc& pie) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_PIE, &pie); }
1078 //! \overload
1079 BL_INLINE BLResult fillPie(double cx, double cy, double r, double start, double sweep) noexcept { return fillPie(BLArc(cx, cy, r, r, start, sweep)); }
1080 //! \overload
1081 BL_INLINE BLResult fillPie(double cx, double cy, double rx, double ry, double start, double sweep) noexcept { return fillPie(BLArc(cx, cy, rx, ry, start, sweep)); }
1082
1083 //! Fills a triangle.
1084 BL_INLINE BLResult fillTriangle(const BLTriangle& triangle) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_TRIANGLE, &triangle); }
1085 //! \overload
1086 BL_INLINE BLResult fillTriangle(double x0, double y0, double x1, double y1, double x2, double y2) noexcept { return fillTriangle(BLTriangle(x0, y0, x1, y1, x2, y2)); }
1087
1088 //! Fills a polygon.
1089 BL_INLINE BLResult fillPolygon(const BLArrayView<BLPoint>& poly) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_POLYGOND, &poly); }
1090 //! \overload
1091 BL_INLINE BLResult fillPolygon(const BLPoint* poly, size_t n) noexcept { return fillPolygon(BLArrayView<BLPoint>{poly, n}); }
1092
1093 //! Fills a polygon.
1094 BL_INLINE BLResult fillPolygon(const BLArrayView<BLPointI>& poly) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_POLYGONI, &poly); }
1095 //! \overload
1096 BL_INLINE BLResult fillPolygon(const BLPointI* poly, size_t n) noexcept { return fillPolygon(BLArrayView<BLPointI>{poly, n}); }
1097
1098 //! Fills an array of boxes.
1099 BL_INLINE BLResult fillBoxArray(const BLArrayView<BLBox>& array) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, &array); }
1100 //! \overload
1101 BL_INLINE BLResult fillBoxArray(const BLBox* data, size_t n) noexcept { return fillBoxArray(BLArrayView<BLBox>{data, n}); }
1102
1103 //! Fills an array of boxes.
1104 BL_INLINE BLResult fillBoxArray(const BLArrayView<BLBoxI>& array) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, &array); }
1105 //! \overload
1106 BL_INLINE BLResult fillBoxArray(const BLBoxI* data, size_t n) noexcept { return fillBoxArray(BLArrayView<BLBoxI>{data, n}); }
1107
1108 //! Fills an array of rectangles.
1109 BL_INLINE BLResult fillRectArray(const BLArrayView<BLRect>& array) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, &array); }
1110 //! \overload
1111 BL_INLINE BLResult fillRectArray(const BLRect* data, size_t n) noexcept { return fillRectArray(BLArrayView<BLRect>{data, n}); }
1112
1113 //! Fills an array of rectangles.
1114 BL_INLINE BLResult fillRectArray(const BLArrayView<BLRectI>& array) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, &array); }
1115 //! \overload
1116 BL_INLINE BLResult fillRectArray(const BLRectI* data, size_t n) noexcept { return fillRectArray(BLArrayView<BLRectI>{data, n}); }
1117
1118 //! Fills the given `region`.
1119 BL_INLINE BLResult fillRegion(const BLRegion& region) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_REGION, &region); }
1120
1121 //! Fills the given `path`.
1122 BL_INLINE BLResult fillPath(const BLPath& path) noexcept { return fillGeometry(BL_GEOMETRY_TYPE_PATH, &path); }
1123
1124 //! Fills the passed UTF-8 text by using the given `font`.
1125 BL_INLINE BLResult fillUtf8Text(const BLPointI& dst, const BLFont& font, const char* text, size_t size = SIZE_MAX) noexcept {
1126 return impl->virt->fillTextI(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF8);
1127 }
1128
1129 //! Fills the passed UTF-8 text by using the given `font`.
1130 BL_INLINE BLResult fillUtf8Text(const BLPoint& dst, const BLFont& font, const char* text, size_t size = SIZE_MAX) noexcept {
1131 return impl->virt->fillTextD(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF8);
1132 }
1133
1134 //! Fills the passed UTF-16 text by using the given `font`.
1135 BL_INLINE BLResult fillUtf16Text(const BLPointI& dst, const BLFont& font, const uint16_t* text, size_t size = SIZE_MAX) noexcept {
1136 return impl->virt->fillTextI(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF16);
1137 }
1138
1139 //! Fills the passed UTF-16 text by using the given `font`.
1140 BL_INLINE BLResult fillUtf16Text(const BLPoint& dst, const BLFont& font, const uint16_t* text, size_t size = SIZE_MAX) noexcept {
1141 return impl->virt->fillTextD(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF16);
1142 }
1143
1144 //! Fills the passed UTF-32 text by using the given `font`.
1145 BL_INLINE BLResult fillUtf32Text(const BLPointI& dst, const BLFont& font, const uint32_t* text, size_t size = SIZE_MAX) noexcept {
1146 return impl->virt->fillTextI(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF32);
1147 }
1148
1149 //! Fills the passed UTF-32 text by using the given `font`.
1150 BL_INLINE BLResult fillUtf32Text(const BLPoint& dst, const BLFont& font, const uint32_t* text, size_t size = SIZE_MAX) noexcept {
1151 return impl->virt->fillTextD(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF32);
1152 }
1153
1154 //! Fills the passed `glyphRun` by using the given `font`.
1155 BL_INLINE BLResult fillGlyphRun(const BLPointI& dst, const BLFont& font, const BLGlyphRun& glyphRun) noexcept {
1156 return impl->virt->fillGlyphRunI(impl, &dst, &font, &glyphRun);
1157 }
1158
1159 //! Fills the passed `glyphRun` by using the given `font`.
1160 BL_INLINE BLResult fillGlyphRun(const BLPoint& dst, const BLFont& font, const BLGlyphRun& glyphRun) noexcept {
1161 return impl->virt->fillGlyphRunD(impl, &dst, &font, &glyphRun);
1162 }
1163
1164 //! \}
1165
1166 //! \name Stroke Operations
1167 //! \{
1168
1169 //! Strokes the passed geometry specified by `geometryType` and `geometryData` [Internal].
1170 BL_INLINE BLResult strokeGeometry(uint32_t geometryType, const void* geometryData) noexcept { return impl->virt->strokeGeometry(impl, geometryType, geometryData); }
1171
1172 //! Strokes a box.
1173 BL_INLINE BLResult strokeBox(const BLBox& box) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_BOXD, &box); }
1174 // \overload
1175 BL_INLINE BLResult strokeBox(const BLBoxI& box) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_BOXI, &box); }
1176 // \overload
1177 BL_INLINE BLResult strokeBox(double x0, double y0, double x1, double y1) noexcept { return strokeBox(BLBox(x0, y0, x1, y1)); }
1178
1179 //! Strokes a rectangle.
1180 BL_INLINE BLResult strokeRect(const BLRect& rect) noexcept { return impl->virt->strokeRectD(impl, &rect); }
1181 //! \overload
1182 BL_INLINE BLResult strokeRect(const BLRectI& rect) noexcept { return impl->virt->strokeRectI(impl, &rect); }
1183 //! \overload
1184 BL_INLINE BLResult strokeRect(double x, double y, double w, double h) noexcept { return strokeRect(BLRect(x, y, w, h)); }
1185
1186 //! Strokes a line.
1187 BL_INLINE BLResult strokeLine(const BLLine& line) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_LINE, &line); }
1188 //! \overload
1189 BL_INLINE BLResult strokeLine(const BLPoint& p0, const BLPoint& p1) noexcept { return strokeLine(BLLine(p0.x, p0.y, p1.x, p1.y)); }
1190 //! \overload
1191 BL_INLINE BLResult strokeLine(double x0, double y0, double x1, double y1) noexcept { return strokeLine(BLLine(x0, y0, x1, y1)); }
1192
1193 //! Strokes a circle.
1194 BL_INLINE BLResult strokeCircle(const BLCircle& circle) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_CIRCLE, &circle); }
1195 //! \overload
1196 BL_INLINE BLResult strokeCircle(double cx, double cy, double r) noexcept { return strokeCircle(BLCircle(cx, cy, r)); }
1197
1198 //! Strokes an ellipse.
1199 BL_INLINE BLResult strokeEllipse(const BLEllipse& ellipse) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_ELLIPSE, &ellipse); }
1200 //! \overload
1201 BL_INLINE BLResult strokeEllipse(double cx, double cy, double rx, double ry) noexcept { return strokeEllipse(BLEllipse(cx, cy, rx, ry)); }
1202
1203 //! Strokes a round.
1204 BL_INLINE BLResult strokeRoundRect(const BLRoundRect& rr) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_ROUND_RECT, &rr); }
1205 //! \overload
1206 BL_INLINE BLResult strokeRoundRect(const BLRect& rect, double r) noexcept { return strokeRoundRect(BLRoundRect(rect.x, rect.y, rect.w, rect.h, r)); }
1207 //! \overload
1208 BL_INLINE BLResult strokeRoundRect(const BLRect& rect, double rx, double ry) noexcept { return strokeRoundRect(BLRoundRect(rect.x, rect.y, rect.w, rect.h, rx, ry)); }
1209 //! \overload
1210 BL_INLINE BLResult strokeRoundRect(double x, double y, double w, double h, double r) noexcept { return strokeRoundRect(BLRoundRect(x, y, w, h, r)); }
1211 //! \overload
1212 BL_INLINE BLResult strokeRoundRect(double x, double y, double w, double h, double rx, double ry) noexcept { return strokeRoundRect(BLRoundRect(x, y, w, h, rx, ry)); }
1213
1214 //! Strokes an arc.
1215 BL_INLINE BLResult strokeArc(const BLArc& arc) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_ARC, &arc); }
1216 //! \overload
1217 BL_INLINE BLResult strokeArc(double cx, double cy, double r, double start, double sweep) noexcept { return strokeArc(BLArc(cx, cy, r, r, start, sweep)); }
1218 //! \overload
1219 BL_INLINE BLResult strokeArc(double cx, double cy, double rx, double ry, double start, double sweep) noexcept { return strokeArc(BLArc(cx, cy, rx, ry, start, sweep)); }
1220
1221 //! Strokes a chord.
1222 BL_INLINE BLResult strokeChord(const BLArc& chord) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_CHORD, &chord); }
1223 //! \overload
1224 BL_INLINE BLResult strokeChord(double cx, double cy, double r, double start, double sweep) noexcept { return strokeChord(BLArc(cx, cy, r, r, start, sweep)); }
1225 //! \overload
1226 BL_INLINE BLResult strokeChord(double cx, double cy, double rx, double ry, double start, double sweep) noexcept { return strokeChord(BLArc(cx, cy, rx, ry, start, sweep)); }
1227
1228 //! Strokes a pie.
1229 BL_INLINE BLResult strokePie(const BLArc& pie) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_PIE, &pie); }
1230 //! \overload
1231 BL_INLINE BLResult strokePie(double cx, double cy, double r, double start, double sweep) noexcept { return strokePie(BLArc(cx, cy, r, r, start, sweep)); }
1232 //! \overload
1233 BL_INLINE BLResult strokePie(double cx, double cy, double rx, double ry, double start, double sweep) noexcept { return strokePie(BLArc(cx, cy, rx, ry, start, sweep)); }
1234
1235 //! Strokes a triangle.
1236 BL_INLINE BLResult strokeTriangle(const BLTriangle& triangle) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_TRIANGLE, &triangle); }
1237 //! \overload
1238 BL_INLINE BLResult strokeTriangle(double x0, double y0, double x1, double y1, double x2, double y2) noexcept { return strokeTriangle(BLTriangle(x0, y0, x1, y1, x2, y2)); }
1239
1240 //! Strokes a polyline.
1241 BL_INLINE BLResult strokePolyline(const BLArrayView<BLPoint>& poly) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_POLYLINED, &poly); }
1242 //! \overload
1243 BL_INLINE BLResult strokePolyline(const BLPoint* poly, size_t n) noexcept { return strokePolyline(BLArrayView<BLPoint>{poly, n}); }
1244
1245 //! Strokes a polyline.
1246 BL_INLINE BLResult strokePolyline(const BLArrayView<BLPointI>& poly) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_POLYLINED, &poly); }
1247 //! \overload
1248 BL_INLINE BLResult strokePolyline(const BLPointI* poly, size_t n) noexcept { return strokePolyline(BLArrayView<BLPointI>{poly, n}); }
1249
1250 //! Strokes a polygon.
1251 BL_INLINE BLResult strokePolygon(const BLArrayView<BLPoint>& poly) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_POLYGOND, &poly); }
1252 //! \overload
1253 BL_INLINE BLResult strokePolygon(const BLPoint* poly, size_t n) noexcept { return strokePolygon(BLArrayView<BLPoint>{poly, n}); }
1254
1255 //! Strokes a polygon.
1256 BL_INLINE BLResult strokePolygon(const BLArrayView<BLPointI>& poly) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_POLYGONI, &poly); }
1257 //! \overload
1258 BL_INLINE BLResult strokePolygon(const BLPointI* poly, size_t n) noexcept { return strokePolygon(BLArrayView<BLPointI>{poly, n}); }
1259
1260 //! Strokes an array of boxes.
1261 BL_INLINE BLResult strokeBoxArray(const BLArrayView<BLBox>& array) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD, &array); }
1262 //! \overload
1263 BL_INLINE BLResult strokeBoxArray(const BLBox* data, size_t n) noexcept { return strokeBoxArray(BLArrayView<BLBox>{data, n}); }
1264
1265 //! Strokes an array of boxes.
1266 BL_INLINE BLResult strokeBoxArray(const BLArrayView<BLBoxI>& array) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI, &array); }
1267 //! \overload
1268 BL_INLINE BLResult strokeBoxArray(const BLBoxI* data, size_t n) noexcept { return strokeBoxArray(BLArrayView<BLBoxI>{data, n}); }
1269
1270 //! Strokes an array of rectangles.
1271 BL_INLINE BLResult strokeRectArray(const BLArrayView<BLRect>& array) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD, &array); }
1272 //! \overload
1273 BL_INLINE BLResult strokeRectArray(const BLRect* data, size_t n) noexcept { return strokeRectArray(BLArrayView<BLRect>{data, n}); }
1274
1275 //! Strokes an array of rectangles.
1276 BL_INLINE BLResult strokeRectArray(const BLArrayView<BLRectI>& array) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI, &array); }
1277 //! \overload
1278 BL_INLINE BLResult strokeRectArray(const BLRectI* data, size_t n) noexcept { return strokeRectArray(BLArrayView<BLRectI>{data, n}); }
1279
1280 //! Strokes a path.
1281 BL_INLINE BLResult strokePath(const BLPath& path) noexcept { return strokeGeometry(BL_GEOMETRY_TYPE_PATH, &path); }
1282
1283 //! Strokes the passed UTF-8 text by using the given `font`.
1284 BL_INLINE BLResult strokeUtf8Text(const BLPointI& dst, const BLFont& font, const char* text, size_t size = SIZE_MAX) noexcept {
1285 return impl->virt->strokeTextI(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF8);
1286 }
1287
1288 //! Strokes the passed UTF-8 text by using the given `font`.
1289 BL_INLINE BLResult strokeUtf8Text(const BLPoint& dst, const BLFont& font, const char* text, size_t size = SIZE_MAX) noexcept {
1290 return impl->virt->strokeTextD(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF8);
1291 }
1292
1293 //! Strokes the passed UTF-16 text by using the given `font`.
1294 BL_INLINE BLResult strokeUtf16Text(const BLPointI& dst, const BLFont& font, const uint16_t* text, size_t size = SIZE_MAX) noexcept {
1295 return impl->virt->strokeTextI(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF16);
1296 }
1297
1298 //! Strokes the passed UTF-16 text by using the given `font`.
1299 BL_INLINE BLResult strokeUtf16Text(const BLPoint& dst, const BLFont& font, const uint16_t* text, size_t size = SIZE_MAX) noexcept {
1300 return impl->virt->strokeTextD(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF16);
1301 }
1302
1303 //! Strokes the passed UTF-32 text by using the given `font`.
1304 BL_INLINE BLResult strokeUtf32Text(const BLPointI& dst, const BLFont& font, const uint32_t* text, size_t size = SIZE_MAX) noexcept {
1305 return impl->virt->strokeTextI(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF32);
1306 }
1307
1308 //! Strokes the passed UTF-32 text by using the given `font`.
1309 BL_INLINE BLResult strokeUtf32Text(const BLPoint& dst, const BLFont& font, const uint32_t* text, size_t size = SIZE_MAX) noexcept {
1310 return impl->virt->strokeTextD(impl, &dst, &font, text, size, BL_TEXT_ENCODING_UTF32);
1311 }
1312
1313 //! Strokes the passed `glyphRun` by using the given `font`.
1314 BL_INLINE BLResult strokeGlyphRun(const BLPointI& dst, const BLFont& font, const BLGlyphRun& glyphRun) noexcept {
1315 return impl->virt->strokeGlyphRunI(impl, &dst, &font, &glyphRun);
1316 }
1317
1318 //! Strokes the passed `glyphRun` by using the given `font`.
1319 BL_INLINE BLResult strokeGlyphRun(const BLPoint& dst, const BLFont& font, const BLGlyphRun& glyphRun) noexcept {
1320 return impl->virt->strokeGlyphRunD(impl, &dst, &font, &glyphRun);
1321 }
1322
1323 //! \}
1324
1325 //! \name Image Blitting
1326 //! \{
1327
1328 //! Blits source image `src` at coordinates specified by `dst`..
1329 BL_INLINE BLResult blitImage(const BLPoint& dst, const BLImage& src) noexcept { return impl->virt->blitImageD(impl, &dst, &src, nullptr); }
1330 //! Blits an area of source image `src` specified by `srcArea` at coordinates specified by `dst`.
1331 BL_INLINE BLResult blitImage(const BLPoint& dst, const BLImage& src, const BLRectI& srcArea) noexcept { return impl->virt->blitImageD(impl, &dst, &src, &srcArea); }
1332
1333 //! Blits source image `src` at coordinates specified by `dst`. (int coordinates).
1334 BL_INLINE BLResult blitImage(const BLPointI& dst, const BLImage& src) noexcept { return impl->virt->blitImageI(impl, &dst, &src, nullptr); }
1335 //! Blits an area in source image `src` specified by `srcArea` at coordinates specified by `dst`. (int coordinates).
1336 BL_INLINE BLResult blitImage(const BLPointI& dst, const BLImage& src, const BLRectI& srcArea) noexcept { return impl->virt->blitImageI(impl, &dst, &src, &srcArea); }
1337
1338 //! Blits a source image `src` scaled to fit into `dst` rectangle.
1339 BL_INLINE BLResult blitImage(const BLRect& dst, const BLImage& src) noexcept { return impl->virt->blitScaledImageD(impl, &dst, &src, nullptr); }
1340 //! Blits an area of source image `src` specified by `srcArea` scaled to fit into `dst` rectangle.
1341 BL_INLINE BLResult blitImage(const BLRect& dst, const BLImage& src, const BLRectI& srcArea) noexcept { return impl->virt->blitScaledImageD(impl, &dst, &src, &srcArea); }
1342
1343 //! Blits a source image `src` scaled to fit into `dst` rectangle (int coordinates).
1344 BL_INLINE BLResult blitImage(const BLRectI& dst, const BLImage& src) noexcept { return impl->virt->blitScaledImageI(impl, &dst, &src, nullptr); }
1345 //! Blits an area of source image `src` specified by `srcArea` scaled to fit into `dst` rectangle (int coordinates).
1346 BL_INLINE BLResult blitImage(const BLRectI& dst, const BLImage& src, const BLRectI& srcArea) noexcept { return impl->virt->blitScaledImageI(impl, &dst, &src, &srcArea); }
1347
1348 //! \}
1349
1350 static BL_INLINE const BLContext& none() noexcept { return reinterpret_cast<const BLContext*>(blNone)[kImplType]; }
1351};
1352#endif
1353
1354//! \}
1355
1356#endif // BLEND2D_BLCONTEXT_H
1357