ThorVG: Sync with upstream 0.7.1
Changes: https://github.com/Samsung/thorvg/releases/tag/v0.7.1
This commit is contained in:
parent
9467350f37
commit
3382e0304d
4
thirdparty/README.md
vendored
4
thirdparty/README.md
vendored
@ -606,7 +606,7 @@ instead of `miniz.h` as an external dependency.
|
|||||||
## thorvg
|
## thorvg
|
||||||
|
|
||||||
- Upstream: https://github.com/Samsung/thorvg
|
- Upstream: https://github.com/Samsung/thorvg
|
||||||
- Version: 0.7.0 (e527f565b770f0a41df821e6618ccaeea94f465e, 2021)
|
- Version: 0.7.1 (d53eb2a880002cb770ace1c1ace9c5dfcfc28252, 2022)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
@ -614,8 +614,6 @@ Files extracted from upstream source:
|
|||||||
See `thorvg/update-thorvg.sh` for extraction instructions. Set the version
|
See `thorvg/update-thorvg.sh` for extraction instructions. Set the version
|
||||||
number and run the script.
|
number and run the script.
|
||||||
|
|
||||||
Patches in the `patches` directory should be re-applied after updates.
|
|
||||||
|
|
||||||
|
|
||||||
## vhacd
|
## vhacd
|
||||||
|
|
||||||
|
2
thirdparty/thorvg/AUTHORS
vendored
2
thirdparty/thorvg/AUTHORS
vendored
@ -13,3 +13,5 @@ Pankaj Kumar <pankaj.m1@samsung.com>
|
|||||||
Patryk Kaczmarek <patryk.k@partner.samsung.com>
|
Patryk Kaczmarek <patryk.k@partner.samsung.com>
|
||||||
Michal Maciola <m.maciola@samsung.com>
|
Michal Maciola <m.maciola@samsung.com>
|
||||||
Peter Vullings <peter@projectitis.com>
|
Peter Vullings <peter@projectitis.com>
|
||||||
|
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>
|
||||||
|
Rémi Verschelde <rverschelde@gmail.com>
|
||||||
|
2
thirdparty/thorvg/inc/config.h
vendored
2
thirdparty/thorvg/inc/config.h
vendored
@ -13,5 +13,5 @@
|
|||||||
|
|
||||||
#define THORVG_JPG_LOADER_SUPPORT 1
|
#define THORVG_JPG_LOADER_SUPPORT 1
|
||||||
|
|
||||||
#define THORVG_VERSION_STRING "0.7.0"
|
#define THORVG_VERSION_STRING "0.7.1"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
|
|
||||||
index def8ae169a..cf103774c5 100644
|
|
||||||
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
|
|
||||||
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
|
|
||||||
@@ -51,6 +51,7 @@
|
|
||||||
|
|
||||||
#define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++.
|
|
||||||
|
|
||||||
+#include <cstring>
|
|
||||||
#include <fstream>
|
|
||||||
#include <float.h>
|
|
||||||
#include <math.h>
|
|
||||||
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
|
|
||||||
index 2b62315de8..32685ee620 100644
|
|
||||||
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
|
|
||||||
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
|
|
||||||
@@ -50,6 +50,7 @@
|
|
||||||
|
|
||||||
#define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++.
|
|
||||||
|
|
||||||
+#include <cstring>
|
|
||||||
#include <math.h>
|
|
||||||
#include <clocale>
|
|
||||||
#include <ctype.h>
|
|
||||||
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
|
|
||||||
index 8701fe32b1..ae17634f31 100644
|
|
||||||
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
|
|
||||||
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
|
|
||||||
@@ -49,6 +49,7 @@
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
+#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
#include "tvgMath.h"
|
|
||||||
#include "tvgSvgLoaderCommon.h"
|
|
||||||
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
|
|
||||||
index d5b9cdcf7b..9f269b29a2 100644
|
|
||||||
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
|
|
||||||
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
|
|
||||||
@@ -20,6 +20,7 @@
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
+#include <cstring>
|
|
||||||
#include <math.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include "tvgSvgUtil.h"
|
|
||||||
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
|
|
||||||
index 2e3d5928d9..1571aa4e25 100644
|
|
||||||
--- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
|
|
||||||
+++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
|
|
||||||
@@ -20,6 +20,7 @@
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
+#include <cstring>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
|
|
||||||
index 9450d80e88..9dd57e5a89 100644
|
|
||||||
--- a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
|
|
||||||
+++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
|
|
||||||
@@ -24,6 +24,8 @@
|
|
||||||
#include "tvgTvgSaver.h"
|
|
||||||
#include "tvgLzw.h"
|
|
||||||
|
|
||||||
+#include <cstring>
|
|
||||||
+
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <malloc.h>
|
|
||||||
#else
|
|
@ -1,49 +0,0 @@
|
|||||||
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
|
|
||||||
index 78537e7726..c75e73760e 100644
|
|
||||||
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
|
|
||||||
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
|
|
||||||
@@ -23,6 +23,7 @@
|
|
||||||
#include "tvgSwCommon.h"
|
|
||||||
#include "tvgTaskScheduler.h"
|
|
||||||
#include "tvgSwRenderer.h"
|
|
||||||
+#include "tvgMath.h"
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* Internal Class Implementation */
|
|
||||||
@@ -594,10 +595,10 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform,
|
|
||||||
task->surface = surface;
|
|
||||||
task->mpool = mpool;
|
|
||||||
task->flags = flags;
|
|
||||||
- task->bbox.min.x = max(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.x));
|
|
||||||
- task->bbox.min.y = max(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.y));
|
|
||||||
- task->bbox.max.x = min(static_cast<SwCoord>(surface->w), static_cast<SwCoord>(vport.x + vport.w));
|
|
||||||
- task->bbox.max.y = min(static_cast<SwCoord>(surface->h), static_cast<SwCoord>(vport.y + vport.h));
|
|
||||||
+ task->bbox.min.x = mathMax(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.x));
|
|
||||||
+ task->bbox.min.y = mathMax(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.y));
|
|
||||||
+ task->bbox.max.x = mathMin(static_cast<SwCoord>(surface->w), static_cast<SwCoord>(vport.x + vport.w));
|
|
||||||
+ task->bbox.max.y = mathMin(static_cast<SwCoord>(surface->h), static_cast<SwCoord>(vport.y + vport.h));
|
|
||||||
|
|
||||||
if (!task->pushed) {
|
|
||||||
task->pushed = true;
|
|
||||||
diff --git a/thirdparty/thorvg/src/lib/tvgMath.h b/thirdparty/thorvg/src/lib/tvgMath.h
|
|
||||||
index 9e5c915fc3..94b4fe1cf1 100644
|
|
||||||
--- a/thirdparty/thorvg/src/lib/tvgMath.h
|
|
||||||
+++ b/thirdparty/thorvg/src/lib/tvgMath.h
|
|
||||||
@@ -29,6 +29,10 @@
|
|
||||||
#include "tvgCommon.h"
|
|
||||||
|
|
||||||
|
|
||||||
+#define mathMin(x, y) (((x) < (y)) ? (x) : (y))
|
|
||||||
+#define mathMax(x, y) (((x) > (y)) ? (x) : (y))
|
|
||||||
+
|
|
||||||
+
|
|
||||||
static inline bool mathZero(float a)
|
|
||||||
{
|
|
||||||
return (fabsf(a) < FLT_EPSILON) ? true : false;
|
|
||||||
@@ -154,4 +158,4 @@ static inline Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-#endif //_TVG_MATH_H_
|
|
||||||
\ No newline at end of file
|
|
||||||
+#endif //_TVG_MATH_H_
|
|
@ -84,8 +84,8 @@ bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipReg
|
|||||||
|
|
||||||
//Fast track: Non-transformed image but just shifted.
|
//Fast track: Non-transformed image but just shifted.
|
||||||
if (image->direct) {
|
if (image->direct) {
|
||||||
image->ox = -static_cast<uint32_t>(round(transform->e13));
|
image->ox = -static_cast<int32_t>(round(transform->e13));
|
||||||
image->oy = -static_cast<uint32_t>(round(transform->e23));
|
image->oy = -static_cast<int32_t>(round(transform->e23));
|
||||||
//Figure out the scale factor by transform matrix
|
//Figure out the scale factor by transform matrix
|
||||||
} else {
|
} else {
|
||||||
auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21));
|
auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21));
|
||||||
|
@ -481,7 +481,10 @@ static bool _rasterScaledRleRGBAImage(SwSurface* surface, const SwImage* image,
|
|||||||
static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
|
static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
|
||||||
{
|
{
|
||||||
Matrix itransform;
|
Matrix itransform;
|
||||||
if (transform && !mathInverse(transform, &itransform)) return false;
|
|
||||||
|
if (transform) {
|
||||||
|
if (!mathInverse(transform, &itransform)) return false;
|
||||||
|
} else mathIdentity(&itransform);
|
||||||
|
|
||||||
auto halfScale = _halfScale(image->scale);
|
auto halfScale = _halfScale(image->scale);
|
||||||
|
|
||||||
@ -816,7 +819,10 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con
|
|||||||
static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
|
static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
|
||||||
{
|
{
|
||||||
Matrix itransform;
|
Matrix itransform;
|
||||||
if (transform && !mathInverse(transform, &itransform)) return false;
|
|
||||||
|
if (transform) {
|
||||||
|
if (!mathInverse(transform, &itransform)) return false;
|
||||||
|
} else mathIdentity(&itransform);
|
||||||
|
|
||||||
auto halfScale = _halfScale(image->scale);
|
auto halfScale = _halfScale(image->scale);
|
||||||
|
|
||||||
@ -1113,12 +1119,12 @@ static bool _rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRleD
|
|||||||
auto dst = &surface->buffer[span->y * surface->stride + span->x];
|
auto dst = &surface->buffer[span->y * surface->stride + span->x];
|
||||||
fillFetchLinear(fill, buffer, span->y, span->x, span->len);
|
fillFetchLinear(fill, buffer, span->y, span->x, span->len);
|
||||||
if (span->coverage == 255) {
|
if (span->coverage == 255) {
|
||||||
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
|
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
|
||||||
*dst = buffer[i] + ALPHA_BLEND(*dst, _ialpha(buffer[i]));
|
*dst = buffer[x] + ALPHA_BLEND(*dst, _ialpha(buffer[x]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
|
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
|
||||||
auto tmp = ALPHA_BLEND(buffer[i], span->coverage);
|
auto tmp = ALPHA_BLEND(buffer[x], span->coverage);
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
|
*dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1142,8 +1148,8 @@ static bool _rasterSolidLinearGradientRle(SwSurface* surface, const SwRleData* r
|
|||||||
} else {
|
} else {
|
||||||
fillFetchLinear(fill, buf, span->y, span->x, span->len);
|
fillFetchLinear(fill, buf, span->y, span->x, span->len);
|
||||||
auto dst = &surface->buffer[span->y * surface->stride + span->x];
|
auto dst = &surface->buffer[span->y * surface->stride + span->x];
|
||||||
for (uint32_t i = 0; i < span->len; ++i) {
|
for (uint32_t x = 0; x < span->len; ++x) {
|
||||||
dst[i] = INTERPOLATE(span->coverage, buf[i], dst[i]);
|
dst[x] = INTERPOLATE(span->coverage, buf[x], dst[x]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1302,12 +1308,12 @@ static bool _rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRleD
|
|||||||
auto dst = &surface->buffer[span->y * surface->stride + span->x];
|
auto dst = &surface->buffer[span->y * surface->stride + span->x];
|
||||||
fillFetchRadial(fill, buffer, span->y, span->x, span->len);
|
fillFetchRadial(fill, buffer, span->y, span->x, span->len);
|
||||||
if (span->coverage == 255) {
|
if (span->coverage == 255) {
|
||||||
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
|
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
|
||||||
*dst = buffer[i] + ALPHA_BLEND(*dst, _ialpha(buffer[i]));
|
*dst = buffer[x] + ALPHA_BLEND(*dst, _ialpha(buffer[x]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
|
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
|
||||||
auto tmp = ALPHA_BLEND(buffer[i], span->coverage);
|
auto tmp = ALPHA_BLEND(buffer[x], span->coverage);
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
|
*dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1332,8 +1338,8 @@ static bool _rasterSolidRadialGradientRle(SwSurface* surface, const SwRleData* r
|
|||||||
} else {
|
} else {
|
||||||
fillFetchRadial(fill, buf, span->y, span->x, span->len);
|
fillFetchRadial(fill, buf, span->y, span->x, span->len);
|
||||||
auto ialpha = 255 - span->coverage;
|
auto ialpha = 255 - span->coverage;
|
||||||
for (uint32_t i = 0; i < span->len; ++i, ++dst) {
|
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
|
||||||
*dst = ALPHA_BLEND(buf[i], span->coverage) + ALPHA_BLEND(*dst, ialpha);
|
*dst = ALPHA_BLEND(buf[x], span->coverage) + ALPHA_BLEND(*dst, ialpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1487,7 +1493,7 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint
|
|||||||
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity)
|
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity)
|
||||||
{
|
{
|
||||||
//Verify Boundary
|
//Verify Boundary
|
||||||
if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= surface->w || bbox.min.y >= surface->h) return false;
|
if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return false;
|
||||||
|
|
||||||
//TOOD: switch (image->format)
|
//TOOD: switch (image->format)
|
||||||
//TODO: case: _rasterRGBImage()
|
//TODO: case: _rasterRGBImage()
|
||||||
|
@ -58,8 +58,8 @@
|
|||||||
y = yStart;
|
y = yStart;
|
||||||
|
|
||||||
while (y < yEnd) {
|
while (y < yEnd) {
|
||||||
x1 = _xa;
|
x1 = (int32_t)_xa;
|
||||||
x2 = _xb;
|
x2 = (int32_t)_xb;
|
||||||
|
|
||||||
if (!region) {
|
if (!region) {
|
||||||
minx = INT32_MAX;
|
minx = INT32_MAX;
|
||||||
@ -160,4 +160,4 @@ next:
|
|||||||
xb = _xb;
|
xb = _xb;
|
||||||
ua = _ua;
|
ua = _ua;
|
||||||
va = _va;
|
va = _va;
|
||||||
}
|
}
|
||||||
|
2
thirdparty/thorvg/src/lib/tvgMath.h
vendored
2
thirdparty/thorvg/src/lib/tvgMath.h
vendored
@ -47,7 +47,7 @@ static inline bool mathEqual(float a, float b)
|
|||||||
|
|
||||||
static inline bool mathRightAngle(const Matrix* m)
|
static inline bool mathRightAngle(const Matrix* m)
|
||||||
{
|
{
|
||||||
auto radian = fabsf(atan2(m->e21, m->e11));
|
auto radian = fabsf(atan2f(m->e21, m->e11));
|
||||||
if (radian < FLT_EPSILON || mathEqual(radian, float(M_PI_2)) || mathEqual(radian, float(M_PI))) return true;
|
if (radian < FLT_EPSILON || mathEqual(radian, float(M_PI_2)) || mathEqual(radian, float(M_PI))) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ JpgLoader::~JpgLoader()
|
|||||||
{
|
{
|
||||||
jpgdDelete(decoder);
|
jpgdDelete(decoder);
|
||||||
if (freeData) free(data);
|
if (freeData) free(data);
|
||||||
|
free(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -128,5 +129,9 @@ unique_ptr<Surface> JpgLoader::bitmap()
|
|||||||
|
|
||||||
void JpgLoader::run(unsigned tid)
|
void JpgLoader::run(unsigned tid)
|
||||||
{
|
{
|
||||||
|
if (image) {
|
||||||
|
free(image);
|
||||||
|
image = nullptr;
|
||||||
|
}
|
||||||
image = jpgdDecompress(decoder);
|
image = jpgdDecompress(decoder);
|
||||||
}
|
}
|
@ -1080,7 +1080,9 @@ namespace DCT_Upsample
|
|||||||
// Unconditionally frees all allocated m_blocks.
|
// Unconditionally frees all allocated m_blocks.
|
||||||
void jpeg_decoder::free_all_blocks()
|
void jpeg_decoder::free_all_blocks()
|
||||||
{
|
{
|
||||||
|
delete(m_pStream);
|
||||||
m_pStream = nullptr;
|
m_pStream = nullptr;
|
||||||
|
|
||||||
for (mem_block *b = m_pMem_blocks; b; ) {
|
for (mem_block *b = m_pMem_blocks; b; ) {
|
||||||
mem_block *n = b->m_pNext;
|
mem_block *n = b->m_pNext;
|
||||||
free(b);
|
free(b);
|
||||||
@ -2815,7 +2817,6 @@ int jpeg_decoder::begin_decoding()
|
|||||||
jpeg_decoder::~jpeg_decoder()
|
jpeg_decoder::~jpeg_decoder()
|
||||||
{
|
{
|
||||||
free_all_blocks();
|
free_all_blocks();
|
||||||
delete(m_pStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3025,4 +3026,4 @@ unsigned char* jpgdDecompress(jpeg_decoder* decoder)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pImage_data;
|
return pImage_data;
|
||||||
}
|
}
|
||||||
|
2
thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h
vendored
2
thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h
vendored
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
|
* Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -72,6 +72,7 @@ PngLoader::PngLoader()
|
|||||||
PngLoader::~PngLoader()
|
PngLoader::~PngLoader()
|
||||||
{
|
{
|
||||||
if (freeData) free(data);
|
if (freeData) free(data);
|
||||||
|
free(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -121,7 +122,7 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy)
|
|||||||
clear();
|
clear();
|
||||||
|
|
||||||
lodepng_state_init(&state);
|
lodepng_state_init(&state);
|
||||||
|
|
||||||
unsigned int width, height;
|
unsigned int width, height;
|
||||||
if (lodepng_inspect(&width, &height, &state, (unsigned char*)(data), size) > 0) return false;
|
if (lodepng_inspect(&width, &height, &state, (unsigned char*)(data), size) > 0) return false;
|
||||||
|
|
||||||
@ -180,10 +181,14 @@ unique_ptr<Surface> PngLoader::bitmap()
|
|||||||
|
|
||||||
void PngLoader::run(unsigned tid)
|
void PngLoader::run(unsigned tid)
|
||||||
{
|
{
|
||||||
|
if (image) {
|
||||||
|
free(image);
|
||||||
|
image = nullptr;
|
||||||
|
}
|
||||||
auto width = static_cast<unsigned>(w);
|
auto width = static_cast<unsigned>(w);
|
||||||
auto height = static_cast<unsigned>(h);
|
auto height = static_cast<unsigned>(h);
|
||||||
|
|
||||||
lodepng_decode(&image, &width, &height, &state, data, size);
|
lodepng_decode(&image, &width, &height, &state, data, size);
|
||||||
|
|
||||||
_premultiply((uint32_t*)(image), width, height);
|
_premultiply((uint32_t*)(image), width, height);
|
||||||
}
|
}
|
||||||
|
224
thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
vendored
224
thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
vendored
@ -541,7 +541,7 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char**
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (len >= 3 && !strncmp(str, "url", 3)) {
|
} else if (ref && len >= 3 && !strncmp(str, "url", 3)) {
|
||||||
*ref = _idFromUrl((const char*)(str + 3));
|
*ref = _idFromUrl((const char*)(str + 3));
|
||||||
} else {
|
} else {
|
||||||
//Handle named color
|
//Handle named color
|
||||||
@ -789,7 +789,7 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value)
|
|||||||
return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
|
return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
|
||||||
}
|
}
|
||||||
#ifdef THORVG_LOG_ENABLED
|
#ifdef THORVG_LOG_ENABLED
|
||||||
else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON ) {
|
else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON) {
|
||||||
TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value);
|
TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1611,6 +1611,7 @@ static bool _attrParseImageNode(void* data, const char* key, const char* value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
||||||
|
if (image->href && value) free(image->href);
|
||||||
image->href = _idFromHref(value);
|
image->href = _idFromHref(value);
|
||||||
} else if (!strcmp(key, "id")) {
|
} else if (!strcmp(key, "id")) {
|
||||||
if (node->id && value) free(node->id);
|
if (node->id && value) free(node->id);
|
||||||
@ -1728,6 +1729,112 @@ error_grad_alloc:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* parent)
|
||||||
|
{
|
||||||
|
if (parent == nullptr) return;
|
||||||
|
//Inherit the property of parent if not present in child.
|
||||||
|
if (!child->curColorSet) {
|
||||||
|
child->color = parent->color;
|
||||||
|
child->curColorSet = parent->curColorSet;
|
||||||
|
}
|
||||||
|
//Fill
|
||||||
|
if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
|
||||||
|
child->fill.paint.color = parent->fill.paint.color;
|
||||||
|
child->fill.paint.none = parent->fill.paint.none;
|
||||||
|
child->fill.paint.curColor = parent->fill.paint.curColor;
|
||||||
|
if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url);
|
||||||
|
}
|
||||||
|
if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) {
|
||||||
|
child->fill.opacity = parent->fill.opacity;
|
||||||
|
}
|
||||||
|
if (!((int)child->fill.flags & (int)SvgFillFlags::FillRule)) {
|
||||||
|
child->fill.fillRule = parent->fill.fillRule;
|
||||||
|
}
|
||||||
|
//Stroke
|
||||||
|
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Paint)) {
|
||||||
|
child->stroke.paint.color = parent->stroke.paint.color;
|
||||||
|
child->stroke.paint.none = parent->stroke.paint.none;
|
||||||
|
child->stroke.paint.curColor = parent->stroke.paint.curColor;
|
||||||
|
child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr;
|
||||||
|
}
|
||||||
|
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
|
||||||
|
child->stroke.opacity = parent->stroke.opacity;
|
||||||
|
}
|
||||||
|
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Width)) {
|
||||||
|
child->stroke.width = parent->stroke.width;
|
||||||
|
}
|
||||||
|
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) {
|
||||||
|
if (parent->stroke.dash.array.count > 0) {
|
||||||
|
child->stroke.dash.array.clear();
|
||||||
|
child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
|
||||||
|
for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) {
|
||||||
|
child->stroke.dash.array.push(parent->stroke.dash.array.data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Cap)) {
|
||||||
|
child->stroke.cap = parent->stroke.cap;
|
||||||
|
}
|
||||||
|
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Join)) {
|
||||||
|
child->stroke.join = parent->stroke.join;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from)
|
||||||
|
{
|
||||||
|
if (from == nullptr) return;
|
||||||
|
//Copy the properties of 'from' only if they were explicitly set (not the default ones).
|
||||||
|
if (from->curColorSet) {
|
||||||
|
to->color = from->color;
|
||||||
|
to->curColorSet = true;
|
||||||
|
}
|
||||||
|
//Fill
|
||||||
|
to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)from->fill.flags);
|
||||||
|
if (((int)from->fill.flags & (int)SvgFillFlags::Paint)) {
|
||||||
|
to->fill.paint.color = from->fill.paint.color;
|
||||||
|
to->fill.paint.none = from->fill.paint.none;
|
||||||
|
to->fill.paint.curColor = from->fill.paint.curColor;
|
||||||
|
if (from->fill.paint.url) to->fill.paint.url = _copyId(from->fill.paint.url);
|
||||||
|
}
|
||||||
|
if (((int)from->fill.flags & (int)SvgFillFlags::Opacity)) {
|
||||||
|
to->fill.opacity = from->fill.opacity;
|
||||||
|
}
|
||||||
|
if (((int)from->fill.flags & (int)SvgFillFlags::FillRule)) {
|
||||||
|
to->fill.fillRule = from->fill.fillRule;
|
||||||
|
}
|
||||||
|
//Stroke
|
||||||
|
to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)from->stroke.flags);
|
||||||
|
if (((int)from->stroke.flags & (int)SvgStrokeFlags::Paint)) {
|
||||||
|
to->stroke.paint.color = from->stroke.paint.color;
|
||||||
|
to->stroke.paint.none = from->stroke.paint.none;
|
||||||
|
to->stroke.paint.curColor = from->stroke.paint.curColor;
|
||||||
|
to->stroke.paint.url = from->stroke.paint.url ? _copyId(from->stroke.paint.url) : nullptr;
|
||||||
|
}
|
||||||
|
if (((int)from->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
|
||||||
|
to->stroke.opacity = from->stroke.opacity;
|
||||||
|
}
|
||||||
|
if (((int)from->stroke.flags & (int)SvgStrokeFlags::Width)) {
|
||||||
|
to->stroke.width = from->stroke.width;
|
||||||
|
}
|
||||||
|
if (((int)from->stroke.flags & (int)SvgStrokeFlags::Dash)) {
|
||||||
|
if (from->stroke.dash.array.count > 0) {
|
||||||
|
to->stroke.dash.array.clear();
|
||||||
|
to->stroke.dash.array.reserve(from->stroke.dash.array.count);
|
||||||
|
for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) {
|
||||||
|
to->stroke.dash.array.push(from->stroke.dash.array.data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (((int)from->stroke.flags & (int)SvgStrokeFlags::Cap)) {
|
||||||
|
to->stroke.cap = from->stroke.cap;
|
||||||
|
}
|
||||||
|
if (((int)from->stroke.flags & (int)SvgStrokeFlags::Join)) {
|
||||||
|
to->stroke.join = from->stroke.join;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _copyAttr(SvgNode* to, const SvgNode* from)
|
static void _copyAttr(SvgNode* to, const SvgNode* from)
|
||||||
{
|
{
|
||||||
//Copy matrix attribute
|
//Copy matrix attribute
|
||||||
@ -1736,7 +1843,8 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
|
|||||||
if (to->transform) *to->transform = *from->transform;
|
if (to->transform) *to->transform = *from->transform;
|
||||||
}
|
}
|
||||||
//Copy style attribute
|
//Copy style attribute
|
||||||
*to->style = *from->style;
|
_styleCopy(to->style, from->style);
|
||||||
|
to->style->flags = (SvgStyleFlags)((int)to->style->flags | (int)from->style->flags);
|
||||||
if (from->style->fill.paint.url) to->style->fill.paint.url = strdup(from->style->fill.paint.url);
|
if (from->style->fill.paint.url) to->style->fill.paint.url = strdup(from->style->fill.paint.url);
|
||||||
if (from->style->stroke.paint.url) to->style->stroke.paint.url = strdup(from->style->stroke.paint.url);
|
if (from->style->stroke.paint.url) to->style->stroke.paint.url = strdup(from->style->stroke.paint.url);
|
||||||
if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url);
|
if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url);
|
||||||
@ -1780,15 +1888,17 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SvgNodeType::Polygon: {
|
case SvgNodeType::Polygon: {
|
||||||
to->node.polygon.pointsCount = from->node.polygon.pointsCount;
|
if ((to->node.polygon.pointsCount = from->node.polygon.pointsCount)) {
|
||||||
to->node.polygon.points = (float*)malloc(to->node.polygon.pointsCount * sizeof(float));
|
to->node.polygon.points = (float*)malloc(to->node.polygon.pointsCount * sizeof(float));
|
||||||
memcpy(to->node.polygon.points, from->node.polygon.points, to->node.polygon.pointsCount * sizeof(float));
|
memcpy(to->node.polygon.points, from->node.polygon.points, to->node.polygon.pointsCount * sizeof(float));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SvgNodeType::Polyline: {
|
case SvgNodeType::Polyline: {
|
||||||
to->node.polyline.pointsCount = from->node.polyline.pointsCount;
|
if ((to->node.polyline.pointsCount = from->node.polyline.pointsCount)) {
|
||||||
to->node.polyline.points = (float*)malloc(to->node.polyline.pointsCount * sizeof(float));
|
to->node.polyline.points = (float*)malloc(to->node.polyline.pointsCount * sizeof(float));
|
||||||
memcpy(to->node.polyline.points, from->node.polyline.points, to->node.polyline.pointsCount * sizeof(float));
|
memcpy(to->node.polyline.points, from->node.polyline.points, to->node.polyline.pointsCount * sizeof(float));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SvgNodeType::Image: {
|
case SvgNodeType::Image: {
|
||||||
@ -1806,35 +1916,45 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _cloneNode(SvgNode* from, SvgNode* parent)
|
static void _cloneNode(SvgNode* from, SvgNode* parent, int depth)
|
||||||
{
|
{
|
||||||
|
/* Exception handling: Prevent invalid SVG data input.
|
||||||
|
The size is the arbitrary value, we need an experimental size. */
|
||||||
|
if (depth == 8192) {
|
||||||
|
TVGERR("SVG", "Infinite recursive call - stopped after %d calls! Svg file may be incorrectly formatted.", depth);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SvgNode* newNode;
|
SvgNode* newNode;
|
||||||
if (!from || !parent) return;
|
if (!from || !parent || from == parent) return;
|
||||||
|
|
||||||
newNode = _createNode(parent, from->type);
|
newNode = _createNode(parent, from->type);
|
||||||
|
|
||||||
if (!newNode) return;
|
if (!newNode) return;
|
||||||
|
|
||||||
|
_styleInherit(newNode->style, parent->style);
|
||||||
_copyAttr(newNode, from);
|
_copyAttr(newNode, from);
|
||||||
|
|
||||||
auto child = from->child.data;
|
auto child = from->child.data;
|
||||||
for (uint32_t i = 0; i < from->child.count; ++i, ++child) {
|
for (uint32_t i = 0; i < from->child.count; ++i, ++child) {
|
||||||
_cloneNode(*child, newNode);
|
_cloneNode(*child, newNode, depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, char* id) {
|
static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, char* id)
|
||||||
|
{
|
||||||
loader->cloneNodes.push({node, id});
|
loader->cloneNodes.push({node, id});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes) {
|
static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc)
|
||||||
|
{
|
||||||
for (uint32_t i = 0; i < cloneNodes->count; ++i) {
|
for (uint32_t i = 0; i < cloneNodes->count; ++i) {
|
||||||
auto nodeIdPair = cloneNodes->data[i];
|
auto nodeIdPair = cloneNodes->data[i];
|
||||||
auto defs = _getDefsNode(nodeIdPair.node);
|
auto defs = _getDefsNode(nodeIdPair.node);
|
||||||
auto nodeFrom = _findChildById(defs, nodeIdPair.id);
|
auto nodeFrom = _findChildById(defs, nodeIdPair.id);
|
||||||
_cloneNode(nodeFrom, nodeIdPair.node);
|
if (!nodeFrom) nodeFrom = _findChildById(doc, nodeIdPair.id);
|
||||||
|
_cloneNode(nodeFrom, nodeIdPair.node, 0);
|
||||||
free(nodeIdPair.id);
|
free(nodeIdPair.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1875,7 +1995,7 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
|
|||||||
defs = _getDefsNode(node);
|
defs = _getDefsNode(node);
|
||||||
nodeFrom = _findChildById(defs, id);
|
nodeFrom = _findChildById(defs, id);
|
||||||
if (nodeFrom) {
|
if (nodeFrom) {
|
||||||
_cloneNode(nodeFrom, node);
|
_cloneNode(nodeFrom, node, 0);
|
||||||
free(id);
|
free(id);
|
||||||
} else {
|
} else {
|
||||||
//some svg export software include <defs> element at the end of the file
|
//some svg export software include <defs> element at the end of the file
|
||||||
@ -1883,10 +2003,6 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
|
|||||||
//after the whole file is parsed
|
//after the whole file is parsed
|
||||||
_postponeCloneNode(loader, node, id);
|
_postponeCloneNode(loader, node, id);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(key, "clip-path")) {
|
|
||||||
_handleClipPathAttr(loader, node, value);
|
|
||||||
} else if (!strcmp(key, "mask")) {
|
|
||||||
_handleMaskAttr(loader, node, value);
|
|
||||||
} else {
|
} else {
|
||||||
return _attrParseGNode(data, key, value);
|
return _attrParseGNode(data, key, value);
|
||||||
}
|
}
|
||||||
@ -2081,10 +2197,12 @@ static bool _attrParseRadialGradientNode(void* data, const char* key, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(key, "id")) {
|
if (!strcmp(key, "id")) {
|
||||||
|
if (grad->id && value) free(grad->id);
|
||||||
grad->id = _copyId(value);
|
grad->id = _copyId(value);
|
||||||
} else if (!strcmp(key, "spreadMethod")) {
|
} else if (!strcmp(key, "spreadMethod")) {
|
||||||
grad->spread = _parseSpreadValue(value);
|
grad->spread = _parseSpreadValue(value);
|
||||||
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
||||||
|
if (grad->ref && value) free(grad->ref);
|
||||||
grad->ref = _idFromHref(value);
|
grad->ref = _idFromHref(value);
|
||||||
} else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) {
|
} else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) {
|
||||||
grad->userSpace = true;
|
grad->userSpace = true;
|
||||||
@ -2269,10 +2387,12 @@ static bool _attrParseLinearGradientNode(void* data, const char* key, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(key, "id")) {
|
if (!strcmp(key, "id")) {
|
||||||
|
if (grad->id && value) free(grad->id);
|
||||||
grad->id = _copyId(value);
|
grad->id = _copyId(value);
|
||||||
} else if (!strcmp(key, "spreadMethod")) {
|
} else if (!strcmp(key, "spreadMethod")) {
|
||||||
grad->spread = _parseSpreadValue(value);
|
grad->spread = _parseSpreadValue(value);
|
||||||
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
||||||
|
if (grad->ref && value) free(grad->ref);
|
||||||
grad->ref = _idFromHref(value);
|
grad->ref = _idFromHref(value);
|
||||||
} else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) {
|
} else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) {
|
||||||
grad->userSpace = true;
|
grad->userSpace = true;
|
||||||
@ -2408,6 +2528,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
|||||||
|
|
||||||
if ((method = _findGroupFactory(tagName))) {
|
if ((method = _findGroupFactory(tagName))) {
|
||||||
//Group
|
//Group
|
||||||
|
if (empty) return;
|
||||||
if (!loader->doc) {
|
if (!loader->doc) {
|
||||||
if (strcmp(tagName, "svg")) return; //Not a valid svg document
|
if (strcmp(tagName, "svg")) return; //Not a valid svg document
|
||||||
node = method(loader, nullptr, attrs, attrsLength);
|
node = method(loader, nullptr, attrs, attrsLength);
|
||||||
@ -2493,59 +2614,8 @@ static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* parent)
|
static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node)
|
||||||
{
|
{
|
||||||
if (parent == nullptr) return;
|
|
||||||
//Inherit the property of parent if not present in child.
|
|
||||||
//Fill
|
|
||||||
if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
|
|
||||||
child->fill.paint.color = parent->fill.paint.color;
|
|
||||||
child->fill.paint.none = parent->fill.paint.none;
|
|
||||||
child->fill.paint.curColor = parent->fill.paint.curColor;
|
|
||||||
if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url);
|
|
||||||
} else if (child->fill.paint.curColor && !child->curColorSet) {
|
|
||||||
child->color = parent->color;
|
|
||||||
}
|
|
||||||
if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) {
|
|
||||||
child->fill.opacity = parent->fill.opacity;
|
|
||||||
}
|
|
||||||
if (!((int)child->fill.flags & (int)SvgFillFlags::FillRule)) {
|
|
||||||
child->fill.fillRule = parent->fill.fillRule;
|
|
||||||
}
|
|
||||||
//Stroke
|
|
||||||
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Paint)) {
|
|
||||||
child->stroke.paint.color = parent->stroke.paint.color;
|
|
||||||
child->stroke.paint.none = parent->stroke.paint.none;
|
|
||||||
child->stroke.paint.curColor = parent->stroke.paint.curColor;
|
|
||||||
child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr;
|
|
||||||
} else if (child->stroke.paint.curColor && !child->curColorSet) {
|
|
||||||
child->color = parent->color;
|
|
||||||
}
|
|
||||||
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
|
|
||||||
child->stroke.opacity = parent->stroke.opacity;
|
|
||||||
}
|
|
||||||
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Width)) {
|
|
||||||
child->stroke.width = parent->stroke.width;
|
|
||||||
}
|
|
||||||
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) {
|
|
||||||
if (parent->stroke.dash.array.count > 0) {
|
|
||||||
child->stroke.dash.array.clear();
|
|
||||||
child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
|
|
||||||
for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) {
|
|
||||||
child->stroke.dash.array.push(parent->stroke.dash.array.data[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Cap)) {
|
|
||||||
child->stroke.cap = parent->stroke.cap;
|
|
||||||
}
|
|
||||||
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Join)) {
|
|
||||||
child->stroke.join = parent->stroke.join;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node){
|
|
||||||
#ifdef THORVG_LOG_ENABLED
|
#ifdef THORVG_LOG_ENABLED
|
||||||
auto type = simpleXmlNodeTypeToString(node->type);
|
auto type = simpleXmlNodeTypeToString(node->type);
|
||||||
|
|
||||||
@ -2838,14 +2908,14 @@ void SvgLoader::run(unsigned tid)
|
|||||||
if (loaderData.doc) {
|
if (loaderData.doc) {
|
||||||
_updateStyle(loaderData.doc, nullptr);
|
_updateStyle(loaderData.doc, nullptr);
|
||||||
auto defs = loaderData.doc->node.doc.defs;
|
auto defs = loaderData.doc->node.doc.defs;
|
||||||
if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients);
|
|
||||||
|
|
||||||
if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients);
|
|
||||||
|
|
||||||
_updateComposite(loaderData.doc, loaderData.doc);
|
_updateComposite(loaderData.doc, loaderData.doc);
|
||||||
if (defs) _updateComposite(loaderData.doc, defs);
|
if (defs) _updateComposite(loaderData.doc, defs);
|
||||||
|
|
||||||
if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes);
|
if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes, loaderData.doc);
|
||||||
|
|
||||||
|
if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients);
|
||||||
|
if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients);
|
||||||
}
|
}
|
||||||
root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect, svgPath);
|
root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect, svgPath);
|
||||||
}
|
}
|
||||||
|
@ -220,15 +220,15 @@ static SimpleXMLType _getXMLType(const char* itr, const char* itrEnd, size_t &to
|
|||||||
if ((itr + sizeof("<!DOCTYPE>") - 1 < itrEnd) && (!memcmp(itr + 2, "DOCTYPE", sizeof("DOCTYPE") - 1)) && ((itr[2 + sizeof("DOCTYPE") - 1] == '>') || (isspace((unsigned char)itr[2 + sizeof("DOCTYPE") - 1])))) {
|
if ((itr + sizeof("<!DOCTYPE>") - 1 < itrEnd) && (!memcmp(itr + 2, "DOCTYPE", sizeof("DOCTYPE") - 1)) && ((itr[2 + sizeof("DOCTYPE") - 1] == '>') || (isspace((unsigned char)itr[2 + sizeof("DOCTYPE") - 1])))) {
|
||||||
toff = sizeof("!DOCTYPE") - 1;
|
toff = sizeof("!DOCTYPE") - 1;
|
||||||
return SimpleXMLType::Doctype;
|
return SimpleXMLType::Doctype;
|
||||||
} else if (itr + sizeof("<!>") - 1 < itrEnd) {
|
|
||||||
toff = sizeof("!") - 1;
|
|
||||||
return SimpleXMLType::DoctypeChild;
|
|
||||||
} else if ((itr + sizeof("<![CDATA[]]>") - 1 < itrEnd) && (!memcmp(itr + 2, "[CDATA[", sizeof("[CDATA[") - 1))) {
|
} else if ((itr + sizeof("<![CDATA[]]>") - 1 < itrEnd) && (!memcmp(itr + 2, "[CDATA[", sizeof("[CDATA[") - 1))) {
|
||||||
toff = sizeof("![CDATA[") - 1;
|
toff = sizeof("![CDATA[") - 1;
|
||||||
return SimpleXMLType::CData;
|
return SimpleXMLType::CData;
|
||||||
} else if ((itr + sizeof("<!---->") - 1 < itrEnd) && (!memcmp(itr + 2, "--", sizeof("--") - 1))) {
|
} else if ((itr + sizeof("<!---->") - 1 < itrEnd) && (!memcmp(itr + 2, "--", sizeof("--") - 1))) {
|
||||||
toff = sizeof("!--") - 1;
|
toff = sizeof("!--") - 1;
|
||||||
return SimpleXMLType::Comment;
|
return SimpleXMLType::Comment;
|
||||||
|
} else if (itr + sizeof("<!>") - 1 < itrEnd) {
|
||||||
|
toff = sizeof("!") - 1;
|
||||||
|
return SimpleXMLType::DoctypeChild;
|
||||||
}
|
}
|
||||||
return SimpleXMLType::Open;
|
return SimpleXMLType::Open;
|
||||||
}
|
}
|
||||||
|
2
thirdparty/thorvg/update-thorvg.sh
vendored
2
thirdparty/thorvg/update-thorvg.sh
vendored
@ -1,4 +1,4 @@
|
|||||||
VERSION=0.7.0
|
VERSION=0.7.1
|
||||||
rm -rf AUTHORS inc LICENSE src *.zip
|
rm -rf AUTHORS inc LICENSE src *.zip
|
||||||
curl -L -O https://github.com/Samsung/thorvg/archive/refs/tags/v$VERSION.zip
|
curl -L -O https://github.com/Samsung/thorvg/archive/refs/tags/v$VERSION.zip
|
||||||
bsdtar --strip-components=1 -xvf *.zip
|
bsdtar --strip-components=1 -xvf *.zip
|
||||||
|
Loading…
Reference in New Issue
Block a user