Merge pull request #82542 from capnm/update_godot4.2_tip_from_0.10.7_revision_to_thorvg_0.11.0_release
ThorVG: update to v0.11.0 release.
This commit is contained in:
commit
2566cbec5c
71 changed files with 629 additions and 467 deletions
|
@ -11,39 +11,45 @@ thirdparty_obj = []
|
|||
|
||||
thirdparty_dir = "#thirdparty/thorvg/"
|
||||
thirdparty_sources = [
|
||||
"src/lib/sw_engine/tvgSwFill.cpp",
|
||||
"src/lib/sw_engine/tvgSwImage.cpp",
|
||||
"src/lib/sw_engine/tvgSwMath.cpp",
|
||||
"src/lib/sw_engine/tvgSwMemPool.cpp",
|
||||
"src/lib/sw_engine/tvgSwRaster.cpp",
|
||||
"src/lib/sw_engine/tvgSwRenderer.cpp",
|
||||
"src/lib/sw_engine/tvgSwRle.cpp",
|
||||
"src/lib/sw_engine/tvgSwShape.cpp",
|
||||
"src/lib/sw_engine/tvgSwStroke.cpp",
|
||||
"src/lib/tvgAccessor.cpp",
|
||||
"src/lib/tvgCanvas.cpp",
|
||||
"src/lib/tvgFill.cpp",
|
||||
"src/lib/tvgGlCanvas.cpp",
|
||||
"src/lib/tvgInitializer.cpp",
|
||||
"src/lib/tvgLoader.cpp",
|
||||
"src/lib/tvgPaint.cpp",
|
||||
"src/lib/tvgPicture.cpp",
|
||||
"src/lib/tvgRender.cpp",
|
||||
"src/lib/tvgSaver.cpp",
|
||||
"src/lib/tvgScene.cpp",
|
||||
"src/lib/tvgShape.cpp",
|
||||
"src/lib/tvgSwCanvas.cpp",
|
||||
"src/lib/tvgTaskScheduler.cpp",
|
||||
"src/utils/tvgBezier.cpp",
|
||||
"src/utils/tvgCompressor.cpp",
|
||||
"src/utils/tvgStr.cpp",
|
||||
"src/loaders/raw/tvgRawLoader.cpp",
|
||||
# common
|
||||
"src/common/tvgBezier.cpp",
|
||||
"src/common/tvgCompressor.cpp",
|
||||
"src/common/tvgMath.cpp",
|
||||
"src/common/tvgStr.cpp",
|
||||
# SVG parser
|
||||
"src/loaders/svg/tvgSvgCssStyle.cpp",
|
||||
"src/loaders/svg/tvgSvgLoader.cpp",
|
||||
"src/loaders/svg/tvgSvgPath.cpp",
|
||||
"src/loaders/svg/tvgSvgSceneBuilder.cpp",
|
||||
"src/loaders/svg/tvgSvgUtil.cpp",
|
||||
"src/loaders/svg/tvgXmlParser.cpp",
|
||||
"src/loaders/raw/tvgRawLoader.cpp",
|
||||
# renderer common
|
||||
"src/renderer/tvgAccessor.cpp",
|
||||
# "src/renderer/tvgAnimation.cpp",
|
||||
"src/renderer/tvgCanvas.cpp",
|
||||
"src/renderer/tvgFill.cpp",
|
||||
# "src/renderer/tvgGlCanvas.cpp",
|
||||
"src/renderer/tvgInitializer.cpp",
|
||||
"src/renderer/tvgLoader.cpp",
|
||||
"src/renderer/tvgPaint.cpp",
|
||||
"src/renderer/tvgPicture.cpp",
|
||||
"src/renderer/tvgRender.cpp",
|
||||
# "src/renderer/tvgSaver.cpp",
|
||||
"src/renderer/tvgScene.cpp",
|
||||
"src/renderer/tvgShape.cpp",
|
||||
"src/renderer/tvgSwCanvas.cpp",
|
||||
"src/renderer/tvgTaskScheduler.cpp",
|
||||
# renderer sw_engine
|
||||
"src/renderer/sw_engine/tvgSwFill.cpp",
|
||||
"src/renderer/sw_engine/tvgSwImage.cpp",
|
||||
"src/renderer/sw_engine/tvgSwMath.cpp",
|
||||
"src/renderer/sw_engine/tvgSwMemPool.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRaster.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRenderer.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRle.cpp",
|
||||
"src/renderer/sw_engine/tvgSwShape.cpp",
|
||||
"src/renderer/sw_engine/tvgSwStroke.cpp",
|
||||
]
|
||||
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
@ -57,16 +63,13 @@ env_thirdparty = env_svg.Clone()
|
|||
env_thirdparty.disable_warnings()
|
||||
env_thirdparty.Prepend(
|
||||
CPPPATH=[
|
||||
thirdparty_dir + "src/lib",
|
||||
thirdparty_dir + "src/lib/sw_engine",
|
||||
thirdparty_dir + "src/loaders/raw",
|
||||
thirdparty_dir + "src/common",
|
||||
thirdparty_dir + "src/loaders/svg",
|
||||
thirdparty_dir + "src/utils",
|
||||
thirdparty_dir + "src/renderer",
|
||||
thirdparty_dir + "src/renderer/sw_engine",
|
||||
thirdparty_dir + "src/loaders/raw",
|
||||
]
|
||||
)
|
||||
# Also requires libpng headers
|
||||
if env["builtin_libpng"]:
|
||||
env_thirdparty.Prepend(CPPPATH=["#thirdparty/libpng"])
|
||||
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
|
||||
env.modules_sources += thirdparty_obj
|
||||
|
|
|
@ -40,7 +40,11 @@ msdfgen_enabled = "msdfgen" in env.module_list
|
|||
|
||||
if "svg" in env.module_list:
|
||||
env_text_server_adv.Prepend(
|
||||
CPPPATH=["#thirdparty/thorvg/inc", "#thirdparty/thorvg/src/lib", "#thirdparty/thorvg/src/utils"]
|
||||
CPPPATH=[
|
||||
"#thirdparty/thorvg/inc",
|
||||
"#thirdparty/thorvg/src/common",
|
||||
"#thirdparty/thorvg/src/renderer",
|
||||
]
|
||||
)
|
||||
# Enable ThorVG static object linking.
|
||||
env_text_server_adv.Append(CPPDEFINES=["TVG_STATIC"])
|
||||
|
|
|
@ -42,51 +42,56 @@ if env["thorvg_enabled"] and env["freetype_enabled"]:
|
|||
|
||||
thirdparty_tvg_dir = "../../../thirdparty/thorvg/"
|
||||
thirdparty_tvg_sources = [
|
||||
"src/lib/sw_engine/tvgSwFill.cpp",
|
||||
"src/lib/sw_engine/tvgSwImage.cpp",
|
||||
"src/lib/sw_engine/tvgSwMath.cpp",
|
||||
"src/lib/sw_engine/tvgSwMemPool.cpp",
|
||||
"src/lib/sw_engine/tvgSwRaster.cpp",
|
||||
"src/lib/sw_engine/tvgSwRenderer.cpp",
|
||||
"src/lib/sw_engine/tvgSwRle.cpp",
|
||||
"src/lib/sw_engine/tvgSwShape.cpp",
|
||||
"src/lib/sw_engine/tvgSwStroke.cpp",
|
||||
"src/lib/tvgAccessor.cpp",
|
||||
"src/lib/tvgCanvas.cpp",
|
||||
"src/lib/tvgFill.cpp",
|
||||
"src/lib/tvgGlCanvas.cpp",
|
||||
"src/lib/tvgInitializer.cpp",
|
||||
"src/lib/tvgLoader.cpp",
|
||||
"src/lib/tvgPaint.cpp",
|
||||
"src/lib/tvgPicture.cpp",
|
||||
"src/lib/tvgRender.cpp",
|
||||
"src/lib/tvgSaver.cpp",
|
||||
"src/lib/tvgScene.cpp",
|
||||
"src/lib/tvgShape.cpp",
|
||||
"src/lib/tvgSwCanvas.cpp",
|
||||
"src/lib/tvgTaskScheduler.cpp",
|
||||
"src/utils/tvgBezier.cpp",
|
||||
"src/utils/tvgCompressor.cpp",
|
||||
"src/utils/tvgStr.cpp",
|
||||
"src/loaders/raw/tvgRawLoader.cpp",
|
||||
# common
|
||||
"src/common/tvgBezier.cpp",
|
||||
"src/common/tvgCompressor.cpp",
|
||||
"src/common/tvgMath.cpp",
|
||||
"src/common/tvgStr.cpp",
|
||||
# SVG parser
|
||||
"src/loaders/svg/tvgSvgCssStyle.cpp",
|
||||
"src/loaders/svg/tvgSvgLoader.cpp",
|
||||
"src/loaders/svg/tvgSvgPath.cpp",
|
||||
"src/loaders/svg/tvgSvgSceneBuilder.cpp",
|
||||
"src/loaders/svg/tvgSvgUtil.cpp",
|
||||
"src/loaders/svg/tvgXmlParser.cpp",
|
||||
"src/loaders/raw/tvgRawLoader.cpp",
|
||||
# renderer common
|
||||
"src/renderer/tvgAccessor.cpp",
|
||||
# "src/renderer/tvgAnimation.cpp",
|
||||
"src/renderer/tvgCanvas.cpp",
|
||||
"src/renderer/tvgFill.cpp",
|
||||
# "src/renderer/tvgGlCanvas.cpp",
|
||||
"src/renderer/tvgInitializer.cpp",
|
||||
"src/renderer/tvgLoader.cpp",
|
||||
"src/renderer/tvgPaint.cpp",
|
||||
"src/renderer/tvgPicture.cpp",
|
||||
"src/renderer/tvgRender.cpp",
|
||||
# "src/renderer/tvgSaver.cpp",
|
||||
"src/renderer/tvgScene.cpp",
|
||||
"src/renderer/tvgShape.cpp",
|
||||
"src/renderer/tvgSwCanvas.cpp",
|
||||
"src/renderer/tvgTaskScheduler.cpp",
|
||||
# renderer sw_engine
|
||||
"src/renderer/sw_engine/tvgSwFill.cpp",
|
||||
"src/renderer/sw_engine/tvgSwImage.cpp",
|
||||
"src/renderer/sw_engine/tvgSwMath.cpp",
|
||||
"src/renderer/sw_engine/tvgSwMemPool.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRaster.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRenderer.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRle.cpp",
|
||||
"src/renderer/sw_engine/tvgSwShape.cpp",
|
||||
"src/renderer/sw_engine/tvgSwStroke.cpp",
|
||||
]
|
||||
thirdparty_tvg_sources = [thirdparty_tvg_dir + file for file in thirdparty_tvg_sources]
|
||||
|
||||
env_tvg.Append(
|
||||
CPPPATH=[
|
||||
"../../../thirdparty/thorvg/inc",
|
||||
"../../../thirdparty/thorvg/src/lib",
|
||||
"../../../thirdparty/thorvg/src/lib/sw_engine",
|
||||
"../../../thirdparty/thorvg/src/loaders/raw",
|
||||
"../../../thirdparty/thorvg/src/common",
|
||||
"../../../thirdparty/thorvg/src/loaders/svg",
|
||||
"../../../thirdparty/thorvg/src/utils",
|
||||
"../../../thirdparty/libpng",
|
||||
"../../../thirdparty/thorvg/src/loaders/raw",
|
||||
"../../../thirdparty/thorvg/src/renderer",
|
||||
"../../../thirdparty/thorvg/src/renderer/sw_engine",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -96,8 +101,8 @@ if env["thorvg_enabled"] and env["freetype_enabled"]:
|
|||
env.Append(
|
||||
CPPPATH=[
|
||||
"../../../thirdparty/thorvg/inc",
|
||||
"../../../thirdparty/thorvg/src/lib",
|
||||
"../../../thirdparty/thorvg/src/utils",
|
||||
"../../../thirdparty/thorvg/src/common",
|
||||
"../../../thirdparty/thorvg/src/renderer",
|
||||
]
|
||||
)
|
||||
env.Append(CPPDEFINES=["MODULE_SVG_ENABLED"])
|
||||
|
|
|
@ -10,7 +10,7 @@ env_text_server_fb = env_modules.Clone()
|
|||
|
||||
if "svg" in env.module_list:
|
||||
env_text_server_fb.Prepend(
|
||||
CPPPATH=["#thirdparty/thorvg/inc", "#thirdparty/thorvg/src/lib", "#thirdparty/thorvg/src/utils"]
|
||||
CPPPATH=["#thirdparty/thorvg/inc", "#thirdparty/thorvg/src/common", "#thirdparty/thorvg/src/renderer"]
|
||||
)
|
||||
# Enable ThorVG static object linking.
|
||||
env_text_server_fb.Append(CPPDEFINES=["TVG_STATIC"])
|
||||
|
|
|
@ -37,51 +37,56 @@ if env["thorvg_enabled"] and env["freetype_enabled"]:
|
|||
|
||||
thirdparty_tvg_dir = "../../../thirdparty/thorvg/"
|
||||
thirdparty_tvg_sources = [
|
||||
"src/lib/sw_engine/tvgSwFill.cpp",
|
||||
"src/lib/sw_engine/tvgSwImage.cpp",
|
||||
"src/lib/sw_engine/tvgSwMath.cpp",
|
||||
"src/lib/sw_engine/tvgSwMemPool.cpp",
|
||||
"src/lib/sw_engine/tvgSwRaster.cpp",
|
||||
"src/lib/sw_engine/tvgSwRenderer.cpp",
|
||||
"src/lib/sw_engine/tvgSwRle.cpp",
|
||||
"src/lib/sw_engine/tvgSwShape.cpp",
|
||||
"src/lib/sw_engine/tvgSwStroke.cpp",
|
||||
"src/lib/tvgAccessor.cpp",
|
||||
"src/lib/tvgCanvas.cpp",
|
||||
"src/lib/tvgFill.cpp",
|
||||
"src/lib/tvgGlCanvas.cpp",
|
||||
"src/lib/tvgInitializer.cpp",
|
||||
"src/lib/tvgLoader.cpp",
|
||||
"src/lib/tvgPaint.cpp",
|
||||
"src/lib/tvgPicture.cpp",
|
||||
"src/lib/tvgRender.cpp",
|
||||
"src/lib/tvgSaver.cpp",
|
||||
"src/lib/tvgScene.cpp",
|
||||
"src/lib/tvgShape.cpp",
|
||||
"src/lib/tvgSwCanvas.cpp",
|
||||
"src/lib/tvgTaskScheduler.cpp",
|
||||
"src/utils/tvgBezier.cpp",
|
||||
"src/utils/tvgCompressor.cpp",
|
||||
"src/utils/tvgStr.cpp",
|
||||
"src/loaders/raw/tvgRawLoader.cpp",
|
||||
# common
|
||||
"src/common/tvgBezier.cpp",
|
||||
"src/common/tvgCompressor.cpp",
|
||||
"src/common/tvgMath.cpp",
|
||||
"src/common/tvgStr.cpp",
|
||||
# SVG parser
|
||||
"src/loaders/svg/tvgSvgCssStyle.cpp",
|
||||
"src/loaders/svg/tvgSvgLoader.cpp",
|
||||
"src/loaders/svg/tvgSvgPath.cpp",
|
||||
"src/loaders/svg/tvgSvgSceneBuilder.cpp",
|
||||
"src/loaders/svg/tvgSvgUtil.cpp",
|
||||
"src/loaders/svg/tvgXmlParser.cpp",
|
||||
"src/loaders/raw/tvgRawLoader.cpp",
|
||||
# renderer common
|
||||
"src/renderer/tvgAccessor.cpp",
|
||||
# "src/renderer/tvgAnimation.cpp",
|
||||
"src/renderer/tvgCanvas.cpp",
|
||||
"src/renderer/tvgFill.cpp",
|
||||
# "src/renderer/tvgGlCanvas.cpp",
|
||||
"src/renderer/tvgInitializer.cpp",
|
||||
"src/renderer/tvgLoader.cpp",
|
||||
"src/renderer/tvgPaint.cpp",
|
||||
"src/renderer/tvgPicture.cpp",
|
||||
"src/renderer/tvgRender.cpp",
|
||||
# "src/renderer/tvgSaver.cpp",
|
||||
"src/renderer/tvgScene.cpp",
|
||||
"src/renderer/tvgShape.cpp",
|
||||
"src/renderer/tvgSwCanvas.cpp",
|
||||
"src/renderer/tvgTaskScheduler.cpp",
|
||||
# renderer sw_engine
|
||||
"src/renderer/sw_engine/tvgSwFill.cpp",
|
||||
"src/renderer/sw_engine/tvgSwImage.cpp",
|
||||
"src/renderer/sw_engine/tvgSwMath.cpp",
|
||||
"src/renderer/sw_engine/tvgSwMemPool.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRaster.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRenderer.cpp",
|
||||
"src/renderer/sw_engine/tvgSwRle.cpp",
|
||||
"src/renderer/sw_engine/tvgSwShape.cpp",
|
||||
"src/renderer/sw_engine/tvgSwStroke.cpp",
|
||||
]
|
||||
thirdparty_tvg_sources = [thirdparty_tvg_dir + file for file in thirdparty_tvg_sources]
|
||||
|
||||
env_tvg.Append(
|
||||
CPPPATH=[
|
||||
"../../../thirdparty/thorvg/inc",
|
||||
"../../../thirdparty/thorvg/src/lib",
|
||||
"../../../thirdparty/thorvg/src/lib/sw_engine",
|
||||
"../../../thirdparty/thorvg/src/loaders/raw",
|
||||
"../../../thirdparty/thorvg/src/common",
|
||||
"../../../thirdparty/thorvg/src/loaders/svg",
|
||||
"../../../thirdparty/thorvg/src/utils",
|
||||
"../../../thirdparty/libpng",
|
||||
"../../../thirdparty/thorvg/src/loaders/raw",
|
||||
"../../../thirdparty/thorvg/src/renderer",
|
||||
"../../../thirdparty/thorvg/src/renderer/sw_engine",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -91,8 +96,8 @@ if env["thorvg_enabled"] and env["freetype_enabled"]:
|
|||
env.Append(
|
||||
CPPPATH=[
|
||||
"../../../thirdparty/thorvg/inc",
|
||||
"../../../thirdparty/thorvg/src/lib",
|
||||
"../../../thirdparty/thorvg/src/utils",
|
||||
"../../../thirdparty/thorvg/src/common",
|
||||
"../../../thirdparty/thorvg/src/renderer",
|
||||
]
|
||||
)
|
||||
env.Append(CPPDEFINES=["MODULE_SVG_ENABLED"])
|
||||
|
|
2
thirdparty/README.md
vendored
2
thirdparty/README.md
vendored
|
@ -784,7 +784,7 @@ instead of `miniz.h` as an external dependency.
|
|||
## thorvg
|
||||
|
||||
- Upstream: https://github.com/thorvg/thorvg
|
||||
- Version: 0.10.7 (026ff4ce7eda10dd0cf80eeaef56fe3a5ed89f93, 2023)
|
||||
- Version: 0.11.0 (12260198d12719ea20939b68492accfc155d9ff5, 2023)
|
||||
- License: MIT
|
||||
|
||||
Files extracted from upstream source:
|
||||
|
|
2
thirdparty/thorvg/AUTHORS
vendored
2
thirdparty/thorvg/AUTHORS
vendored
|
@ -21,3 +21,5 @@ EunSik Jeong <rinechran@outlook.jp>
|
|||
Samsung Electronics Co., Ltd
|
||||
Rafał Mikrut <mikrutrafal@protonmail.com>
|
||||
Martin Capitanio <capnm@capitanio.org>
|
||||
RuiwenTang <tangruiwen1989@gmail.com>
|
||||
YouJin Lee <ol-of@naver.com>
|
||||
|
|
6
thirdparty/thorvg/inc/config.h
vendored
6
thirdparty/thorvg/inc/config.h
vendored
|
@ -2,8 +2,10 @@
|
|||
#define THORVG_CONFIG_H
|
||||
|
||||
#define THORVG_SW_RASTER_SUPPORT
|
||||
|
||||
#define THORVG_SVG_LOADER_SUPPORT
|
||||
|
||||
#define THORVG_VERSION_STRING "0.10.7"
|
||||
// For internal debugging:
|
||||
//#define THORVG_LOG_ENABLED
|
||||
|
||||
#define THORVG_VERSION_STRING "0.11.0"
|
||||
#endif
|
||||
|
|
34
thirdparty/thorvg/inc/thorvg.h
vendored
34
thirdparty/thorvg/inc/thorvg.h
vendored
|
@ -171,7 +171,7 @@ enum class CompositeMethod
|
|||
AlphaMask, ///< Alpha Masking using the compositing target's pixels as an alpha value.
|
||||
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. @BETA_API
|
||||
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
|
||||
|
@ -240,6 +240,7 @@ struct Matrix
|
|||
float e31, e32, e33;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief A data structure representing a texture mesh vertex
|
||||
*
|
||||
|
@ -622,14 +623,16 @@ public:
|
|||
virtual Result push(std::unique_ptr<Paint> paint) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Sets the total number of the paints pushed into the canvas to be zero.
|
||||
* Depending on the value of the @p free argument, the paints are freed or not.
|
||||
* @brief Clear the internal canvas resources that used for the drawing.
|
||||
*
|
||||
* This API sets the total number of paints pushed into the canvas to zero.
|
||||
* Depending on the value of the @p free argument, the paints are either freed or retained.
|
||||
* So if you need to update paint properties while maintaining the existing scene structure, you can set @p free = false.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
* @see Canvas::push()
|
||||
* @see Canvas::paints()
|
||||
*/
|
||||
|
@ -818,7 +821,7 @@ public:
|
|||
/**
|
||||
* @brief Resets the properties of the shape path.
|
||||
*
|
||||
* The color, the fill and the stroke properties are retained.
|
||||
* The transformation matrix, the color, the fill and the stroke properties are retained.
|
||||
*
|
||||
* @return Result::Success when succeed.
|
||||
*
|
||||
|
@ -1038,7 +1041,7 @@ public:
|
|||
*
|
||||
* @return Result::Success when succeed, Result::NonSupport unsupported value, Result::FailedAllocation otherwise.
|
||||
*
|
||||
* @BETA_API
|
||||
* @since 0.11
|
||||
*/
|
||||
Result strokeMiterlimit(float miterlimit) noexcept;
|
||||
|
||||
|
@ -1192,7 +1195,7 @@ public:
|
|||
*
|
||||
* @return The stroke miterlimit value when succeed, 4 if no stroke was set.
|
||||
*
|
||||
* @BETA_API
|
||||
* @since 0.11
|
||||
*/
|
||||
float strokeMiterlimit() const noexcept;
|
||||
|
||||
|
@ -1306,17 +1309,6 @@ public:
|
|||
*/
|
||||
Result size(float* w, float* h) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Gets the pixels information of the picture.
|
||||
*
|
||||
* @note The data must be pre-multiplied by the alpha channels.
|
||||
*
|
||||
* @warning Please do not use it, this API is not official one. It could be modified in the next version.
|
||||
*
|
||||
* @BETA_API
|
||||
*/
|
||||
const uint32_t* data(uint32_t* w, uint32_t* h) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Loads a raw data from a memory block with a given size.
|
||||
*
|
||||
|
@ -1863,8 +1855,7 @@ public:
|
|||
|
||||
/**
|
||||
* @brief The cast() function is a utility function used to cast a 'Paint' to type 'T'.
|
||||
*
|
||||
* @BETA_API
|
||||
* @since 0.11
|
||||
*/
|
||||
template<typename T>
|
||||
std::unique_ptr<T> cast(Paint* paint)
|
||||
|
@ -1875,8 +1866,7 @@ std::unique_ptr<T> cast(Paint* paint)
|
|||
|
||||
/**
|
||||
* @brief The cast() function is a utility function used to cast a 'Fill' to type 'T'.
|
||||
*
|
||||
* @BETA_API
|
||||
* @since 0.11
|
||||
*/
|
||||
template<typename T>
|
||||
std::unique_ptr<T> cast(Fill* fill)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define _TVG_ARRAY_H_
|
||||
|
||||
#include <memory.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace tvg
|
||||
{
|
||||
|
@ -135,6 +136,12 @@ struct Array
|
|||
return count == 0;
|
||||
}
|
||||
|
||||
template<class COMPARE>
|
||||
void sort()
|
||||
{
|
||||
qsort<COMPARE>(data, 0, static_cast<int32_t>(count) - 1);
|
||||
}
|
||||
|
||||
void operator=(const Array& rhs)
|
||||
{
|
||||
reserve(rhs.count);
|
||||
|
@ -146,6 +153,32 @@ struct Array
|
|||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
private:
|
||||
template<class COMPARE>
|
||||
void qsort(T* arr, int32_t low, int32_t high)
|
||||
{
|
||||
if (low < high) {
|
||||
int32_t i = low;
|
||||
int32_t j = high;
|
||||
T tmp = arr[low];
|
||||
while (i < j) {
|
||||
while (i < j && !COMPARE{}(arr[j], tmp)) --j;
|
||||
if (i < j) {
|
||||
arr[i] = arr[j];
|
||||
++i;
|
||||
}
|
||||
while (i < j && COMPARE{}(arr[i], tmp)) ++i;
|
||||
if (i < j) {
|
||||
arr[j] = arr[i];
|
||||
--j;
|
||||
}
|
||||
}
|
||||
arr[i] = tmp;
|
||||
qsort<COMPARE>(arr, low, i - 1);
|
||||
qsort<COMPARE>(arr, i + 1, high);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
90
thirdparty/thorvg/src/common/tvgList.h
vendored
Normal file
90
thirdparty/thorvg/src/common/tvgList.h
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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<typename T>
|
||||
struct LinkedList
|
||||
{
|
||||
T *head = nullptr;
|
||||
T *tail = nullptr;
|
||||
|
||||
LinkedList() = default;
|
||||
LinkedList(T *head, T *tail) : head(head), tail(tail)
|
||||
{
|
||||
}
|
||||
|
||||
template<T *T::*Prev, T *T::*Next>
|
||||
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<T *T::*Prev, T *T::*Next>
|
||||
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 <T* T::*Next>
|
||||
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_
|
102
thirdparty/thorvg/src/common/tvgMath.cpp
vendored
Normal file
102
thirdparty/thorvg/src/common/tvgMath.cpp
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2021 - 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.
|
||||
*/
|
||||
|
||||
#include "tvgMath.h"
|
||||
|
||||
|
||||
bool mathInverse(const Matrix* m, Matrix* out)
|
||||
{
|
||||
auto det = m->e11 * (m->e22 * m->e33 - m->e32 * m->e23) -
|
||||
m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) +
|
||||
m->e13 * (m->e21 * m->e32 - m->e22 * m->e31);
|
||||
|
||||
if (mathZero(det)) return false;
|
||||
|
||||
auto invDet = 1 / det;
|
||||
|
||||
out->e11 = (m->e22 * m->e33 - m->e32 * m->e23) * invDet;
|
||||
out->e12 = (m->e13 * m->e32 - m->e12 * m->e33) * invDet;
|
||||
out->e13 = (m->e12 * m->e23 - m->e13 * m->e22) * invDet;
|
||||
out->e21 = (m->e23 * m->e31 - m->e21 * m->e33) * invDet;
|
||||
out->e22 = (m->e11 * m->e33 - m->e13 * m->e31) * invDet;
|
||||
out->e23 = (m->e21 * m->e13 - m->e11 * m->e23) * invDet;
|
||||
out->e31 = (m->e21 * m->e32 - m->e31 * m->e22) * invDet;
|
||||
out->e32 = (m->e31 * m->e12 - m->e11 * m->e32) * invDet;
|
||||
out->e33 = (m->e11 * m->e22 - m->e21 * m->e12) * invDet;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs)
|
||||
{
|
||||
Matrix m;
|
||||
|
||||
m.e11 = lhs->e11 * rhs->e11 + lhs->e12 * rhs->e21 + lhs->e13 * rhs->e31;
|
||||
m.e12 = lhs->e11 * rhs->e12 + lhs->e12 * rhs->e22 + lhs->e13 * rhs->e32;
|
||||
m.e13 = lhs->e11 * rhs->e13 + lhs->e12 * rhs->e23 + lhs->e13 * rhs->e33;
|
||||
|
||||
m.e21 = lhs->e21 * rhs->e11 + lhs->e22 * rhs->e21 + lhs->e23 * rhs->e31;
|
||||
m.e22 = lhs->e21 * rhs->e12 + lhs->e22 * rhs->e22 + lhs->e23 * rhs->e32;
|
||||
m.e23 = lhs->e21 * rhs->e13 + lhs->e22 * rhs->e23 + lhs->e23 * rhs->e33;
|
||||
|
||||
m.e31 = lhs->e31 * rhs->e11 + lhs->e32 * rhs->e21 + lhs->e33 * rhs->e31;
|
||||
m.e32 = lhs->e31 * rhs->e12 + lhs->e32 * rhs->e22 + lhs->e33 * rhs->e32;
|
||||
m.e33 = lhs->e31 * rhs->e13 + lhs->e32 * rhs->e23 + lhs->e33 * rhs->e33;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
void mathRotate(Matrix* m, float degree)
|
||||
{
|
||||
if (degree == 0.0f) return;
|
||||
|
||||
auto radian = degree / 180.0f * M_PI;
|
||||
auto cosVal = cosf(radian);
|
||||
auto sinVal = sinf(radian);
|
||||
|
||||
m->e12 = m->e11 * -sinVal;
|
||||
m->e11 *= cosVal;
|
||||
m->e21 = m->e22 * sinVal;
|
||||
m->e22 *= cosVal;
|
||||
}
|
||||
|
||||
|
||||
bool mathIdentity(const Matrix* m)
|
||||
{
|
||||
if (m->e11 != 1.0f || m->e12 != 0.0f || m->e13 != 0.0f ||
|
||||
m->e21 != 0.0f || m->e22 != 1.0f || m->e23 != 0.0f ||
|
||||
m->e31 != 0.0f || m->e32 != 0.0f || m->e33 != 1.0f) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void mathMultiply(Point* pt, const Matrix* transform)
|
||||
{
|
||||
auto tx = pt->x * transform->e11 + pt->y * transform->e12 + transform->e13;
|
||||
auto ty = pt->x * transform->e21 + pt->y * transform->e22 + transform->e23;
|
||||
pt->x = tx;
|
||||
pt->y = ty;
|
||||
}
|
|
@ -36,6 +36,13 @@
|
|||
#define mathMax(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
|
||||
bool mathInverse(const Matrix* m, Matrix* out);
|
||||
Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs);
|
||||
void mathRotate(Matrix* m, float degree);
|
||||
bool mathIdentity(const Matrix* m);
|
||||
void mathMultiply(Point* pt, const Matrix* transform);
|
||||
|
||||
|
||||
static inline bool mathZero(float a)
|
||||
{
|
||||
return (fabsf(a) < FLT_EPSILON) ? true : false;
|
||||
|
@ -73,41 +80,6 @@ static inline bool mathSkewed(const Matrix* m)
|
|||
}
|
||||
|
||||
|
||||
static inline bool mathIdentity(const Matrix* m)
|
||||
{
|
||||
if (!mathEqual(m->e11, 1.0f) || !mathZero(m->e12) || !mathZero(m->e13) ||
|
||||
!mathZero(m->e21) || !mathEqual(m->e22, 1.0f) || !mathZero(m->e23) ||
|
||||
!mathZero(m->e31) || !mathZero(m->e32) || !mathEqual(m->e33, 1.0f)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline bool mathInverse(const Matrix* m, Matrix* out)
|
||||
{
|
||||
auto det = m->e11 * (m->e22 * m->e33 - m->e32 * m->e23) -
|
||||
m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) +
|
||||
m->e13 * (m->e21 * m->e32 - m->e22 * m->e31);
|
||||
|
||||
if (mathZero(det)) return false;
|
||||
|
||||
auto invDet = 1 / det;
|
||||
|
||||
out->e11 = (m->e22 * m->e33 - m->e32 * m->e23) * invDet;
|
||||
out->e12 = (m->e13 * m->e32 - m->e12 * m->e33) * invDet;
|
||||
out->e13 = (m->e12 * m->e23 - m->e13 * m->e22) * invDet;
|
||||
out->e21 = (m->e23 * m->e31 - m->e21 * m->e33) * invDet;
|
||||
out->e22 = (m->e11 * m->e33 - m->e13 * m->e31) * invDet;
|
||||
out->e23 = (m->e21 * m->e13 - m->e11 * m->e23) * invDet;
|
||||
out->e31 = (m->e21 * m->e32 - m->e31 * m->e22) * invDet;
|
||||
out->e32 = (m->e31 * m->e12 - m->e11 * m->e32) * invDet;
|
||||
out->e33 = (m->e11 * m->e22 - m->e21 * m->e12) * invDet;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline void mathIdentity(Matrix* m)
|
||||
{
|
||||
m->e11 = 1.0f;
|
||||
|
@ -158,48 +130,6 @@ static inline void mathTranslate(Matrix* m, float x, float y)
|
|||
}
|
||||
|
||||
|
||||
static inline void mathRotate(Matrix* m, float degree)
|
||||
{
|
||||
auto radian = degree / 180.0f * M_PI;
|
||||
auto cosVal = cosf(radian);
|
||||
auto sinVal = sinf(radian);
|
||||
|
||||
m->e12 = m->e11 * -sinVal;
|
||||
m->e11 *= cosVal;
|
||||
m->e21 = m->e22 * sinVal;
|
||||
m->e22 *= cosVal;
|
||||
}
|
||||
|
||||
|
||||
static inline void mathMultiply(Point* pt, const Matrix* transform)
|
||||
{
|
||||
auto tx = pt->x * transform->e11 + pt->y * transform->e12 + transform->e13;
|
||||
auto ty = pt->x * transform->e21 + pt->y * transform->e22 + transform->e23;
|
||||
pt->x = tx;
|
||||
pt->y = ty;
|
||||
}
|
||||
|
||||
|
||||
static inline Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs)
|
||||
{
|
||||
Matrix m;
|
||||
|
||||
m.e11 = lhs->e11 * rhs->e11 + lhs->e12 * rhs->e21 + lhs->e13 * rhs->e31;
|
||||
m.e12 = lhs->e11 * rhs->e12 + lhs->e12 * rhs->e22 + lhs->e13 * rhs->e32;
|
||||
m.e13 = lhs->e11 * rhs->e13 + lhs->e12 * rhs->e23 + lhs->e13 * rhs->e33;
|
||||
|
||||
m.e21 = lhs->e21 * rhs->e11 + lhs->e22 * rhs->e21 + lhs->e23 * rhs->e31;
|
||||
m.e22 = lhs->e21 * rhs->e12 + lhs->e22 * rhs->e22 + lhs->e23 * rhs->e32;
|
||||
m.e23 = lhs->e21 * rhs->e13 + lhs->e22 * rhs->e23 + lhs->e23 * rhs->e33;
|
||||
|
||||
m.e31 = lhs->e31 * rhs->e11 + lhs->e32 * rhs->e21 + lhs->e33 * rhs->e31;
|
||||
m.e32 = lhs->e31 * rhs->e12 + lhs->e32 * rhs->e22 + lhs->e33 * rhs->e32;
|
||||
m.e33 = lhs->e31 * rhs->e13 + lhs->e32 * rhs->e23 + lhs->e33 * rhs->e33;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
static inline void mathTranslateR(Matrix* m, float x, float y)
|
||||
{
|
||||
if (x == 0.0f && y == 0.0f) return;
|
|
@ -48,13 +48,9 @@
|
|||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++.
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include "tvgLoader.h"
|
||||
#include "tvgXmlParser.h"
|
||||
#include "tvgSvgLoader.h"
|
||||
|
@ -3508,8 +3504,29 @@ static bool _svgLoaderParserForValidCheck(void* data, SimpleXMLType type, const
|
|||
}
|
||||
|
||||
|
||||
void SvgLoader::clear()
|
||||
void SvgLoader::clear(bool all)
|
||||
{
|
||||
//flush out the intermediate data
|
||||
free(loaderData.svgParse);
|
||||
loaderData.svgParse = nullptr;
|
||||
|
||||
for (auto gradient = loaderData.gradients.data; gradient < loaderData.gradients.end(); ++gradient) {
|
||||
(*gradient)->clear();
|
||||
free(*gradient);
|
||||
}
|
||||
loaderData.gradients.reset();
|
||||
|
||||
_freeNode(loaderData.doc);
|
||||
loaderData.doc = nullptr;
|
||||
loaderData.stack.reset();
|
||||
|
||||
if (!all) return;
|
||||
|
||||
for (auto p = loaderData.images.data; p < loaderData.images.end(); ++p) {
|
||||
free(*p);
|
||||
}
|
||||
loaderData.images.reset();
|
||||
|
||||
if (copy) free((char*)content);
|
||||
size = 0;
|
||||
content = nullptr;
|
||||
|
@ -3561,6 +3578,20 @@ void SvgLoader::run(unsigned tid)
|
|||
if (defs) _updateGradient(&loaderData, loaderData.doc, &defs->node.defs.gradients);
|
||||
}
|
||||
root = svgSceneBuild(loaderData, {vx, vy, vw, vh}, w, h, align, meetOrSlice, svgPath, viewFlag);
|
||||
|
||||
//In case no viewbox and width/height data is provided the completion of loading
|
||||
//has to be forced, in order to establish this data based on the whole picture.
|
||||
if (!(viewFlag & SvgViewFlag::Viewbox)) {
|
||||
//Override viewbox & size again after svg loading.
|
||||
vx = loaderData.doc->node.doc.vx;
|
||||
vy = loaderData.doc->node.doc.vy;
|
||||
vw = loaderData.doc->node.doc.vw;
|
||||
vh = loaderData.doc->node.doc.vh;
|
||||
w = loaderData.doc->node.doc.w;
|
||||
h = loaderData.doc->node.doc.h;
|
||||
}
|
||||
|
||||
clear(false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3630,14 +3661,6 @@ bool SvgLoader::header()
|
|||
}
|
||||
|
||||
run(0);
|
||||
|
||||
//Override viewbox & size again after svg loading.
|
||||
vx = loaderData.doc->node.doc.vx;
|
||||
vy = loaderData.doc->node.doc.vy;
|
||||
vw = loaderData.doc->node.doc.vw;
|
||||
vh = loaderData.doc->node.doc.vh;
|
||||
w = loaderData.doc->node.doc.w;
|
||||
h = loaderData.doc->node.doc.h;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3717,22 +3740,6 @@ bool SvgLoader::close()
|
|||
{
|
||||
this->done();
|
||||
|
||||
if (loaderData.svgParse) {
|
||||
free(loaderData.svgParse);
|
||||
loaderData.svgParse = nullptr;
|
||||
}
|
||||
auto gradients = loaderData.gradients.data;
|
||||
for (size_t i = 0; i < loaderData.gradients.count; ++i) {
|
||||
(*gradients)->clear();
|
||||
free(*gradients);
|
||||
++gradients;
|
||||
}
|
||||
loaderData.gradients.reset();
|
||||
|
||||
_freeNode(loaderData.doc);
|
||||
loaderData.doc = nullptr;
|
||||
loaderData.stack.reset();
|
||||
|
||||
clear();
|
||||
|
||||
return true;
|
||||
|
|
|
@ -61,7 +61,7 @@ private:
|
|||
float vh = 0;
|
||||
|
||||
bool header();
|
||||
void clear();
|
||||
void clear(bool all = true);
|
||||
void run(unsigned tid) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -556,6 +556,7 @@ struct SvgLoaderData
|
|||
SvgParser* svgParse = nullptr;
|
||||
Array<SvgNodeIdPair> cloneNodes;
|
||||
Array<SvgNodeIdPair> nodesToStyle;
|
||||
Array<char*> images; //embedded images
|
||||
int level = 0;
|
||||
bool result = false;
|
||||
bool style = false;
|
||||
|
|
|
@ -20,39 +20,10 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright notice for the EFL:
|
||||
|
||||
* Copyright (C) EFL developers (see AUTHORS)
|
||||
|
||||
* All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "tvgMath.h" /* to include math.h before cstring */
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "tvgShapeImpl.h"
|
||||
#include "tvgShape.h"
|
||||
#include "tvgCompressor.h"
|
||||
#include "tvgPaint.h"
|
||||
#include "tvgFill.h"
|
||||
|
@ -66,9 +37,9 @@
|
|||
/* Internal Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
static bool _appendShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath);
|
||||
static bool _appendClipShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform);
|
||||
static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite = nullptr);
|
||||
static bool _appendShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath);
|
||||
static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform);
|
||||
static unique_ptr<Scene> _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite = nullptr);
|
||||
|
||||
|
||||
static inline bool _isGroupType(SvgNodeType type)
|
||||
|
@ -223,7 +194,7 @@ static unique_ptr<RadialGradient> _applyRadialGradientProperty(SvgStyleGradient*
|
|||
|
||||
|
||||
//The SVG standard allows only for 'use' nodes that point directly to a basic shape.
|
||||
static bool _appendClipUseNode(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath)
|
||||
static bool _appendClipUseNode(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath)
|
||||
{
|
||||
if (node->child.count != 1) return false;
|
||||
auto child = *(node->child.data);
|
||||
|
@ -236,16 +207,16 @@ static bool _appendClipUseNode(SvgNode* node, Shape* shape, const Box& vBox, con
|
|||
}
|
||||
if (child->transform) finalTransform = mathMultiply(child->transform, &finalTransform);
|
||||
|
||||
return _appendClipShape(child, shape, vBox, svgPath, mathIdentity((const Matrix*)(&finalTransform)) ? nullptr : &finalTransform);
|
||||
return _appendClipShape(loaderData, child, shape, vBox, svgPath, mathIdentity((const Matrix*)(&finalTransform)) ? nullptr : &finalTransform);
|
||||
}
|
||||
|
||||
|
||||
static bool _appendClipChild(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, bool clip)
|
||||
static bool _appendClipChild(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, bool clip)
|
||||
{
|
||||
if (node->type == SvgNodeType::Use) {
|
||||
return _appendClipUseNode(node, shape, vBox, svgPath);
|
||||
return _appendClipUseNode(loaderData, node, shape, vBox, svgPath);
|
||||
}
|
||||
return _appendClipShape(node, shape, vBox, svgPath, nullptr);
|
||||
return _appendClipShape(loaderData, node, shape, vBox, svgPath, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -269,7 +240,7 @@ static Matrix _compositionTransform(Paint* paint, const SvgNode* node, const Svg
|
|||
}
|
||||
|
||||
|
||||
static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox, const string& svgPath)
|
||||
static void _applyComposition(SvgLoaderData& loaderData, Paint* paint, const SvgNode* node, const Box& vBox, const string& svgPath)
|
||||
{
|
||||
/* ClipPath */
|
||||
/* Do not drop in Circular Dependency for ClipPath.
|
||||
|
@ -287,7 +258,7 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
|
|||
auto valid = false; //Composite only when valid shapes exist
|
||||
|
||||
for (uint32_t i = 0; i < compNode->child.count; ++i, ++child) {
|
||||
if (_appendClipChild(*child, comp.get(), vBox, svgPath, compNode->child.count > 1)) valid = true;
|
||||
if (_appendClipChild(loaderData, *child, comp.get(), vBox, svgPath, compNode->child.count > 1)) valid = true;
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
|
@ -312,7 +283,7 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
|
|||
node->style->mask.applying = true;
|
||||
|
||||
bool isMaskWhite = true;
|
||||
if (auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true, 0, &isMaskWhite)) {
|
||||
if (auto comp = _sceneBuildHelper(loaderData, compNode, vBox, svgPath, true, 0, &isMaskWhite)) {
|
||||
Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::Mask);
|
||||
comp->transform(finalTransform);
|
||||
|
||||
|
@ -329,7 +300,7 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
|
|||
}
|
||||
|
||||
|
||||
static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const string& svgPath, bool clip)
|
||||
static void _applyProperty(SvgLoaderData& loaderData, SvgNode* node, Shape* vg, const Box& vBox, const string& svgPath, bool clip)
|
||||
{
|
||||
SvgStyleProperty* style = node->style;
|
||||
|
||||
|
@ -404,14 +375,14 @@ static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const stri
|
|||
vg->stroke(style->stroke.paint.color.r, style->stroke.paint.color.g, style->stroke.paint.color.b, style->stroke.opacity);
|
||||
}
|
||||
|
||||
_applyComposition(vg, node, vBox, svgPath);
|
||||
_applyComposition(loaderData, vg, node, vBox, svgPath);
|
||||
}
|
||||
|
||||
|
||||
static unique_ptr<Shape> _shapeBuildHelper(SvgNode* node, const Box& vBox, const string& svgPath)
|
||||
static unique_ptr<Shape> _shapeBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const Box& vBox, const string& svgPath)
|
||||
{
|
||||
auto shape = Shape::gen();
|
||||
if (_appendShape(node, shape.get(), vBox, svgPath)) return shape;
|
||||
if (_appendShape(loaderData, node, shape.get(), vBox, svgPath)) return shape;
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
|
@ -473,16 +444,16 @@ static bool _recognizeShape(SvgNode* node, Shape* shape)
|
|||
}
|
||||
|
||||
|
||||
static bool _appendShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath)
|
||||
static bool _appendShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath)
|
||||
{
|
||||
if (!_recognizeShape(node, shape)) return false;
|
||||
|
||||
_applyProperty(node, shape, vBox, svgPath, false);
|
||||
_applyProperty(loaderData, node, shape, vBox, svgPath, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool _appendClipShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform)
|
||||
static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform)
|
||||
{
|
||||
//The 'transform' matrix has higher priority than the node->transform, since it already contains it
|
||||
auto m = transform ? transform : (node->transform ? node->transform : nullptr);
|
||||
|
@ -503,7 +474,7 @@ static bool _appendClipShape(SvgNode* node, Shape* shape, const Box& vBox, const
|
|||
while (currentPtsCnt++ < ptsCnt) mathMultiply(p++, m);
|
||||
}
|
||||
|
||||
_applyProperty(node, shape, vBox, svgPath, true);
|
||||
_applyProperty(loaderData, node, shape, vBox, svgPath, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -581,7 +552,7 @@ static bool _isValidImageMimeTypeAndEncoding(const char** href, const char** mim
|
|||
|
||||
#include "tvgTaskScheduler.h"
|
||||
|
||||
static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, const Box& vBox, const string& svgPath)
|
||||
static unique_ptr<Picture> _imageBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const Box& vBox, const string& svgPath)
|
||||
{
|
||||
if (!node->node.image.href) return nullptr;
|
||||
auto picture = Picture::gen();
|
||||
|
@ -594,24 +565,23 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, const Box& vBox, con
|
|||
const char* mimetype;
|
||||
imageMimeTypeEncoding encoding;
|
||||
if (!_isValidImageMimeTypeAndEncoding(&href, &mimetype, &encoding)) return nullptr; //not allowed mime type or encoding
|
||||
char *decoded = nullptr;
|
||||
if (encoding == imageMimeTypeEncoding::base64) {
|
||||
char* decoded = nullptr;
|
||||
auto size = b64Decode(href, strlen(href), &decoded);
|
||||
//OPTIMIZE: Skip data copy.
|
||||
if (picture->load(decoded, size, mimetype, true) != Result::Success) {
|
||||
if (picture->load(decoded, size, mimetype, false) != Result::Success) {
|
||||
free(decoded);
|
||||
TaskScheduler::async(true);
|
||||
return nullptr;
|
||||
}
|
||||
free(decoded);
|
||||
} else {
|
||||
string decoded = svgUtilURLDecode(href);
|
||||
//OPTIMIZE: Skip data copy.
|
||||
if (picture->load(decoded.c_str(), decoded.size(), mimetype, true) != Result::Success) {
|
||||
auto size = svgUtilURLDecode(href, &decoded);
|
||||
if (picture->load(decoded, size, mimetype, false) != Result::Success) {
|
||||
free(decoded);
|
||||
TaskScheduler::async(true);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
loaderData.images.push(decoded);
|
||||
} else {
|
||||
if (!strncmp(href, "file://", sizeof("file://") - 1)) href += sizeof("file://") - 1;
|
||||
//TODO: protect against recursive svg image loading
|
||||
|
@ -645,7 +615,8 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, const Box& vBox, con
|
|||
if (node->transform) m = mathMultiply(node->transform, &m);
|
||||
picture->transform(m);
|
||||
|
||||
_applyComposition(picture.get(), node, vBox, svgPath);
|
||||
_applyComposition(loaderData, picture.get(), node, vBox, svgPath);
|
||||
|
||||
return picture;
|
||||
}
|
||||
|
||||
|
@ -724,10 +695,10 @@ static Matrix _calculateAspectRatioMatrix(AspectRatioAlign align, AspectRatioMee
|
|||
}
|
||||
|
||||
|
||||
static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, int depth, bool* isMaskWhite)
|
||||
static unique_ptr<Scene> _useBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, int depth, bool* isMaskWhite)
|
||||
{
|
||||
unique_ptr<Scene> finalScene;
|
||||
auto scene = _sceneBuildHelper(node, vBox, svgPath, false, depth + 1, isMaskWhite);
|
||||
auto scene = _sceneBuildHelper(loaderData, node, vBox, svgPath, false, depth + 1, isMaskWhite);
|
||||
|
||||
// mUseTransform = mUseTransform * mTranslate
|
||||
Matrix mUseTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
|
||||
|
@ -786,7 +757,7 @@ static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, c
|
|||
finalScene = std::move(root);
|
||||
}
|
||||
} else {
|
||||
if (!mathIdentity((const Matrix*)(&mUseTransform))) scene->transform(mUseTransform);
|
||||
scene->transform(mUseTransform);
|
||||
finalScene = std::move(scene);
|
||||
}
|
||||
|
||||
|
@ -794,7 +765,7 @@ static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, c
|
|||
}
|
||||
|
||||
|
||||
static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite)
|
||||
static unique_ptr<Scene> _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite)
|
||||
{
|
||||
/* Exception handling: Prevent invalid SVG data input.
|
||||
The size is the arbitrary value, we need an experimental size. */
|
||||
|
@ -813,17 +784,17 @@ static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox,
|
|||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
||||
if (_isGroupType((*child)->type)) {
|
||||
if ((*child)->type == SvgNodeType::Use)
|
||||
scene->push(_useBuildHelper(*child, vBox, svgPath, depth + 1, isMaskWhite));
|
||||
scene->push(_useBuildHelper(loaderData, *child, vBox, svgPath, depth + 1, isMaskWhite));
|
||||
else
|
||||
scene->push(_sceneBuildHelper(*child, vBox, svgPath, false, depth + 1, isMaskWhite));
|
||||
scene->push(_sceneBuildHelper(loaderData, *child, vBox, svgPath, false, depth + 1, isMaskWhite));
|
||||
} else if ((*child)->type == SvgNodeType::Image) {
|
||||
auto image = _imageBuildHelper(*child, vBox, svgPath);
|
||||
auto image = _imageBuildHelper(loaderData, *child, vBox, svgPath);
|
||||
if (image) {
|
||||
scene->push(std::move(image));
|
||||
if (isMaskWhite) *isMaskWhite = false;
|
||||
}
|
||||
} else if ((*child)->type != SvgNodeType::Mask) {
|
||||
auto shape = _shapeBuildHelper(*child, vBox, svgPath);
|
||||
auto shape = _shapeBuildHelper(loaderData, *child, vBox, svgPath);
|
||||
if (shape) {
|
||||
if (isMaskWhite) {
|
||||
uint8_t r, g, b;
|
||||
|
@ -837,7 +808,7 @@ static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox,
|
|||
}
|
||||
}
|
||||
}
|
||||
_applyComposition(scene.get(), node, vBox, svgPath);
|
||||
_applyComposition(loaderData, scene.get(), node, vBox, svgPath);
|
||||
scene->opacity(node->style->opacity);
|
||||
}
|
||||
return scene;
|
||||
|
@ -876,7 +847,7 @@ unique_ptr<Scene> svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, fl
|
|||
|
||||
if (!loaderData.doc || (loaderData.doc->type != SvgNodeType::Doc)) return nullptr;
|
||||
|
||||
auto docNode = _sceneBuildHelper(loaderData.doc, vBox, svgPath, false, 0);
|
||||
auto docNode = _sceneBuildHelper(loaderData, loaderData.doc, vBox, svgPath, false, 0);
|
||||
|
||||
if (!(viewFlag & SvgViewFlag::Viewbox)) _updateInvalidViewSize(docNode.get(), vBox, w, h, viewFlag);
|
||||
|
||||
|
|
21
thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
vendored
21
thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
vendored
|
@ -39,29 +39,32 @@ static uint8_t _hexCharToDec(const char c)
|
|||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
string svgUtilURLDecode(const char *src)
|
||||
size_t svgUtilURLDecode(const char *src, char** dst)
|
||||
{
|
||||
if (!src) return nullptr;
|
||||
if (!src) return 0;
|
||||
|
||||
auto length = strlen(src);
|
||||
if (length == 0) return nullptr;
|
||||
if (length == 0) return 0;
|
||||
|
||||
string decoded;
|
||||
decoded.reserve(length);
|
||||
char* decoded = (char*)malloc(sizeof(char) * length + 1);
|
||||
decoded[length] = '\0';
|
||||
|
||||
char a, b;
|
||||
int idx =0;
|
||||
while (*src) {
|
||||
if (*src == '%' &&
|
||||
((a = src[1]) && (b = src[2])) &&
|
||||
(isxdigit(a) && isxdigit(b))) {
|
||||
decoded += (_hexCharToDec(a) << 4) + _hexCharToDec(b);
|
||||
decoded[idx++] = (_hexCharToDec(a) << 4) + _hexCharToDec(b);
|
||||
src+=3;
|
||||
} else if (*src == '+') {
|
||||
decoded += ' ';
|
||||
decoded[idx++] = ' ';
|
||||
src++;
|
||||
} else {
|
||||
decoded += *src++;
|
||||
decoded[idx++] = *src++;
|
||||
}
|
||||
}
|
||||
return decoded;
|
||||
|
||||
*dst = decoded;
|
||||
return length + 1;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,6 @@
|
|||
|
||||
#include "tvgCommon.h"
|
||||
|
||||
string svgUtilURLDecode(const char *src);
|
||||
size_t svgUtilURLDecode(const char *src, char** dst);
|
||||
|
||||
#endif //_TVG_SVG_UTIL_H_
|
||||
|
|
|
@ -273,6 +273,7 @@ struct SwMpool
|
|||
{
|
||||
SwOutline* outline;
|
||||
SwOutline* strokeOutline;
|
||||
SwOutline* dashOutline;
|
||||
unsigned allocSize;
|
||||
};
|
||||
|
||||
|
@ -544,6 +545,8 @@ SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx);
|
|||
void mpoolRetOutline(SwMpool* mpool, unsigned idx);
|
||||
SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx);
|
||||
void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx);
|
||||
SwOutline* mpoolReqDashOutline(SwMpool* mpool, unsigned idx);
|
||||
void mpoolRetDashOutline(SwMpool* mpool, unsigned idx);
|
||||
|
||||
bool rasterCompositor(SwSurface* surface);
|
||||
bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id);
|
|
@ -48,7 +48,7 @@ static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix* tr
|
|||
if (mesh->triangleCnt > 0) {
|
||||
// TODO: Optimise me. We appear to calculate this exact min/max bounding area in multiple
|
||||
// places. We should be able to re-use one we have already done? Also see:
|
||||
// tvgPictureImpl.h --> bounds
|
||||
// tvgPicture.h --> bounds
|
||||
// tvgSwRasterTexmap.h --> _rasterTexmapPolygonMesh
|
||||
//
|
||||
// TODO: Should we calculate the exact path(s) of the triangle mesh instead?
|
|
@ -62,54 +62,52 @@ void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx)
|
|||
}
|
||||
|
||||
|
||||
SwOutline* mpoolReqDashOutline(SwMpool* mpool, unsigned idx)
|
||||
{
|
||||
return &mpool->dashOutline[idx];
|
||||
}
|
||||
|
||||
|
||||
void mpoolRetDashOutline(SwMpool* mpool, unsigned idx)
|
||||
{
|
||||
mpool->dashOutline[idx].pts.clear();
|
||||
mpool->dashOutline[idx].cntrs.clear();
|
||||
mpool->dashOutline[idx].types.clear();
|
||||
mpool->dashOutline[idx].closed.clear();
|
||||
}
|
||||
|
||||
|
||||
SwMpool* mpoolInit(unsigned threads)
|
||||
{
|
||||
auto allocSize = threads + 1;
|
||||
|
||||
auto mpool = static_cast<SwMpool*>(calloc(sizeof(SwMpool), 1));
|
||||
mpool->outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline) * allocSize));
|
||||
if (!mpool->outline) goto err;
|
||||
|
||||
mpool->strokeOutline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline) * allocSize));
|
||||
if (!mpool->strokeOutline) goto err;
|
||||
|
||||
mpool->dashOutline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline) * allocSize));
|
||||
mpool->allocSize = allocSize;
|
||||
|
||||
return mpool;
|
||||
|
||||
err:
|
||||
if (mpool->outline) {
|
||||
free(mpool->outline);
|
||||
mpool->outline = nullptr;
|
||||
}
|
||||
|
||||
if (mpool->strokeOutline) {
|
||||
free(mpool->strokeOutline);
|
||||
mpool->strokeOutline = nullptr;
|
||||
}
|
||||
free(mpool);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool mpoolClear(SwMpool* mpool)
|
||||
{
|
||||
SwOutline* p;
|
||||
|
||||
for (unsigned i = 0; i < mpool->allocSize; ++i) {
|
||||
//Outline
|
||||
p = &mpool->outline[i];
|
||||
p->pts.reset();
|
||||
p->cntrs.reset();
|
||||
p->types.reset();
|
||||
p->closed.reset();
|
||||
mpool->outline[i].pts.reset();
|
||||
mpool->outline[i].cntrs.reset();
|
||||
mpool->outline[i].types.reset();
|
||||
mpool->outline[i].closed.reset();
|
||||
|
||||
//StrokeOutline
|
||||
p = &mpool->strokeOutline[i];
|
||||
p->pts.reset();
|
||||
p->cntrs.reset();
|
||||
p->types.reset();
|
||||
p->closed.reset();
|
||||
mpool->strokeOutline[i].pts.reset();
|
||||
mpool->strokeOutline[i].cntrs.reset();
|
||||
mpool->strokeOutline[i].types.reset();
|
||||
mpool->strokeOutline[i].closed.reset();
|
||||
|
||||
mpool->dashOutline[i].pts.reset();
|
||||
mpool->dashOutline[i].cntrs.reset();
|
||||
mpool->dashOutline[i].types.reset();
|
||||
mpool->dashOutline[i].closed.reset();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -122,16 +120,9 @@ bool mpoolTerm(SwMpool* mpool)
|
|||
|
||||
mpoolClear(mpool);
|
||||
|
||||
if (mpool->outline) {
|
||||
free(mpool->outline);
|
||||
mpool->outline = nullptr;
|
||||
}
|
||||
|
||||
if (mpool->strokeOutline) {
|
||||
free(mpool->strokeOutline);
|
||||
mpool->strokeOutline = nullptr;
|
||||
}
|
||||
|
||||
free(mpool->outline);
|
||||
free(mpool->strokeOutline);
|
||||
free(mpool->dashOutline);
|
||||
free(mpool);
|
||||
|
||||
return true;
|
|
@ -2024,11 +2024,11 @@ bool rasterConvertCS(Surface* surface, ColorSpace to)
|
|||
//TOOD: Support SIMD accelerations
|
||||
auto from = surface->cs;
|
||||
|
||||
if ((from == ColorSpace::ABGR8888 && to == ColorSpace::ARGB8888) || (from == ColorSpace::ABGR8888S && to == ColorSpace::ARGB8888S)) {
|
||||
if (((from == ColorSpace::ABGR8888) || (from == ColorSpace::ABGR8888S)) && ((to == ColorSpace::ARGB8888) || (to == ColorSpace::ARGB8888S))) {
|
||||
surface->cs = to;
|
||||
return cRasterABGRtoARGB(surface);
|
||||
}
|
||||
if ((from == ColorSpace::ARGB8888 && to == ColorSpace::ABGR8888) || (from == ColorSpace::ARGB8888S && to == ColorSpace::ABGR8888S)) {
|
||||
if (((from == ColorSpace::ARGB8888) || (from == ColorSpace::ARGB8888S)) && ((to == ColorSpace::ABGR8888) || (to == ColorSpace::ABGR8888S))) {
|
||||
surface->cs = to;
|
||||
return cRasterARGBtoABGR(surface);
|
||||
}
|
|
@ -742,6 +742,12 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform,
|
|||
task->transform = nullptr;
|
||||
}
|
||||
|
||||
//zero size?
|
||||
if (task->transform) {
|
||||
if (task->transform->e11 == 0.0f && task->transform->e12 == 0.0f) return task; //zero width
|
||||
if (task->transform->e21 == 0.0f && task->transform->e22 == 0.0f) return task; //zero height
|
||||
}
|
||||
|
||||
task->opacity = opacity;
|
||||
task->surface = surface;
|
||||
task->mpool = mpool;
|
||||
|
@ -767,10 +773,8 @@ RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderD
|
|||
//prepare task
|
||||
auto task = static_cast<SwImageTask*>(data);
|
||||
if (!task) task = new SwImageTask;
|
||||
if (flags & RenderUpdateFlag::Image) {
|
||||
task->source = surface;
|
||||
task->mesh = mesh;
|
||||
}
|
||||
task->source = surface;
|
||||
task->mesh = mesh;
|
||||
return prepareCommon(task, transform, clips, opacity, flags);
|
||||
}
|
||||
|
|
@ -212,7 +212,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
|
|||
}
|
||||
|
||||
|
||||
static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* transform, float length)
|
||||
static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* transform, float length, SwMpool* mpool, unsigned tid)
|
||||
{
|
||||
const PathCommand* cmds = rshape->path.cmds.data;
|
||||
auto cmdCnt = rshape->path.cmds.count;
|
||||
|
@ -283,8 +283,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
|
|||
}
|
||||
}
|
||||
|
||||
//OPTMIZE ME: Use mempool???
|
||||
dash.outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline)));
|
||||
dash.outline = mpoolReqDashOutline(mpool, tid);
|
||||
|
||||
//smart reservation
|
||||
auto closeCnt = 0;
|
||||
|
@ -567,16 +566,16 @@ bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix*
|
|||
{
|
||||
SwOutline* shapeOutline = nullptr;
|
||||
SwOutline* strokeOutline = nullptr;
|
||||
bool freeOutline = false;
|
||||
bool ret = true;
|
||||
auto dashStroking = false;
|
||||
auto ret = true;
|
||||
|
||||
auto length = rshape->strokeTrim() ? _outlineLength(rshape) : 0.0f;
|
||||
|
||||
//Dash style (+trimming)
|
||||
if (rshape->stroke->dashCnt > 0 || length > 0) {
|
||||
shapeOutline = _genDashOutline(rshape, transform, length);
|
||||
shapeOutline = _genDashOutline(rshape, transform, length, mpool, tid);
|
||||
if (!shapeOutline) return false;
|
||||
freeOutline = true;
|
||||
dashStroking = true;
|
||||
//Normal style
|
||||
} else {
|
||||
if (!shape->outline) {
|
||||
|
@ -587,26 +586,20 @@ bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix*
|
|||
|
||||
if (!strokeParseOutline(shape->stroke, *shapeOutline)) {
|
||||
ret = false;
|
||||
goto fail;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
strokeOutline = strokeExportOutline(shape->stroke, mpool, tid);
|
||||
|
||||
if (!mathUpdateOutlineBBox(strokeOutline, clipRegion, renderRegion, false)) {
|
||||
ret = false;
|
||||
goto fail;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
shape->strokeRle = rleRender(shape->strokeRle, strokeOutline, renderRegion, true);
|
||||
|
||||
fail:
|
||||
if (freeOutline) {
|
||||
free(shapeOutline->cntrs.data);
|
||||
free(shapeOutline->pts.data);
|
||||
free(shapeOutline->types.data);
|
||||
free(shapeOutline->closed.data);
|
||||
free(shapeOutline);
|
||||
}
|
||||
clear:
|
||||
if (dashStroking) mpoolRetDashOutline(mpool, tid);
|
||||
mpoolRetStrokeOutline(mpool, tid);
|
||||
|
||||
return ret;
|
|
@ -373,6 +373,10 @@ void _firstSubPath(SwStroke& stroke, SwFixed startAngle, SwFixed lineLength)
|
|||
static void _lineTo(SwStroke& stroke, const SwPoint& to)
|
||||
{
|
||||
auto delta = to - stroke.center;
|
||||
|
||||
//a zero-length lineto is a no-op; avoid creating a spurious corner
|
||||
if (delta.zero()) return;
|
||||
|
||||
//compute length of line
|
||||
auto angle = mathAtan(delta);
|
||||
|
|
@ -20,11 +20,10 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
//#include "tvgAnimationImpl.h"
|
||||
#include "tvgCommon.h"
|
||||
#include "tvgFrameModule.h"
|
||||
#include "tvgPaint.h"
|
||||
#include "tvgPictureImpl.h"
|
||||
#include "tvgPicture.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* Internal Class Implementation */
|
||||
|
@ -37,12 +36,12 @@ struct Animation::Impl
|
|||
Impl()
|
||||
{
|
||||
picture = Picture::gen().release();
|
||||
static_cast<Paint*>(picture)->pImpl->ref();
|
||||
PP(picture)->ref();
|
||||
}
|
||||
|
||||
~Impl()
|
||||
{
|
||||
if (static_cast<Paint*>(picture)->pImpl->unref() == 0) {
|
||||
if (PP(picture)->unref() == 0) {
|
||||
delete(picture);
|
||||
}
|
||||
}
|
|
@ -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 "001000" //Major 00, Minor 10, Micro 00
|
||||
#define TVG_HEADER_VERSION "001100" //Major 00, Minor 11, 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
|
||||
|
@ -82,6 +82,7 @@ using TvgBinFlag = TvgBinByte;
|
|||
#define TVG_TAG_SHAPE_STROKE_DASHPTRN (TvgBinTag)0x55
|
||||
#define TVG_TAG_SHAPE_STROKE_MITERLIMIT (TvgBinTag)0x56
|
||||
#define TVG_TAG_SHAPE_STROKE_ORDER (TvgBinTag)0x57
|
||||
#define TVG_TAG_SHAPE_STROKE_DASH_OFFSET (TvgBinTag)0x58
|
||||
|
||||
|
||||
//Fill
|
||||
|
@ -90,7 +91,7 @@ using TvgBinFlag = TvgBinByte;
|
|||
#define TVG_TAG_FILL_COLORSTOPS (TvgBinTag)0x62
|
||||
#define TVG_TAG_FILL_FILLSPREAD (TvgBinTag)0x63
|
||||
#define TVG_TAG_FILL_TRANSFORM (TvgBinTag)0x64
|
||||
|
||||
#define TVG_TAG_FILL_RADIAL_GRADIENT_FOCAL (TvgBinTag)0x65
|
||||
|
||||
//Picture
|
||||
#define TVG_TAG_PICTURE_RAW_IMAGE (TvgBinTag)0x70
|
|
@ -20,7 +20,7 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tvgCanvasImpl.h"
|
||||
#include "tvgCanvas.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* External Class Implementation */
|
|
@ -53,6 +53,7 @@ struct Canvas::Impl
|
|||
|
||||
auto p = paint.release();
|
||||
if (!p) return Result::MemoryCorruption;
|
||||
PP(p)->ref();
|
||||
paints.push_back(p);
|
||||
|
||||
return update(p, true);
|
||||
|
@ -64,14 +65,15 @@ struct Canvas::Impl
|
|||
if (!renderer || !renderer->clear()) return Result::InsufficientCondition;
|
||||
|
||||
//Free paints
|
||||
for (auto paint : paints) {
|
||||
if (paint->pImpl->dispose(*renderer)) {
|
||||
if (free && paint->pImpl->unref() == 0) delete(paint);
|
||||
}
|
||||
if (free) {
|
||||
for (auto paint : paints) {
|
||||
P(paint)->unref();
|
||||
if (paint->pImpl->dispose(*renderer) && P(paint)->refCnt == 0) {
|
||||
delete(paint);
|
||||
}
|
||||
}
|
||||
paints.clear();
|
||||
}
|
||||
|
||||
paints.clear();
|
||||
|
||||
drawing = false;
|
||||
|
||||
return Result::Success;
|
|
@ -20,7 +20,7 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tvgCanvasImpl.h"
|
||||
#include "tvgCanvas.h"
|
||||
|
||||
#ifdef THORVG_GL_RASTER_SUPPORT
|
||||
#include "tvgGlRenderer.h"
|
|
@ -220,7 +220,7 @@ shared_ptr<LoadModule> LoaderMgr::loader(const char* data, uint32_t size, const
|
|||
if (loader->open(data, size, copy)) {
|
||||
return shared_ptr<LoadModule>(loader);
|
||||
} else {
|
||||
TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported. Will try again with other types.", mimeType.c_str());
|
||||
TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str());
|
||||
delete(loader);
|
||||
}
|
||||
}
|
|
@ -132,7 +132,7 @@ bool Paint::Impl::scale(float factor)
|
|||
if (rTransform) {
|
||||
if (mathEqual(factor, rTransform->scale)) return true;
|
||||
} else {
|
||||
if (mathZero(factor)) return true;
|
||||
if (mathEqual(factor, 1.0f)) return true;
|
||||
rTransform = new RenderTransform();
|
||||
}
|
||||
rTransform->scale = factor;
|
|
@ -24,7 +24,7 @@
|
|||
#define _TVG_PAINT_H_
|
||||
|
||||
#include "tvgRender.h"
|
||||
|
||||
#include "tvgMath.h"
|
||||
|
||||
namespace tvg
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ namespace tvg
|
|||
uint8_t ctxFlag = ContextFlag::Invalid;
|
||||
uint8_t id;
|
||||
uint8_t opacity = 255;
|
||||
uint8_t refCnt = 1;
|
||||
uint8_t refCnt = 0;
|
||||
|
||||
~Impl()
|
||||
{
|
||||
|
@ -100,6 +100,7 @@ namespace tvg
|
|||
bool transform(const Matrix& m)
|
||||
{
|
||||
if (!rTransform) {
|
||||
if (mathIdentity(&m)) return true;
|
||||
rTransform = new RenderTransform();
|
||||
if (!rTransform) return false;
|
||||
}
|
|
@ -20,7 +20,40 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tvgPictureImpl.h"
|
||||
#include "tvgPicture.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* Internal Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
RenderUpdateFlag Picture::Impl::load()
|
||||
{
|
||||
if (loader) {
|
||||
if (!paint) {
|
||||
if (auto p = loader->paint()) {
|
||||
paint = p.release();
|
||||
loader->close();
|
||||
if (w != loader->w || h != loader->h) {
|
||||
if (!resizing) {
|
||||
w = loader->w;
|
||||
h = loader->h;
|
||||
}
|
||||
loader->resize(paint, w, h);
|
||||
resizing = false;
|
||||
}
|
||||
if (paint) return RenderUpdateFlag::None;
|
||||
}
|
||||
} else loader->sync();
|
||||
|
||||
if (!surface) {
|
||||
if ((surface = loader->bitmap().release())) {
|
||||
loader->close();
|
||||
return RenderUpdateFlag::Image;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RenderUpdateFlag::None;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* External Class Implementation */
|
||||
|
@ -97,23 +130,6 @@ Result Picture::size(float* w, float* h) const noexcept
|
|||
}
|
||||
|
||||
|
||||
const uint32_t* Picture::data(uint32_t* w, uint32_t* h) const noexcept
|
||||
{
|
||||
//Try it, If not loaded yet.
|
||||
pImpl->load();
|
||||
|
||||
if (pImpl->loader) {
|
||||
if (w) *w = static_cast<uint32_t>(pImpl->loader->w);
|
||||
if (h) *h = static_cast<uint32_t>(pImpl->loader->h);
|
||||
} else {
|
||||
if (w) *w = 0;
|
||||
if (h) *h = 0;
|
||||
}
|
||||
if (pImpl->surface) return pImpl->surface->buf32;
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Result Picture::mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept
|
||||
{
|
||||
if (!triangles && triangleCnt > 0) return Result::InvalidArguments;
|
|
@ -89,35 +89,6 @@ struct Picture::Impl
|
|||
return true;
|
||||
}
|
||||
|
||||
RenderUpdateFlag load()
|
||||
{
|
||||
if (loader) {
|
||||
if (!paint) {
|
||||
if (auto p = loader->paint()) {
|
||||
paint = p.release();
|
||||
loader->close();
|
||||
if (w != loader->w || h != loader->h) {
|
||||
if (!resizing) {
|
||||
w = loader->w;
|
||||
h = loader->h;
|
||||
}
|
||||
loader->resize(paint, w, h);
|
||||
resizing = false;
|
||||
}
|
||||
if (paint) return RenderUpdateFlag::None;
|
||||
}
|
||||
} else loader->sync();
|
||||
|
||||
if (!surface) {
|
||||
if ((surface = loader->bitmap().release())) {
|
||||
loader->close();
|
||||
return RenderUpdateFlag::Image;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RenderUpdateFlag::None;
|
||||
}
|
||||
|
||||
RenderTransform resizeTransform(const RenderTransform* pTransform)
|
||||
{
|
||||
//Overriding Transformation by the desired image size
|
||||
|
@ -317,6 +288,24 @@ struct Picture::Impl
|
|||
load();
|
||||
return new PictureIterator(paint);
|
||||
}
|
||||
|
||||
uint32_t* data(uint32_t* w, uint32_t* h)
|
||||
{
|
||||
//Try it, If not loaded yet.
|
||||
load();
|
||||
|
||||
if (loader) {
|
||||
if (w) *w = static_cast<uint32_t>(loader->w);
|
||||
if (h) *h = static_cast<uint32_t>(loader->h);
|
||||
} else {
|
||||
if (w) *w = 0;
|
||||
if (h) *h = 0;
|
||||
}
|
||||
if (surface) return surface->buf32;
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
RenderUpdateFlag load();
|
||||
};
|
||||
|
||||
#endif //_TVG_PICTURE_IMPL_H_
|
|
@ -35,12 +35,7 @@
|
|||
void RenderTransform::override(const Matrix& m)
|
||||
{
|
||||
this->m = m;
|
||||
|
||||
if (m.e11 == 0.0f && m.e12 == 0.0f && m.e13 == 0.0f &&
|
||||
m.e21 == 0.0f && m.e22 == 0.0f && m.e23 == 0.0f &&
|
||||
m.e31 == 0.0f && m.e32 == 0.0f && m.e33 == 0.0f) {
|
||||
overriding = false;
|
||||
} else overriding = true;
|
||||
overriding = true;
|
||||
}
|
||||
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tvgSceneImpl.h"
|
||||
#include "tvgScene.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* External Class Implementation */
|
||||
|
@ -55,6 +55,7 @@ Result Scene::push(unique_ptr<Paint> paint) noexcept
|
|||
{
|
||||
auto p = paint.release();
|
||||
if (!p) return Result::MemoryCorruption;
|
||||
PP(p)->ref();
|
||||
pImpl->paints.push_back(p);
|
||||
|
||||
return Result::Success;
|
|
@ -220,7 +220,9 @@ struct Scene::Impl
|
|||
auto dup = ret.get()->pImpl;
|
||||
|
||||
for (auto paint : paints) {
|
||||
dup->paints.push_back(paint->duplicate());
|
||||
auto cdup = paint->duplicate();
|
||||
P(cdup)->ref();
|
||||
dup->paints.push_back(cdup);
|
||||
}
|
||||
|
||||
return ret.release();
|
||||
|
@ -231,8 +233,8 @@ struct Scene::Impl
|
|||
auto dispose = renderer ? true : false;
|
||||
|
||||
for (auto paint : paints) {
|
||||
if (dispose) free &= paint->pImpl->dispose(*renderer);
|
||||
if (free) delete(paint);
|
||||
if (dispose) free &= P(paint)->dispose(*renderer);
|
||||
if (P(paint)->unref() == 0 && free) delete(paint);
|
||||
}
|
||||
paints.clear();
|
||||
renderer = nullptr;
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "tvgMath.h"
|
||||
#include "tvgShapeImpl.h"
|
||||
#include "tvgShape.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* Internal Class Implementation */
|
|
@ -20,7 +20,7 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tvgCanvasImpl.h"
|
||||
#include "tvgCanvas.h"
|
||||
|
||||
#ifdef THORVG_SW_RASTER_SUPPORT
|
||||
#include "tvgSwRenderer.h"
|
33
thirdparty/thorvg/update-thorvg.sh
vendored
33
thirdparty/thorvg/update-thorvg.sh
vendored
|
@ -1,14 +1,25 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
VERSION=0.10.7
|
||||
VERSION=0.11.0
|
||||
|
||||
cd thirdparty/thorvg/ || true
|
||||
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/
|
||||
|
||||
mkdir tmp/ && pushd tmp/
|
||||
|
||||
# Release
|
||||
curl -L -O https://github.com/thorvg/thorvg/archive/v$VERSION.tar.gz
|
||||
# Current Github main branch tip
|
||||
#curl -L -O https://github.com/thorvg/thorvg/archive/refs/heads/main.tar.gz
|
||||
|
||||
tar --strip-components=1 -xvf *.tar.gz
|
||||
rm *.tar.gz
|
||||
|
||||
# Install from local git checkout "thorvg-git" in the same directory
|
||||
# as godot git checkout.
|
||||
#d="../../../../thorvg-git"
|
||||
#cp -r ${d}/AUTHORS ${d}/inc ${d}/LICENSE ${d}/src .
|
||||
|
||||
find . -type f -name 'meson.build' -delete
|
||||
|
||||
# Fix newline at end of file.
|
||||
|
@ -24,24 +35,26 @@ cat << EOF > ../inc/config.h
|
|||
#define THORVG_CONFIG_H
|
||||
|
||||
#define THORVG_SW_RASTER_SUPPORT
|
||||
|
||||
#define THORVG_SVG_LOADER_SUPPORT
|
||||
|
||||
// For internal debugging:
|
||||
//#define THORVG_LOG_ENABLED
|
||||
|
||||
#define THORVG_VERSION_STRING "$VERSION"
|
||||
#endif
|
||||
EOF
|
||||
|
||||
mkdir ../src
|
||||
cp -rv src/lib src/utils ../src/
|
||||
# Only sw_engine is enabled.
|
||||
rm -rfv ../src/lib/gl_engine
|
||||
cp -rv src/common ../src
|
||||
cp -rv src/renderer ../src/
|
||||
|
||||
# Only svg loader is enabled.
|
||||
# Only sw_engine is enabled.
|
||||
rm -rfv ../src/renderer/gl_engine
|
||||
|
||||
# Only svg (+raw) loader is enabled.
|
||||
mkdir ../src/loaders
|
||||
cp -rv src/loaders/svg src/loaders/raw ../src/loaders/
|
||||
|
||||
# Future versions
|
||||
# cp -rv src/utils ../src
|
||||
|
||||
popd
|
||||
rm -rf tmp/
|
||||
rm -rf tmp
|
||||
|
||||
|
|
Loading…
Reference in a new issue