diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 4b8a246df01..c549761beb2 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -483,7 +483,7 @@ License: Expat Files: ./thirdparty/thorvg/ Comment: ThorVG -Copyright: 2020-2023, The ThorVG Project +Copyright: 2020-2024, The ThorVG Project License: Expat Files: ./thirdparty/tinyexr/ diff --git a/modules/svg/SCsub b/modules/svg/SCsub index d0c6250b11d..ff0c3c9141c 100644 --- a/modules/svg/SCsub +++ b/modules/svg/SCsub @@ -43,6 +43,8 @@ thirdparty_sources = [ "src/renderer/tvgShape.cpp", "src/renderer/tvgSwCanvas.cpp", "src/renderer/tvgTaskScheduler.cpp", + "src/renderer/tvgText.cpp", + # "src/renderer/tvgWgCanvas.cpp", # renderer sw_engine "src/renderer/sw_engine/tvgSwFill.cpp", "src/renderer/sw_engine/tvgSwImage.cpp", diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct index f6d3b24cee4..cd4331b60e2 100644 --- a/modules/text_server_adv/gdextension_build/SConstruct +++ b/modules/text_server_adv/gdextension_build/SConstruct @@ -74,6 +74,8 @@ if env["thorvg_enabled"] and env["freetype_enabled"]: "src/renderer/tvgShape.cpp", "src/renderer/tvgSwCanvas.cpp", "src/renderer/tvgTaskScheduler.cpp", + "src/renderer/tvgText.cpp", + # "src/renderer/tvgWgCanvas.cpp", # renderer sw_engine "src/renderer/sw_engine/tvgSwFill.cpp", "src/renderer/sw_engine/tvgSwImage.cpp", diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct index 0d2fbd97fd0..0efced0bfc1 100644 --- a/modules/text_server_fb/gdextension_build/SConstruct +++ b/modules/text_server_fb/gdextension_build/SConstruct @@ -69,6 +69,8 @@ if env["thorvg_enabled"] and env["freetype_enabled"]: "src/renderer/tvgShape.cpp", "src/renderer/tvgSwCanvas.cpp", "src/renderer/tvgTaskScheduler.cpp", + "src/renderer/tvgText.cpp", + # "src/renderer/tvgWgCanvas.cpp", # renderer sw_engine "src/renderer/sw_engine/tvgSwFill.cpp", "src/renderer/sw_engine/tvgSwImage.cpp", diff --git a/thirdparty/README.md b/thirdparty/README.md index 510219194ba..6922af0c0d6 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -861,7 +861,7 @@ instead of `miniz.h` as an external dependency. ## thorvg - Upstream: https://github.com/thorvg/thorvg -- Version: 0.11.6 (3dba4f12f8f05f86acbc51096ca3a15f5d96bc06, 2023) +- Version: 0.12.0 (25ea242d3867ed66807714f5a52d080984d3c8cc, 2024) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/thorvg/AUTHORS b/thirdparty/thorvg/AUTHORS index 3a459e9bb49..d5d5e9be97d 100644 --- a/thirdparty/thorvg/AUTHORS +++ b/thirdparty/thorvg/AUTHORS @@ -23,3 +23,5 @@ RafaƂ Mikrut Martin Capitanio RuiwenTang YouJin Lee +SergeyLebedkin +Jinny You diff --git a/thirdparty/thorvg/LICENSE b/thirdparty/thorvg/LICENSE index d056ff6cbff..f97be650054 100644 --- a/thirdparty/thorvg/LICENSE +++ b/thirdparty/thorvg/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020 - 2023 notice for the ThorVG Project (see AUTHORS) +Copyright (c) 2020 - 2024 notice for the ThorVG Project (see AUTHORS) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h index 98f35a6e457..d1abc5a2901 100644 --- a/thirdparty/thorvg/inc/config.h +++ b/thirdparty/thorvg/inc/config.h @@ -9,5 +9,5 @@ // For internal debugging: //#define THORVG_LOG_ENABLED -#define THORVG_VERSION_STRING "0.11.6" +#define THORVG_VERSION_STRING "0.12.0" #endif diff --git a/thirdparty/thorvg/inc/thorvg.h b/thirdparty/thorvg/inc/thorvg.h index 20acda7667f..6aee53f7e07 100644 --- a/thirdparty/thorvg/inc/thorvg.h +++ b/thirdparty/thorvg/inc/thorvg.h @@ -1,17 +1,3 @@ -/*! - * @file thorvg.h - * - * The main APIs enabling the TVG initialization, preparation of the canvas and provisioning of its content: - * - drawing shapes: line, arc, curve, path, polygon... - * - drawing pictures: tvg, svg, png, jpg, bitmap... - * - drawing fillings: solid, linear and radial gradient... - * - drawing stroking: continuous stroking with arbitrary width, join, cap, dash styles. - * - drawing composition: blending, masking, path clipping... - * - drawing scene graph & affine transformation (translation, rotation, scale, ...) - * and finally drawing the canvas and TVG termination. - */ - - #ifndef _THORVG_H_ #define _THORVG_H_ @@ -172,10 +158,10 @@ enum class CompositeMethod InvAlphaMask, ///< Alpha Masking using the complement to the compositing target's pixels as an alpha value. LumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the compositing target's pixels. @since 0.9 InvLumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the complement to the compositing target's pixels. - AddMask, ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) @BETA_API - SubtractMask, ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) @BETA_API - 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 - 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 + AddMask, ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) (Experimental API) + SubtractMask, ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) (Experimental API) + 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) + 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) }; @@ -186,7 +172,7 @@ enum class CompositeMethod * * @see Paint::blend() * - * @BETA_API + * @note Experimental API */ enum class BlendMethod : uint8_t { @@ -213,7 +199,8 @@ enum class BlendMethod : uint8_t enum class CanvasEngine { Sw = (1 << 1), ///< CPU rasterizer. - Gl = (1 << 2) ///< OpenGL rasterizer. + Gl = (1 << 2), ///< OpenGL rasterizer. + Wg = (1 << 3), ///< WebGPU rasterizer. (Experimental API) }; @@ -247,7 +234,7 @@ struct Matrix * @param pt The vertex coordinate * @param uv The normalized texture coordinate in the range (0.0..1.0, 0.0..1.0) * - * @BETA_API + * @note Experimental API */ struct Vertex { @@ -261,7 +248,7 @@ struct Vertex * * @param vertex The three vertices that make up the polygon * - * @BETA_API + * @note Experimental API */ struct Polygon { @@ -291,7 +278,7 @@ public: * * @param[in] degree The value of the angle in degrees. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result rotate(float degree) noexcept; @@ -300,7 +287,7 @@ public: * * @param[in] factor The value of the scaling factor. The default value is 1. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result scale(float factor) noexcept; @@ -313,7 +300,7 @@ public: * @param[in] x The value of the horizontal shift. * @param[in] y The value of the vertical shift. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result translate(float x, float y) noexcept; @@ -324,7 +311,7 @@ public: * * @param[in] m The 3x3 augmented matrix. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result transform(const Matrix& m) noexcept; @@ -345,7 +332,7 @@ public: * * @param[in] o The opacity value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note Setting the opacity with this API may require multiple render pass for composition. It is recommended to avoid changing the opacity if possible. * @note ClipPath won't use the opacity value. (see: enum class CompositeMethod::ClipPath) @@ -358,7 +345,7 @@ public: * @param[in] target The paint of the target object. * @param[in] method The method used to composite the source object with the target. * - * @return Result::Success when succeed, Result::InvalidArguments otherwise. + * @retval Result::Success when succeed, Result::InvalidArguments otherwise. */ Result composite(std::unique_ptr target, CompositeMethod method) noexcept; @@ -371,9 +358,9 @@ public: * * @param[in] method The blending method to be set. * - * @return Result::Success when the blending method is successfully set. + * @retval Result::Success when the blending method is successfully set. * - * @BETA_API + * @note Experimental API */ Result blend(BlendMethod method) const noexcept; @@ -404,7 +391,7 @@ public: * @param[out] h The height of the object. * @param[in] transformed If @c true, the paint's transformations are taken into account, otherwise they aren't. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * * @note The bounding box doesn't indicate the actual drawing region. It's the smallest rectangle that encloses the object. */ @@ -442,7 +429,7 @@ public: * * @return The blending method * - * @BETA_API + * @note Experimental API */ BlendMethod blend() const noexcept; @@ -493,7 +480,7 @@ public: * @param[in] colorStops An array of ColorStop data structure. * @param[in] cnt The count of the @p colorStops array equal to the colors number used in the gradient. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result colorStops(const ColorStop* colorStops, uint32_t cnt) noexcept; @@ -502,7 +489,7 @@ public: * * @param[in] s The FillSpread value. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result spread(FillSpread s) noexcept; @@ -513,7 +500,7 @@ public: * * @param[in] m The 3x3 augmented matrix. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result transform(const Matrix& m) noexcept; @@ -538,7 +525,7 @@ public: * * In case no transformation was applied, the identity matrix is returned. * - * @retval The augmented transformation matrix. + * @return The augmented transformation matrix. */ Matrix transform() const noexcept; @@ -600,7 +587,7 @@ public: * @warning Please avoid accessing the paints during Canvas update/draw. You can access them after calling sync(). * @see Canvas::sync() * - * @BETA_API + * @note Experimental API */ std::list& paints() noexcept; @@ -631,7 +618,7 @@ public: * * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * * @see Canvas::push() * @see Canvas::paints() @@ -646,7 +633,7 @@ public: * * @param[in] paint A pointer to the Paint object or @c nullptr. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * * @note The Update behavior can be asynchronous if the assigned thread number is greater than zero. */ @@ -655,7 +642,7 @@ public: /** * @brief Requests the canvas to draw the Paint objects. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * * @note Drawing can be asynchronous if the assigned thread number is greater than zero. To guarantee the drawing is done, call sync() afterwards. * @see Canvas::sync() @@ -668,7 +655,7 @@ public: * The Canvas rendering can be performed asynchronously. To make sure that rendering is finished, * the sync() must be called after the draw() regardless of threading. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. * @see Canvas::draw() */ virtual Result sync() noexcept; @@ -702,7 +689,7 @@ public: * @param[in] x2 The horizontal coordinate of the second point used to determine the gradient bounds. * @param[in] y2 The vertical coordinate of the second point used to determine the gradient bounds. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note In case the first and the second points are equal, an object filled with such a gradient fill is not rendered. */ @@ -720,7 +707,7 @@ public: * @param[out] x2 The horizontal coordinate of the second point used to determine the gradient bounds. * @param[out] y2 The vertical coordinate of the second point used to determine the gradient bounds. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result linear(float* x1, float* y1, float* x2, float* y2) const noexcept; @@ -764,7 +751,7 @@ public: * @param[in] cy The vertical coordinate of the center of the bounding circle. * @param[in] radius The radius of the bounding circle. * - * @return Result::Success when succeed, Result::InvalidArguments in case the @p radius value is zero or less. + * @retval Result::Success when succeed, Result::InvalidArguments in case the @p radius value is zero or less. */ Result radial(float cx, float cy, float radius) noexcept; @@ -777,7 +764,7 @@ public: * @param[out] cy The vertical coordinate of the center of the bounding circle. * @param[out] radius The radius of the bounding circle. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result radial(float* cx, float* cy, float* radius) const noexcept; @@ -823,7 +810,7 @@ public: * * The transformation matrix, the color, the fill and the stroke properties are retained. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note The memory, where the path data is stored, is not deallocated at this stage for caching effect. */ @@ -837,7 +824,7 @@ public: * @param[in] x The horizontal coordinate of the initial point of the sub-path. * @param[in] y The vertical coordinate of the initial point of the sub-path. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result moveTo(float x, float y) noexcept; @@ -849,7 +836,7 @@ public: * @param[in] x The horizontal coordinate of the end-point of the line. * @param[in] y The vertical coordinate of the end-point of the line. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note In case this is the first command in the path, it corresponds to the moveTo() call. */ @@ -868,7 +855,7 @@ public: * @param[in] x The horizontal coordinate of the end-point of the curve. * @param[in] y The vertical coordinate of the end-point of the curve. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note In case this is the first command in the path, no data from the path are rendered. */ @@ -879,7 +866,7 @@ public: * * The value of the current point is set to the initial point of the closed sub-path. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note In case the sub-path does not contain any points, this function has no effect. */ @@ -905,7 +892,7 @@ public: * @param[in] rx The x-axis radius of the ellipse defining the rounded corners of the rectangle. * @param[in] ry The y-axis radius of the ellipse defining the rounded corners of the rectangle. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @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. */ @@ -925,7 +912,7 @@ public: * @param[in] rx The x-axis radius of the ellipse. * @param[in] ry The y-axis radius of the ellipse. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result appendCircle(float cx, float cy, float rx, float ry) noexcept; @@ -942,7 +929,7 @@ public: * @param[in] sweep The central angle of the arc given in degrees, measured counter-clockwise from @p startAngle. * @param[in] pie Specifies whether to draw radii from the arc's center to both of its end-point - drawn if @c true. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note Setting @p sweep value greater than 360 degrees, is equivalent to calling appendCircle(cx, cy, radius, radius). */ @@ -960,7 +947,7 @@ public: * @param[in] pts The array of the two-dimensional points. * @param[in] ptsCnt The number of the points in the @p pts array. * - * @return Result::Success when succeed, Result::InvalidArguments otherwise. + * @retval Result::Success when succeed, Result::InvalidArguments otherwise. * * @note The interface is designed for optimal path setting if the caller has a completed path commands already. */ @@ -971,7 +958,7 @@ public: * * @param[in] width The width of the stroke. The default value is 0. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result stroke(float width) noexcept; @@ -983,7 +970,7 @@ public: * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. * @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. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result stroke(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) noexcept; @@ -1018,7 +1005,7 @@ public: * * @param[in] cap The cap style value. The default value is @c StrokeCap::Square. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result stroke(StrokeCap cap) noexcept; @@ -1029,7 +1016,7 @@ public: * * @param[in] join The join style value. The default value is @c StrokeJoin::Bevel. * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. */ Result stroke(StrokeJoin join) noexcept; @@ -1039,7 +1026,7 @@ public: * * @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. * - * @return Result::Success when succeed, Result::NonSupport unsupported value, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::NonSupport unsupported value, Result::FailedAllocation otherwise. * * @since 0.11 */ @@ -1055,7 +1042,7 @@ public: * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. * @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. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. * * @note Either a solid color or a gradient fill is applied, depending on what was set as last. * @note ClipPath won't use the fill values. (see: enum class CompositeMethod::ClipPath) @@ -1069,7 +1056,7 @@ public: * * @param[in] f The unique pointer to the gradient fill. * - * @return Result::Success when succeed, Result::MemoryCorruption otherwise. + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. * * @note Either a solid color or a gradient fill is applied, depending on what was set as last. */ @@ -1080,7 +1067,7 @@ public: * * @param[in] r The fill rule value. The default value is @c FillRule::Winding. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result fill(FillRule r) noexcept; @@ -1090,7 +1077,7 @@ public: * * @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). * - * @return Result::Success when succeed, Result::FailedAllocation otherwise. + * @retval Result::Success when succeed, Result::FailedAllocation otherwise. * * @since 0.10 */ @@ -1156,7 +1143,7 @@ public: * @param[out] b The blue color channel value in the range [0 ~ 255]. * @param[out] a The alpha channel value in the range [0 ~ 255], where 0 is completely transparent and 255 is opaque. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. */ Result strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a = nullptr) const noexcept; @@ -1295,7 +1282,7 @@ public: * @param[in] w A new width of the image in pixels. * @param[in] h A new height of the image in pixels. * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. */ Result size(float w, float h) noexcept; @@ -1305,13 +1292,20 @@ public: * @param[out] w The width of the image in pixels. * @param[out] h The height of the image in pixels. * - * @return Result::Success when succeed. + * @retval Result::Success when succeed. */ Result size(float* w, float* h) const noexcept; /** * @brief Loads a raw data from a memory block with a given size. * + * @param[in] paint A Tvg_Paint pointer to the picture object. + * @param[in] data A pointer to a memory location where the content of the picture raw data is stored. + * @param[in] w The width of the image @p data in pixels. + * @param[in] h The height of the image @p data in pixels. + * @param[in] premultiplied If @c true, the given image data is alpha-premultiplied. + * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. + * * @retval Result::Success When succeed, Result::InsufficientCondition otherwise. * @retval Result::FailedAllocation An internal error possibly with memory allocation. * @@ -1339,7 +1333,7 @@ public: * @note The Polygons are copied internally, so modifying them after calling Mesh::mesh has no affect. * @warning Please do not use it, this API is not official one. It could be modified in the next version. * - * @BETA_API + * @note Experimental API */ Result mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept; @@ -1348,12 +1342,12 @@ public: * * @param[out] triangles Optional. A pointer to the array of Polygons used by this mesh. * - * @return uint32_t The number of polygons in the array. + * @return The number of polygons in the array. * * @note Modifying the triangles returned by this method will modify them directly within the mesh. * @warning Please do not use it, this API is not official one. It could be modified in the next version. * - * @BETA_API + * @note Experimental API */ uint32_t mesh(const Polygon** triangles) const noexcept; @@ -1402,7 +1396,7 @@ public: * * @param[in] paint A Paint object to be drawn. * - * @return Result::Success when succeed, Result::MemoryCorruption otherwise. + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. * * @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. * @see Scene::paints() @@ -1432,7 +1426,7 @@ public: * @see Scene::push() * @see Scene::clear() * - * @BETA_API + * @note Experimental API */ std::list& paints() noexcept; @@ -1442,7 +1436,7 @@ public: * * @param[in] free If @c true, the memory occupied by paints is deallocated, otherwise it is not. * - * @return Result::Success when succeed + * @retval Result::Success when succeed * * @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. * @@ -1470,6 +1464,138 @@ public: }; +/** + * @class Text + * + * @brief A class to represent text objects in a graphical context, allowing for rendering and manipulation of unicode text. + * + * @note Experimental API + */ +class TVG_API Text final : public Paint +{ +public: + ~Text(); + + /** + * @brief Sets the font properties for the text. + * + * This function allows you to define the font characteristics used for text rendering. + * It sets the font name, size and optionally the style. + * + * @param[in] name The name of the font. This should correspond to a font available in the canvas. + * @param[in] size The size of the font in points. This determines how large the text will appear. + * @param[in] style The style of the font. It can be used to set the font to 'italic'. + * If not specified, the default style is used. Only 'italic' style is supported currently. + * + * @retval Result::Success when the font properties are set successfully. + * @retval Result::InsufficientCondition when the specified @p name cannot be found. + * + * @note Experimental API + */ + Result font(const char* name, float size, const char* style = nullptr) noexcept; + + /** + * @brief Assigns the given unicode text to be rendered. + * + * This function sets the unicode string that will be displayed by the rendering system. + * The text is set according to the specified UTF encoding method, which defaults to UTF-8. + * + * @param[in] text The multi-byte text encoded with utf8 string to be rendered. + * + * @retval Result::Success when succeed. + * + * @note Experimental API + */ + Result text(const char* text) noexcept; + + /** + * @brief Sets the text color. + * + * @param[in] r The red color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] g The green color channel value in the range [0 ~ 255]. The default value is 0. + * @param[in] b The blue color channel value in the range [0 ~ 255]. The default value is 0. + * + * @retval Result::Success when succeed. + * @retval Result::InsufficientCondition when the font has not been set up prior to this operation. + * + * @see Text::font() + * + * @note Experimental API + */ + Result fill(uint8_t r, uint8_t g, uint8_t b) noexcept; + + /** + * @brief Sets the gradient fill for all of the figures from the text. + * + * The parts of the text defined as inner are filled. + * + * @param[in] f The unique pointer to the gradient fill. + * + * @retval Result::Success when succeed, Result::MemoryCorruption otherwise. + * @retval Result::InsufficientCondition when the font has not been set up prior to this operation. + * + * @note Either a solid color or a gradient fill is applied, depending on what was set as last. + * @note Experimental API + * + * @see Text::font() + */ + Result fill(std::unique_ptr f) noexcept; + + /** + * @brief Loads a scalable font data(ttf) from a file. + * + * @param[in] path The path to the font file. + * + * @retval Result::Success When succeed. + * @retval Result::InvalidArguments In case the @p path is invalid. + * @retval Result::NonSupport When trying to load a file with an unknown extension. + * @retval Result::Unknown If an error occurs at a later stage. + * + * @note Experimental API + * + * @see Text::unload(const std::string& path) + */ + static Result load(const std::string& path) noexcept; + + /** + * @brief Unloads the specified scalable font data (TTF) that was previously loaded. + * + * This function is used to release resources associated with a font file that has been loaded into memory. + * + * @param[in] path The file path of the loaded font. + * + * @retval Result::Success Successfully unloads the font data. + * @retval Result::InsufficientCondition Fails if the loader is not initialized. + * + * @note If the font data is currently in use, it will not be immediately unloaded. + * @note Experimental API + * + * @see Text::load(const std::string& path) + */ + static Result unload(const std::string& path) noexcept; + + /** + * @brief Creates a new Text object. + * + * @return A new Text object. + * + * @note Experimental API + */ + static std::unique_ptr gen() noexcept; + + /** + * @brief Return the unique id value of this class. + * + * This method can be referred for identifying the Text class type. + * + * @return The type id of the Text class. + */ + static uint32_t identifier() noexcept; + + _TVG_DECLARE_PRIVATE(Text); +}; + + /** * @class SwCanvas * @@ -1487,8 +1613,8 @@ public: { ABGR8888 = 0, ///< The channels are joined in the order: alpha, blue, green, red. Colors are alpha-premultiplied. (a << 24 | b << 16 | g << 8 | r) ARGB8888, ///< The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. (a << 24 | r << 16 | g << 8 | b) - ABGR8888S, ///< @BETA_API The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. - ARGB8888S, ///< @BETA_API The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. + ABGR8888S, ///< The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. @since 0.12 + ARGB8888S, ///< The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. @since 0.12 }; /** @@ -1564,7 +1690,7 @@ public: * * @warning Please do not use it. This class is not fully supported yet. * - * @BETA_API + * @note Experimental API */ class TVG_API GlCanvas final : public Canvas { @@ -1576,7 +1702,7 @@ public: * * @warning Please do not use it, this API is not official one. It could be modified in the next version. * - * @BETA_API + * @note Experimental API */ Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) noexcept; @@ -1585,7 +1711,7 @@ public: * * @return A new GlCanvas object. * - * @BETA_API + * @note Experimental API */ static std::unique_ptr gen() noexcept; @@ -1593,6 +1719,42 @@ public: }; +/** + * @class WgCanvas + * + * @brief A class for the rendering graphic elements with a WebGPU raster engine. + * + * @warning Please do not use it. This class is not fully supported yet. + * + * @note Experimental API + */ +class TVG_API WgCanvas final : public Canvas +{ +public: + ~WgCanvas(); + + /** + * @brief Sets the target window for the rasterization. + * + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @note Experimental API + */ + Result target(void* window, uint32_t w, uint32_t h) noexcept; + + /** + * @brief Creates a new WgCanvas object. + * + * @return A new WgCanvas object. + * + * @note Experimental API + */ + static std::unique_ptr gen() noexcept; + + _TVG_DECLARE_PRIVATE(WgCanvas); +}; + + /** * @class Initializer * @@ -1650,7 +1812,7 @@ public: * * This class supports the display and control of animation frames. * - * @BETA_API + * @note Experimental API */ class TVG_API Animation @@ -1669,7 +1831,7 @@ public: * * @see totalFrame() * - * @BETA_API + * @note Experimental API */ Result frame(float no) noexcept; @@ -1684,7 +1846,7 @@ public: * * @warning The picture instance is owned by Animation. It should not be deleted manually. * - * @BETA_API + * @note Experimental API */ Picture* picture() const noexcept; @@ -1698,7 +1860,7 @@ public: * @see Animation::frame(float no) * @see Animation::totalFrame() * - * @BETA_API + * @note Experimental API */ float curFrame() const noexcept; @@ -1710,7 +1872,7 @@ public: * @note Frame numbering starts from 0. * @note If the Picture is not properly configured, this function will return 0. * - * @BETA_API + * @note Experimental API */ float totalFrame() const noexcept; @@ -1721,7 +1883,7 @@ public: * * @note If the Picture is not properly configured, this function will return 0. * - * @BETA_API + * @% Experimental API */ float duration() const noexcept; @@ -1730,7 +1892,7 @@ public: * * @return A new Animation object. * - * @BETA_API + * @note Experimental API */ static std::unique_ptr gen() noexcept; @@ -1760,6 +1922,15 @@ class TVG_API Saver final public: ~Saver(); + /** + * @brief Sets the base background content for the saved image. + * + * @param[in] paint The paint to be drawn as the background image for the saving paint. + * + * @note Experimental API + */ + Result background(std::unique_ptr paint) noexcept; + /** * @brief Exports the given @p paint data to the given @p path * @@ -1794,18 +1965,18 @@ public: * @param[in] quality The encoded quality level. @c 0 is the minimum, @c 100 is the maximum value(recommended). * @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. * - * @return Result::Success if the export succeeds. - * @return Result::InsufficientCondition if there are ongoing resource-saving operations. - * @return Result::NonSupport if an attempt is made to save the file with an unknown extension or in an unsupported format. - * @return Result::MemoryCorruption in case of an internal error. - * @return Result::Unknown if attempting to save an empty paint. + * @retval Result::Success if the export succeeds. + * @retval Result::InsufficientCondition if there are ongoing resource-saving operations. + * @retval Result::NonSupport if an attempt is made to save the file with an unknown extension or in an unsupported format. + * @retval Result::MemoryCorruption in case of an internal error. + * @retval Result::Unknown if attempting to save an empty paint. * * @note A higher frames per second (FPS) would result in a larger file size. It is recommended to use the default value. * @note Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call sync() afterwards. * * @see Saver::sync() * - * @note: Experimental API + * @note Experimental API */ Result save(std::unique_ptr animation, const std::string& path, uint32_t quality = 100, uint32_t fps = 0) noexcept; @@ -1882,7 +2053,7 @@ public: * @brief The cast() function is a utility function used to cast a 'Paint' to type 'T'. * @since 0.11 */ -template +template std::unique_ptr cast(Paint* paint) { return std::unique_ptr(static_cast(paint)); @@ -1893,7 +2064,7 @@ std::unique_ptr cast(Paint* paint) * @brief The cast() function is a utility function used to cast a 'Fill' to type 'T'. * @since 0.11 */ -template +template std::unique_ptr cast(Fill* fill) { return std::unique_ptr(static_cast(fill)); diff --git a/thirdparty/thorvg/src/common/tvgArray.h b/thirdparty/thorvg/src/common/tvgArray.h index 1afc647b688..acb3a41b973 100644 --- a/thirdparty/thorvg/src/common/tvgArray.h +++ b/thirdparty/thorvg/src/common/tvgArray.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,6 +39,11 @@ struct Array Array(){} + Array(int32_t size) + { + reserve(size); + } + Array(const Array& rhs) { reset(); diff --git a/thirdparty/thorvg/src/common/tvgBezier.cpp b/thirdparty/thorvg/src/common/tvgBezier.cpp index f9daf07b84c..5fb501721e2 100644 --- a/thirdparty/thorvg/src/common/tvgBezier.cpp +++ b/thirdparty/thorvg/src/common/tvgBezier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/common/tvgBezier.h b/thirdparty/thorvg/src/common/tvgBezier.h index 539a63bdd32..cb2766c5055 100644 --- a/thirdparty/thorvg/src/common/tvgBezier.h +++ b/thirdparty/thorvg/src/common/tvgBezier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/common/tvgCompressor.cpp b/thirdparty/thorvg/src/common/tvgCompressor.cpp index e38940f3d00..778fc4d0a23 100644 --- a/thirdparty/thorvg/src/common/tvgCompressor.cpp +++ b/thirdparty/thorvg/src/common/tvgCompressor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/common/tvgCompressor.h b/thirdparty/thorvg/src/common/tvgCompressor.h index 05d23f42932..0756127ec61 100644 --- a/thirdparty/thorvg/src/common/tvgCompressor.h +++ b/thirdparty/thorvg/src/common/tvgCompressor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/common/tvgInlist.h b/thirdparty/thorvg/src/common/tvgInlist.h new file mode 100644 index 00000000000..ff28cfd48ea --- /dev/null +++ b/thirdparty/thorvg/src/common/tvgInlist.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_INLIST_H_ +#define _TVG_INLIST_H_ + +namespace tvg { + +//NOTE: declare this in your list item +#define INLIST_ITEM(T) \ + T* prev; \ + T* next + +template +struct Inlist +{ + T* head = nullptr; + T* tail = nullptr; + + void free() + { + while (head) { + auto t = head; + head = t->next; + delete(t); + } + head = tail = nullptr; + } + + void back(T* element) + { + if (tail) { + tail->next = element; + element->prev = tail; + element->next = nullptr; + tail = element; + } else { + head = tail = element; + element->prev = nullptr; + element->next = nullptr; + } + } + + void front(T* element) + { + if (head) { + head->prev = element; + element->prev = nullptr; + element->next = head; + head = element; + } else { + head = tail = element; + element->prev = nullptr; + element->next = nullptr; + } + } + + T* back() + { + if (!tail) return nullptr; + auto t = tail; + tail = t->prev; + if (!tail) head = nullptr; + return t; + } + + T* front() + { + if (!head) return nullptr; + auto t = head; + head = t->next; + if (!head) tail = nullptr; + return t; + } + + void remove(T* element) + { + if (element->prev) element->prev->next = element->next; + if (element->next) element->next->prev = element->prev; + if (element == head) head = element->next; + if (element == tail) tail = element->prev; + } + + bool empty() + { + return head ? false : true; + } +}; + +} + +#endif // _TVG_INLIST_H_ diff --git a/thirdparty/thorvg/src/common/tvgList.h b/thirdparty/thorvg/src/common/tvgList.h deleted file mode 100644 index 01e87a840fa..00000000000 --- a/thirdparty/thorvg/src/common/tvgList.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2023 the ThorVG project. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _TVG_LIST_H_ -#define _TVG_LIST_H_ - -namespace tvg { - -template -struct LinkedList -{ - T *head = nullptr; - T *tail = nullptr; - - LinkedList() = default; - LinkedList(T *head, T *tail) : head(head), tail(tail) - { - } - - template - static void insert(T *t, T *prev, T *next, T **head, T **tail) - { - t->*Prev = prev; - t->*Next = next; - - if (prev) { - prev->*Next = t; - } else if (head) { - *head = t; - } - - if (next) { - next->*Prev = t; - } else if (tail) { - *tail = t; - } - } - - template - static void remove(T *t, T **head, T **tail) - { - if (t->*Prev) { - t->*Prev->*Next = t->*Next; - } else if (head) { - *head = t->*Next; - } - - if (t->*Next) { - t->*Next->*Prev = t->*Prev; - } else if (tail) { - *tail = t->*Prev; - } - - t->*Prev = t->*Next = nullptr; - } - - template - static bool contains(T *t, T **head, T **tail) { - for (T *it = *head; it; it = it->*Next) { - if (it == t) { - return true; - } - } - - return false; - } -}; - -} - -#endif // _TVG_LIST_H_ diff --git a/thirdparty/thorvg/src/common/tvgMath.cpp b/thirdparty/thorvg/src/common/tvgMath.cpp index a9463c80773..42bc2cf4aaf 100644 --- a/thirdparty/thorvg/src/common/tvgMath.cpp +++ b/thirdparty/thorvg/src/common/tvgMath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/common/tvgMath.h b/thirdparty/thorvg/src/common/tvgMath.h index 004fff1e7b0..50c3458efc8 100644 --- a/thirdparty/thorvg/src/common/tvgMath.h +++ b/thirdparty/thorvg/src/common/tvgMath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -174,6 +174,18 @@ static inline Point operator*(const Point& lhs, float rhs) } +static inline Point operator*(const float& lhs, const Point& rhs) +{ + return {lhs * rhs.x, lhs * rhs.y}; +} + + +static inline Point operator/(const Point& lhs, const float rhs) +{ + return {lhs.x / rhs, lhs.y / rhs}; +} + + template static inline T mathLerp(const T &start, const T &end, float t) { diff --git a/thirdparty/thorvg/src/common/tvgStr.cpp b/thirdparty/thorvg/src/common/tvgStr.cpp index eeed4fc404b..311b9865113 100644 --- a/thirdparty/thorvg/src/common/tvgStr.cpp +++ b/thirdparty/thorvg/src/common/tvgStr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/common/tvgStr.h b/thirdparty/thorvg/src/common/tvgStr.h index 448cc69336f..9e5f9ba9b57 100644 --- a/thirdparty/thorvg/src/common/tvgStr.h +++ b/thirdparty/thorvg/src/common/tvgStr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp index 30a66f9cada..10277f846d7 100644 --- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,19 +20,25 @@ * SOFTWARE. */ -#include "tvgLoader.h" #include "tvgPngLoader.h" /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ +void PngLoader::clear() +{ + png_image_free(image); + free(image); + image = nullptr; +} + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ -PngLoader::PngLoader() +PngLoader::PngLoader() : ImageLoader(FileType::Png) { image = static_cast(calloc(1, sizeof(png_image))); image->version = PNG_IMAGE_VERSION; @@ -41,13 +47,11 @@ PngLoader::PngLoader() PngLoader::~PngLoader() { - if (content) { - free((void*)content); - content = nullptr; - } - free(image); + clear(); + free((void*)surface.buf32); } + bool PngLoader::open(const string& path) { image->opaque = NULL; @@ -56,11 +60,11 @@ bool PngLoader::open(const string& path) w = (float)image->width; h = (float)image->height; - cs = ColorSpace::ARGB8888; return true; } + bool PngLoader::open(const char* data, uint32_t size, bool copy) { image->opaque = NULL; @@ -69,7 +73,6 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy) w = (float)image->width; h = (float)image->height; - cs = ColorSpace::ARGB8888; return true; } @@ -77,6 +80,10 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy) bool PngLoader::read() { + if (!LoadModule::read()) return true; + + if (w == 0 || h == 0) return false; + png_bytep buffer; image->format = PNG_FORMAT_BGRA; buffer = static_cast(malloc(PNG_IMAGE_SIZE((*image)))); @@ -89,32 +96,17 @@ bool PngLoader::read() free(buffer); return false; } - content = reinterpret_cast(buffer); + + //setup the surface + surface.buf32 = reinterpret_cast(buffer); + surface.stride = (uint32_t)w; + surface.w = (uint32_t)w; + surface.h = (uint32_t)h; + surface.channelSize = sizeof(uint32_t); + surface.cs = ColorSpace::ARGB8888; + surface.premultiplied = false; + + clear(); return true; } - -bool PngLoader::close() -{ - png_image_free(image); - return true; -} - -unique_ptr PngLoader::bitmap() -{ - if (!content) return nullptr; - - //TODO: It's better to keep this surface instance in the loader side - auto surface = new Surface; - surface->buf32 = content; - surface->stride = (uint32_t)w; - surface->w = (uint32_t)w; - surface->h = (uint32_t)h; - surface->cs = cs; - surface->channelSize = sizeof(uint32_t); - surface->owner = true; - surface->premultiplied = false; - - return unique_ptr(surface); -} - diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h index 5354e1bdd60..c45544eb07c 100644 --- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,24 +24,22 @@ #define _TVG_PNG_LOADER_H_ #include +#include "tvgLoader.h" -class PngLoader : public LoadModule +class PngLoader : public ImageLoader { public: PngLoader(); ~PngLoader(); - using LoadModule::open; bool open(const string& path) override; bool open(const char* data, uint32_t size, bool copy) override; bool read() override; - bool close() override; - - unique_ptr bitmap() override; private: + void clear(); + png_imagep image = nullptr; - uint32_t* content = nullptr; }; #endif //_TVG_PNG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp index 6edda86cc13..86a46245d98 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,7 +21,6 @@ */ #include -#include "tvgLoader.h" #include "tvgJpgLoader.h" /************************************************************************/ @@ -38,30 +37,45 @@ void JpgLoader::clear() } +void JpgLoader::run(unsigned tid) +{ + surface.buf8 = jpgdDecompress(decoder); + surface.stride = static_cast(w); + surface.w = static_cast(w); + surface.h = static_cast(h); + surface.cs = ColorSpace::ARGB8888; + surface.channelSize = sizeof(uint32_t); + surface.premultiplied = true; + + clear(); +} + + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ +JpgLoader::JpgLoader() : ImageLoader(FileType::Jpg) +{ + +} + JpgLoader::~JpgLoader() { - jpgdDelete(decoder); - if (freeData) free(data); - free(image); + clear(); + free(surface.buf8); } bool JpgLoader::open(const string& path) { - clear(); - int width, height; decoder = jpgdHeader(path.c_str(), &width, &height); if (!decoder) return false; w = static_cast(width); h = static_cast(height); - cs = ColorSpace::ARGB8888; return true; } @@ -69,8 +83,6 @@ bool JpgLoader::open(const string& path) bool JpgLoader::open(const char* data, uint32_t size, bool copy) { - clear(); - if (copy) { this->data = (char *) malloc(size); if (!this->data) return false; @@ -87,7 +99,6 @@ bool JpgLoader::open(const char* data, uint32_t size, bool copy) w = static_cast(width); h = static_cast(height); - cs = ColorSpace::ARGB8888; return true; } @@ -96,7 +107,9 @@ bool JpgLoader::open(const char* data, uint32_t size, bool copy) bool JpgLoader::read() { - if (!decoder || w <= 0 || h <= 0) return false; + if (!LoadModule::read()) return true; + + if (!decoder || w == 0 || h == 0) return false; TaskScheduler::request(this); @@ -106,38 +119,14 @@ bool JpgLoader::read() bool JpgLoader::close() { + if (!LoadModule::close()) return false; this->done(); - clear(); return true; } -unique_ptr JpgLoader::bitmap() +Surface* JpgLoader::bitmap() { this->done(); - - if (!image) return nullptr; - - //TODO: It's better to keep this surface instance in the loader side - auto surface = new Surface; - surface->buf8 = image; - surface->stride = static_cast(w); - surface->w = static_cast(w); - surface->h = static_cast(h); - surface->cs = cs; - surface->channelSize = sizeof(uint32_t); - surface->premultiplied = true; - surface->owner = true; - - return unique_ptr(surface); -} - - -void JpgLoader::run(unsigned tid) -{ - if (image) { - free(image); - image = nullptr; - } - image = jpgdDecompress(decoder); + return ImageLoader::bitmap(); } diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h index 6d2febe94f0..05cbb54c852 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,30 +23,30 @@ #ifndef _TVG_JPG_LOADER_H_ #define _TVG_JPG_LOADER_H_ +#include "tvgLoader.h" #include "tvgTaskScheduler.h" #include "tvgJpgd.h" -class JpgLoader : public LoadModule, public Task +class JpgLoader : public ImageLoader, public Task { private: jpeg_decoder* decoder = nullptr; char* data = nullptr; - unsigned char *image = nullptr; bool freeData = false; void clear(); + void run(unsigned tid) override; public: + JpgLoader(); ~JpgLoader(); - using LoadModule::open; bool open(const string& path) override; bool open(const char* data, uint32_t size, bool copy) override; bool read() override; bool close() override; - unique_ptr bitmap() override; - void run(unsigned tid) override; + Surface* bitmap() override; }; #endif //_TVG_JPG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp index 3cd852a4bb8..6f2bd916d5e 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h index 030fdc29466..e1fe35f4887 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp b/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp index fc4cce40610..fb7527f0453 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp +++ b/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/png/tvgLodePng.h b/thirdparty/thorvg/src/loaders/png/tvgLodePng.h index 7254a554774..cd3efacf987 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgLodePng.h +++ b/thirdparty/thorvg/src/loaders/png/tvgLodePng.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp index 32ff57c5c38..111180b6571 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp +++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,14 +29,22 @@ /* Internal Class Implementation */ /************************************************************************/ -void PngLoader::clear() -{ - lodepng_state_cleanup(&state); - if (freeData) free(data); - data = nullptr; - size = 0; - freeData = false; +void PngLoader::run(unsigned tid) +{ + auto width = static_cast(w); + auto height = static_cast(h); + + if (lodepng_decode(&surface.buf8, &width, &height, &state, data, size)) { + TVGERR("PNG", "Failed to decode image"); + } + + //setup the surface + surface.stride = width; + surface.w = width; + surface.h = height; + surface.channelSize = sizeof(uint32_t); + surface.premultiplied = false; } @@ -44,7 +52,7 @@ void PngLoader::clear() /* External Class Implementation */ /************************************************************************/ -PngLoader::PngLoader() +PngLoader::PngLoader() : ImageLoader(FileType::Png) { lodepng_state_init(&state); } @@ -53,14 +61,13 @@ PngLoader::PngLoader() PngLoader::~PngLoader() { if (freeData) free(data); - free(image); + free(surface.buf8); + lodepng_state_cleanup(&state); } bool PngLoader::open(const string& path) { - clear(); - auto pngFile = fopen(path.c_str(), "rb"); if (!pngFile) return false; @@ -76,26 +83,23 @@ bool PngLoader::open(const string& path) freeData = true; - if (fread(data, size, 1, pngFile) < 1) goto failure; + if (fread(data, size, 1, pngFile) < 1) goto finalize; lodepng_state_init(&state); unsigned int width, height; - if (lodepng_inspect(&width, &height, &state, data, size) > 0) goto failure; + if (lodepng_inspect(&width, &height, &state, data, size) > 0) goto finalize; w = static_cast(width); h = static_cast(height); - if (state.info_png.color.colortype == LCT_RGBA) cs = ColorSpace::ABGR8888; - else cs = ColorSpace::ARGB8888; + if (state.info_png.color.colortype == LCT_RGBA) surface.cs = ColorSpace::ABGR8888; + else surface.cs = ColorSpace::ARGB8888; ret = true; goto finalize; -failure: - clear(); - finalize: fclose(pngFile); return ret; @@ -104,10 +108,6 @@ finalize: bool PngLoader::open(const char* data, uint32_t size, bool copy) { - clear(); - - lodepng_state_init(&state); - unsigned int width, height; if (lodepng_inspect(&width, &height, &state, (unsigned char*)(data), size) > 0) return false; @@ -125,7 +125,7 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy) h = static_cast(height); this->size = size; - cs = ColorSpace::ABGR8888; + surface.cs = ColorSpace::ABGR8888; return true; } @@ -133,7 +133,9 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy) bool PngLoader::read() { - if (!data || w <= 0 || h <= 0) return false; + if (!data || w == 0 || h == 0) return false; + + if (!LoadModule::read()) return true; TaskScheduler::request(this); @@ -141,45 +143,8 @@ bool PngLoader::read() } -bool PngLoader::close() +Surface* PngLoader::bitmap() { this->done(); - clear(); - return true; -} - - -unique_ptr PngLoader::bitmap() -{ - this->done(); - - if (!image) return nullptr; - - //TODO: It's better to keep this surface instance in the loader side - auto surface = new Surface; - surface->buf8 = image; - surface->stride = static_cast(w); - surface->w = static_cast(w); - surface->h = static_cast(h); - surface->cs = cs; - surface->channelSize = sizeof(uint32_t); - surface->premultiplied = false; - surface->owner = true; - - return unique_ptr(surface); -} - - -void PngLoader::run(unsigned tid) -{ - if (image) { - free(image); - image = nullptr; - } - auto width = static_cast(w); - auto height = static_cast(h); - - if (lodepng_decode(&image, &width, &height, &state, data, size)) { - TVGERR("PNG", "Failed to decode image"); - } + return ImageLoader::bitmap(); } diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h index 579d197ad65..06fbbf73495 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h +++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,29 +27,25 @@ #include "tvgTaskScheduler.h" -class PngLoader : public LoadModule, public Task +class PngLoader : public ImageLoader, public Task { private: LodePNGState state; unsigned char* data = nullptr; - unsigned char *image = nullptr; unsigned long size = 0; bool freeData = false; - void clear(); + void run(unsigned tid) override; public: PngLoader(); ~PngLoader(); - using LoadModule::open; bool open(const string& path) override; bool open(const char* data, uint32_t size, bool copy) override; bool read() override; - bool close() override; - unique_ptr bitmap() override; - void run(unsigned tid) override; + Surface* bitmap() override; }; #endif //_TVG_PNG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp index 5f5e72b0ddc..b797f98218e 100644 --- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,17 +34,21 @@ /* External Class Implementation */ /************************************************************************/ +RawLoader::RawLoader() : ImageLoader(FileType::Raw) +{ +} + + RawLoader::~RawLoader() { - if (copy && content) { - free((void*)content); - content = nullptr; - } + if (copy) free(surface.buf32); } bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { + if (!LoadModule::read()) return true; + if (!data || w == 0 || h == 0) return false; this->w = (float)w; @@ -52,13 +56,19 @@ bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) this->copy = copy; if (copy) { - content = (uint32_t*)malloc(sizeof(uint32_t) * w * h); - if (!content) return false; - memcpy((void*)content, data, sizeof(uint32_t) * w * h); + surface.buf32 = (uint32_t*)malloc(sizeof(uint32_t) * w * h); + if (!surface.buf32) return false; + memcpy((void*)surface.buf32, data, sizeof(uint32_t) * w * h); } - else content = const_cast(data); + else surface.buf32 = const_cast(data); - cs = ColorSpace::ARGB8888; + //setup the surface + surface.stride = w; + surface.w = w; + surface.h = h; + surface.cs = ColorSpace::ARGB8888; + surface.channelSize = sizeof(uint32_t); + surface.premultiplied = true; return true; } @@ -66,30 +76,7 @@ bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) bool RawLoader::read() { + LoadModule::read(); + return true; } - - -bool RawLoader::close() -{ - return true; -} - - -unique_ptr RawLoader::bitmap() -{ - if (!content) return nullptr; - - //TODO: It's better to keep this surface instance in the loader side - auto surface = new Surface; - surface->buf32 = content; - surface->stride = static_cast(w); - surface->w = static_cast(w); - surface->h = static_cast(h); - surface->cs = cs; - surface->channelSize = sizeof(uint32_t); - surface->premultiplied = true; - surface->owner = true; - - return unique_ptr(surface); -} diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h index 69f9bdc47a7..970cdd9c832 100644 --- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,20 +23,17 @@ #ifndef _TVG_RAW_LOADER_H_ #define _TVG_RAW_LOADER_H_ -class RawLoader : public LoadModule +class RawLoader : public ImageLoader { public: - uint32_t* content = nullptr; bool copy = false; + RawLoader(); ~RawLoader(); using LoadModule::open; - bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) override; + bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy); bool read() override; - bool close() override; - - unique_ptr bitmap() override; }; diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp index c3c477a263c..2826dc91342 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2022 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h index 228c5996daf..7d8dcfa94a0 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2022 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp index be99ec085ca..6e524766257 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -3528,6 +3528,10 @@ void SvgLoader::clear(bool all) loaderData.images.reset(); if (copy) free((char*)content); + + delete(root); + root = nullptr; + size = 0; content = nullptr; copy = false; @@ -3538,14 +3542,15 @@ void SvgLoader::clear(bool all) /* External Class Implementation */ /************************************************************************/ -SvgLoader::SvgLoader() +SvgLoader::SvgLoader() : ImageLoader(FileType::Svg) { } SvgLoader::~SvgLoader() { - close(); + this->done(); + clear(); } @@ -3554,7 +3559,7 @@ void SvgLoader::run(unsigned tid) //According to the SVG standard the value of the width/height of the viewbox set to 0 disables rendering if ((viewFlag & SvgViewFlag::Viewbox) && (fabsf(vw) <= FLT_EPSILON || fabsf(vh) <= FLT_EPSILON)) { TVGLOG("SVG", "The width and/or height set to 0 - rendering disabled."); - root = Scene::gen(); + root = Scene::gen().release(); return; } @@ -3727,6 +3732,8 @@ bool SvgLoader::read() { if (!content || size == 0) return false; + if (!LoadModule::read()) return true; + //the loading has been already completed in header() if (root) return true; @@ -3738,16 +3745,17 @@ bool SvgLoader::read() bool SvgLoader::close() { + if (!LoadModule::close()) return false; this->done(); - clear(); - return true; } -unique_ptr SvgLoader::paint() +Paint* SvgLoader::paint() { this->done(); - return std::move(root); + auto ret = root; + root = nullptr; + return ret; } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h index 4bac52e0b97..e0cba8b11ef 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,7 @@ #include "tvgTaskScheduler.h" #include "tvgSvgLoaderCommon.h" -class SvgLoader : public LoadModule, public Task +class SvgLoader : public ImageLoader, public Task { public: string filePath; @@ -35,21 +35,20 @@ public: uint32_t size = 0; SvgLoaderData loaderData; - unique_ptr root; + Scene* root = nullptr; bool copy = false; SvgLoader(); ~SvgLoader(); - using LoadModule::open; bool open(const string& path) override; bool open(const char* data, uint32_t size, bool copy) override; bool resize(Paint* paint, float w, float h) override; bool read() override; bool close() override; - unique_ptr paint() override; + Paint* paint() override; private: SvgViewFlag viewFlag = SvgViewFlag::None; diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h index b4ee3e8e0d1..d6febd68255 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp index 79a9c0771dd..f618a3c827c 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -53,6 +53,7 @@ #include #include #include +#include "tvgShape.h" #include "tvgSvgLoaderCommon.h" #include "tvgSvgPath.h" #include "tvgStr.h" @@ -534,7 +535,7 @@ static char* _nextCommand(char* path, char* cmd, float* arr, int* count) /************************************************************************/ -bool svgPathToTvgPath(const char* svgPath, Array& cmds, Array& pts) +bool svgPathToShape(const char* svgPath, Shape* shape) { float numberArray[7]; int numberCount = 0; @@ -545,11 +546,16 @@ bool svgPathToTvgPath(const char* svgPath, Array& cmds, Arrayrs.path.pts; + auto& cmds = P(shape)->rs.path.cmds; + auto lastCmds = cmds.count; + while ((path[0] != '\0')) { path = _nextCommand(path, &cmd, numberArray, &numberCount); if (!path) break; if (!_processCommand(&cmds, &pts, cmd, numberArray, numberCount, &cur, &curCtl, &startPoint, &isQuadratic)) break; } + if (cmds.count > lastCmds && cmds[lastCmds] != PathCommand::MoveTo) return false; return true; } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h index 4199088dc10..b8641dd1658 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,6 @@ #include -bool svgPathToTvgPath(const char* svgPath, Array& cmds, Array& pts); +bool svgPathToShape(const char* svgPath, Shape* shape); #endif //_TVG_SVG_PATH_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp index 1791df57f0d..674c30f5bd5 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -396,10 +396,9 @@ static bool _recognizeShape(SvgNode* node, Shape* shape) switch (node->type) { case SvgNodeType::Path: { if (node->node.path.path) { - Array cmds; - Array pts; - if (svgPathToTvgPath(node->node.path.path, cmds, pts)) { - shape->appendPath(cmds.data, cmds.count, pts.data, pts.count); + if (!svgPathToShape(node->node.path.path, shape)) { + TVGERR("SVG", "Invalid path information."); + return false; } } break; @@ -845,7 +844,7 @@ static void _updateInvalidViewSize(const Scene* scene, Box& vBox, float& w, floa /* External Class Implementation */ /************************************************************************/ -unique_ptr svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag) +Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag) { //TODO: aspect ratio is valid only if viewBox was set @@ -863,8 +862,7 @@ unique_ptr svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, fl } auto viewBoxClip = Shape::gen(); - viewBoxClip->appendRect(0, 0, w, h, 0, 0); - viewBoxClip->fill(0, 0, 0); + viewBoxClip->appendRect(0, 0, w, h); auto compositeLayer = Scene::gen(); compositeLayer->composite(std::move(viewBoxClip), CompositeMethod::ClipPath); @@ -880,5 +878,5 @@ unique_ptr svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, fl loaderData.doc->node.doc.w = w; loaderData.doc->node.doc.h = h; - return root; + return root.release(); } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h index f6a60f850d9..0663a37f05a 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,6 @@ #include "tvgCommon.h" -unique_ptr svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag); +Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag); #endif //_TVG_SVG_SCENE_BUILDER_H_ diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp index 7940188ade9..32affd04c65 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h index ee0e3f88610..220a4b3e552 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp index dbc3b17b70e..aec30d2384c 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h index 7333bb09fb3..30ca23b565f 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwCommon.h b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwCommon.h index 8fe7b77edd2..3d73075a4a4 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwCommon.h +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -261,13 +261,26 @@ struct SwSurface : Surface SwAlpha alphas[4]; //Alpha:2, InvAlpha:3, Luma:4, InvLuma:5 SwBlender blender = nullptr; //blender (optional) SwCompositor* compositor = nullptr; //compositor (optional) - BlendMethod blendMethod; //blending method (uint8_t) + BlendMethod blendMethod; //blending method (uint8_t) SwAlpha alpha(CompositeMethod method) { auto idx = (int)(method) - 2; //0: None, 1: ClipPath return alphas[idx > 3 ? 0 : idx]; //CompositeMethod has only four Matting methods. } + + SwSurface() + { + } + + SwSurface(const SwSurface* rhs) : Surface(rhs) + { + join = rhs->join; + memcpy(alphas, rhs->alphas, sizeof(alphas)); + blender = rhs->blender; + compositor = rhs->compositor; + blendMethod = rhs->blendMethod; + } }; struct SwCompositor : Compositor diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp index cede9e6eb7a..8956cd9f246 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -167,7 +167,6 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr fill->linear.dy = dx * invTransform.e12 + fill->linear.dy * invTransform.e22; fill->linear.len = fill->linear.dx * fill->linear.dx + fill->linear.dy * fill->linear.dy; - if (fill->linear.len < FLT_EPSILON) return true; } return true; diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp index b1624037bc1..c1629455017 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp index d58dd9e3c5a..42e405195eb 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMemPool.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMemPool.cpp index 54ae594bffd..68eb7a5a6fe 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMemPool.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMemPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp index 96a0ed35ad8..9a6dc459501 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -1714,7 +1714,7 @@ static bool _rasterSolidGradientRle(SwSurface* surface, const SwRleData* rle, co static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) { - if (!rle || fill->linear.len < FLT_EPSILON) return false; + if (!rle) return false; if (_compositing(surface)) { if (_matting(surface)) return _rasterGradientMattedRle(surface, rle, fill); @@ -1855,7 +1855,9 @@ void rasterUnpremultiply(Surface* surface) void rasterPremultiply(Surface* surface) { - if (surface->channelSize != sizeof(uint32_t)) return; + unique_lock lock{surface->mtx}; + if (surface->premultiplied || (surface->channelSize != sizeof(uint32_t))) return; + surface->premultiplied = true; TVGLOG("SW_ENGINE", "Premultiply [Size: %d x %d]", surface->w, surface->h); @@ -1869,7 +1871,6 @@ void rasterPremultiply(Surface* surface) *dst = (c & 0xff000000) + ((((c >> 8) & 0xff) * a) & 0xff00) + ((((c & 0x00ff00ff) * a) >> 8) & 0x00ff00ff); } } - surface->premultiplied = true; } @@ -1935,6 +1936,9 @@ bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, con bool rasterConvertCS(Surface* surface, ColorSpace to) { + unique_lock lock{surface->mtx}; + if (surface->cs == to) return true; + //TOOD: Support SIMD accelerations auto from = surface->cs; @@ -1946,6 +1950,5 @@ bool rasterConvertCS(Surface* surface, ColorSpace to) surface->cs = to; return cRasterARGBtoABGR(surface); } - return false; } diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterAvx.h b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterAvx.h index 090fa29a7aa..177c7b847f8 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterAvx.h +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterAvx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterC.h b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterC.h index da3c7077e8f..6d0bd9383da 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterC.h +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterC.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterNeon.h b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterNeon.h index ba77ed53cf6..cfbeb0cacac 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterNeon.h +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterNeon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterTexmap.h b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterTexmap.h index 698ab37da29..04e382b842a 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterTexmap.h +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRasterTexmap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp index 18815e69a94..c9c543fbb58 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,8 +45,11 @@ struct SwTask : Task bool pushed = false; //Pushed into task list? bool disposed = false; //Disposed task? - RenderRegion bounds() const + RenderRegion bounds() { + //Can we skip the synchronization? + done(); + RenderRegion region; //Range over? @@ -278,10 +281,8 @@ struct SwImageTask : SwTask auto clipRegion = bbox; //Convert colorspace if it's not aligned. - if (source->owner) { - if (source->cs != surface->cs) rasterConvertCS(source, surface->cs); - if (!source->premultiplied) rasterPremultiply(source); - } + rasterConvertCS(source, surface->cs); + rasterPremultiply(source); image.data = source->data; image.w = source->w; @@ -433,7 +434,6 @@ bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, surface->cs = cs; surface->channelSize = CHANNEL_SIZE(cs); surface->premultiplied = true; - surface->owner = true; vport.x = vport.y = 0; vport.w = surface->w; @@ -635,11 +635,8 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) //New Composition if (!cmp) { - cmp = new SwSurface; - //Inherits attributes from main surface - *cmp = *surface; - + cmp = new SwSurface(surface); cmp->compositor = new SwCompositor; //TODO: We can optimize compositor surface size from (surface->stride x surface->h) to Parameter(w x h) diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h index 4393740bd99..83d942388fd 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp index a4a7fabdee1..33c94e10638 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp index ae2ddd2af79..e001ced2a82 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwStroke.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwStroke.cpp index 75c5fa56670..8f44cf36164 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwStroke.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwStroke.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgAccessor.cpp b/thirdparty/thorvg/src/renderer/tvgAccessor.cpp index 0c636979b58..903437f29d3 100644 --- a/thirdparty/thorvg/src/renderer/tvgAccessor.cpp +++ b/thirdparty/thorvg/src/renderer/tvgAccessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgAnimation.cpp b/thirdparty/thorvg/src/renderer/tvgAnimation.cpp index b4ea534b91f..995eca7f415 100644 --- a/thirdparty/thorvg/src/renderer/tvgAnimation.cpp +++ b/thirdparty/thorvg/src/renderer/tvgAnimation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -64,7 +64,7 @@ Animation::Animation() : pImpl(new Impl) Result Animation::frame(float no) noexcept { - auto loader = pImpl->picture->pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader; if (!loader) return Result::InsufficientCondition; if (!loader->animatable()) return Result::NonSupport; @@ -82,7 +82,7 @@ Picture* Animation::picture() const noexcept float Animation::curFrame() const noexcept { - auto loader = pImpl->picture->pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader; if (!loader) return 0; if (!loader->animatable()) return 0; @@ -93,7 +93,7 @@ float Animation::curFrame() const noexcept float Animation::totalFrame() const noexcept { - auto loader = pImpl->picture->pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader; if (!loader) return 0; if (!loader->animatable()) return 0; @@ -104,7 +104,7 @@ float Animation::totalFrame() const noexcept float Animation::duration() const noexcept { - auto loader = pImpl->picture->pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader; if (!loader) return 0; if (!loader->animatable()) return 0; diff --git a/thirdparty/thorvg/src/renderer/tvgBinaryDesc.h b/thirdparty/thorvg/src/renderer/tvgBinaryDesc.h index b1468148d67..29f84eb82a6 100644 --- a/thirdparty/thorvg/src/renderer/tvgBinaryDesc.h +++ b/thirdparty/thorvg/src/renderer/tvgBinaryDesc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,7 +36,7 @@ using TvgBinFlag = TvgBinByte; #define TVG_HEADER_SIZE 33 //TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH + 2*SIZE(float) + TVG_HEADER_RESERVED_LENGTH + TVG_HEADER_COMPRESS_SIZE #define TVG_HEADER_SIGNATURE "ThorVG" #define TVG_HEADER_SIGNATURE_LENGTH 6 -#define TVG_HEADER_VERSION "001100" //Major 00, Minor 11, Micro 00 +#define TVG_HEADER_VERSION "001200" //Major 00, Minor 12, Micro 00 #define TVG_HEADER_VERSION_LENGTH 6 #define TVG_HEADER_RESERVED_LENGTH 1 //Storing flags for extensions #define TVG_HEADER_COMPRESS_SIZE 12 //TVG_HEADER_UNCOMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE_BITS diff --git a/thirdparty/thorvg/src/renderer/tvgCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgCanvas.cpp index 25741f611df..11d6b778f74 100644 --- a/thirdparty/thorvg/src/renderer/tvgCanvas.cpp +++ b/thirdparty/thorvg/src/renderer/tvgCanvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgCanvas.h b/thirdparty/thorvg/src/renderer/tvgCanvas.h index f893f9f7c05..25181de47e1 100644 --- a/thirdparty/thorvg/src/renderer/tvgCanvas.h +++ b/thirdparty/thorvg/src/renderer/tvgCanvas.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,14 +20,11 @@ * SOFTWARE. */ -#ifndef _TVG_CANVAS_IMPL_H_ -#define _TVG_CANVAS_IMPL_H_ +#ifndef _TVG_CANVAS_H_ +#define _TVG_CANVAS_H_ #include "tvgPaint.h" -/************************************************************************/ -/* Internal Class Implementation */ -/************************************************************************/ struct Canvas::Impl { @@ -143,4 +140,4 @@ struct Canvas::Impl } }; -#endif /* _TVG_CANVAS_IMPL_H_ */ +#endif /* _TVG_CANVAS_H_ */ diff --git a/thirdparty/thorvg/src/renderer/tvgCommon.h b/thirdparty/thorvg/src/renderer/tvgCommon.h index 2b67681a403..deb419bc65e 100644 --- a/thirdparty/thorvg/src/renderer/tvgCommon.h +++ b/thirdparty/thorvg/src/renderer/tvgCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -61,8 +61,9 @@ using namespace tvg; #define TVG_CLASS_ID_PICTURE 3 #define TVG_CLASS_ID_LINEAR 4 #define TVG_CLASS_ID_RADIAL 5 +#define TVG_CLASS_ID_TEXT 6 -enum class FileType { Tvg = 0, Svg, Lottie, Raw, Png, Jpg, Webp, Gif, Unknown }; +enum class FileType { Tvg = 0, Svg, Ttf, Lottie, Raw, Png, Jpg, Webp, Gif, Unknown }; using Size = Point; diff --git a/thirdparty/thorvg/src/renderer/tvgFill.cpp b/thirdparty/thorvg/src/renderer/tvgFill.cpp index 9215882c8d9..ea1010051ee 100644 --- a/thirdparty/thorvg/src/renderer/tvgFill.cpp +++ b/thirdparty/thorvg/src/renderer/tvgFill.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgFill.h b/thirdparty/thorvg/src/renderer/tvgFill.h index ff3dd48c492..47f0c051c02 100644 --- a/thirdparty/thorvg/src/renderer/tvgFill.h +++ b/thirdparty/thorvg/src/renderer/tvgFill.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgFrameModule.h b/thirdparty/thorvg/src/renderer/tvgFrameModule.h index 332cca30908..df97ccb8947 100644 --- a/thirdparty/thorvg/src/renderer/tvgFrameModule.h +++ b/thirdparty/thorvg/src/renderer/tvgFrameModule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,9 +28,10 @@ namespace tvg { -class FrameModule: public LoadModule +class FrameModule: public ImageLoader { public: + FrameModule(FileType type) : ImageLoader(type) {} virtual ~FrameModule() {} virtual bool frame(float no) = 0; //set the current frame number diff --git a/thirdparty/thorvg/src/renderer/tvgGlCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgGlCanvas.cpp index aa7f8dbe2ab..f6f0d354d1c 100644 --- a/thirdparty/thorvg/src/renderer/tvgGlCanvas.cpp +++ b/thirdparty/thorvg/src/renderer/tvgGlCanvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgInitializer.cpp b/thirdparty/thorvg/src/renderer/tvgInitializer.cpp index b7326a9fbc4..76d89b40edb 100644 --- a/thirdparty/thorvg/src/renderer/tvgInitializer.cpp +++ b/thirdparty/thorvg/src/renderer/tvgInitializer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +36,10 @@ #include "tvgGlRenderer.h" #endif +#ifdef THORVG_WG_RASTER_SUPPORT + #include "tvgWgRenderer.h" +#endif + /************************************************************************/ /* Internal Class Implementation */ @@ -91,19 +95,27 @@ static bool _buildVersionInfo() Result Initializer::init(CanvasEngine engine, uint32_t threads) noexcept { auto nonSupport = true; + if (static_cast(engine) == 0) return Result::InvalidArguments; if (engine & CanvasEngine::Sw) { #ifdef THORVG_SW_RASTER_SUPPORT if (!SwRenderer::init(threads)) return Result::FailedAllocation; nonSupport = false; #endif - } else if (engine & CanvasEngine::Gl) { + } + + if (engine & CanvasEngine::Gl) { #ifdef THORVG_GL_RASTER_SUPPORT if (!GlRenderer::init(threads)) return Result::FailedAllocation; nonSupport = false; #endif - } else { - return Result::InvalidArguments; + } + + if (engine & CanvasEngine::Wg) { + #ifdef THORVG_WG_RASTER_SUPPORT + if (!WgRenderer::init(threads)) return Result::FailedAllocation; + nonSupport = false; + #endif } if (nonSupport) return Result::NonSupport; @@ -125,19 +137,27 @@ Result Initializer::term(CanvasEngine engine) noexcept if (_initCnt == 0) return Result::InsufficientCondition; auto nonSupport = true; + if (static_cast(engine) == 0) return Result::InvalidArguments; if (engine & CanvasEngine::Sw) { #ifdef THORVG_SW_RASTER_SUPPORT if (!SwRenderer::term()) return Result::InsufficientCondition; nonSupport = false; #endif - } else if (engine & CanvasEngine::Gl) { + } + + if (engine & CanvasEngine::Gl) { #ifdef THORVG_GL_RASTER_SUPPORT if (!GlRenderer::term()) return Result::InsufficientCondition; nonSupport = false; #endif - } else { - return Result::InvalidArguments; + } + + if (engine & CanvasEngine::Wg) { + #ifdef THORVG_WG_RASTER_SUPPORT + if (!WgRenderer::term()) return Result::InsufficientCondition; + nonSupport = false; + #endif } if (nonSupport) return Result::NonSupport; @@ -156,3 +176,4 @@ uint16_t THORVG_VERSION_NUMBER() { return _version; } + diff --git a/thirdparty/thorvg/src/renderer/tvgIteratorAccessor.h b/thirdparty/thorvg/src/renderer/tvgIteratorAccessor.h index 2347613ed83..46e900a5828 100644 --- a/thirdparty/thorvg/src/renderer/tvgIteratorAccessor.h +++ b/thirdparty/thorvg/src/renderer/tvgIteratorAccessor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgLoadModule.h b/thirdparty/thorvg/src/renderer/tvgLoadModule.h index 29ceba3fcc5..0ea766395e1 100644 --- a/thirdparty/thorvg/src/renderer/tvgLoadModule.h +++ b/thirdparty/thorvg/src/renderer/tvgLoadModule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,35 +24,73 @@ #define _TVG_LOAD_MODULE_H_ #include "tvgRender.h" +#include "tvgInlist.h" -namespace tvg + +struct LoadModule { + INLIST_ITEM(LoadModule); -class LoadModule -{ -public: - float w = 0, h = 0; //default image size - ColorSpace cs = ColorSpace::Unsupported; //must be clarified at open() + //Use either hashkey(data) or hashpath(path) + uint64_t hashkey; + char* hashpath = nullptr; - virtual ~LoadModule() {} + FileType type; //current loader file type + uint16_t sharing = 0; //reference count + bool readied = false; //read done already. + + LoadModule(FileType type) : type(type) {} + virtual ~LoadModule() + { + free(hashpath); + } virtual bool open(const string& path) { return false; } virtual bool open(const char* data, uint32_t size, bool copy) { return false; } - virtual bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { return false; } - - //Override this if the vector-format has own resizing policy. virtual bool resize(Paint* paint, float w, float h) { return false; } - - virtual bool animatable() { return false; } //true if this loader supports animation. virtual void sync() {}; //finish immediately if any async update jobs. - virtual bool read() = 0; - virtual bool close() = 0; + virtual bool read() + { + if (readied) return false; + readied = true; + return true; + } - virtual unique_ptr bitmap() { return nullptr; } - virtual unique_ptr paint() { return nullptr; } + virtual bool close() + { + if (sharing == 0) return true; + --sharing; + return false; + } }; -} + +struct ImageLoader : LoadModule +{ + float w = 0, h = 0; //default image size + Surface surface; + + ImageLoader(FileType type) : LoadModule(type) {} + + virtual bool animatable() { return false; } //true if this loader supports animation. + virtual Paint* paint() { return nullptr; } + + virtual Surface* bitmap() + { + if (surface.data) return &surface; + return nullptr; + } +}; + + +struct FontLoader : LoadModule +{ + float scale = 1.0f; + + FontLoader(FileType type) : LoadModule(type) {} + + virtual bool request(Shape* shape, char* text, bool italic = false) = 0; +}; #endif //_TVG_LOAD_MODULE_H_ diff --git a/thirdparty/thorvg/src/renderer/tvgLoader.cpp b/thirdparty/thorvg/src/renderer/tvgLoader.cpp index 65330e9e778..628b0fa17f8 100644 --- a/thirdparty/thorvg/src/renderer/tvgLoader.cpp +++ b/thirdparty/thorvg/src/renderer/tvgLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,6 +20,9 @@ * SOFTWARE. */ +#include + +#include "tvgInlist.h" #include "tvgLoader.h" #ifdef THORVG_SVG_LOADER_SUPPORT @@ -42,16 +45,30 @@ #include "tvgWebpLoader.h" #endif +#ifdef THORVG_TTF_LOADER_SUPPORT + #include "tvgTtfLoader.h" +#endif + #ifdef THORVG_LOTTIE_LOADER_SUPPORT #include "tvgLottieLoader.h" #endif #include "tvgRawLoader.h" + +uint64_t HASH_KEY(const char* data, uint64_t size) +{ + return (((uint64_t) data) << 32) | size; +} + /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ +static mutex mtx; +static Inlist _activeLoaders; + + static LoadModule* _find(FileType type) { switch(type) { @@ -64,6 +81,12 @@ static LoadModule* _find(FileType type) case FileType::Svg: { #ifdef THORVG_SVG_LOADER_SUPPORT return new SvgLoader; +#endif + break; + } + case FileType::Ttf: { +#ifdef THORVG_TTF_LOADER_SUPPORT + return new TtfLoader; #endif break; } @@ -111,6 +134,10 @@ static LoadModule* _find(FileType type) format = "SVG"; break; } + case FileType::Ttf: { + format = "TTF"; + break; + } case FileType::Lottie: { format = "lottie(json)"; break; @@ -152,29 +179,71 @@ static LoadModule* _findByPath(const string& path) if (!ext.compare("png")) return _find(FileType::Png); if (!ext.compare("jpg")) return _find(FileType::Jpg); if (!ext.compare("webp")) return _find(FileType::Webp); + if (!ext.compare("ttf") || !ext.compare("ttc")) return _find(FileType::Ttf); + if (!ext.compare("otf") || !ext.compare("otc")) return _find(FileType::Ttf); return nullptr; } -static LoadModule* _findByType(const string& mimeType) +static FileType _convert(const string& mimeType) { - if (mimeType.empty()) return nullptr; - auto type = FileType::Unknown; if (mimeType == "tvg") type = FileType::Tvg; else if (mimeType == "svg" || mimeType == "svg+xml") type = FileType::Svg; + else if (mimeType == "ttf" || mimeType == "otf") type = FileType::Ttf; else if (mimeType == "lottie") type = FileType::Lottie; else if (mimeType == "raw") type = FileType::Raw; else if (mimeType == "png") type = FileType::Png; else if (mimeType == "jpg" || mimeType == "jpeg") type = FileType::Jpg; else if (mimeType == "webp") type = FileType::Webp; - else { - TVGLOG("RENDERER", "Given mimetype is unknown = \"%s\".", mimeType.c_str()); - return nullptr; - } + else TVGLOG("RENDERER", "Given mimetype is unknown = \"%s\".", mimeType.c_str()); - return _find(type); + return type; +} + + +static LoadModule* _findByType(const string& mimeType) +{ + return _find(_convert(mimeType)); +} + + +static LoadModule* _findFromCache(const string& path) +{ + unique_lock lock{mtx}; + + auto loader = _activeLoaders.head; + + while (loader) { + if (loader->hashpath && !strcmp(loader->hashpath, path.c_str())) { + ++loader->sharing; + return loader; + } + loader = loader->next; + } + return nullptr; +} + + +static LoadModule* _findFromCache(const char* data, uint32_t size, const string& mimeType) +{ + auto type = _convert(mimeType); + if (type == FileType::Unknown) return nullptr; + + unique_lock lock{mtx}; + auto loader = _activeLoaders.head; + + auto key = HASH_KEY(data, size); + + while (loader) { + if (loader->type == type && loader->hashkey == key) { + ++loader->sharing; + return loader; + } + loader = loader->next; + } + return nullptr; } @@ -185,40 +254,95 @@ static LoadModule* _findByType(const string& mimeType) bool LoaderMgr::init() { - //TODO: - return true; } bool LoaderMgr::term() { - //TODO: + auto loader = _activeLoaders.head; + //clean up the remained font loaders which is globally used. + while (loader && loader->type == FileType::Ttf) { + auto ret = loader->close(); + auto tmp = loader; + loader = loader->next; + _activeLoaders.remove(tmp); + if (ret) delete(loader); + } return true; } -shared_ptr LoaderMgr::loader(const string& path, bool* invalid) +bool LoaderMgr::retrieve(LoadModule* loader) +{ + if (!loader) return false; + if (loader->close()) { + { + unique_lock lock{mtx}; + _activeLoaders.remove(loader); + } + delete(loader); + } + return true; +} + + +LoadModule* LoaderMgr::loader(const string& path, bool* invalid) { *invalid = false; + if (auto loader = _findFromCache(path)) return loader; + if (auto loader = _findByPath(path)) { - if (loader->open(path)) return shared_ptr(loader); - else delete(loader); + if (loader->open(path)) { + loader->hashpath = strdup(path.c_str()); + { + unique_lock lock{mtx}; + _activeLoaders.back(loader); + } + return loader; + } + delete(loader); *invalid = true; } return nullptr; } -shared_ptr LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy) +bool LoaderMgr::retrieve(const string& path) { + return retrieve(_findFromCache(path)); +} + + +LoadModule* LoaderMgr::loader(const char* key) +{ + auto loader = _activeLoaders.head; + + while (loader) { + if (loader->hashpath && strstr(loader->hashpath, key)) { + ++loader->sharing; + return loader; + } + loader = loader->next; + } + return nullptr; +} + + +LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy) +{ + if (auto loader = _findFromCache(data, size, mimeType)) return loader; + //Try with the given MimeType if (!mimeType.empty()) { if (auto loader = _findByType(mimeType)) { if (loader->open(data, size, copy)) { - return shared_ptr(loader); + loader->hashkey = HASH_KEY(data, size); + unique_lock lock{mtx}; + _activeLoaders.back(loader); + return loader; } else { TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str()); delete(loader); @@ -229,8 +353,15 @@ shared_ptr LoaderMgr::loader(const char* data, uint32_t size, const for (int i = 0; i < static_cast(FileType::Unknown); i++) { auto loader = _find(static_cast(i)); if (loader) { - if (loader->open(data, size, copy)) return shared_ptr(loader); - else delete(loader); + if (loader->open(data, size, copy)) { + loader->hashkey = HASH_KEY(data, size); + { + unique_lock lock{mtx}; + _activeLoaders.back(loader); + } + return loader; + } + delete(loader); } } } @@ -238,12 +369,21 @@ shared_ptr LoaderMgr::loader(const char* data, uint32_t size, const } -shared_ptr LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) +LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) { + //TODO: should we check premultiplied?? + if (auto loader = _findFromCache((const char*)(data), w * h, "raw")) return loader; + //function is dedicated for raw images only auto loader = new RawLoader; - if (loader->open(data, w, h, copy)) return shared_ptr(loader); - else delete(loader); - + if (loader->open(data, w, h, copy)) { + loader->hashkey = HASH_KEY((const char*)data, w * h); + { + unique_lock lock{mtx}; + _activeLoaders.back(loader); + } + return loader; + } + delete(loader); return nullptr; } diff --git a/thirdparty/thorvg/src/renderer/tvgLoader.h b/thirdparty/thorvg/src/renderer/tvgLoader.h index 17ff9e2637c..b15032df274 100644 --- a/thirdparty/thorvg/src/renderer/tvgLoader.h +++ b/thirdparty/thorvg/src/renderer/tvgLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,9 +29,12 @@ struct LoaderMgr { static bool init(); static bool term(); - static shared_ptr loader(const string& path, bool* invalid); - static shared_ptr loader(const char* data, uint32_t size, const string& mimeType, bool copy); - static shared_ptr loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); + static LoadModule* loader(const string& path, bool* invalid); + static LoadModule* loader(const char* data, uint32_t size, const string& mimeType, bool copy); + static LoadModule* loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); + static LoadModule* loader(const char* key); + static bool retrieve(const string& path); + static bool retrieve(LoadModule* loader); }; #endif //_TVG_LOADER_H_ diff --git a/thirdparty/thorvg/src/renderer/tvgPaint.cpp b/thirdparty/thorvg/src/renderer/tvgPaint.cpp index 008e6589b5d..563db3b44a0 100644 --- a/thirdparty/thorvg/src/renderer/tvgPaint.cpp +++ b/thirdparty/thorvg/src/renderer/tvgPaint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,7 @@ #include "tvgShape.h" #include "tvgPicture.h" #include "tvgScene.h" +#include "tvgText.h" /************************************************************************/ /* Internal Class Implementation */ @@ -35,6 +36,7 @@ case TVG_CLASS_ID_SHAPE: ret = P((Shape*)paint)->METHOD; break; \ case TVG_CLASS_ID_SCENE: ret = P((Scene*)paint)->METHOD; break; \ case TVG_CLASS_ID_PICTURE: ret = P((Picture*)paint)->METHOD; break; \ + case TVG_CLASS_ID_TEXT: ret = P((Text*)paint)->METHOD; break; \ default: ret = {}; \ } diff --git a/thirdparty/thorvg/src/renderer/tvgPaint.h b/thirdparty/thorvg/src/renderer/tvgPaint.h index f4721f8e15b..4ec9fa7f7e9 100644 --- a/thirdparty/thorvg/src/renderer/tvgPaint.h +++ b/thirdparty/thorvg/src/renderer/tvgPaint.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgPicture.cpp b/thirdparty/thorvg/src/renderer/tvgPicture.cpp index e3827956982..7f120593f45 100644 --- a/thirdparty/thorvg/src/renderer/tvgPicture.cpp +++ b/thirdparty/thorvg/src/renderer/tvgPicture.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,9 +30,8 @@ RenderUpdateFlag Picture::Impl::load() { if (loader) { if (!paint) { - if (auto p = loader->paint()) { - paint = p.release(); - loader->close(); + paint = loader->paint(); + if (paint) { if (w != loader->w || h != loader->h) { if (!resizing) { w = loader->w; @@ -41,13 +40,12 @@ RenderUpdateFlag Picture::Impl::load() loader->resize(paint, w, h); resizing = false; } - if (paint) return RenderUpdateFlag::None; + return RenderUpdateFlag::None; } } else loader->sync(); if (!surface) { - if ((surface = loader->bitmap().release())) { - loader->close(); + if ((surface = loader->bitmap())) { return RenderUpdateFlag::Image; } } @@ -55,6 +53,93 @@ RenderUpdateFlag Picture::Impl::load() return RenderUpdateFlag::None; } + +bool Picture::Impl::needComposition(uint8_t opacity) +{ + //In this case, paint(scene) would try composition itself. + if (opacity < 255) return false; + + //Composition test + const Paint* target; + auto method = picture->composite(&target); + if (!target || method == tvg::CompositeMethod::ClipPath) return false; + if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false; + + return true; +} + + +bool Picture::Impl::render(RenderMethod &renderer) +{ + bool ret = false; + if (surface) return renderer.renderImage(rd); + else if (paint) { + Compositor* cmp = nullptr; + if (needComp) { + cmp = renderer.target(bounds(renderer), renderer.colorSpace()); + renderer.beginComposite(cmp, CompositeMethod::None, 255); + } + ret = paint->pImpl->render(renderer); + if (cmp) renderer.endComposite(cmp); + } + return ret; +} + + +bool Picture::Impl::size(float w, float h) +{ + this->w = w; + this->h = h; + resizing = true; + return true; +} + + +RenderRegion Picture::Impl::bounds(RenderMethod& renderer) +{ + if (rd) return renderer.region(rd); + if (paint) return paint->pImpl->bounds(renderer); + return {0, 0, 0, 0}; +} + + +RenderTransform Picture::Impl::resizeTransform(const RenderTransform* pTransform) +{ + //Overriding Transformation by the desired image size + auto sx = w / loader->w; + auto sy = h / loader->h; + auto scale = sx < sy ? sx : sy; + + RenderTransform tmp; + tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1}; + + if (!pTransform) return tmp; + else return RenderTransform(pTransform, &tmp); +} + + +Result Picture::Impl::load(ImageLoader* loader) +{ + //Same resource has been loaded. + if (this->loader == loader) { + this->loader->sharing--; //make it sure the reference counting. + return Result::Success; + } else if (this->loader) { + LoaderMgr::retrieve(this->loader); + } + + this->loader = loader; + + if (!loader->read()) return Result::Unknown; + + this->w = loader->w; + this->h = loader->h; + + return Result::Success; +} + + + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ diff --git a/thirdparty/thorvg/src/renderer/tvgPicture.h b/thirdparty/thorvg/src/renderer/tvgPicture.h index 447f56ecb79..26a171ba663 100644 --- a/thirdparty/thorvg/src/renderer/tvgPicture.h +++ b/thirdparty/thorvg/src/renderer/tvgPicture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,16 +20,13 @@ * SOFTWARE. */ -#ifndef _TVG_PICTURE_IMPL_H_ -#define _TVG_PICTURE_IMPL_H_ +#ifndef _TVG_PICTURE_H_ +#define _TVG_PICTURE_H_ #include #include "tvgPaint.h" #include "tvgLoader.h" -/************************************************************************/ -/* Internal Class Implementation */ -/************************************************************************/ struct PictureIterator : Iterator { @@ -60,7 +57,7 @@ struct PictureIterator : Iterator struct Picture::Impl { - shared_ptr loader = nullptr; + ImageLoader* loader = nullptr; Paint* paint = nullptr; //vector picture uses Surface* surface = nullptr; //bitmap picture uses @@ -71,14 +68,21 @@ struct Picture::Impl bool resizing = false; bool needComp = false; //need composition + RenderTransform resizeTransform(const RenderTransform* pTransform); + bool needComposition(uint8_t opacity); + bool render(RenderMethod &renderer); + bool size(float w, float h); + RenderRegion bounds(RenderMethod& renderer); + Result load(ImageLoader* ploader); + Impl(Picture* p) : picture(p) { } ~Impl() { + LoaderMgr::retrieve(loader); delete(paint); - delete(surface); } bool dispose(RenderMethod& renderer) @@ -89,34 +93,6 @@ struct Picture::Impl return true; } - RenderTransform resizeTransform(const RenderTransform* pTransform) - { - //Overriding Transformation by the desired image size - auto sx = w / loader->w; - auto sy = h / loader->h; - auto scale = sx < sy ? sx : sy; - - RenderTransform tmp; - tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1}; - - if (!pTransform) return tmp; - else return RenderTransform(pTransform, &tmp); - } - - bool needComposition(uint8_t opacity) - { - //In this case, paint(scene) would try composition itself. - if (opacity < 255) return false; - - //Composition test - const Paint* target; - auto method = picture->composite(&target); - if (!target || method == tvg::CompositeMethod::ClipPath) return false; - if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false; - - return true; - } - RenderData update(RenderMethod &renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { auto flag = load(); @@ -135,30 +111,6 @@ struct Picture::Impl return rd; } - bool render(RenderMethod &renderer) - { - bool ret = false; - if (surface) return renderer.renderImage(rd); - else if (paint) { - Compositor* cmp = nullptr; - if (needComp) { - cmp = renderer.target(bounds(renderer), renderer.colorSpace()); - renderer.beginComposite(cmp, CompositeMethod::None, 255); - } - ret = paint->pImpl->render(renderer); - if (cmp) renderer.endComposite(cmp); - } - return ret; - } - - bool size(float w, float h) - { - this->w = w; - this->h = h; - resizing = true; - return true; - } - bool bounds(float* x, float* y, float* w, float* h, bool stroking) { if (rm.triangleCnt > 0) { @@ -195,50 +147,35 @@ struct Picture::Impl return true; } - RenderRegion bounds(RenderMethod& renderer) - { - if (rd) return renderer.region(rd); - if (paint) return paint->pImpl->bounds(renderer); - return {0, 0, 0, 0}; - } - Result load(const string& path) { if (paint || surface) return Result::InsufficientCondition; - if (loader) loader->close(); + bool invalid; //Invalid Path - loader = LoaderMgr::loader(path, &invalid); + auto loader = static_cast(LoaderMgr::loader(path, &invalid)); if (!loader) { if (invalid) return Result::InvalidArguments; return Result::NonSupport; } - if (!loader->read()) return Result::Unknown; - w = loader->w; - h = loader->h; - return Result::Success; + return load(loader); } Result load(const char* data, uint32_t size, const string& mimeType, bool copy) { if (paint || surface) return Result::InsufficientCondition; - if (loader) loader->close(); - loader = LoaderMgr::loader(data, size, mimeType, copy); + auto loader = static_cast(LoaderMgr::loader(data, size, mimeType, copy)); if (!loader) return Result::NonSupport; - if (!loader->read()) return Result::Unknown; - w = loader->w; - h = loader->h; - return Result::Success; + return load(loader); } Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) { if (paint || surface) return Result::InsufficientCondition; - if (loader) loader->close(); - loader = LoaderMgr::loader(data, w, h, copy); + + auto loader = static_cast(LoaderMgr::loader(data, w, h, copy)); if (!loader) return Result::FailedAllocation; - this->w = loader->w; - this->h = loader->h; - return Result::Success; + + return load(loader); } void mesh(const Polygon* triangles, const uint32_t triangleCnt) @@ -258,18 +195,17 @@ struct Picture::Impl { load(); - auto ret = Picture::gen(); + auto ret = Picture::gen().release(); + auto dup = ret->pImpl; - auto dup = ret.get()->pImpl; if (paint) dup->paint = paint->duplicate(); - dup->loader = loader; - if (surface) { - dup->surface = new Surface; - *dup->surface = *surface; - //TODO: A dupilcation is not a proxy... it needs copy of the pixel data? - dup->surface->owner = false; + if (loader) { + dup->loader = loader; + ++dup->loader->sharing; } + + dup->surface = surface; dup->w = w; dup->h = h; dup->resizing = resizing; @@ -280,7 +216,7 @@ struct Picture::Impl memcpy(dup->rm.triangles, rm.triangles, sizeof(Polygon) * rm.triangleCnt); } - return ret.release(); + return ret; } Iterator* iterator() @@ -308,4 +244,4 @@ struct Picture::Impl RenderUpdateFlag load(); }; -#endif //_TVG_PICTURE_IMPL_H_ +#endif //_TVG_PICTURE_H_ diff --git a/thirdparty/thorvg/src/renderer/tvgRender.cpp b/thirdparty/thorvg/src/renderer/tvgRender.cpp index 64d76d35620..bdfb9f322eb 100644 --- a/thirdparty/thorvg/src/renderer/tvgRender.cpp +++ b/thirdparty/thorvg/src/renderer/tvgRender.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgRender.h b/thirdparty/thorvg/src/renderer/tvgRender.h index 6c0a7d5f135..1e70b534940 100644 --- a/thirdparty/thorvg/src/renderer/tvgRender.h +++ b/thirdparty/thorvg/src/renderer/tvgRender.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ #ifndef _TVG_RENDER_H_ #define _TVG_RENDER_H_ +#include #include "tvgCommon.h" #include "tvgArray.h" @@ -49,17 +50,33 @@ enum ColorSpace struct Surface { union { - pixel_t* data; //system based data pointer - uint32_t* buf32; //for explicit 32bits channels - uint8_t* buf8; //for explicit 8bits grayscale + pixel_t* data = nullptr; //system based data pointer + uint32_t* buf32; //for explicit 32bits channels + uint8_t* buf8; //for explicit 8bits grayscale }; - uint32_t stride; - uint32_t w, h; - ColorSpace cs; - uint8_t channelSize; + mutex mtx; //used for thread safety + uint32_t stride = 0; + uint32_t w = 0, h = 0; + ColorSpace cs = ColorSpace::Unsupported; + uint8_t channelSize = 0; + bool premultiplied = 0; //Alpha-premultiplied + + Surface() + { + } + + Surface(const Surface* rhs) + { + data = rhs->data; + stride = rhs->stride; + w = rhs->w; + h = rhs->h; + cs = rhs->cs; + channelSize = rhs->channelSize; + premultiplied = rhs->premultiplied; + } + - bool premultiplied; //Alpha-premultiplied - bool owner; //Only owner could modify the buffer }; struct Compositor diff --git a/thirdparty/thorvg/src/renderer/tvgSaveModule.h b/thirdparty/thorvg/src/renderer/tvgSaveModule.h index 09e7bde72bb..fed05c52dfd 100644 --- a/thirdparty/thorvg/src/renderer/tvgSaveModule.h +++ b/thirdparty/thorvg/src/renderer/tvgSaveModule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,7 +34,7 @@ public: virtual ~SaveModule() {} virtual bool save(Paint* paint, const string& path, bool compress) = 0; - virtual bool save(Animation* animation, const string& path, uint32_t quality, uint32_t fps) = 0; + virtual bool save(Animation* animation, Paint* bg, const string& path, uint32_t quality, uint32_t fps) = 0; virtual bool close() = 0; }; diff --git a/thirdparty/thorvg/src/renderer/tvgSaver.cpp b/thirdparty/thorvg/src/renderer/tvgSaver.cpp index 038d1ad097b..11eb24d4379 100644 --- a/thirdparty/thorvg/src/renderer/tvgSaver.cpp +++ b/thirdparty/thorvg/src/renderer/tvgSaver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,9 +37,12 @@ struct Saver::Impl { SaveModule* saveModule = nullptr; + Paint* bg = nullptr; + ~Impl() { delete(saveModule); + delete(bg); } }; @@ -139,7 +142,16 @@ Result Saver::save(std::unique_ptr paint, const string& path, bool compre } -Result Saver::save(std::unique_ptr animation, const string& path, uint32_t quality, uint32_t fps) noexcept +Result Saver::background(unique_ptr paint) noexcept +{ + delete(pImpl->bg); + pImpl->bg = paint.release(); + + return Result::Success; +} + + +Result Saver::save(unique_ptr animation, const string& path, uint32_t quality, uint32_t fps) noexcept { auto a = animation.release(); if (!a) return Result::MemoryCorruption; @@ -156,7 +168,7 @@ Result Saver::save(std::unique_ptr animation, const string& path, uin } if (auto saveModule = _find(path)) { - if (saveModule->save(a, path, quality, fps)) { + if (saveModule->save(a, pImpl->bg, path, quality, fps)) { pImpl->saveModule = saveModule; return Result::Success; } else { diff --git a/thirdparty/thorvg/src/renderer/tvgScene.cpp b/thirdparty/thorvg/src/renderer/tvgScene.cpp index cd73913b303..f5809cf93b5 100644 --- a/thirdparty/thorvg/src/renderer/tvgScene.cpp +++ b/thirdparty/thorvg/src/renderer/tvgScene.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgScene.h b/thirdparty/thorvg/src/renderer/tvgScene.h index b558e95a2f5..1a5600c231b 100644 --- a/thirdparty/thorvg/src/renderer/tvgScene.h +++ b/thirdparty/thorvg/src/renderer/tvgScene.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,15 +20,12 @@ * SOFTWARE. */ -#ifndef _TVG_SCENE_IMPL_H_ -#define _TVG_SCENE_IMPL_H_ +#ifndef _TVG_SCENE_H_ +#define _TVG_SCENE_H_ #include #include "tvgPaint.h" -/************************************************************************/ -/* Internal Class Implementation */ -/************************************************************************/ struct SceneIterator : Iterator { @@ -126,8 +123,7 @@ struct Scene::Impl this->renderer = &renderer; if (clipper) { - Array rds; - rds.reserve(paints.size()); + Array rds(paints.size()); for (auto paint : paints) { rds.push(paint->pImpl->update(renderer, transform, clips, opacity, flag, true)); } @@ -216,9 +212,8 @@ struct Scene::Impl Paint* duplicate() { - auto ret = Scene::gen(); - - auto dup = ret.get()->pImpl; + auto ret = Scene::gen().release(); + auto dup = ret->pImpl; for (auto paint : paints) { auto cdup = paint->duplicate(); @@ -226,7 +221,7 @@ struct Scene::Impl dup->paints.push_back(cdup); } - return ret.release(); + return ret; } void clear(bool free) @@ -247,4 +242,4 @@ struct Scene::Impl } }; -#endif //_TVG_SCENE_IMPL_H_ +#endif //_TVG_SCENE_H_ diff --git a/thirdparty/thorvg/src/renderer/tvgShape.cpp b/thirdparty/thorvg/src/renderer/tvgShape.cpp index 9a64c7df9fa..23b8006dd99 100644 --- a/thirdparty/thorvg/src/renderer/tvgShape.cpp +++ b/thirdparty/thorvg/src/renderer/tvgShape.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgShape.h b/thirdparty/thorvg/src/renderer/tvgShape.h index 46b2d7d0dbd..a7f12266900 100644 --- a/thirdparty/thorvg/src/renderer/tvgShape.h +++ b/thirdparty/thorvg/src/renderer/tvgShape.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,16 +20,13 @@ * SOFTWARE. */ -#ifndef _TVG_SHAPE_IMPL_H_ -#define _TVG_SHAPE_IMPL_H_ +#ifndef _TVG_SHAPE_H_ +#define _TVG_SHAPE_H_ #include #include "tvgMath.h" #include "tvgPaint.h" -/************************************************************************/ -/* Internal Class Implementation */ -/************************************************************************/ struct Shape::Impl { @@ -341,9 +338,9 @@ struct Shape::Impl Paint* duplicate() { - auto ret = Shape::gen(); + auto ret = Shape::gen().release(); + auto dup = ret->pImpl; - auto dup = ret.get()->pImpl; dup->rs.rule = rs.rule; //Color @@ -379,7 +376,7 @@ struct Shape::Impl dup->flag |= RenderUpdateFlag::Gradient; } - return ret.release(); + return ret; } Iterator* iterator() @@ -388,4 +385,4 @@ struct Shape::Impl } }; -#endif //_TVG_SHAPE_IMPL_H_ +#endif //_TVG_SHAPE_H_ diff --git a/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp index 95df6b486da..44040570496 100644 --- a/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp +++ b/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/thirdparty/thorvg/src/renderer/tvgTaskScheduler.cpp b/thirdparty/thorvg/src/renderer/tvgTaskScheduler.cpp index e3887c60fc3..36d1ce1f8b0 100644 --- a/thirdparty/thorvg/src/renderer/tvgTaskScheduler.cpp +++ b/thirdparty/thorvg/src/renderer/tvgTaskScheduler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,11 +20,11 @@ * SOFTWARE. */ -#include #include -#include #include #include +#include "tvgArray.h" +#include "tvgInlist.h" #include "tvgTaskScheduler.h" /************************************************************************/ @@ -34,7 +34,7 @@ namespace tvg { struct TaskQueue { - deque taskDeque; + Inlist taskDeque; mutex mtx; condition_variable ready; bool done = false; @@ -44,8 +44,6 @@ struct TaskQueue { unique_lock lock{mtx, try_to_lock}; if (!lock || taskDeque.empty()) return false; *task = taskDeque.front(); - taskDeque.pop_front(); - return true; } @@ -54,11 +52,9 @@ struct TaskQueue { { unique_lock lock{mtx, try_to_lock}; if (!lock) return false; - taskDeque.push_back(task); + taskDeque.back(task); } - ready.notify_one(); - return true; } @@ -82,8 +78,6 @@ struct TaskQueue { if (taskDeque.empty()) return false; *task = taskDeque.front(); - taskDeque.pop_front(); - return true; } @@ -91,12 +85,10 @@ struct TaskQueue { { { unique_lock lock{mtx}; - taskDeque.push_back(task); + taskDeque.back(task); } - ready.notify_one(); } - }; @@ -105,24 +97,36 @@ static thread_local bool _async = true; //toggle async tasking for each thread struct TaskSchedulerImpl { - uint32_t threadCnt; - vector threads; - vector taskQueues; + Array threads; + Array taskQueues; atomic idx{0}; - TaskSchedulerImpl(unsigned threadCnt) : threadCnt(threadCnt), taskQueues(threadCnt) + TaskSchedulerImpl(unsigned threadCnt) { threads.reserve(threadCnt); + taskQueues.reserve(threadCnt); for (unsigned i = 0; i < threadCnt; ++i) { - threads.emplace_back([&, i] { run(i); }); + taskQueues.push(new TaskQueue); + threads.push(new thread); + } + for (unsigned i = 0; i < threadCnt; ++i) { + *threads.data[i] = thread([&, i] { run(i); }); } } ~TaskSchedulerImpl() { - for (auto& queue : taskQueues) queue.complete(); - for (auto& thread : threads) thread.join(); + for (auto tq = taskQueues.data; tq < taskQueues.end(); ++tq) { + (*tq)->complete(); + } + for (auto thread = threads.data; thread < threads.end(); ++thread) { + (*thread)->join(); + delete(*thread); + } + for (auto tq = taskQueues.data; tq < taskQueues.end(); ++tq) { + delete(*tq); + } } void run(unsigned i) @@ -132,14 +136,14 @@ struct TaskSchedulerImpl //Thread Loop while (true) { auto success = false; - for (unsigned x = 0; x < threadCnt * 2; ++x) { - if (taskQueues[(i + x) % threadCnt].tryPop(&task)) { + for (unsigned x = 0; x < threads.count * 2; ++x) { + if (taskQueues[(i + x) % threads.count]->tryPop(&task)) { success = true; break; } } - if (!success && !taskQueues[i].pop(&task)) break; + if (!success && !taskQueues[i]->pop(&task)) break; (*task)(i + 1); } } @@ -147,13 +151,13 @@ struct TaskSchedulerImpl void request(Task* task) { //Async - if (threadCnt > 0 && _async) { + if (threads.count > 0 && _async) { task->prepare(); auto i = idx++; - for (unsigned n = 0; n < threadCnt; ++n) { - if (taskQueues[(i + n) % threadCnt].tryPush(task)) return; + for (unsigned n = 0; n < threads.count; ++n) { + if (taskQueues[(i + n) % threads.count]->tryPush(task)) return; } - taskQueues[i % threadCnt].push(task); + taskQueues[i % threads.count]->push(task); //Sync } else { task->run(0); @@ -192,7 +196,7 @@ void TaskScheduler::request(Task* task) unsigned TaskScheduler::threads() { - if (inst) return inst->threadCnt; + if (inst) return inst->threads.count; return 0; } diff --git a/thirdparty/thorvg/src/renderer/tvgTaskScheduler.h b/thirdparty/thorvg/src/renderer/tvgTaskScheduler.h index 2dad80f5d04..483e0848803 100644 --- a/thirdparty/thorvg/src/renderer/tvgTaskScheduler.h +++ b/thirdparty/thorvg/src/renderer/tvgTaskScheduler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved. + * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,7 @@ #include #include #include "tvgCommon.h" +#include "tvgInlist.h" namespace tvg { @@ -50,6 +51,8 @@ private: bool pending = false; public: + INLIST_ITEM(Task); + virtual ~Task() = default; void done() diff --git a/thirdparty/thorvg/src/renderer/tvgText.cpp b/thirdparty/thorvg/src/renderer/tvgText.cpp new file mode 100644 index 00000000000..1fe244c11d3 --- /dev/null +++ b/thirdparty/thorvg/src/renderer/tvgText.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "tvgText.h" + + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + +Text::Text() : pImpl(new Impl) +{ + Paint::pImpl->id = TVG_CLASS_ID_TEXT; +} + + +Text::~Text() +{ + delete(pImpl); +} + + +Result Text::text(const char* text) noexcept +{ + return pImpl->text(text); +} + + +Result Text::font(const char* name, float size, const char* style) noexcept +{ + return pImpl->font(name, size, style); +} + + +Result Text::load(const std::string& path) noexcept +{ + bool invalid; //invalid path + if (!LoaderMgr::loader(path, &invalid)) { + if (invalid) return Result::InvalidArguments; + else return Result::NonSupport; + } + + return Result::Success; +} + + +Result Text::unload(const std::string& path) noexcept +{ + if (LoaderMgr::retrieve(path)) return Result::Success; + return Result::InsufficientCondition; +} + + +Result Text::fill(uint8_t r, uint8_t g, uint8_t b) noexcept +{ + if (!pImpl->paint) return Result::InsufficientCondition; + + return pImpl->fill(r, g, b); +} + + +Result Text::fill(unique_ptr f) noexcept +{ + if (!pImpl->paint) return Result::InsufficientCondition; + + auto p = f.release(); + if (!p) return Result::MemoryCorruption; + + return pImpl->fill(p); +} + + +unique_ptr Text::gen() noexcept +{ + return unique_ptr(new Text); +} + + +uint32_t Text::identifier() noexcept +{ + return TVG_CLASS_ID_TEXT; +} diff --git a/thirdparty/thorvg/src/renderer/tvgText.h b/thirdparty/thorvg/src/renderer/tvgText.h new file mode 100644 index 00000000000..b9f7ef60794 --- /dev/null +++ b/thirdparty/thorvg/src/renderer/tvgText.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _TVG_TEXT_H +#define _TVG_TEXT_H + +#include +#include "tvgShape.h" +#include "tvgFill.h" + +#ifdef THORVG_TTF_LOADER_SUPPORT + #include "tvgTtfLoader.h" +#else + #include "tvgLoader.h" +#endif + +struct Text::Impl +{ + RenderData rd = nullptr; + FontLoader* loader = nullptr; + Shape* paint = nullptr; + char* utf8 = nullptr; + float fontSize; + bool italic = false; + bool changed = false; + + ~Impl() + { + free(utf8); + LoaderMgr::retrieve(loader); + delete(paint); + } + + Result fill(uint8_t r, uint8_t g, uint8_t b) + { + return paint->fill(r, g, b); + } + + Result fill(Fill* f) + { + return paint->fill(cast(f)); + } + + Result text(const char* utf8) + { + free(this->utf8); + if (utf8) this->utf8 = strdup(utf8); + else this->utf8 = nullptr; + changed = true; + + return Result::Success; + } + + Result font(const char* name, float size, const char* style) + { + auto loader = LoaderMgr::loader(name); + if (!loader) return Result::InsufficientCondition; + + //Same resource has been loaded. + if (this->loader == loader) { + this->loader->sharing--; //make it sure the reference counting. + return Result::Success; + } else if (this->loader) { + LoaderMgr::retrieve(this->loader); + } + this->loader = static_cast(loader); + + if (!paint) paint = Shape::gen().release(); + + fontSize = size; + if (style && strstr(style, "italic")) italic = true; + changed = true; + return Result::Success; + } + + RenderRegion bounds(RenderMethod& renderer) + { + return renderer.region(rd); + } + + bool render(RenderMethod& renderer) + { + if (paint) return PP(paint)->render(renderer); + return false; + } + + bool load() + { + if (!loader) return false; + + //reload + if (changed) { + loader->request(paint, utf8, italic); + loader->read(); + changed = false; + } + if (paint) { + loader->resize(paint, fontSize, fontSize); + return true; + } + return false; + } + + RenderData update(RenderMethod& renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + { + if (!load()) return nullptr; + + //transform the gradient coordinates based on the final scaled font. + if (P(paint)->flag & RenderUpdateFlag::Gradient) { + auto fill = P(paint)->rs.fill; + auto scale = 1.0f / loader->scale; + if (fill->identifier() == TVG_CLASS_ID_LINEAR) { + P(static_cast(fill))->x1 *= scale; + P(static_cast(fill))->y1 *= scale; + P(static_cast(fill))->x2 *= scale; + P(static_cast(fill))->y2 *= scale; + } else { + P(static_cast(fill))->cx *= scale; + P(static_cast(fill))->cy *= scale; + P(static_cast(fill))->r *= scale; + P(static_cast(fill))->fx *= scale; + P(static_cast(fill))->fy *= scale; + P(static_cast(fill))->fr *= scale; + } + } + rd = PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper); + return rd; + } + + bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking) + { + if (!load() || !paint) return false; + paint->bounds(x, y, w, h, true); + return true; + } + + bool dispose(RenderMethod& renderer) + { + renderer.dispose(rd); + this->rd = nullptr; + return true; + } + + Paint* duplicate() + { + load(); + + auto ret = Text::gen().release(); + auto dup = ret->pImpl; + if (paint) dup->paint = static_cast(paint->duplicate()); + + if (loader) { + dup->loader = loader; + ++dup->loader->sharing; + } + + dup->utf8 = strdup(utf8); + dup->italic = italic; + dup->fontSize = fontSize; + + return ret; + } + + Iterator* iterator() + { + return nullptr; + } +}; + + + +#endif //_TVG_TEXT_H diff --git a/thirdparty/thorvg/src/renderer/tvgWgCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgWgCanvas.cpp new file mode 100644 index 00000000000..5205df17372 --- /dev/null +++ b/thirdparty/thorvg/src/renderer/tvgWgCanvas.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "tvgCanvas.h" + +#ifdef THORVG_WG_RASTER_SUPPORT + #include "tvgWgRenderer.h" +#endif + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct WgCanvas::Impl +{ +}; + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#ifdef THORVG_WG_RASTER_SUPPORT +WgCanvas::WgCanvas() : Canvas(WgRenderer::gen()), pImpl(new Impl) +#else +WgCanvas::WgCanvas() : Canvas(nullptr), pImpl(nullptr) +#endif +{ +} + +WgCanvas::~WgCanvas() +{ + delete pImpl; +} + +Result WgCanvas::target(void* window, uint32_t w, uint32_t h) noexcept +{ +#ifdef THORVG_WG_RASTER_SUPPORT + if (!window) return Result::InvalidArguments; + if ((w == 0) || (h == 0)) return Result::InvalidArguments; + + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl->renderer); + if (!renderer) return Result::MemoryCorruption; + + if (!renderer->target(window, w, h)) return Result::Unknown; + + //Paints must be updated again with this new target. + Canvas::pImpl->needRefresh(); + + return Result::Success; +#endif + return Result::NonSupport; +} + +unique_ptr WgCanvas::gen() noexcept +{ +#ifdef THORVG_WG_RASTER_SUPPORT + return unique_ptr(new WgCanvas); +#endif + return nullptr; +} diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh index d4323848da7..a1732d5157b 100755 --- a/thirdparty/thorvg/update-thorvg.sh +++ b/thirdparty/thorvg/update-thorvg.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -VERSION=0.11.6 +VERSION=0.12.0 cd thirdparty/thorvg/ || true rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/ @@ -52,6 +52,7 @@ cp -rv src/renderer ../src/ # Only sw_engine is enabled. rm -rfv ../src/renderer/gl_engine +rm -rfv ../src/renderer/wg_engine # Enabled embedded loaders: raw, JPEG, PNG. mkdir ../src/loaders