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