1 #ifndef _THORVG_H_
2 #define _THORVG_H_
3 
4 #include "../../lv_conf_internal.h"
5 
6 /*Testing of dependencies*/
7 #if LV_USE_THORVG && LV_USE_VECTOR_GRAPHIC == 0
8 #error "ThorVG: LV_USE_VECTOR_GRAPHIC is required. Enable it in lv_conf.h"
9 #endif
10 
11 #if LV_USE_THORVG_INTERNAL
12 #define TVG_BUILD 1
13 
14 
15 #include <functional>
16 #include <memory>
17 #include <string>
18 #include <list>
19 
20 #ifdef TVG_API
21     #undef TVG_API
22 #endif
23 
24 #ifndef TVG_STATIC
25     #ifdef _WIN32
26         #if TVG_BUILD
27             #define TVG_API __declspec(dllexport)
28         #else
29             #define TVG_API __declspec(dllimport)
30         #endif
31     #elif (defined(__SUNPRO_C)  || defined(__SUNPRO_CC))
32         #define TVG_API __global
33     #else
34         #if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__INTEL_COMPILER)
35             #define TVG_API __attribute__ ((visibility("default")))
36         #else
37             #define TVG_API
38         #endif
39     #endif
40 #else
41     #define TVG_API
42 #endif
43 
44 #ifdef TVG_DEPRECATED
45     #undef TVG_DEPRECATED
46 #endif
47 
48 #ifdef _WIN32
49     #define TVG_DEPRECATED __declspec(deprecated)
50 #elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
51     #define TVG_DEPRECATED __attribute__ ((__deprecated__))
52 #else
53     #define TVG_DEPRECATED
54 #endif
55 
56 #define _TVG_DECLARE_PRIVATE(A) \
57     struct Impl; \
58     Impl* pImpl; \
59 protected: \
60     A(const A&) = delete; \
61     const A& operator=(const A&) = delete; \
62     A()
63 
64 #define _TVG_DISABLE_CTOR(A) \
65     A() = delete; \
66     ~A() = delete
67 
68 #define _TVG_DECLARE_ACCESSOR(A) \
69     friend A
70 
71 namespace tvg
72 {
73 
74 class RenderMethod;
75 class Animation;
76 
77 /**
78  * @defgroup ThorVG ThorVG
79  * @brief ThorVG classes and enumerations providing C++ APIs.
80  */
81 
82 /**@{*/
83 
84 /**
85  * @brief Enumeration specifying the result from the APIs.
86  *
87  * All ThorVG APIs could potentially return one of the values in the list.
88  * Please note that some APIs may additionally specify the reasons that trigger their return values.
89  *
90  */
91 enum class Result
92 {
93     Success = 0,           ///< The value returned in case of a correct request execution.
94     InvalidArguments,      ///< The value returned in the event of a problem with the arguments given to the API - e.g. empty paths or null pointers.
95     InsufficientCondition, ///< The value returned in case the request cannot be processed - e.g. asking for properties of an object, which does not exist.
96     FailedAllocation,      ///< The value returned in case of unsuccessful memory allocation.
97     MemoryCorruption,      ///< The value returned in the event of bad memory handling - e.g. failing in pointer releasing or casting
98     NonSupport,            ///< The value returned in case of choosing unsupported engine features(options).
99     Unknown                ///< The value returned in all other cases.
100 };
101 
102 
103 /**
104  * @brief Enumeration specifying the values of the path commands accepted by TVG.
105  *
106  * Not to be confused with the path commands from the svg path element (like M, L, Q, H and many others).
107  * TVG interprets all of them and translates to the ones from the PathCommand values.
108  */
109 enum class PathCommand
110 {
111     Close = 0, ///< Ends the current sub-path and connects it with its initial point. This command doesn't expect any points.
112     MoveTo,    ///< Sets a new initial point of the sub-path and a new current point. This command expects 1 point: the starting position.
113     LineTo,    ///< Draws a line from the current point to the given point and sets a new value of the current point. This command expects 1 point: the end-position of the line.
114     CubicTo    ///< Draws a cubic Bezier curve from the current point to the given point using two given control points and sets a new value of the current point. This command expects 3 points: the 1st control-point, the 2nd control-point, the end-point of the curve.
115 };
116 
117 
118 /**
119  * @brief Enumeration determining the ending type of a stroke in the open sub-paths.
120  */
121 enum class StrokeCap
122 {
123     Square = 0, ///< The stroke is extended in both end-points of a sub-path by a rectangle, with the width equal to the stroke width and the length equal to the half of the stroke width. For zero length sub-paths the square is rendered with the size of the stroke width.
124     Round,      ///< The stroke is extended in both end-points of a sub-path by a half circle, with a radius equal to the half of a stroke width. For zero length sub-paths a full circle is rendered.
125     Butt        ///< The stroke ends exactly at each of the two end-points of a sub-path. For zero length sub-paths no stroke is rendered.
126 };
127 
128 
129 /**
130  * @brief Enumeration determining the style used at the corners of joined stroked path segments.
131  */
132 enum class StrokeJoin
133 {
134     Bevel = 0, ///< The outer corner of the joined path segments is bevelled at the join point. The triangular region of the corner is enclosed by a straight line between the outer corners of each stroke.
135     Round,     ///< The outer corner of the joined path segments is rounded. The circular region is centered at the join point.
136     Miter      ///< The outer corner of the joined path segments is spiked. The spike is created by extension beyond the join point of the outer edges of the stroke until they intersect. In case the extension goes beyond the limit, the join style is converted to the Bevel style.
137 };
138 
139 
140 /**
141  * @brief Enumeration specifying how to fill the area outside the gradient bounds.
142  */
143 enum class FillSpread
144 {
145     Pad = 0, ///< The remaining area is filled with the closest stop color.
146     Reflect, ///< The gradient pattern is reflected outside the gradient area until the expected region is filled.
147     Repeat   ///< The gradient pattern is repeated continuously beyond the gradient area until the expected region is filled.
148 };
149 
150 
151 /**
152  * @brief Enumeration specifying the algorithm used to establish which parts of the shape are treated as the inside of the shape.
153  */
154 enum class FillRule
155 {
156     Winding = 0, ///< A line from the point to a location outside the shape is drawn. The intersections of the line with the path segment of the shape are counted. Starting from zero, if the path segment of the shape crosses the line clockwise, one is added, otherwise one is subtracted. If the resulting sum is non zero, the point is inside the shape.
157     EvenOdd      ///< A line from the point to a location outside the shape is drawn and its intersections with the path segments of the shape are counted. If the number of intersections is an odd number, the point is inside the shape.
158 };
159 
160 
161 /**
162  * @brief Enumeration indicating the method used in the composition of two objects - the target and the source.
163  *
164  * Notation: S(Source), T(Target), SA(Source Alpha), TA(Target Alpha)
165  *
166  * @see Paint::composite()
167  */
168 enum class CompositeMethod
169 {
170     None = 0,           ///< No composition is applied.
171     ClipPath,           ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. Note that ClipPath only supports the Shape type. @deprecated Use Paint::clip() instead.
172     AlphaMask,          ///< Alpha Masking using the compositing target's pixels as an alpha value.
173     InvAlphaMask,       ///< Alpha Masking using the complement to the compositing target's pixels as an alpha value.
174     LumaMask,           ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the compositing target's pixels. @since 0.9
175     InvLumaMask,        ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the complement to the compositing target's pixels. @since 0.11
176     AddMask,            ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) (Experimental API)
177     SubtractMask,       ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) (Experimental API)
178     IntersectMask,      ///< Computes the result by taking the minimum value between the target alpha and the source alpha and multiplies it with the target color. (T * min(TA, SA)) (Experimental API)
179     DifferenceMask,     ///< Calculates the absolute difference between the target color and the source color multiplied by the complement of the target alpha. abs(T - S * (255 - TA)) (Experimental API)
180     LightenMask,        ///< Where multiple masks intersect, the highest transparency value is used. (Experimental API)
181     DarkenMask          ///< Where multiple masks intersect, the lowest transparency value is used. (Experimental API)
182 };
183 
184 
185 /**
186  * @brief Enumeration indicates the method used for blending paint. Please refer to the respective formulas for each method.
187  *
188  * Notation: S(source paint as the top layer), D(destination as the bottom layer), Sa(source paint alpha), Da(destination alpha)
189  *
190  * @see Paint::blend()
191  *
192  * @since 0.15
193  */
194 enum class BlendMethod : uint8_t
195 {
196     Normal = 0,        ///< Perform the alpha blending(default). S if (Sa == 255), otherwise (Sa * S) + (255 - Sa) * D
197     Multiply,          ///< Takes the RGB channel values from 0 to 255 of each pixel in the top layer and multiples them with the values for the corresponding pixel from the bottom layer. (S * D)
198     Screen,            ///< The values of the pixels in the two layers are inverted, multiplied, and then inverted again. (S + D) - (S * D)
199     Overlay,           ///< Combines Multiply and Screen blend modes. (2 * S * D) if (2 * D < Da), otherwise (Sa * Da) - 2 * (Da - S) * (Sa - D)
200     SrcOver,           ///< Replace the bottom layer with the top layer.
201     Darken,            ///< Creates a pixel that retains the smallest components of the top and bottom layer pixels. min(S, D)
202     Lighten,           ///< Only has the opposite action of Darken Only. max(S, D)
203     ColorDodge,        ///< Divides the bottom layer by the inverted top layer. D / (255 - S)
204     ColorBurn,         ///< Divides the inverted bottom layer by the top layer, and then inverts the result. 255 - (255 - D) / S
205     HardLight,         ///< The same as Overlay but with the color roles reversed. (2 * S * D) if (S < Sa), otherwise (Sa * Da) - 2 * (Da - S) * (Sa - D)
206     SoftLight,         ///< The same as Overlay but with applying pure black or white does not result in pure black or white. (1 - 2 * S) * (D ^ 2) + (2 * S * D)
207     Difference,        ///< Subtracts the bottom layer from the top layer or the other way around, to always get a non-negative value. (S - D) if (S > D), otherwise (D - S)
208     Exclusion,         ///< The result is twice the product of the top and bottom layers, subtracted from their sum. s + d - (2 * s * d)
209     Hue,               ///< Reserved. Not supported.
210     Saturation,        ///< Reserved. Not supported.
211     Color,             ///< Reserved. Not supported.
212     Luminosity,        ///< Reserved. Not supported.
213     Add,               ///< Simply adds pixel values of one layer with the other. (S + D)
214     HardMix            ///< Reserved. Not supported.
215 };
216 
217 
218 /**
219  * @brief Enumeration that defines methods used for Scene Effects.
220  *
221  * This enum provides options to apply various post-processing effects to a scene.
222  * Scene effects are typically applied to modify the final appearance of a rendered scene, such as blurring.
223  *
224  * @see Scene::push(SceneEffect effect, ...)
225  *
226  * @note Experimental API
227  */
228 enum class SceneEffect : uint8_t
229 {
230     ClearAll = 0,      ///< Reset all previously applied scene effects, restoring the scene to its original state.
231     GaussianBlur       ///< Apply a blur effect with a Gaussian filter. Param(3) = {sigma(float)[> 0], direction(int)[both: 0 / horizontal: 1 / vertical: 2], border(int)[duplicate: 0 / wrap: 1], quality(int)[0 - 100]}
232 };
233 
234 
235 /**
236  * @brief Enumeration specifying the engine type used for the graphics backend. For multiple backends bitwise operation is allowed.
237  */
238 enum class CanvasEngine
239 {
240     Sw = (1 << 1), ///< CPU rasterizer.
241     Gl = (1 << 2), ///< OpenGL rasterizer.
242     Wg = (1 << 3), ///< WebGPU rasterizer. @since 0.15
243 };
244 
245 
246 /**
247  * @brief Enumeration specifying the ThorVG class type value.
248  *
249  * ThorVG's drawing objects can return class type values, allowing you to identify the specific class of each object.
250  *
251  * @see Paint::type()
252  * @see Fill::type()
253  *
254  * @note Experimental API
255  */
256 enum class Type : uint8_t
257 {
258     Undefined = 0,         ///< Unkown class
259     Shape,                 ///< Shape class
260     Scene,                 ///< Scene class
261     Picture,               ///< Picture class
262     Text,                  ///< Text class
263     LinearGradient = 10,   ///< LinearGradient class
264     RadialGradient         ///< RadialGradient class
265 };
266 
267 
268 /**
269  * @brief A data structure representing a point in two-dimensional space.
270  */
271 struct Point
272 {
273     float x, y;
274 };
275 
276 
277 /**
278  * @brief A data structure representing a three-dimensional matrix.
279  *
280  * The elements e11, e12, e21 and e22 represent the rotation matrix, including the scaling factor.
281  * The elements e13 and e23 determine the translation of the object along the x and y-axis, respectively.
282  * The elements e31 and e32 are set to 0, e33 is set to 1.
283  */
284 struct Matrix
285 {
286     float e11, e12, e13;
287     float e21, e22, e23;
288     float e31, e32, e33;
289 };
290 
291 
292 /**
293  * @class Paint
294  *
295  * @brief An abstract class for managing graphical elements.
296  *
297  * A graphical element in TVG is any object composed into a Canvas.
298  * Paint represents such a graphical object and its behaviors such as duplication, transformation and composition.
299  * TVG recommends the user to regard a paint as a set of volatile commands. They can prepare a Paint and then request a Canvas to run them.
300  */
301 class TVG_API Paint
302 {
303 public:
304     virtual ~Paint();
305 
306     /**
307      * @brief Sets the angle by which the object is rotated.
308      *
309      * The angle in measured clockwise from the horizontal axis.
310      * The rotational axis passes through the point on the object with zero coordinates.
311      *
312      * @param[in] degree The value of the angle in degrees.
313      *
314      * @retval Result::InsufficientCondition in case a custom transform is applied.
315      * @see Paint::transform()
316      */
317     Result rotate(float degree) noexcept;
318 
319     /**
320      * @brief Sets the scale value of the object.
321      *
322      * @param[in] factor The value of the scaling factor. The default value is 1.
323      *
324      * @retval Result::InsufficientCondition in case a custom transform is applied.
325      * @see Paint::transform()
326      */
327     Result scale(float factor) noexcept;
328 
329     /**
330      * @brief Sets the values by which the object is moved in a two-dimensional space.
331      *
332      * The origin of the coordinate system is in the upper-left corner of the canvas.
333      * The horizontal and vertical axes point to the right and down, respectively.
334      *
335      * @param[in] x The value of the horizontal shift.
336      * @param[in] y The value of the vertical shift.
337      *
338      * @retval Result::InsufficientCondition in case a custom transform is applied.
339      * @see Paint::transform()
340      */
341     Result translate(float x, float y) noexcept;
342 
343     /**
344      * @brief Sets the matrix of the affine transformation for the object.
345      *
346      * The augmented matrix of the transformation is expected to be given.
347      *
348      * @param[in] m The 3x3 augmented matrix.
349      */
350     Result transform(const Matrix& m) noexcept;
351 
352     /**
353      * @brief Gets the matrix of the affine transformation of the object.
354      *
355      * The values of the matrix can be set by the transform() API, as well by the translate(),
356      * scale() and rotate(). In case no transformation was applied, the identity matrix is returned.
357      *
358      * @return The augmented transformation matrix.
359      *
360      * @since 0.4
361      */
362     Matrix transform() noexcept;
363 
364     /**
365      * @brief Sets the opacity of the object.
366      *
367      * @param[in] o The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque.
368      *
369      * @note Setting the opacity with this API may require multiple render pass for composition. It is recommended to avoid changing the opacity if possible.
370      */
371     Result opacity(uint8_t o) noexcept;
372 
373     /**
374      * @brief Sets the composition target object and the composition method.
375      *
376      * @param[in] target The paint of the target object.
377      * @param[in] method The method used to composite the source object with the target.
378      */
379     Result composite(std::unique_ptr<Paint> target, CompositeMethod method) noexcept;
380 
381     /**
382      * @brief Clip the drawing region of the paint object.
383      *
384      * This function restricts the drawing area of the paint object to the specified shape's paths.
385      *
386      * @param[in] clipper The shape object as the clipper.
387      *
388      * @retval Result::NonSupport If the @p clipper type is not Shape.
389      *
390      * @note @p clipper only supports the Shape type.
391      * @note Experimental API
392      */
393     Result clip(std::unique_ptr<Paint> clipper) noexcept;
394 
395     /**
396      * @brief Sets the blending method for the paint object.
397      *
398      * The blending feature allows you to combine colors to create visually appealing effects, including transparency, lighting, shading, and color mixing, among others.
399      * its process involves the combination of colors or images from the source paint object with the destination (the lower layer image) using blending operations.
400      * The blending operation is determined by the chosen @p BlendMethod, which specifies how the colors or images are combined.
401      *
402      * @param[in] method The blending method to be set.
403      *
404      * @note Experimental API
405      */
406     Result blend(BlendMethod method) noexcept;
407 
408     /**
409      * @deprecated Use bounds(float* x, float* y, float* w, float* h, bool transformed) instead
410      */
411     TVG_DEPRECATED Result bounds(float* x, float* y, float* w, float* h) const noexcept;
412 
413     /**
414      * @brief Gets the axis-aligned bounding box of the paint object.
415      *
416      * @param[out] x The x-coordinate of the upper-left corner of the object.
417      * @param[out] y The y-coordinate of the upper-left corner of the object.
418      * @param[out] w The width of the object.
419      * @param[out] h The height of the object.
420      * @param[in] transformed If @c true, the paint's transformations are taken into account in the scene it belongs to. Otherwise they aren't.
421      *
422      * @note This is useful when you need to figure out the bounding box of the paint in the canvas space.
423      * @note The bounding box doesn't indicate the actual drawing region. It's the smallest rectangle that encloses the object.
424      * @note If @p transformed is @c true, the paint needs to be pushed into a canvas and updated before this api is called.
425      * @see Canvas::update()
426      */
427     Result bounds(float* x, float* y, float* w, float* h, bool transformed) const noexcept;
428 
429     /**
430      * @brief Duplicates the object.
431      *
432      * Creates a new object and sets its all properties as in the original object.
433      *
434      * @return The created object when succeed, @c nullptr otherwise.
435      */
436     Paint* duplicate() const noexcept;
437 
438     /**
439      * @brief Gets the opacity value of the object.
440      *
441      * @return The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque.
442      */
443     uint8_t opacity() const noexcept;
444 
445     /**
446      * @brief Gets the composition target object and the composition method.
447      *
448      * @param[out] target The paint of the target object.
449      *
450      * @return The method used to composite the source object with the target.
451      *
452      * @since 0.5
453      */
454     CompositeMethod composite(const Paint** target) const noexcept;
455 
456     /**
457      * @brief Returns the ID value of this class.
458      *
459      * This method can be used to check the current concrete instance type.
460      *
461      * @return The class type ID of the Paint instance.
462      *
463      * @since Experimental API
464      */
465     virtual Type type() const noexcept = 0;
466 
467     /**
468      * @brief Unique ID of this instance.
469      *
470      * This is reserved to specify an paint instance in a scene.
471      *
472      * @since Experimental API
473      */
474     uint32_t id = 0;
475 
476     /**
477      * @see Paint::type()
478      */
479     TVG_DEPRECATED uint32_t identifier() const noexcept;
480 
481     _TVG_DECLARE_PRIVATE(Paint);
482 };
483 
484 
485 /**
486  * @class Fill
487  *
488  * @brief An abstract class representing the gradient fill of the Shape object.
489  *
490  * It contains the information about the gradient colors and their arrangement
491  * inside the gradient bounds. The gradients bounds are defined in the LinearGradient
492  * or RadialGradient class, depending on the type of the gradient to be used.
493  * It specifies the gradient behavior in case the area defined by the gradient bounds
494  * is smaller than the area to be filled.
495  */
496 class TVG_API Fill
497 {
498 public:
499     /**
500      * @brief A data structure storing the information about the color and its relative position inside the gradient bounds.
501      */
502     struct ColorStop
503     {
504         float offset; /**< The relative position of the color. */
505         uint8_t r;    /**< The red color channel value in the range [0 ~ 255]. */
506         uint8_t g;    /**< The green color channel value in the range [0 ~ 255]. */
507         uint8_t b;    /**< The blue color channel value in the range [0 ~ 255]. */
508         uint8_t a;    /**< The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. */
509     };
510 
511     virtual ~Fill();
512 
513     /**
514      * @brief Sets the parameters of the colors of the gradient and their position.
515      *
516      * @param[in] colorStops An array of ColorStop data structure.
517      * @param[in] cnt The count of the @p colorStops array equal to the colors number used in the gradient.
518      */
519     Result colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept;
520 
521     /**
522      * @brief Sets the FillSpread value, which specifies how to fill the area outside the gradient bounds.
523      *
524      * @param[in] s The FillSpread value.
525      */
526     Result spread(FillSpread s) noexcept;
527 
528     /**
529      * @brief Sets the matrix of the affine transformation for the gradient fill.
530      *
531      * The augmented matrix of the transformation is expected to be given.
532      *
533      * @param[in] m The 3x3 augmented matrix.
534      */
535     Result transform(const Matrix& m) noexcept;
536 
537     /**
538      * @brief Gets the parameters of the colors of the gradient, their position and number.
539      *
540      * @param[out] colorStops A pointer to the memory location, where the array of the gradient's ColorStop is stored.
541      *
542      * @return The number of colors used in the gradient. This value corresponds to the length of the @p colorStops array.
543      */
544     uint32_t colorStops(const ColorStop** colorStops) const noexcept;
545 
546     /**
547      * @brief Gets the FillSpread value of the fill.
548      *
549      * @return The FillSpread value of this Fill.
550      */
551     FillSpread spread() const noexcept;
552 
553     /**
554      * @brief Gets the matrix of the affine transformation of the gradient fill.
555      *
556      * In case no transformation was applied, the identity matrix is returned.
557      *
558      * @return The augmented transformation matrix.
559      */
560     Matrix transform() const noexcept;
561 
562     /**
563      * @brief Creates a copy of the Fill object.
564      *
565      * Return a newly created Fill object with the properties copied from the original.
566      *
567      * @return A copied Fill object when succeed, @c nullptr otherwise.
568      */
569     Fill* duplicate() const noexcept;
570 
571     /**
572      * @brief Returns the ID value of this class.
573      *
574      * This method can be used to check the current concrete instance type.
575      *
576      * @return The class type ID of the Fill instance.
577      *
578      * @since Experimental API
579      */
580     virtual Type type() const noexcept = 0;
581 
582     /**
583      * @see Fill::type()
584      */
585     TVG_DEPRECATED uint32_t identifier() const noexcept;
586 
587     _TVG_DECLARE_PRIVATE(Fill);
588 };
589 
590 
591 /**
592  * @class Canvas
593  *
594  * @brief An abstract class for drawing graphical elements.
595  *
596  * A canvas is an entity responsible for drawing the target. It sets up the drawing engine and the buffer, which can be drawn on the screen. It also manages given Paint objects.
597  *
598  * @note A Canvas behavior depends on the raster engine though the final content of the buffer is expected to be identical.
599  * @warning The Paint objects belonging to one Canvas can't be shared among multiple Canvases.
600  */
601 class TVG_API Canvas
602 {
603 public:
604     Canvas(RenderMethod*);
605     virtual ~Canvas();
606 
607     TVG_DEPRECATED Result reserve(uint32_t n) noexcept;
608 
609     /**
610      * @brief Returns the list of the paints that currently held by the Canvas.
611      *
612      * This function provides the list of paint nodes, allowing users a direct opportunity to modify the scene tree.
613      *
614      * @warning Please avoid accessing the paints during Canvas update/draw. You can access them after calling sync().
615      * @see Canvas::sync()
616      *
617      * @note Experimental API
618      */
619     std::list<Paint*>& paints() noexcept;
620 
621     /**
622      * @brief Passes drawing elements to the Canvas using Paint objects.
623      *
624      * Only pushed paints in the canvas will be drawing targets.
625      * They are retained by the canvas until you call Canvas::clear().
626      *
627      * @param[in] paint A Paint object to be drawn.
628      *
629      * @retval Result::MemoryCorruption In case a @c nullptr is passed as the argument.
630      *
631      * @note The rendering order of the paints is the same as the order as they were pushed into the canvas. Consider sorting the paints before pushing them if you intend to use layering.
632      * @see Canvas::paints()
633      * @see Canvas::clear()
634      */
635     virtual Result push(std::unique_ptr<Paint> paint) noexcept;
636 
637     /**
638      * @brief Clear the internal canvas resources that used for the drawing.
639      *
640      * This API sets the total number of paints pushed into the canvas to zero.
641      * Depending on the value of the @p free argument, the paints are either freed or retained.
642      * So if you need to update paint properties while maintaining the existing scene structure, you can set @p free = false.
643      *
644      * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not.
645      *
646      *
647      * @see Canvas::push()
648      * @see Canvas::paints()
649      */
650     virtual Result clear(bool free = true) noexcept;
651 
652     /**
653      * @brief Request the canvas to update the paint objects.
654      *
655      * If a @c nullptr is passed all paint objects retained by the Canvas are updated,
656      * otherwise only the paint to which the given @p paint points.
657      *
658      * @param[in] paint A pointer to the Paint object or @c nullptr.
659      *
660      * @note The Update behavior can be asynchronous if the assigned thread number is greater than zero.
661      */
662     virtual Result update(Paint* paint = nullptr) noexcept;
663 
664     /**
665      * @brief Requests the canvas to draw the Paint objects.
666      *
667      * @note Drawing can be asynchronous if the assigned thread number is greater than zero. To guarantee the drawing is done, call sync() afterwards.
668      * @see Canvas::sync()
669      */
670     virtual Result draw() noexcept;
671 
672     /**
673      * @brief Sets the drawing region in the canvas.
674      *
675      * This function defines the rectangular area of the canvas that will be used for drawing operations.
676      * The specified viewport is used to clip the rendering output to the boundaries of the rectangle.
677      *
678      * @param[in] x The x-coordinate of the upper-left corner of the rectangle.
679      * @param[in] y The y-coordinate of the upper-left corner of the rectangle.
680      * @param[in] w The width of the rectangle.
681      * @param[in] h The height of the rectangle.
682      *
683      * @see SwCanvas::target()
684      * @see GlCanvas::target()
685      * @see WgCanvas::target()
686      *
687      * @warning It's not allowed to change the viewport during Canvas::push() - Canvas::sync() or Canvas::update() - Canvas::sync().
688      *
689      * @note When resetting the target, the viewport will also be reset to the target size.
690      * @since 0.15
691      */
692     virtual Result viewport(int32_t x, int32_t y, int32_t w, int32_t h) noexcept;
693 
694     /**
695      * @brief Guarantees that drawing task is finished.
696      *
697      * The Canvas rendering can be performed asynchronously. To make sure that rendering is finished,
698      * the sync() must be called after the draw() regardless of threading.
699      *
700      * @retval Result::InsufficientCondition: The canvas is either already in sync condition or in a damaged condition (a draw is required before syncing).
701      *
702      * @see Canvas::draw()
703      */
704     virtual Result sync() noexcept;
705 
706     _TVG_DECLARE_PRIVATE(Canvas);
707 };
708 
709 
710 /**
711  * @class LinearGradient
712  *
713  * @brief A class representing the linear gradient fill of the Shape object.
714  *
715  * Besides the APIs inherited from the Fill class, it enables setting and getting the linear gradient bounds.
716  * The behavior outside the gradient bounds depends on the value specified in the spread API.
717  */
718 class TVG_API LinearGradient final : public Fill
719 {
720 public:
721     ~LinearGradient();
722 
723     /**
724      * @brief Sets the linear gradient bounds.
725      *
726      * The bounds of the linear gradient are defined as a surface constrained by two parallel lines crossing
727      * the given points (@p x1, @p y1) and (@p x2, @p y2), respectively. Both lines are perpendicular to the line linking
728      * (@p x1, @p y1) and (@p x2, @p y2).
729      *
730      * @param[in] x1 The horizontal coordinate of the first point used to determine the gradient bounds.
731      * @param[in] y1 The vertical coordinate of the first point used to determine the gradient bounds.
732      * @param[in] x2 The horizontal coordinate of the second point used to determine the gradient bounds.
733      * @param[in] y2 The vertical coordinate of the second point used to determine the gradient bounds.
734      *
735      * @note In case the first and the second points are equal, an object is filled with a single color using the last color specified in the colorStops().
736      * @see Fill::colorStops()
737      */
738     Result linear(float x1, float y1, float x2, float y2) noexcept;
739 
740     /**
741      * @brief Gets the linear gradient bounds.
742      *
743      * The bounds of the linear gradient are defined as a surface constrained by two parallel lines crossing
744      * the given points (@p x1, @p y1) and (@p x2, @p y2), respectively. Both lines are perpendicular to the line linking
745      * (@p x1, @p y1) and (@p x2, @p y2).
746      *
747      * @param[out] x1 The horizontal coordinate of the first point used to determine the gradient bounds.
748      * @param[out] y1 The vertical coordinate of the first point used to determine the gradient bounds.
749      * @param[out] x2 The horizontal coordinate of the second point used to determine the gradient bounds.
750      * @param[out] y2 The vertical coordinate of the second point used to determine the gradient bounds.
751      */
752     Result linear(float* x1, float* y1, float* x2, float* y2) const noexcept;
753 
754     /**
755      * @brief Creates a new LinearGradient object.
756      *
757      * @return A new LinearGradient object.
758      */
759     static std::unique_ptr<LinearGradient> gen() noexcept;
760 
761     /**
762      * @brief Returns the ID value of this class.
763      *
764      * This method can be used to check the current concrete instance type.
765      *
766      * @return The class type ID of the LinearGradient instance.
767      *
768      * @since Experimental API
769      */
770     Type type() const noexcept override;
771 
772     /**
773      * @see LinearGradient::type()
774      */
775     TVG_DEPRECATED static uint32_t identifier() noexcept;
776 
777     _TVG_DECLARE_PRIVATE(LinearGradient);
778 };
779 
780 
781 /**
782  * @class RadialGradient
783  *
784  * @brief A class representing the radial gradient fill of the Shape object.
785  *
786  */
787 class TVG_API RadialGradient final : public Fill
788 {
789 public:
790     ~RadialGradient();
791 
792     /**
793      * @brief Sets the radial gradient bounds.
794      *
795      * The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius.
796      *
797      * @param[in] cx The horizontal coordinate of the center of the bounding circle.
798      * @param[in] cy The vertical coordinate of the center of the bounding circle.
799      * @param[in] radius The radius of the bounding circle.
800      *
801      * @retval Result::InvalidArguments in case the @p radius value is zero or less.
802      *
803      * @note In case the @p radius is zero, an object is filled with a single color using the last color specified in the colorStops().
804      */
805     Result radial(float cx, float cy, float radius) noexcept;
806 
807     /**
808      * @brief Gets the radial gradient bounds.
809      *
810      * The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius.
811      *
812      * @param[out] cx The horizontal coordinate of the center of the bounding circle.
813      * @param[out] cy The vertical coordinate of the center of the bounding circle.
814      * @param[out] radius The radius of the bounding circle.
815      *
816      */
817     Result radial(float* cx, float* cy, float* radius) const noexcept;
818 
819     /**
820      * @brief Creates a new RadialGradient object.
821      *
822      * @return A new RadialGradient object.
823      */
824     static std::unique_ptr<RadialGradient> gen() noexcept;
825 
826     /**
827      * @brief Returns the ID value of this class.
828      *
829      * This method can be used to check the current concrete instance type.
830      *
831      * @return The class type ID of the LinearGradient instance.
832      *
833      * @since Experimental API
834      */
835     Type type() const noexcept override;
836 
837     /**
838      * @see RadialGradient::type()
839      */
840     TVG_DEPRECATED static uint32_t identifier() noexcept;
841 
842     _TVG_DECLARE_PRIVATE(RadialGradient);
843 };
844 
845 
846 /**
847  * @class Shape
848  *
849  * @brief A class representing two-dimensional figures and their properties.
850  *
851  * A shape has three major properties: shape outline, stroking, filling. The outline in the Shape is retained as the path.
852  * Path can be composed by accumulating primitive commands such as moveTo(), lineTo(), cubicTo(), or complete shape interfaces such as appendRect(), appendCircle(), etc.
853  * Path can consists of sub-paths. One sub-path is determined by a close command.
854  *
855  * The stroke of Shape is an optional property in case the Shape needs to be represented with/without the outline borders.
856  * It's efficient since the shape path and the stroking path can be shared with each other. It's also convenient when controlling both in one context.
857  */
858 class TVG_API Shape final : public Paint
859 {
860 public:
861     ~Shape();
862 
863     /**
864      * @brief Resets the shape path.
865      *
866      * The transformation matrix, color, fill, and stroke properties are retained.
867      *
868      * @note The memory where the path data is stored is not deallocated at this stage to allow for caching.
869      */
870     Result reset() noexcept;
871 
872     /**
873      * @brief Sets the initial point of the sub-path.
874      *
875      * The value of the current point is set to the given point.
876      *
877      * @param[in] x The horizontal coordinate of the initial point of the sub-path.
878      * @param[in] y The vertical coordinate of the initial point of the sub-path.
879      */
880     Result moveTo(float x, float y) noexcept;
881 
882     /**
883      * @brief Adds a new point to the sub-path, which results in drawing a line from the current point to the given end-point.
884      *
885      * The value of the current point is set to the given end-point.
886      *
887      * @param[in] x The horizontal coordinate of the end-point of the line.
888      * @param[in] y The vertical coordinate of the end-point of the line.
889      *
890      * @note In case this is the first command in the path, it corresponds to the moveTo() call.
891      */
892     Result lineTo(float x, float y) noexcept;
893 
894     /**
895      * @brief Adds new points to the sub-path, which results in drawing a cubic Bezier curve starting
896      * at the current point and ending at the given end-point (@p x, @p y) using the control points (@p cx1, @p cy1) and (@p cx2, @p cy2).
897      *
898      * The value of the current point is set to the given end-point.
899      *
900      * @param[in] cx1 The horizontal coordinate of the 1st control point.
901      * @param[in] cy1 The vertical coordinate of the 1st control point.
902      * @param[in] cx2 The horizontal coordinate of the 2nd control point.
903      * @param[in] cy2 The vertical coordinate of the 2nd control point.
904      * @param[in] x The horizontal coordinate of the end-point of the curve.
905      * @param[in] y The vertical coordinate of the end-point of the curve.
906      *
907      * @note In case this is the first command in the path, no data from the path are rendered.
908      */
909     Result cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) noexcept;
910 
911     /**
912      * @brief Closes the current sub-path by drawing a line from the current point to the initial point of the sub-path.
913      *
914      * The value of the current point is set to the initial point of the closed sub-path.
915      *
916      * @note In case the sub-path does not contain any points, this function has no effect.
917      */
918     Result close() noexcept;
919 
920     /**
921      * @brief Appends a rectangle to the path.
922      *
923      * The rectangle with rounded corners can be achieved by setting non-zero values to @p rx and @p ry arguments.
924      * The @p rx and @p ry values specify the radii of the ellipse defining the rounding of the corners.
925      *
926      * The position of the rectangle is specified by the coordinates of its upper-left corner - @p x and @p y arguments.
927      *
928      * The rectangle is treated as a new sub-path - it is not connected with the previous sub-path.
929      *
930      * The value of the current point is set to (@p x + @p rx, @p y) - in case @p rx is greater
931      * than @p w/2 the current point is set to (@p x + @p w/2, @p y)
932      *
933      * @param[in] x The horizontal coordinate of the upper-left corner of the rectangle.
934      * @param[in] y The vertical coordinate of the upper-left corner of the rectangle.
935      * @param[in] w The width of the rectangle.
936      * @param[in] h The height of the rectangle.
937      * @param[in] rx The x-axis radius of the ellipse defining the rounded corners of the rectangle.
938      * @param[in] ry The y-axis radius of the ellipse defining the rounded corners of the rectangle.
939      *
940      * @note For @p rx and @p ry greater than or equal to the half of @p w and the half of @p h, respectively, the shape become an ellipse.
941      */
942     Result appendRect(float x, float y, float w, float h, float rx = 0, float ry = 0) noexcept;
943 
944     /**
945      * @brief Appends an ellipse to the path.
946      *
947      * The position of the ellipse is specified by the coordinates of its center - @p cx and @p cy arguments.
948      *
949      * The ellipse is treated as a new sub-path - it is not connected with the previous sub-path.
950      *
951      * The value of the current point is set to (@p cx, @p cy - @p ry).
952      *
953      * @param[in] cx The horizontal coordinate of the center of the ellipse.
954      * @param[in] cy The vertical coordinate of the center of the ellipse.
955      * @param[in] rx The x-axis radius of the ellipse.
956      * @param[in] ry The y-axis radius of the ellipse.
957      *
958      */
959     Result appendCircle(float cx, float cy, float rx, float ry) noexcept;
960 
961     /**
962      * @brief Appends a circular arc to the path.
963      *
964      * The arc is treated as a new sub-path - it is not connected with the previous sub-path.
965      * The current point value is set to the end-point of the arc in case @p pie is @c false, and to the center of the arc otherwise.
966      *
967      * @param[in] cx The horizontal coordinate of the center of the arc.
968      * @param[in] cy The vertical coordinate of the center of the arc.
969      * @param[in] radius The radius of the arc.
970      * @param[in] startAngle The start angle of the arc given in degrees, measured counter-clockwise from the horizontal line.
971      * @param[in] sweep The central angle of the arc given in degrees, measured counter-clockwise from @p startAngle.
972      * @param[in] pie Specifies whether to draw radii from the arc's center to both of its end-point - drawn if @c true.
973      *
974      * @note Setting @p sweep value greater than 360 degrees, is equivalent to calling appendCircle(cx, cy, radius, radius).
975      */
976     Result appendArc(float cx, float cy, float radius, float startAngle, float sweep, bool pie) noexcept;
977 
978     /**
979      * @brief Appends a given sub-path to the path.
980      *
981      * The current point value is set to the last point from the sub-path.
982      * For each command from the @p cmds array, an appropriate number of points in @p pts array should be specified.
983      * If the number of points in the @p pts array is different than the number required by the @p cmds array, the shape with this sub-path will not be displayed on the screen.
984      *
985      * @param[in] cmds The array of the commands in the sub-path.
986      * @param[in] cmdCnt The number of the sub-path's commands.
987      * @param[in] pts The array of the two-dimensional points.
988      * @param[in] ptsCnt The number of the points in the @p pts array.
989      *
990      * @note The interface is designed for optimal path setting if the caller has a completed path commands already.
991      */
992     Result appendPath(const PathCommand* cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt) noexcept;
993 
994     /**
995      * @brief Sets the stroke width for all of the figures from the path.
996      *
997      * @param[in] width The width of the stroke. The default value is 0.
998      *
999      */
1000     Result stroke(float width) noexcept;
1001 
1002     /**
1003      * @brief Sets the color of the stroke for all of the figures from the path.
1004      *
1005      * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0.
1006      * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0.
1007      * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0.
1008      * @param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0.
1009      *
1010      */
1011     Result stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) noexcept;
1012 
1013     /**
1014      * @brief Sets the gradient fill of the stroke for all of the figures from the path.
1015      *
1016      * @param[in] f The gradient fill.
1017      *
1018      * @retval Result::MemoryCorruption In case a @c nullptr is passed as the argument.
1019      */
1020     Result stroke(std::unique_ptr<Fill> f) noexcept;
1021 
1022     /**
1023      * @brief Sets the dash pattern of the stroke.
1024      *
1025      * @param[in] dashPattern The array of consecutive pair values of the dash length and the gap length.
1026      * @param[in] cnt The length of the @p dashPattern array.
1027      *
1028      * @retval Result::InvalidArguments In case @p dashPattern is @c nullptr and @p cnt > 0, @p cnt is zero, any of the dash pattern values is zero or less.
1029      *
1030      * @note To reset the stroke dash pattern, pass @c nullptr to @p dashPattern and zero to @p cnt.
1031      * @warning @p cnt must be greater than 1 if the dash pattern is valid.
1032      */
1033     Result stroke(const float* dashPattern, uint32_t cnt) noexcept;
1034 
1035     /**
1036      * @brief Sets the cap style of the stroke in the open sub-paths.
1037      *
1038      * @param[in] cap The cap style value. The default value is @c StrokeCap::Square.
1039      *
1040      */
1041     Result stroke(StrokeCap cap) noexcept;
1042 
1043     /**
1044      * @brief Sets the join style for stroked path segments.
1045      *
1046      * The join style is used for joining the two line segment while stroking the path.
1047      *
1048      * @param[in] join The join style value. The default value is @c StrokeJoin::Bevel.
1049      *
1050      */
1051     Result stroke(StrokeJoin join) noexcept;
1052 
1053     /**
1054      * @brief Sets the stroke miterlimit.
1055      *
1056      * @param[in] miterlimit The miterlimit imposes a limit on the extent of the stroke join, when the @c StrokeJoin::Miter join style is set. The default value is 4.
1057      *
1058      * @retval Result::InvalidArgument for @p miterlimit values less than zero.
1059      *
1060      * @since 0.11
1061      */
1062     Result strokeMiterlimit(float miterlimit) noexcept;
1063 
1064     /**
1065      * @brief Sets the trim of the stroke along the defined path segment, allowing control over which part of the stroke is visible.
1066      *
1067      * If the values of the arguments @p begin and @p end exceed the 0-1 range, they are wrapped around in a manner similar to angle wrapping, effectively treating the range as circular.
1068      *
1069      * @param[in] begin Specifies the start of the segment to display along the path.
1070      * @param[in] end Specifies the end of the segment to display along the path.
1071      * @param[in] simultaneous Determines how to trim multiple paths within a single shape. If set to @c true (default), trimming is applied simultaneously to all paths;
1072      * Otherwise, all paths are treated as a single entity with a combined length equal to the sum of their individual lengths and are trimmed as such.
1073      *
1074      * @note Experimental API
1075      */
1076     Result strokeTrim(float begin, float end, bool simultaneous = true) noexcept;
1077 
1078     /**
1079      * @brief Sets the solid color for all of the figures from the path.
1080      *
1081      * The parts of the shape defined as inner are colored.
1082      *
1083      * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0.
1084      * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0.
1085      * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0.
1086      * @param[in] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. The default value is 0.
1087      *
1088      * @note Either a solid color or a gradient fill is applied, depending on what was set as last.
1089      */
1090     Result fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) noexcept;
1091 
1092     /**
1093      * @brief Sets the gradient fill for all of the figures from the path.
1094      *
1095      * The parts of the shape defined as inner are filled.
1096      *
1097      * @param[in] f The unique pointer to the gradient fill.
1098      *
1099      * @note Either a solid color or a gradient fill is applied, depending on what was set as last.
1100      */
1101     Result fill(std::unique_ptr<Fill> f) noexcept;
1102 
1103     /**
1104      * @brief Sets the fill rule for the Shape object.
1105      *
1106      * @param[in] r The fill rule value. The default value is @c FillRule::Winding.
1107      */
1108     Result fill(FillRule r) noexcept;
1109 
1110     /**
1111      * @brief Sets the rendering order of the stroke and the fill.
1112      *
1113      * @param[in] strokeFirst If @c true the stroke is rendered before the fill, otherwise the stroke is rendered as the second one (the default option).
1114      *
1115      * @since 0.10
1116      */
1117     Result order(bool strokeFirst) noexcept;
1118 
1119     /**
1120      * @brief Gets the commands data of the path.
1121      *
1122      * @param[out] cmds The pointer to the array of the commands from the path.
1123      *
1124      * @return The length of the @p cmds array when succeed, zero otherwise.
1125      */
1126     uint32_t pathCommands(const PathCommand** cmds) const noexcept;
1127 
1128     /**
1129      * @brief Gets the points values of the path.
1130      *
1131      * @param[out] pts The pointer to the array of the two-dimensional points from the path.
1132      *
1133      * @return The length of the @p pts array when succeed, zero otherwise.
1134      */
1135     uint32_t pathCoords(const Point** pts) const noexcept;
1136 
1137     /**
1138      * @brief Gets the pointer to the gradient fill of the shape.
1139      *
1140      * @return The pointer to the gradient fill of the stroke when succeed, @c nullptr in case no fill was set.
1141      */
1142     const Fill* fill() const noexcept;
1143 
1144     /**
1145      * @brief Gets the solid color of the shape.
1146      *
1147      * @param[out] r The red color channel value in the range [0 ~ 255].
1148      * @param[out] g The green color channel value in the range [0 ~ 255].
1149      * @param[out] b The blue color channel value in the range [0 ~ 255].
1150      * @param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque.
1151      *
1152      */
1153     Result fillColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a = nullptr) const noexcept;
1154 
1155     /**
1156      * @brief Gets the fill rule value.
1157      *
1158      * @return The fill rule value of the shape.
1159      */
1160     FillRule fillRule() const noexcept;
1161 
1162     /**
1163      * @brief Gets the stroke width.
1164      *
1165      * @return The stroke width value when succeed, zero if no stroke was set.
1166      */
1167     float strokeWidth() const noexcept;
1168 
1169     /**
1170      * @brief Gets the color of the shape's stroke.
1171      *
1172      * @param[out] r The red color channel value in the range [0 ~ 255].
1173      * @param[out] g The green color channel value in the range [0 ~ 255].
1174      * @param[out] b The blue color channel value in the range [0 ~ 255].
1175      * @param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque.
1176      *
1177      */
1178     Result strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a = nullptr) const noexcept;
1179 
1180     /**
1181      * @brief Gets the pointer to the gradient fill of the stroke.
1182      *
1183      * @return The pointer to the gradient fill of the stroke when succeed, @c nullptr otherwise.
1184      */
1185     const Fill* strokeFill() const noexcept;
1186 
1187     /**
1188      * @brief Gets the dash pattern of the stroke.
1189      *
1190      * @param[out] dashPattern The pointer to the memory, where the dash pattern array is stored.
1191      *
1192      * @return The length of the @p dashPattern array.
1193      */
1194     uint32_t strokeDash(const float** dashPattern) const noexcept;
1195 
1196     /**
1197      * @brief Gets the cap style used for stroking the path.
1198      *
1199      * @return The cap style value of the stroke.
1200      */
1201     StrokeCap strokeCap() const noexcept;
1202 
1203     /**
1204      * @brief Gets the join style value used for stroking the path.
1205      *
1206      * @return The join style value of the stroke.
1207      */
1208     StrokeJoin strokeJoin() const noexcept;
1209 
1210     /**
1211      * @brief Gets the stroke miterlimit.
1212      *
1213      * @return The stroke miterlimit value when succeed, 4 if no stroke was set.
1214      *
1215      * @since 0.11
1216      */
1217     float strokeMiterlimit() const noexcept;
1218 
1219     /**
1220      * @brief Creates a new Shape object.
1221      *
1222      * @return A new Shape object.
1223      */
1224     static std::unique_ptr<Shape> gen() noexcept;
1225 
1226     /**
1227      * @brief Returns the ID value of this class.
1228      *
1229      * This method can be used to check the current concrete instance type.
1230      *
1231      * @return The class type ID of the Shape instance.
1232      *
1233      * @since Experimental API
1234      */
1235     Type type() const noexcept override;
1236 
1237     /**
1238      * @see Shape::type()
1239      */
1240     TVG_DEPRECATED static uint32_t identifier() noexcept;
1241 
1242     _TVG_DECLARE_PRIVATE(Shape);
1243 };
1244 
1245 
1246 /**
1247  * @class Picture
1248  *
1249  * @brief A class representing an image read in one of the supported formats: raw, svg, png, jpg, lottie(json) and etc.
1250  * Besides the methods inherited from the Paint, it provides methods to load & draw images on the canvas.
1251  *
1252  * @note Supported formats are depended on the available TVG loaders.
1253  * @note See Animation class if the picture data is animatable.
1254  */
1255 class TVG_API Picture final : public Paint
1256 {
1257 public:
1258     ~Picture();
1259 
1260     /**
1261      * @brief Loads a picture data directly from a file.
1262      *
1263      * ThorVG efficiently caches the loaded data using the specified @p path as a key.
1264      * This means that loading the same file again will not result in duplicate operations;
1265      * instead, ThorVG will reuse the previously loaded picture data.
1266      *
1267      * @param[in] path A path to the picture file.
1268      *
1269      * @retval Result::InvalidArguments In case the @p path is invalid.
1270      * @retval Result::NonSupport When trying to load a file with an unknown extension.
1271      *
1272      * @note The Load behavior can be asynchronous if the assigned thread number is greater than zero.
1273      * @see Initializer::init()
1274      */
1275     Result load(const std::string& path) noexcept;
1276 
1277     /**
1278      * @deprecated Use load(const char* data, uint32_t size, const std::string& mimeType, bool copy) instead.
1279      */
1280     TVG_DEPRECATED Result load(const char* data, uint32_t size, bool copy = false) noexcept;
1281 
1282     /**
1283      * @brief Loads a picture data from a memory block of a given size.
1284      *
1285      * ThorVG efficiently caches the loaded data using the specified @p data address as a key
1286      * when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations
1287      * for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data.
1288      *
1289      * @param[in] data A pointer to a memory location where the content of the picture file is stored. A null-terminated string is expected for non-binary data if @p copy is @c false.
1290      * @param[in] size The size in bytes of the memory occupied by the @p data.
1291      * @param[in] mimeType Mimetype or extension of data such as "jpg", "jpeg", "lottie", "svg", "svg+xml", "png", etc. In case an empty string or an unknown type is provided, the loaders will be tried one by one.
1292      * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not.
1293      *
1294      * @retval Result::InvalidArguments In case no data are provided or the @p size is zero or less.
1295      * @retval Result::NonSupport When trying to load a file with an unknown extension.
1296      *
1297      * @warning It's the user responsibility to release the @p data memory.
1298      *
1299      * @note If you are unsure about the MIME type, you can provide an empty value like @c "", and thorvg will attempt to figure it out.
1300      * @since 0.5
1301      */
1302     Result load(const char* data, uint32_t size, const std::string& mimeType, bool copy = false) noexcept;
1303 
1304     /**
1305      * @brief Resizes the picture content to the given width and height.
1306      *
1307      * The picture content is resized while keeping the default size aspect ratio.
1308      * The scaling factor is established for each of dimensions and the smaller value is applied to both of them.
1309      *
1310      * @param[in] w A new width of the image in pixels.
1311      * @param[in] h A new height of the image in pixels.
1312      *
1313      */
1314     Result size(float w, float h) noexcept;
1315 
1316     /**
1317      * @brief Gets the size of the image.
1318      *
1319      * @param[out] w The width of the image in pixels.
1320      * @param[out] h The height of the image in pixels.
1321      *
1322      */
1323     Result size(float* w, float* h) const noexcept;
1324 
1325     /**
1326      * @brief Loads raw data in ARGB8888 format from a memory block of the given size.
1327      *
1328      * ThorVG efficiently caches the loaded data using the specified @p data address as a key
1329      * when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations
1330      * for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data.
1331      *
1332      * @param[in] data A pointer to a memory location where the content of the picture raw data is stored.
1333      * @param[in] w The width of the image @p data in pixels.
1334      * @param[in] h The height of the image @p data in pixels.
1335      * @param[in] premultiplied If @c true, the given image data is alpha-premultiplied.
1336      * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not.
1337      *
1338      * @since 0.9
1339      */
1340     Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept;
1341 
1342     /**
1343      * @brief Retrieve a paint object from the Picture scene by its Unique ID.
1344      *
1345      * This function searches for a paint object within the Picture scene that matches the provided @p id.
1346      *
1347      * @param[in] id The Unique ID of the paint object.
1348      *
1349      * @return A pointer to the paint object that matches the given identifier, or @c nullptr if no matching paint object is found.
1350      *
1351      * @see Accessor::id()
1352      *
1353      * @note Experimental API
1354      */
1355     const Paint* paint(uint32_t id) noexcept;
1356 
1357     /**
1358      * @brief Creates a new Picture object.
1359      *
1360      * @return A new Picture object.
1361      */
1362     static std::unique_ptr<Picture> gen() noexcept;
1363 
1364     /**
1365      * @brief Returns the ID value of this class.
1366      *
1367      * This method can be used to check the current concrete instance type.
1368      *
1369      * @return The class type ID of the Picture instance.
1370      *
1371      * @since Experimental API
1372      */
1373     Type type() const noexcept override;
1374 
1375     /**
1376      * @see Picture::type()
1377      */
1378     TVG_DEPRECATED static uint32_t identifier() noexcept;
1379 
1380     _TVG_DECLARE_ACCESSOR(Animation);
1381     _TVG_DECLARE_PRIVATE(Picture);
1382 };
1383 
1384 
1385 /**
1386  * @class Scene
1387  *
1388  * @brief A class to composite children paints.
1389  *
1390  * As the traditional graphics rendering method, TVG also enables scene-graph mechanism.
1391  * This feature supports an array function for managing the multiple paints as one group paint.
1392  *
1393  * As a group, the scene can be transformed, made translucent and composited with other target paints,
1394  * its children will be affected by the scene world.
1395  */
1396 class TVG_API Scene final : public Paint
1397 {
1398 public:
1399     ~Scene();
1400 
1401     /**
1402      * @brief Passes drawing elements to the Scene using Paint objects.
1403      *
1404      * Only the paints pushed into the scene will be the drawn targets.
1405      * The paints are retained by the scene until Scene::clear() is called.
1406      *
1407      * @param[in] paint A Paint object to be drawn.
1408      *
1409      * @note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering.
1410      * @see Scene::paints()
1411      * @see Scene::clear()
1412      */
1413     Result push(std::unique_ptr<Paint> paint) noexcept;
1414 
1415     TVG_DEPRECATED Result reserve(uint32_t size) noexcept;
1416 
1417     /**
1418      * @brief Returns the list of the paints that currently held by the Scene.
1419      *
1420      * This function provides the list of paint nodes, allowing users a direct opportunity to modify the scene tree.
1421      *
1422      * @warning Please avoid accessing the paints during Scene update/draw. You can access them after calling Canvas::sync().
1423      * @see Canvas::sync()
1424      * @see Scene::push(std::unique_ptr<Paint> paint)
1425      * @see Scene::clear()
1426      *
1427      * @note Experimental API
1428      */
1429     std::list<Paint*>& paints() noexcept;
1430 
1431     /**
1432      * @brief Sets the total number of the paints pushed into the scene to be zero.
1433      * Depending on the value of the @p free argument, the paints are freed or not.
1434      *
1435      * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not.
1436      *
1437      * @warning If you don't free the paints they become dangled. They are supposed to be reused, otherwise you are responsible for their lives. Thus please use the @p free argument only when you know how it works, otherwise it's not recommended.
1438      *
1439      * @since 0.2
1440      */
1441     Result clear(bool free = true) noexcept;
1442 
1443     /**
1444      * @brief Apply a post-processing effect to the scene.
1445      *
1446      * This function adds a specified scene effect, such as clearing all effects or applying a Gaussian blur,
1447      * to the scene after it has been rendered. Multiple effects can be applied in sequence.
1448      *
1449      * @param[in] effect The scene effect to apply. Options are defined in the SceneEffect enum.
1450      *                   For example, use SceneEffect::GaussianBlur to apply a blur with specific parameters.
1451      * @param[in] ... Additional variadic parameters required for certain effects (e.g., sigma and direction for GaussianBlur).
1452      *
1453      * @note Experimental API
1454      */
1455     Result push(SceneEffect effect, ...) noexcept;
1456 
1457     /**
1458      * @brief Creates a new Scene object.
1459      *
1460      * @return A new Scene object.
1461      */
1462     static std::unique_ptr<Scene> gen() noexcept;
1463 
1464     /**
1465      * @brief Returns the ID value of this class.
1466      *
1467      * This method can be used to check the current concrete instance type.
1468      *
1469      * @return The class type ID of the Scene instance.
1470      *
1471      * @since Experimental API
1472      */
1473     Type type() const noexcept override;
1474 
1475     /**
1476      * @see Scene::type()
1477      */
1478     TVG_DEPRECATED static uint32_t identifier() noexcept;
1479 
1480     _TVG_DECLARE_PRIVATE(Scene);
1481 };
1482 
1483 
1484 /**
1485  * @class Text
1486  *
1487  * @brief A class to represent text objects in a graphical context, allowing for rendering and manipulation of unicode text.
1488  *
1489  * @since 0.15
1490  */
1491 class TVG_API Text final : public Paint
1492 {
1493 public:
1494     ~Text();
1495 
1496     /**
1497      * @brief Sets the font properties for the text.
1498      *
1499      * This function allows you to define the font characteristics used for text rendering.
1500      * It sets the font name, size and optionally the style.
1501      *
1502      * @param[in] name The name of the font. This should correspond to a font available in the canvas.
1503      * @param[in] size The size of the font in points. This determines how large the text will appear.
1504      * @param[in] style The style of the font. It can be used to set the font to 'italic'.
1505      *                  If not specified, the default style is used. Only 'italic' style is supported currently.
1506      *
1507      * @retval Result::InsufficientCondition when the specified @p name cannot be found.
1508      *
1509      * @note Experimental API
1510      */
1511     Result font(const char* name, float size, const char* style = nullptr) noexcept;
1512 
1513     /**
1514      * @brief Assigns the given unicode text to be rendered.
1515      *
1516      * This function sets the unicode string that will be displayed by the rendering system.
1517      * The text is set according to the specified UTF encoding method, which defaults to UTF-8.
1518      *
1519      * @param[in] text The multi-byte text encoded with utf8 string to be rendered.
1520      *
1521      * @note Experimental API
1522      */
1523     Result text(const char* text) noexcept;
1524 
1525     /**
1526      * @brief Sets the text color.
1527      *
1528      * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0.
1529      * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0.
1530      * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0.
1531      *
1532      * @see Text::font()
1533      *
1534      * @since 0.15
1535      */
1536     Result fill(uint8_t r, uint8_t g, uint8_t b) noexcept;
1537 
1538     /**
1539      * @brief Sets the gradient fill for all of the figures from the text.
1540      *
1541      * The parts of the text defined as inner are filled.
1542      *
1543      * @param[in] f The unique pointer to the gradient fill.
1544      *
1545      * @note Either a solid color or a gradient fill is applied, depending on what was set as last.
1546      * @see Text::font()
1547      *
1548      * @since 0.15
1549      */
1550     Result fill(std::unique_ptr<Fill> f) noexcept;
1551 
1552     /**
1553      * @brief Loads a scalable font data (ttf) from a file.
1554      *
1555      * ThorVG efficiently caches the loaded data using the specified @p path as a key.
1556      * This means that loading the same file again will not result in duplicate operations;
1557      * instead, ThorVG will reuse the previously loaded font data.
1558      *
1559      * @param[in] path The path to the font file.
1560      *
1561      * @retval Result::InvalidArguments In case the @p path is invalid.
1562      * @retval Result::NonSupport When trying to load a file with an unknown extension.
1563      *
1564      * @see Text::unload(const std::string& path)
1565      *
1566      * @since 0.15
1567      */
1568     static Result load(const std::string& path) noexcept;
1569 
1570     /**
1571      * @brief Loads a scalable font data (ttf) from a memory block of a given size.
1572      *
1573      * ThorVG efficiently caches the loaded font data using the specified @p name as a key.
1574      * This means that loading the same fonts again will not result in duplicate operations.
1575      * Instead, ThorVG will reuse the previously loaded font data.
1576      *
1577      * @param[in] name The name under which the font will be stored and accessible (e.x. in a @p font() API).
1578      * @param[in] data A pointer to a memory location where the content of the font data is stored.
1579      * @param[in] size The size in bytes of the memory occupied by the @p data.
1580      * @param[in] mimeType Mimetype or extension of font data. In case an empty string is provided the loader will be determined automatically.
1581      * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not (default).
1582      *
1583      * @retval Result::InvalidArguments If no name is provided or if @p size is zero while @p data points to a valid memory location.
1584      * @retval Result::NonSupport When trying to load a file with an unsupported extension.
1585      * @retval Result::InsufficientCondition If attempting to unload the font data that has not been previously loaded.
1586      *
1587      * @warning It's the user responsibility to release the @p data memory.
1588      *
1589      * @note To unload the font data loaded using this API, pass the proper @p name and @c nullptr as @p data.
1590      * @note If you are unsure about the MIME type, you can provide an empty value like @c "", and thorvg will attempt to figure it out.
1591      * @see Text::font(const char* name, float size, const char* style)
1592      *
1593      * @note 0.15
1594      */
1595     static Result load(const char* name, const char* data, uint32_t size, const std::string& mimeType = "ttf", bool copy = false) noexcept;
1596 
1597     /**
1598      * @brief Unloads the specified scalable font data (TTF) that was previously loaded.
1599      *
1600      * This function is used to release resources associated with a font file that has been loaded into memory.
1601      *
1602      * @param[in] path The file path of the loaded font.
1603      *
1604      * @retval Result::InsufficientCondition Fails if the loader is not initialized.
1605      *
1606      * @note If the font data is currently in use, it will not be immediately unloaded.
1607      * @see Text::load(const std::string& path)
1608      *
1609      * @since 0.15
1610      */
1611     static Result unload(const std::string& path) noexcept;
1612 
1613     /**
1614      * @brief Creates a new Text object.
1615      *
1616      * @return A new Text object.
1617      *
1618      * @since 0.15
1619      */
1620     static std::unique_ptr<Text> gen() noexcept;
1621 
1622     /**
1623      * @brief Returns the ID value of this class.
1624      *
1625      * This method can be used to check the current concrete instance type.
1626      *
1627      * @return The class type ID of the Text instance.
1628      *
1629      * @since Experimental API
1630      */
1631     Type type() const noexcept override;
1632 
1633     _TVG_DECLARE_PRIVATE(Text);
1634 };
1635 
1636 
1637 /**
1638  * @class SwCanvas
1639  *
1640  * @brief A class for the rendering graphical elements with a software raster engine.
1641  */
1642 class TVG_API SwCanvas final : public Canvas
1643 {
1644 public:
1645     ~SwCanvas();
1646 
1647     /**
1648      * @brief Enumeration specifying the methods of combining the 8-bit color channels into 32-bit color.
1649      */
1650     enum Colorspace
1651     {
1652         ABGR8888 = 0,      ///< The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied. (a << 24 | b << 16 | g << 8 | r)
1653         ARGB8888,          ///< The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. (a << 24 | r << 16 | g << 8 | b)
1654         ABGR8888S,         ///< The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. @since 0.12
1655         ARGB8888S,         ///< The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. @since 0.12
1656     };
1657 
1658     /**
1659      * @brief Enumeration specifying the methods of Memory Pool behavior policy.
1660      * @since 0.4
1661      */
1662     enum MempoolPolicy
1663     {
1664         Default = 0, ///< Default behavior that ThorVG is designed to.
1665         Shareable,   ///< Memory Pool is shared among the SwCanvases.
1666         Individual   ///< Allocate designated memory pool that is only used by current instance.
1667     };
1668 
1669     /**
1670      * @brief Sets the drawing target for the rasterization.
1671      *
1672      * The buffer of a desirable size should be allocated and owned by the caller.
1673      *
1674      * @param[in] buffer A pointer to a memory block of the size @p stride x @p h, where the raster data are stored.
1675      * @param[in] stride The stride of the raster image - greater than or equal to @p w.
1676      * @param[in] w The width of the raster image.
1677      * @param[in] h The height of the raster image.
1678      * @param[in] cs The value specifying the way the 32-bits colors should be read/written.
1679      *
1680      * @retval Result::InvalidArguments In case no valid pointer is provided or the width, or the height or the stride is zero.
1681      * @retval Result::InsufficientCondition if the canvas is performing rendering. Please ensure the canvas is synced.
1682      * @retval Result::NonSupport In case the software engine is not supported.
1683      *
1684      * @warning Do not access @p buffer during Canvas::push() - Canvas::sync(). It should not be accessed while the engine is writing on it.
1685      *
1686      * @see Canvas::viewport()
1687      * @see Canvas::sync()
1688     */
1689     Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept;
1690 
1691     /**
1692      * @brief Set sw engine memory pool behavior policy.
1693      *
1694      * Basically ThorVG draws a lot of shapes, it allocates/deallocates a few chunk of memory
1695      * while processing rendering. It internally uses one shared memory pool
1696      * which can be reused among the canvases in order to avoid memory overhead.
1697      *
1698      * Thus ThorVG suggests using a memory pool policy to satisfy user demands,
1699      * if it needs to guarantee the thread-safety of the internal data access.
1700      *
1701      * @param[in] policy The method specifying the Memory Pool behavior. The default value is @c MempoolPolicy::Default.
1702      *
1703      * @retval Result::InsufficientCondition If the canvas contains some paints already.
1704      * @retval Result::NonSupport In case the software engine is not supported.
1705      *
1706      * @note When @c policy is set as @c MempoolPolicy::Individual, the current instance of canvas uses its own individual
1707      *       memory data, which is not shared with others. This is necessary when the canvas is accessed on a worker-thread.
1708      *
1709      * @warning It's not allowed after pushing any paints.
1710      *
1711      * @since 0.4
1712     */
1713     Result mempool(MempoolPolicy policy) noexcept;
1714 
1715     /**
1716      * @brief Creates a new SwCanvas object.
1717      * @return A new SwCanvas object.
1718      */
1719     static std::unique_ptr<SwCanvas> gen() noexcept;
1720 
1721     _TVG_DECLARE_PRIVATE(SwCanvas);
1722 };
1723 
1724 
1725 /**
1726  * @class GlCanvas
1727  *
1728  * @brief A class for the rendering graphic elements with a GL raster engine.
1729  *
1730  * @since 0.14
1731  */
1732 class TVG_API GlCanvas final : public Canvas
1733 {
1734 public:
1735     ~GlCanvas();
1736 
1737     /**
1738      * @brief Sets the drawing target for rasterization.
1739      *
1740      * This function specifies the drawing target where the rasterization will occur. It can target
1741      * a specific framebuffer object (FBO) or the main surface.
1742      *
1743      * @param[in] id The GL target ID, usually indicating the FBO ID. A value of @c 0 specifies the main surface.
1744      * @param[in] w The width (in pixels) of the raster image.
1745      * @param[in] h The height (in pixels) of the raster image.
1746      *
1747      * @retval Result::InsufficientCondition if the canvas is performing rendering. Please ensure the canvas is synced.
1748      * @retval Result::NonSupport In case the gl engine is not supported.
1749      *
1750      * @see Canvas::viewport()
1751      * @see Canvas::sync()
1752      *
1753      * @note Currently, this only allows the GL_RGBA8 color space format.
1754      * @note Experimental API
1755     */
1756     Result target(int32_t id, uint32_t w, uint32_t h) noexcept;
1757 
1758     /**
1759      * @brief Creates a new GlCanvas object.
1760      *
1761      * @return A new GlCanvas object.
1762      *
1763      * @since 0.14
1764      */
1765     static std::unique_ptr<GlCanvas> gen() noexcept;
1766 
1767     _TVG_DECLARE_PRIVATE(GlCanvas);
1768 };
1769 
1770 
1771 /**
1772  * @class WgCanvas
1773  *
1774  * @brief A class for the rendering graphic elements with a WebGPU raster engine.
1775  *
1776  * @warning Please do not use it. This class is not fully supported yet.
1777  *
1778  * @since 0.15
1779  */
1780 class TVG_API WgCanvas final : public Canvas
1781 {
1782 public:
1783     ~WgCanvas();
1784 
1785     /**
1786      * @brief Sets the drawing target for the rasterization.
1787      *
1788      * @param[in] instance WGPUInstance, context for all other wgpu objects.
1789      * @param[in] surface WGPUSurface, handle to a presentable surface.
1790      * @param[in] w The width of the surface.
1791      * @param[in] h The height of the surface.
1792      * @param[in] device WGPUDevice, a desired handle for the wgpu device. If it is @c nullptr, ThorVG will assign an appropriate device internally.
1793      *
1794      * @retval Result::InsufficientCondition if the canvas is performing rendering. Please ensure the canvas is synced.
1795      * @retval Result::NonSupport In case the wg engine is not supported.
1796      *
1797      * @note Experimental API
1798      *
1799      * @see Canvas::viewport()
1800      * @see Canvas::sync()
1801      */
1802     Result target(void* instance, void* surface, uint32_t w, uint32_t h, void* device = nullptr) noexcept;
1803 
1804     /**
1805      * @brief Creates a new WgCanvas object.
1806      *
1807      * @return A new WgCanvas object.
1808      *
1809      * @since 0.15
1810      */
1811     static std::unique_ptr<WgCanvas> gen() noexcept;
1812 
1813     _TVG_DECLARE_PRIVATE(WgCanvas);
1814 };
1815 
1816 
1817 /**
1818  * @class Initializer
1819  *
1820  * @brief A class that enables initialization and termination of the TVG engines.
1821  */
1822 class TVG_API Initializer final
1823 {
1824 public:
1825     /**
1826      * @brief Initializes TVG engines.
1827      *
1828      * TVG requires the running-engine environment.
1829      * TVG runs its own task-scheduler for parallelizing rendering tasks efficiently.
1830      * You can indicate the number of threads, the count of which is designated @p threads.
1831      * In the initialization step, TVG will generate/spawn the threads as set by @p threads count.
1832      *
1833      * @param[in] engine The engine types to initialize. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed.
1834      * @param[in] threads The number of additional threads. Zero indicates only the main thread is to be used.
1835      *
1836      * @retval Result::NonSupport In case the engine type is not supported on the system.
1837      *
1838      * @note The Initializer keeps track of the number of times it was called. Threads count is fixed at the first init() call.
1839      * @see Initializer::term()
1840      */
1841     static Result init(CanvasEngine engine, uint32_t threads) noexcept;
1842 
1843     /**
1844      * @brief Terminates TVG engines.
1845      *
1846      * @param[in] engine The engine types to terminate. This is relative to the Canvas types, in which it will be used. For multiple backends bitwise operation is allowed
1847      *
1848      * @retval Result::InsufficientCondition In case there is nothing to be terminated.
1849      * @retval Result::NonSupport In case the engine type is not supported on the system.
1850      *
1851      * @note Initializer does own reference counting for multiple calls.
1852      * @see Initializer::init()
1853      */
1854     static Result term(CanvasEngine engine) noexcept;
1855 
1856     /**
1857      * @brief Retrieves the version of the TVG engine.
1858      *
1859      * @param[out] major A major version number.
1860      * @param[out] minor A minor version number.
1861      * @param[out] micro A micro version number.
1862      *
1863      * @return The version of the engine in the format major.minor.micro, or a @p nullptr in case of an internal error.
1864      *
1865      * @since 0.15
1866      */
1867     static const char* version(uint32_t* major, uint32_t* minor, uint32_t* micro) noexcept;
1868 
1869     _TVG_DISABLE_CTOR(Initializer);
1870 };
1871 
1872 
1873 /**
1874  * @class Animation
1875  *
1876  * @brief The Animation class enables manipulation of animatable images.
1877  *
1878  * This class supports the display and control of animation frames.
1879  *
1880  * @since 0.13
1881  */
1882 
1883 class TVG_API Animation
1884 {
1885 public:
1886     ~Animation();
1887 
1888     /**
1889      * @brief Specifies the current frame in the animation.
1890      *
1891      * @param[in] no The index of the animation frame to be displayed. The index should be less than the totalFrame().
1892      *
1893      * @retval Result::InsufficientCondition if the given @p no is the same as the current frame value.
1894      * @retval Result::NonSupport The current Picture data does not support animations.
1895      *
1896      * @note For efficiency, ThorVG ignores updates to the new frame value if the difference from the current frame value
1897      *       is less than 0.001. In such cases, it returns @c Result::InsufficientCondition.
1898      *       Values less than 0.001 may be disregarded and may not be accurately retained by the Animation.
1899      *
1900      * @see totalFrame()
1901      *
1902      */
1903     Result frame(float no) noexcept;
1904 
1905     /**
1906      * @brief Retrieves a picture instance associated with this animation instance.
1907      *
1908      * This function provides access to the picture instance that can be used to load animation formats, such as Lottie(json).
1909      * After setting up the picture, it can be pushed to the designated canvas, enabling control over animation frames
1910      * with this Animation instance.
1911      *
1912      * @return A picture instance that is tied to this animation.
1913      *
1914      * @warning The picture instance is owned by Animation. It should not be deleted manually.
1915      *
1916      */
1917     Picture* picture() const noexcept;
1918 
1919     /**
1920      * @brief Retrieves the current frame number of the animation.
1921      *
1922      * @return The current frame number of the animation, between 0 and totalFrame() - 1.
1923      *
1924      * @note If the Picture is not properly configured, this function will return 0.
1925      *
1926      * @see Animation::frame(float no)
1927      * @see Animation::totalFrame()
1928      *
1929      */
1930     float curFrame() const noexcept;
1931 
1932     /**
1933      * @brief Retrieves the total number of frames in the animation.
1934      *
1935      * @return The total number of frames in the animation.
1936      *
1937      * @note Frame numbering starts from 0.
1938      * @note If the Picture is not properly configured, this function will return 0.
1939      *
1940      */
1941     float totalFrame() const noexcept;
1942 
1943     /**
1944      * @brief Retrieves the duration of the animation in seconds.
1945      *
1946      * @return The duration of the animation in seconds.
1947      *
1948      * @note If the Picture is not properly configured, this function will return 0.
1949      *
1950      */
1951     float duration() const noexcept;
1952 
1953     /**
1954      * @brief Specifies the playback segment of the animation.
1955      *
1956      * The set segment is designated as the play area of the animation.
1957      * This is useful for playing a specific segment within the entire animation.
1958      * After setting, the number of animation frames and the playback time are calculated
1959      * by mapping the playback segment as the entire range.
1960      *
1961      * @param[in] begin segment start.
1962      * @param[in] end segment end.
1963      *
1964      * @retval Result::InsufficientCondition In case the animation is not loaded.
1965      * @retval Result::NonSupport When it's not animatable.
1966      *
1967      * @note Animation allows a range from 0.0 to 1.0. @p end should not be higher than @p begin.
1968      * @note If a marker has been specified, its range will be disregarded.
1969      * @see LottieAnimation::segment(const char* marker)
1970      *
1971      * @note Experimental API
1972      */
1973     Result segment(float begin, float end) noexcept;
1974 
1975     /**
1976      * @brief Gets the current segment.
1977      *
1978      * @param[out] begin segment start.
1979      * @param[out] end segment end.
1980      *
1981      * @retval Result::InsufficientCondition In case the animation is not loaded.
1982      * @retval Result::NonSupport When it's not animatable.
1983      *
1984      * @note Experimental API
1985      */
1986     Result segment(float* begin, float* end = nullptr) noexcept;
1987 
1988     /**
1989      * @brief Creates a new Animation object.
1990      *
1991      * @return A new Animation object.
1992      *
1993      */
1994     static std::unique_ptr<Animation> gen() noexcept;
1995 
1996     _TVG_DECLARE_PRIVATE(Animation);
1997 };
1998 
1999 
2000 /**
2001  * @class Saver
2002  *
2003  * @brief A class for exporting a paint object into a specified file, from which to recover the paint data later.
2004  *
2005  * ThorVG provides a feature for exporting & importing paint data. The Saver role is to export the paint data to a file.
2006  * It's useful when you need to save the composed scene or image from a paint object and recreate it later.
2007  *
2008  * The file format is decided by the extension name(i.e. "*.tvg") while the supported formats depend on the TVG packaging environment.
2009  * If it doesn't support the file format, the save() method returns the @c Result::NonSupport result.
2010  *
2011  * Once you export a paint to the file successfully, you can recreate it using the Picture class.
2012  *
2013  * @see Picture::load()
2014  *
2015  * @since 0.5
2016  */
2017 class TVG_API Saver final
2018 {
2019 public:
2020     ~Saver();
2021 
2022     /**
2023      * @brief Sets the base background content for the saved image.
2024      *
2025      * @param[in] paint The paint to be drawn as the background image for the saving paint.
2026      *
2027      * @note Experimental API
2028      */
2029     Result background(std::unique_ptr<Paint> paint) noexcept;
2030 
2031     /**
2032      * @brief Exports the given @p paint data to the given @p path
2033      *
2034      * If the saver module supports any compression mechanism, it will optimize the data size.
2035      * This might affect the encoding/decoding time in some cases. You can turn off the compression
2036      * if you wish to optimize for speed.
2037      *
2038      * @param[in] paint The paint to be saved with all its associated properties.
2039      * @param[in] path A path to the file, in which the paint data is to be saved.
2040      * @param[in] compress If @c true then compress data if possible.
2041      *
2042      * @retval Result::InsufficientCondition If currently saving other resources.
2043      * @retval Result::NonSupport When trying to save a file with an unknown extension or in an unsupported format.
2044      * @retval Result::Unknown In case an empty paint is to be saved.
2045      *
2046      * @note Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call sync() afterwards.
2047      * @see Saver::sync()
2048      *
2049      * @since 0.5
2050      */
2051     Result save(std::unique_ptr<Paint> paint, const std::string& path, bool compress = true) noexcept;
2052 
2053     /**
2054      * @brief Export the provided animation data to the specified file path.
2055      *
2056      * This function exports the given animation data to the provided file path. You can also specify the desired frame rate in frames per second (FPS) by providing the fps parameter.
2057      *
2058      * @param[in] animation The animation to be saved, including all associated properties.
2059      * @param[in] path The path to the file where the animation will be saved.
2060      * @param[in] quality The encoded quality level. @c 0 is the minimum, @c 100 is the maximum value(recommended).
2061      * @param[in] fps The desired frames per second (FPS). For example, to encode data at 60 FPS, pass 60. Pass 0 to keep the original frame data.
2062      *
2063      * @retval Result::InsufficientCondition if there are ongoing resource-saving operations.
2064      * @retval Result::NonSupport if an attempt is made to save the file with an unknown extension or in an unsupported format.
2065      * @retval Result::Unknown if attempting to save an empty paint.
2066      *
2067      * @note A higher frames per second (FPS) would result in a larger file size. It is recommended to use the default value.
2068      * @note Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call sync() afterwards.
2069      *
2070      * @see Saver::sync()
2071      *
2072      * @note Experimental API
2073      */
2074     Result save(std::unique_ptr<Animation> animation, const std::string& path, uint32_t quality = 100, uint32_t fps = 0) noexcept;
2075 
2076     /**
2077      * @brief Guarantees that the saving task is finished.
2078      *
2079      * The behavior of the Saver works on a sync/async basis, depending on the threading setting of the Initializer.
2080      * Thus, if you wish to have a benefit of it, you must call sync() after the save() in the proper delayed time.
2081      * Otherwise, you can call sync() immediately.
2082      *
2083      * @note The asynchronous tasking is dependent on the Saver module implementation.
2084      * @see Saver::save()
2085      *
2086      * @since 0.5
2087      */
2088     Result sync() noexcept;
2089 
2090     /**
2091      * @brief Creates a new Saver object.
2092      *
2093      * @return A new Saver object.
2094      *
2095      * @since 0.5
2096      */
2097     static std::unique_ptr<Saver> gen() noexcept;
2098 
2099     _TVG_DECLARE_PRIVATE(Saver);
2100 };
2101 
2102 
2103 /**
2104  * @class Accessor
2105  *
2106  * @brief The Accessor is a utility class to debug the Scene structure by traversing the scene-tree.
2107  *
2108  * The Accessor helps you search specific nodes to read the property information, figure out the structure of the scene tree and its size.
2109  *
2110  * @warning We strongly warn you not to change the paints of a scene unless you really know the design-structure.
2111  *
2112  * @since 0.10
2113  */
2114 class TVG_API Accessor final
2115 {
2116 public:
2117     ~Accessor();
2118 
2119     TVG_DEPRECATED std::unique_ptr<Picture> set(std::unique_ptr<Picture> picture, std::function<bool(const Paint* paint)> func) noexcept;
2120 
2121     /**
2122      * @brief Set the access function for traversing the Picture scene tree nodes.
2123      *
2124      * @param[in] picture The picture node to traverse the internal scene-tree.
2125      * @param[in] func The callback function calling for every paint nodes of the Picture.
2126      * @param[in] data Data passed to the @p func as its argument.
2127      *
2128      * @note The bitmap based picture might not have the scene-tree.
2129      *
2130      * @note Experimental API
2131      */
2132     Result set(const Picture* picture, std::function<bool(const Paint* paint, void* data)> func, void* data) noexcept;
2133 
2134     /**
2135      * @brief Generate a unique ID (hash key) from a given name.
2136      *
2137      * This function computes a unique identifier value based on the provided string.
2138      * You can use this to assign a unique ID to the Paint object.
2139      *
2140      * @param[in] name The input string to generate the unique identifier from.
2141      *
2142      * @return The generated unique identifier value.
2143      *
2144      * @see Paint::id
2145      *
2146      * @note Experimental API
2147      */
2148     static uint32_t id(const char* name) noexcept;
2149 
2150     /**
2151      * @brief Creates a new Accessor object.
2152      *
2153      * @return A new Accessor object.
2154      */
2155     static std::unique_ptr<Accessor> gen() noexcept;
2156 
2157     _TVG_DECLARE_PRIVATE(Accessor);
2158 };
2159 
2160 
2161 /**
2162  * @brief The cast() function is a utility function used to cast a 'Paint' to type 'T'.
2163  * @since 0.11
2164  */
2165 template<typename T = tvg::Paint>
cast(Paint * paint)2166 std::unique_ptr<T> cast(Paint* paint)
2167 {
2168     return std::unique_ptr<T>(static_cast<T*>(paint));
2169 }
2170 
2171 
2172 /**
2173  * @brief The cast() function is a utility function used to cast a 'Fill' to type 'T'.
2174  * @since 0.11
2175  */
2176 template<typename T = tvg::Fill>
cast(Fill * fill)2177 std::unique_ptr<T> cast(Fill* fill)
2178 {
2179     return std::unique_ptr<T>(static_cast<T*>(fill));
2180 }
2181 
2182 
2183 /** @}*/
2184 
2185 } //namespace
2186 
2187 #endif //_THORVG_H_
2188 
2189 #endif /* LV_USE_THORVG_INTERNAL */
2190 
2191