You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-04 17:04:49 +00:00
4
thirdparty/README.md
vendored
4
thirdparty/README.md
vendored
@@ -825,13 +825,13 @@ instead of `miniz.h` as an external dependency.
|
|||||||
## thorvg
|
## thorvg
|
||||||
|
|
||||||
- Upstream: https://github.com/thorvg/thorvg
|
- Upstream: https://github.com/thorvg/thorvg
|
||||||
- Version: 0.12.5 (9c8eeaab9629b5d241b1092a3398fe6351c259cd, 2024)
|
- Version: 0.12.7 (cddae9966cbb48c431ea17c262d6f48393206fd7, 2024)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from upstream source:
|
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 and apply patches from the `patches` folder.
|
number and run the script.
|
||||||
|
|
||||||
|
|
||||||
## vhacd
|
## vhacd
|
||||||
|
|||||||
2
thirdparty/thorvg/inc/config.h
vendored
2
thirdparty/thorvg/inc/config.h
vendored
@@ -10,5 +10,5 @@
|
|||||||
// For internal debugging:
|
// For internal debugging:
|
||||||
//#define THORVG_LOG_ENABLED
|
//#define THORVG_LOG_ENABLED
|
||||||
|
|
||||||
#define THORVG_VERSION_STRING "0.12.5"
|
#define THORVG_VERSION_STRING "0.12.7"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
16
thirdparty/thorvg/inc/thorvg.h
vendored
16
thirdparty/thorvg/inc/thorvg.h
vendored
@@ -1223,6 +1223,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Loads a picture data directly from a file.
|
* @brief Loads a picture data directly from a file.
|
||||||
*
|
*
|
||||||
|
* ThorVG efficiently caches the loaded data using the specified @p path as a key.
|
||||||
|
* This means that loading the same file again will not result in duplicate operations;
|
||||||
|
* instead, ThorVG will reuse the previously loaded picture data.
|
||||||
|
*
|
||||||
* @param[in] path A path to the picture file.
|
* @param[in] path A path to the picture file.
|
||||||
*
|
*
|
||||||
* @retval Result::Success When succeed.
|
* @retval Result::Success When succeed.
|
||||||
@@ -1238,6 +1242,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Loads a picture data from a memory block of a given size.
|
* @brief Loads a picture data from a memory block of a given size.
|
||||||
*
|
*
|
||||||
|
* ThorVG efficiently caches the loaded data using the specified @p data address as a key
|
||||||
|
* when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations
|
||||||
|
* for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data.
|
||||||
|
*
|
||||||
* @param[in] data A pointer to a memory location where the content of the picture file is stored.
|
* @param[in] data A pointer to a memory location where the content of the picture file is stored.
|
||||||
* @param[in] size The size in bytes of the memory occupied by the @p data.
|
* @param[in] size The size in bytes of the memory occupied by the @p data.
|
||||||
* @param[in] copy Decides whether the data should be copied into the engine local buffer.
|
* @param[in] copy Decides whether the data should be copied into the engine local buffer.
|
||||||
@@ -1299,6 +1307,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Loads a raw data from a memory block with a given size.
|
* @brief Loads a raw data from a memory block with a given size.
|
||||||
*
|
*
|
||||||
|
* ThorVG efficiently caches the loaded data using the specified @p data address as a key
|
||||||
|
* when the @p copy has @c false. This means that loading the same data again will not result in duplicate operations
|
||||||
|
* for the sharable @p data. Instead, ThorVG will reuse the previously loaded picture data.
|
||||||
|
*
|
||||||
* @param[in] paint A Tvg_Paint pointer to the picture object.
|
* @param[in] paint A Tvg_Paint pointer to the picture object.
|
||||||
* @param[in] data A pointer to a memory location where the content of the picture raw data is stored.
|
* @param[in] data A pointer to a memory location where the content of the picture raw data is stored.
|
||||||
* @param[in] w The width of the image @p data in pixels.
|
* @param[in] w The width of the image @p data in pixels.
|
||||||
@@ -1544,6 +1556,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Loads a scalable font data(ttf) from a file.
|
* @brief Loads a scalable font data(ttf) from a file.
|
||||||
*
|
*
|
||||||
|
* ThorVG efficiently caches the loaded data using the specified @p path as a key.
|
||||||
|
* This means that loading the same file again will not result in duplicate operations;
|
||||||
|
* instead, ThorVG will reuse the previously loaded font data.
|
||||||
|
*
|
||||||
* @param[in] path The path to the font file.
|
* @param[in] path The path to the font file.
|
||||||
*
|
*
|
||||||
* @retval Result::Success When succeed.
|
* @retval Result::Success When succeed.
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
diff --git a/thirdparty/thorvg/src/common/tvgLock.h b/thirdparty/thorvg/src/common/tvgLock.h
|
|
||||||
index e6d993a41e..5dd3d5a624 100644
|
|
||||||
--- a/thirdparty/thorvg/src/common/tvgLock.h
|
|
||||||
+++ b/thirdparty/thorvg/src/common/tvgLock.h
|
|
||||||
@@ -38,10 +38,10 @@ namespace tvg {
|
|
||||||
{
|
|
||||||
Key* key = nullptr;
|
|
||||||
|
|
||||||
- ScopedLock(Key& key)
|
|
||||||
+ ScopedLock(Key& k)
|
|
||||||
{
|
|
||||||
- key.mtx.lock();
|
|
||||||
- this->key = &key;
|
|
||||||
+ k.mtx.lock();
|
|
||||||
+ key = &k;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedLock()
|
|
||||||
@@ -68,3 +68,4 @@ namespace tvg {
|
|
||||||
#endif //THORVG_THREAD_SUPPORT
|
|
||||||
|
|
||||||
#endif //_TVG_LOCK_H_
|
|
||||||
+
|
|
||||||
10
thirdparty/thorvg/src/common/tvgArray.h
vendored
10
thirdparty/thorvg/src/common/tvgArray.h
vendored
@@ -90,6 +90,16 @@ struct Array
|
|||||||
return data[idx];
|
return data[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const T* begin() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* begin()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
T* end()
|
T* end()
|
||||||
{
|
{
|
||||||
return data + count;
|
return data + count;
|
||||||
|
|||||||
99
thirdparty/thorvg/src/common/tvgBezier.cpp
vendored
99
thirdparty/thorvg/src/common/tvgBezier.cpp
vendored
@@ -29,7 +29,7 @@
|
|||||||
/* Internal Class Implementation */
|
/* Internal Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static float _lineLength(const Point& pt1, const Point& pt2)
|
static float _lineLengthApprox(const Point& pt1, const Point& pt2)
|
||||||
{
|
{
|
||||||
/* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
|
/* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
|
||||||
With alpha = 1, beta = 3/8, giving results with the largest error less
|
With alpha = 1, beta = 3/8, giving results with the largest error less
|
||||||
@@ -41,6 +41,59 @@ static float _lineLength(const Point& pt1, const Point& pt2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static float _lineLength(const Point& pt1, const Point& pt2)
|
||||||
|
{
|
||||||
|
Point diff = {pt2.x - pt1.x, pt2.y - pt1.y};
|
||||||
|
return sqrtf(diff.x * diff.x + diff.y * diff.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename LengthFunc>
|
||||||
|
float _bezLength(const Bezier& cur, LengthFunc lineLengthFunc)
|
||||||
|
{
|
||||||
|
Bezier left, right;
|
||||||
|
auto len = lineLengthFunc(cur.start, cur.ctrl1) + lineLengthFunc(cur.ctrl1, cur.ctrl2) + lineLengthFunc(cur.ctrl2, cur.end);
|
||||||
|
auto chord = lineLengthFunc(cur.start, cur.end);
|
||||||
|
|
||||||
|
if (fabsf(len - chord) > BEZIER_EPSILON) {
|
||||||
|
tvg::bezSplit(cur, left, right);
|
||||||
|
return _bezLength(left, lineLengthFunc) + _bezLength(right, lineLengthFunc);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename LengthFunc>
|
||||||
|
float _bezAt(const Bezier& bz, float at, float length, LengthFunc lineLengthFunc)
|
||||||
|
{
|
||||||
|
auto biggest = 1.0f;
|
||||||
|
auto smallest = 0.0f;
|
||||||
|
auto t = 0.5f;
|
||||||
|
|
||||||
|
//just in case to prevent an infinite loop
|
||||||
|
if (at <= 0) return 0.0f;
|
||||||
|
if (at >= length) return 1.0f;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto right = bz;
|
||||||
|
Bezier left;
|
||||||
|
bezSplitLeft(right, t, left);
|
||||||
|
length = _bezLength(left, lineLengthFunc);
|
||||||
|
if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (length < at) {
|
||||||
|
smallest = t;
|
||||||
|
t = (t + biggest) * 0.5f;
|
||||||
|
} else {
|
||||||
|
biggest = t;
|
||||||
|
t = (smallest + t) * 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
@@ -48,7 +101,7 @@ static float _lineLength(const Point& pt1, const Point& pt2)
|
|||||||
namespace tvg
|
namespace tvg
|
||||||
{
|
{
|
||||||
|
|
||||||
void bezSplit(const Bezier&cur, Bezier& left, Bezier& right)
|
void bezSplit(const Bezier& cur, Bezier& left, Bezier& right)
|
||||||
{
|
{
|
||||||
auto c = (cur.ctrl1.x + cur.ctrl2.x) * 0.5f;
|
auto c = (cur.ctrl1.x + cur.ctrl2.x) * 0.5f;
|
||||||
left.ctrl1.x = (cur.start.x + cur.ctrl1.x) * 0.5f;
|
left.ctrl1.x = (cur.start.x + cur.ctrl1.x) * 0.5f;
|
||||||
@@ -72,15 +125,13 @@ void bezSplit(const Bezier&cur, Bezier& left, Bezier& right)
|
|||||||
|
|
||||||
float bezLength(const Bezier& cur)
|
float bezLength(const Bezier& cur)
|
||||||
{
|
{
|
||||||
Bezier left, right;
|
return _bezLength(cur, _lineLength);
|
||||||
auto len = _lineLength(cur.start, cur.ctrl1) + _lineLength(cur.ctrl1, cur.ctrl2) + _lineLength(cur.ctrl2, cur.end);
|
}
|
||||||
auto chord = _lineLength(cur.start, cur.end);
|
|
||||||
|
|
||||||
if (fabsf(len - chord) > BEZIER_EPSILON) {
|
|
||||||
bezSplit(cur, left, right);
|
float bezLengthApprox(const Bezier& cur)
|
||||||
return bezLength(left) + bezLength(right);
|
{
|
||||||
}
|
return _bezLength(cur, _lineLengthApprox);
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -110,31 +161,13 @@ void bezSplitLeft(Bezier& cur, float at, Bezier& left)
|
|||||||
|
|
||||||
float bezAt(const Bezier& bz, float at, float length)
|
float bezAt(const Bezier& bz, float at, float length)
|
||||||
{
|
{
|
||||||
auto biggest = 1.0f;
|
return _bezAt(bz, at, length, _lineLength);
|
||||||
auto smallest = 0.0f;
|
}
|
||||||
auto t = 0.5f;
|
|
||||||
|
|
||||||
//just in case to prevent an infinite loop
|
|
||||||
if (at <= 0) return 0.0f;
|
|
||||||
if (at >= length) return 1.0f;
|
|
||||||
|
|
||||||
while (true) {
|
float bezAtApprox(const Bezier& bz, float at, float length)
|
||||||
auto right = bz;
|
{
|
||||||
Bezier left;
|
return _bezAt(bz, at, length, _lineLengthApprox);
|
||||||
bezSplitLeft(right, t, left);
|
|
||||||
length = bezLength(left);
|
|
||||||
if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (length < at) {
|
|
||||||
smallest = t;
|
|
||||||
t = (t + biggest) * 0.5f;
|
|
||||||
} else {
|
|
||||||
biggest = t;
|
|
||||||
t = (smallest + t) * 0.5f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
thirdparty/thorvg/src/common/tvgBezier.h
vendored
2
thirdparty/thorvg/src/common/tvgBezier.h
vendored
@@ -44,6 +44,8 @@ void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right);
|
|||||||
Point bezPointAt(const Bezier& bz, float t);
|
Point bezPointAt(const Bezier& bz, float t);
|
||||||
float bezAngleAt(const Bezier& bz, float t);
|
float bezAngleAt(const Bezier& bz, float t);
|
||||||
|
|
||||||
|
float bezLengthApprox(const Bezier& cur);
|
||||||
|
float bezAtApprox(const Bezier& bz, float at, float length);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //_TVG_BEZIER_H_
|
#endif //_TVG_BEZIER_H_
|
||||||
|
|||||||
1
thirdparty/thorvg/src/common/tvgLock.h
vendored
1
thirdparty/thorvg/src/common/tvgLock.h
vendored
@@ -68,3 +68,4 @@ namespace tvg {
|
|||||||
#endif //THORVG_THREAD_SUPPORT
|
#endif //THORVG_THREAD_SUPPORT
|
||||||
|
|
||||||
#endif //_TVG_LOCK_H_
|
#endif //_TVG_LOCK_H_
|
||||||
|
|
||||||
|
|||||||
1
thirdparty/thorvg/src/common/tvgMath.h
vendored
1
thirdparty/thorvg/src/common/tvgMath.h
vendored
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#define MATH_PI 3.14159265358979323846f
|
#define MATH_PI 3.14159265358979323846f
|
||||||
#define MATH_PI2 1.57079632679489661923f
|
#define MATH_PI2 1.57079632679489661923f
|
||||||
|
#define PATH_KAPPA 0.552284f
|
||||||
|
|
||||||
#define mathMin(x, y) (((x) < (y)) ? (x) : (y))
|
#define mathMin(x, y) (((x) < (y)) ? (x) : (y))
|
||||||
#define mathMax(x, y) (((x) > (y)) ? (x) : (y))
|
#define mathMax(x, y) (((x) > (y)) ? (x) : (y))
|
||||||
|
|||||||
@@ -47,9 +47,6 @@ void PngLoader::run(unsigned tid)
|
|||||||
surface.h = height;
|
surface.h = height;
|
||||||
surface.cs = ColorSpace::ABGR8888;
|
surface.cs = ColorSpace::ABGR8888;
|
||||||
surface.channelSize = sizeof(uint32_t);
|
surface.channelSize = sizeof(uint32_t);
|
||||||
|
|
||||||
if (state.info_png.color.colortype == LCT_RGBA) surface.premultiplied = false;
|
|
||||||
else surface.premultiplied = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ static char* _skipSpace(const char* str, const char* end)
|
|||||||
static char* _copyId(const char* str)
|
static char* _copyId(const char* str)
|
||||||
{
|
{
|
||||||
if (!str) return nullptr;
|
if (!str) return nullptr;
|
||||||
|
if (strlen(str) == 0) return nullptr;
|
||||||
|
|
||||||
return strdup(str);
|
return strdup(str);
|
||||||
}
|
}
|
||||||
@@ -377,19 +378,25 @@ static void _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* das
|
|||||||
|
|
||||||
static char* _idFromUrl(const char* url)
|
static char* _idFromUrl(const char* url)
|
||||||
{
|
{
|
||||||
url = _skipSpace(url, nullptr);
|
auto open = strchr(url, '(');
|
||||||
if ((*url) == '(') {
|
auto close = strchr(url, ')');
|
||||||
++url;
|
if (!open || !close || open >= close) return nullptr;
|
||||||
url = _skipSpace(url, nullptr);
|
|
||||||
|
open = strchr(url, '#');
|
||||||
|
if (!open || open >= close) return nullptr;
|
||||||
|
|
||||||
|
++open;
|
||||||
|
--close;
|
||||||
|
|
||||||
|
//trim the rest of the spaces if any
|
||||||
|
while (open < close && *close == ' ') --close;
|
||||||
|
|
||||||
|
//quick verification
|
||||||
|
for (auto id = open; id < close; id++) {
|
||||||
|
if (*id == ' ' || *id == '\'') return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*url) == '\'') ++url;
|
return strDuplicate(open, (close - open + 1));
|
||||||
if ((*url) == '#') ++url;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while (url[i] > ' ' && url[i] != ')' && url[i] != '\'') ++i;
|
|
||||||
|
|
||||||
return strDuplicate(url, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3494,7 +3501,7 @@ void SvgLoader::clear(bool all)
|
|||||||
free(loaderData.svgParse);
|
free(loaderData.svgParse);
|
||||||
loaderData.svgParse = nullptr;
|
loaderData.svgParse = nullptr;
|
||||||
|
|
||||||
for (auto gradient = loaderData.gradients.data; gradient < loaderData.gradients.end(); ++gradient) {
|
for (auto gradient = loaderData.gradients.begin(); gradient < loaderData.gradients.end(); ++gradient) {
|
||||||
(*gradient)->clear();
|
(*gradient)->clear();
|
||||||
free(*gradient);
|
free(*gradient);
|
||||||
}
|
}
|
||||||
@@ -3506,7 +3513,7 @@ void SvgLoader::clear(bool all)
|
|||||||
|
|
||||||
if (!all) return;
|
if (!all) return;
|
||||||
|
|
||||||
for (auto p = loaderData.images.data; p < loaderData.images.end(); ++p) {
|
for (auto p = loaderData.images.begin(); p < loaderData.images.end(); ++p) {
|
||||||
free(*p);
|
free(*p);
|
||||||
}
|
}
|
||||||
loaderData.images.reset();
|
loaderData.images.reset();
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ static bool _recognizeShape(SvgNode* node, Shape* shape)
|
|||||||
}
|
}
|
||||||
case SvgNodeType::Polygon: {
|
case SvgNodeType::Polygon: {
|
||||||
if (node->node.polygon.pts.count < 2) break;
|
if (node->node.polygon.pts.count < 2) break;
|
||||||
auto pts = node->node.polygon.pts.data;
|
auto pts = node->node.polygon.pts.begin();
|
||||||
shape->moveTo(pts[0], pts[1]);
|
shape->moveTo(pts[0], pts[1]);
|
||||||
for (pts += 2; pts < node->node.polygon.pts.end(); pts += 2) {
|
for (pts += 2; pts < node->node.polygon.pts.end(); pts += 2) {
|
||||||
shape->lineTo(pts[0], pts[1]);
|
shape->lineTo(pts[0], pts[1]);
|
||||||
@@ -419,7 +419,7 @@ static bool _recognizeShape(SvgNode* node, Shape* shape)
|
|||||||
}
|
}
|
||||||
case SvgNodeType::Polyline: {
|
case SvgNodeType::Polyline: {
|
||||||
if (node->node.polyline.pts.count < 2) break;
|
if (node->node.polyline.pts.count < 2) break;
|
||||||
auto pts = node->node.polyline.pts.data;
|
auto pts = node->node.polyline.pts.begin();
|
||||||
shape->moveTo(pts[0], pts[1]);
|
shape->moveTo(pts[0], pts[1]);
|
||||||
for (pts += 2; pts < node->node.polyline.pts.end(); pts += 2) {
|
for (pts += 2; pts < node->node.polyline.pts.end(); pts += 2) {
|
||||||
shape->lineTo(pts[0], pts[1]);
|
shape->lineTo(pts[0], pts[1]);
|
||||||
|
|||||||
@@ -201,7 +201,13 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr
|
|||||||
fill->radial.fy = cy + r * (fy - cy) / dist;
|
fill->radial.fy = cy + r * (fy - cy) / dist;
|
||||||
fill->radial.dx = cx - fill->radial.fx;
|
fill->radial.dx = cx - fill->radial.fx;
|
||||||
fill->radial.dy = cy - fill->radial.fy;
|
fill->radial.dy = cy - fill->radial.fy;
|
||||||
fill->radial.a = fill->radial.dr * fill->radial.dr - fill->radial.dx * fill->radial.dx - fill->radial.dy * fill->radial.dy;
|
// Prevent loss of precision on Apple Silicon when dr=dy and dx=0 due to FMA
|
||||||
|
// https://github.com/thorvg/thorvg/issues/2014
|
||||||
|
auto dr2 = fill->radial.dr * fill->radial.dr;
|
||||||
|
auto dx2 = fill->radial.dx * fill->radial.dx;
|
||||||
|
auto dy2 = fill->radial.dy * fill->radial.dy;
|
||||||
|
|
||||||
|
fill->radial.a = dr2 - dx2 - dy2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fill->radial.a > 0) fill->radial.invA = 1.0f / fill->radial.a;
|
if (fill->radial.a > 0) fill->radial.invA = 1.0f / fill->radial.a;
|
||||||
|
|||||||
@@ -50,12 +50,6 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw
|
|||||||
auto d2 = base[1] - base[2];
|
auto d2 = base[1] - base[2];
|
||||||
auto d3 = base[0] - base[1];
|
auto d3 = base[0] - base[1];
|
||||||
|
|
||||||
if (d1 == d2 || d2 == d3) {
|
|
||||||
if (d3.small()) angleIn = angleMid = angleOut = 0;
|
|
||||||
else angleIn = angleMid = angleOut = mathAtan(d3);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d1.small()) {
|
if (d1.small()) {
|
||||||
if (d2.small()) {
|
if (d2.small()) {
|
||||||
if (d3.small()) {
|
if (d3.small()) {
|
||||||
@@ -293,13 +287,13 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
|
|||||||
{
|
{
|
||||||
if (!outline) return false;
|
if (!outline) return false;
|
||||||
|
|
||||||
auto pt = outline->pts.data;
|
|
||||||
|
|
||||||
if (outline->pts.empty() || outline->cntrs.empty()) {
|
if (outline->pts.empty() || outline->cntrs.empty()) {
|
||||||
renderRegion.reset();
|
renderRegion.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto pt = outline->pts.begin();
|
||||||
|
|
||||||
auto xMin = pt->x;
|
auto xMin = pt->x;
|
||||||
auto xMax = pt->x;
|
auto xMax = pt->x;
|
||||||
auto yMin = pt->y;
|
auto yMin = pt->y;
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ struct SwShapeTask : SwTask
|
|||||||
shapeDelOutline(&shape, mpool, tid);
|
shapeDelOutline(&shape, mpool, tid);
|
||||||
|
|
||||||
//Clip Path
|
//Clip Path
|
||||||
for (auto clip = clips.data; clip < clips.end(); ++clip) {
|
for (auto clip = clips.begin(); clip < clips.end(); ++clip) {
|
||||||
auto clipper = static_cast<SwTask*>(*clip);
|
auto clipper = static_cast<SwTask*>(*clip);
|
||||||
//Clip shape rle
|
//Clip shape rle
|
||||||
if (shape.rle && !clipper->clip(shape.rle)) goto err;
|
if (shape.rle && !clipper->clip(shape.rle)) goto err;
|
||||||
@@ -242,7 +242,7 @@ struct SwSceneTask : SwTask
|
|||||||
rleMerge(sceneRle, clipper1->rle(), clipper2->rle());
|
rleMerge(sceneRle, clipper1->rle(), clipper2->rle());
|
||||||
|
|
||||||
//Unify the remained clippers
|
//Unify the remained clippers
|
||||||
for (auto rd = scene.data + 2; rd < scene.end(); ++rd) {
|
for (auto rd = scene.begin() + 2; rd < scene.end(); ++rd) {
|
||||||
auto clipper = static_cast<SwTask*>(*rd);
|
auto clipper = static_cast<SwTask*>(*rd);
|
||||||
rleMerge(sceneRle, sceneRle, clipper->rle());
|
rleMerge(sceneRle, sceneRle, clipper->rle());
|
||||||
}
|
}
|
||||||
@@ -301,7 +301,7 @@ struct SwImageTask : SwTask
|
|||||||
if (image.rle) {
|
if (image.rle) {
|
||||||
//Clear current task memorypool here if the clippers would use the same memory pool
|
//Clear current task memorypool here if the clippers would use the same memory pool
|
||||||
imageDelOutline(&image, mpool, tid);
|
imageDelOutline(&image, mpool, tid);
|
||||||
for (auto clip = clips.data; clip < clips.end(); ++clip) {
|
for (auto clip = clips.begin(); clip < clips.end(); ++clip) {
|
||||||
auto clipper = static_cast<SwTask*>(*clip);
|
auto clipper = static_cast<SwTask*>(*clip);
|
||||||
if (!clipper->clip(image.rle)) goto err;
|
if (!clipper->clip(image.rle)) goto err;
|
||||||
}
|
}
|
||||||
@@ -377,7 +377,7 @@ SwRenderer::~SwRenderer()
|
|||||||
|
|
||||||
bool SwRenderer::clear()
|
bool SwRenderer::clear()
|
||||||
{
|
{
|
||||||
for (auto task = tasks.data; task < tasks.end(); ++task) {
|
for (auto task = tasks.begin(); task < tasks.end(); ++task) {
|
||||||
if ((*task)->disposed) {
|
if ((*task)->disposed) {
|
||||||
delete(*task);
|
delete(*task);
|
||||||
} else {
|
} else {
|
||||||
@@ -451,7 +451,7 @@ bool SwRenderer::preRender()
|
|||||||
void SwRenderer::clearCompositors()
|
void SwRenderer::clearCompositors()
|
||||||
{
|
{
|
||||||
//Free Composite Caches
|
//Free Composite Caches
|
||||||
for (auto comp = compositors.data; comp < compositors.end(); ++comp) {
|
for (auto comp = compositors.begin(); comp < compositors.end(); ++comp) {
|
||||||
free((*comp)->compositor->image.data);
|
free((*comp)->compositor->image.data);
|
||||||
delete((*comp)->compositor);
|
delete((*comp)->compositor);
|
||||||
delete(*comp);
|
delete(*comp);
|
||||||
@@ -467,7 +467,7 @@ bool SwRenderer::postRender()
|
|||||||
rasterUnpremultiply(surface);
|
rasterUnpremultiply(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto task = tasks.data; task < tasks.end(); ++task) {
|
for (auto task = tasks.begin(); task < tasks.end(); ++task) {
|
||||||
if ((*task)->disposed) delete(*task);
|
if ((*task)->disposed) delete(*task);
|
||||||
else (*task)->pushed = false;
|
else (*task)->pushed = false;
|
||||||
}
|
}
|
||||||
@@ -624,7 +624,7 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs)
|
|||||||
auto reqChannelSize = CHANNEL_SIZE(cs);
|
auto reqChannelSize = CHANNEL_SIZE(cs);
|
||||||
|
|
||||||
//Use cached data
|
//Use cached data
|
||||||
for (auto p = compositors.data; p < compositors.end(); ++p) {
|
for (auto p = compositors.begin(); p < compositors.end(); ++p) {
|
||||||
if ((*p)->compositor->valid && (*p)->compositor->image.channelSize == reqChannelSize) {
|
if ((*p)->compositor->valid && (*p)->compositor->image.channelSize == reqChannelSize) {
|
||||||
cmp = *p;
|
cmp = *p;
|
||||||
break;
|
break;
|
||||||
@@ -723,7 +723,7 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform,
|
|||||||
//TODO: Failed threading them. It would be better if it's possible.
|
//TODO: Failed threading them. It would be better if it's possible.
|
||||||
//See: https://github.com/thorvg/thorvg/issues/1409
|
//See: https://github.com/thorvg/thorvg/issues/1409
|
||||||
//Guarantee composition targets get ready.
|
//Guarantee composition targets get ready.
|
||||||
for (auto clip = clips.data; clip < clips.end(); ++clip) {
|
for (auto clip = clips.begin(); clip < clips.end(); ++clip) {
|
||||||
static_cast<SwTask*>(*clip)->done();
|
static_cast<SwTask*>(*clip)->done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,7 +784,7 @@ RenderData SwRenderer::prepare(const Array<RenderData>& scene, RenderData data,
|
|||||||
//TODO: Failed threading them. It would be better if it's possible.
|
//TODO: Failed threading them. It would be better if it's possible.
|
||||||
//See: https://github.com/thorvg/thorvg/issues/1409
|
//See: https://github.com/thorvg/thorvg/issues/1409
|
||||||
//Guarantee composition targets get ready.
|
//Guarantee composition targets get ready.
|
||||||
for (auto task = scene.data; task < scene.end(); ++task) {
|
for (auto task = scene.begin(); task < scene.end(); ++task) {
|
||||||
static_cast<SwTask*>(*task)->done();
|
static_cast<SwTask*>(*task)->done();
|
||||||
}
|
}
|
||||||
return prepareCommon(task, transform, clips, opacity, flags);
|
return prepareCommon(task, transform, clips, opacity, flags);
|
||||||
|
|||||||
@@ -713,7 +713,7 @@ static void _decomposeOutline(RleWorker& rw)
|
|||||||
auto outline = rw.outline;
|
auto outline = rw.outline;
|
||||||
auto first = 0; //index of first point in contour
|
auto first = 0; //index of first point in contour
|
||||||
|
|
||||||
for (auto cntr = outline->cntrs.data; cntr < outline->cntrs.end(); ++cntr) {
|
for (auto cntr = outline->cntrs.begin(); cntr < outline->cntrs.end(); ++cntr) {
|
||||||
auto last = *cntr;
|
auto last = *cntr;
|
||||||
auto limit = outline->pts.data + last;
|
auto limit = outline->pts.data + last;
|
||||||
auto start = UPSCALE(outline->pts[first]);
|
auto start = UPSCALE(outline->pts[first]);
|
||||||
|
|||||||
@@ -37,13 +37,8 @@ struct Line
|
|||||||
|
|
||||||
static float _lineLength(const Point& pt1, const Point& pt2)
|
static float _lineLength(const Point& pt1, const Point& pt2)
|
||||||
{
|
{
|
||||||
/* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
|
|
||||||
With alpha = 1, beta = 3/8, giving results with the largest error less
|
|
||||||
than 7% compared to the exact value. */
|
|
||||||
Point diff = {pt2.x - pt1.x, pt2.y - pt1.y};
|
Point diff = {pt2.x - pt1.x, pt2.y - pt1.y};
|
||||||
if (diff.x < 0) diff.x = -diff.x;
|
return sqrtf(diff.x * diff.x + diff.y * diff.y);
|
||||||
if (diff.y < 0) diff.y = -diff.y;
|
|
||||||
return (diff.x > diff.y) ? (diff.x + diff.y * 0.375f) : (diff.y + diff.x * 0.375f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -377,9 +377,6 @@ static void _lineTo(SwStroke& stroke, const SwPoint& to)
|
|||||||
//a zero-length lineto is a no-op; avoid creating a spurious corner
|
//a zero-length lineto is a no-op; avoid creating a spurious corner
|
||||||
if (delta.zero()) return;
|
if (delta.zero()) return;
|
||||||
|
|
||||||
//compute length of line
|
|
||||||
auto angle = mathAtan(delta);
|
|
||||||
|
|
||||||
/* The lineLength is used to determine the intersection of strokes outlines.
|
/* The lineLength is used to determine the intersection of strokes outlines.
|
||||||
The scale needs to be reverted since the stroke width has not been scaled.
|
The scale needs to be reverted since the stroke width has not been scaled.
|
||||||
An alternative option is to scale the width of the stroke properly by
|
An alternative option is to scale the width of the stroke properly by
|
||||||
@@ -387,6 +384,7 @@ static void _lineTo(SwStroke& stroke, const SwPoint& to)
|
|||||||
delta.x = static_cast<SwCoord>(delta.x / stroke.sx);
|
delta.x = static_cast<SwCoord>(delta.x / stroke.sx);
|
||||||
delta.y = static_cast<SwCoord>(delta.y / stroke.sy);
|
delta.y = static_cast<SwCoord>(delta.y / stroke.sy);
|
||||||
auto lineLength = mathLength(delta);
|
auto lineLength = mathLength(delta);
|
||||||
|
auto angle = mathAtan(delta);
|
||||||
|
|
||||||
delta = {static_cast<SwCoord>(stroke.width), 0};
|
delta = {static_cast<SwCoord>(stroke.width), 0};
|
||||||
mathRotate(delta, angle + SW_ANGLE_PI2);
|
mathRotate(delta, angle + SW_ANGLE_PI2);
|
||||||
@@ -835,7 +833,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline)
|
|||||||
uint32_t first = 0;
|
uint32_t first = 0;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
for (auto cntr = outline.cntrs.data; cntr < outline.cntrs.end(); ++cntr, ++i) {
|
for (auto cntr = outline.cntrs.begin(); cntr < outline.cntrs.end(); ++cntr, ++i) {
|
||||||
auto last = *cntr; //index of last point in contour
|
auto last = *cntr; //index of last point in contour
|
||||||
auto limit = outline.pts.data + last;
|
auto limit = outline.pts.data + last;
|
||||||
|
|
||||||
|
|||||||
22
thirdparty/thorvg/src/renderer/tvgAnimation.cpp
vendored
22
thirdparty/thorvg/src/renderer/tvgAnimation.cpp
vendored
@@ -20,33 +20,13 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tvgCommon.h"
|
|
||||||
#include "tvgFrameModule.h"
|
#include "tvgFrameModule.h"
|
||||||
#include "tvgPaint.h"
|
#include "tvgAnimation.h"
|
||||||
#include "tvgPicture.h"
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Internal Class Implementation */
|
/* Internal Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
struct Animation::Impl
|
|
||||||
{
|
|
||||||
Picture* picture = nullptr;
|
|
||||||
|
|
||||||
Impl()
|
|
||||||
{
|
|
||||||
picture = Picture::gen().release();
|
|
||||||
PP(picture)->ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Impl()
|
|
||||||
{
|
|
||||||
if (PP(picture)->unref() == 0) {
|
|
||||||
delete(picture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|||||||
48
thirdparty/thorvg/src/renderer/tvgAnimation.h
vendored
Normal file
48
thirdparty/thorvg/src/renderer/tvgAnimation.h
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 the ThorVG project. All rights reserved.
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TVG_ANIMATION_H_
|
||||||
|
#define _TVG_ANIMATION_H_
|
||||||
|
|
||||||
|
#include "tvgCommon.h"
|
||||||
|
#include "tvgPaint.h"
|
||||||
|
#include "tvgPicture.h"
|
||||||
|
|
||||||
|
struct Animation::Impl
|
||||||
|
{
|
||||||
|
Picture* picture = nullptr;
|
||||||
|
|
||||||
|
Impl()
|
||||||
|
{
|
||||||
|
picture = Picture::gen().release();
|
||||||
|
PP(picture)->ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
~Impl()
|
||||||
|
{
|
||||||
|
if (PP(picture)->unref() == 0) {
|
||||||
|
delete(picture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_TVG_ANIMATION_H_
|
||||||
15
thirdparty/thorvg/src/renderer/tvgLoadModule.h
vendored
15
thirdparty/thorvg/src/renderer/tvgLoadModule.h
vendored
@@ -32,17 +32,20 @@ struct LoadModule
|
|||||||
INLIST_ITEM(LoadModule);
|
INLIST_ITEM(LoadModule);
|
||||||
|
|
||||||
//Use either hashkey(data) or hashpath(path)
|
//Use either hashkey(data) or hashpath(path)
|
||||||
uint64_t hashkey;
|
union {
|
||||||
char* hashpath = nullptr;
|
uintptr_t hashkey;
|
||||||
|
char* hashpath = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
FileType type; //current loader file type
|
FileType type; //current loader file type
|
||||||
uint16_t sharing = 0; //reference count
|
uint16_t sharing = 0; //reference count
|
||||||
bool readied = false; //read done already.
|
bool readied = false; //read done already.
|
||||||
|
bool pathcache = false; //cached by path
|
||||||
|
|
||||||
LoadModule(FileType type) : type(type) {}
|
LoadModule(FileType type) : type(type) {}
|
||||||
virtual ~LoadModule()
|
virtual ~LoadModule()
|
||||||
{
|
{
|
||||||
free(hashpath);
|
if (pathcache) free(hashpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool open(const string& path) { return false; }
|
virtual bool open(const string& path) { return false; }
|
||||||
@@ -57,6 +60,12 @@ struct LoadModule
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cached()
|
||||||
|
{
|
||||||
|
if (hashkey) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool close()
|
virtual bool close()
|
||||||
{
|
{
|
||||||
if (sharing == 0) return true;
|
if (sharing == 0) return true;
|
||||||
|
|||||||
44
thirdparty/thorvg/src/renderer/tvgLoader.cpp
vendored
44
thirdparty/thorvg/src/renderer/tvgLoader.cpp
vendored
@@ -57,9 +57,9 @@
|
|||||||
#include "tvgRawLoader.h"
|
#include "tvgRawLoader.h"
|
||||||
|
|
||||||
|
|
||||||
uint64_t HASH_KEY(const char* data, uint64_t size)
|
uintptr_t HASH_KEY(const char* data)
|
||||||
{
|
{
|
||||||
return (((uint64_t) data) << 32) | size;
|
return reinterpret_cast<uintptr_t>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
@@ -219,7 +219,7 @@ static LoadModule* _findFromCache(const string& path)
|
|||||||
auto loader = _activeLoaders.head;
|
auto loader = _activeLoaders.head;
|
||||||
|
|
||||||
while (loader) {
|
while (loader) {
|
||||||
if (loader->hashpath && !strcmp(loader->hashpath, path.c_str())) {
|
if (loader->pathcache && !strcmp(loader->hashpath, path.c_str())) {
|
||||||
++loader->sharing;
|
++loader->sharing;
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ static LoadModule* _findFromCache(const char* data, uint32_t size, const string&
|
|||||||
ScopedLock lock(key);
|
ScopedLock lock(key);
|
||||||
auto loader = _activeLoaders.head;
|
auto loader = _activeLoaders.head;
|
||||||
|
|
||||||
auto key = HASH_KEY(data, size);
|
auto key = HASH_KEY(data);
|
||||||
|
|
||||||
while (loader) {
|
while (loader) {
|
||||||
if (loader->type == type && loader->hashkey == key) {
|
if (loader->type == type && loader->hashkey == key) {
|
||||||
@@ -281,7 +281,7 @@ bool LoaderMgr::retrieve(LoadModule* loader)
|
|||||||
{
|
{
|
||||||
if (!loader) return false;
|
if (!loader) return false;
|
||||||
if (loader->close()) {
|
if (loader->close()) {
|
||||||
{
|
if (loader->cached()) {
|
||||||
ScopedLock lock(key);
|
ScopedLock lock(key);
|
||||||
_activeLoaders.remove(loader);
|
_activeLoaders.remove(loader);
|
||||||
}
|
}
|
||||||
@@ -300,6 +300,7 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
|
|||||||
if (auto loader = _findByPath(path)) {
|
if (auto loader = _findByPath(path)) {
|
||||||
if (loader->open(path)) {
|
if (loader->open(path)) {
|
||||||
loader->hashpath = strdup(path.c_str());
|
loader->hashpath = strdup(path.c_str());
|
||||||
|
loader->pathcache = true;
|
||||||
{
|
{
|
||||||
ScopedLock lock(key);
|
ScopedLock lock(key);
|
||||||
_activeLoaders.back(loader);
|
_activeLoaders.back(loader);
|
||||||
@@ -313,6 +314,7 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
|
|||||||
if (auto loader = _find(static_cast<FileType>(i))) {
|
if (auto loader = _find(static_cast<FileType>(i))) {
|
||||||
if (loader->open(path)) {
|
if (loader->open(path)) {
|
||||||
loader->hashpath = strdup(path.c_str());
|
loader->hashpath = strdup(path.c_str());
|
||||||
|
loader->pathcache = true;
|
||||||
{
|
{
|
||||||
ScopedLock lock(key);
|
ScopedLock lock(key);
|
||||||
_activeLoaders.back(loader);
|
_activeLoaders.back(loader);
|
||||||
@@ -338,7 +340,7 @@ LoadModule* LoaderMgr::loader(const char* key)
|
|||||||
auto loader = _activeLoaders.head;
|
auto loader = _activeLoaders.head;
|
||||||
|
|
||||||
while (loader) {
|
while (loader) {
|
||||||
if (loader->hashpath && strstr(loader->hashpath, key)) {
|
if (loader->pathcache && strstr(loader->hashpath, key)) {
|
||||||
++loader->sharing;
|
++loader->sharing;
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
@@ -350,15 +352,21 @@ LoadModule* LoaderMgr::loader(const char* key)
|
|||||||
|
|
||||||
LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy)
|
LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy)
|
||||||
{
|
{
|
||||||
if (auto loader = _findFromCache(data, size, mimeType)) return loader;
|
//Note that users could use the same data pointer with the different content.
|
||||||
|
//Thus caching is only valid for shareable.
|
||||||
|
if (!copy) {
|
||||||
|
if (auto loader = _findFromCache(data, size, mimeType)) return loader;
|
||||||
|
}
|
||||||
|
|
||||||
//Try with the given MimeType
|
//Try with the given MimeType
|
||||||
if (!mimeType.empty()) {
|
if (!mimeType.empty()) {
|
||||||
if (auto loader = _findByType(mimeType)) {
|
if (auto loader = _findByType(mimeType)) {
|
||||||
if (loader->open(data, size, copy)) {
|
if (loader->open(data, size, copy)) {
|
||||||
loader->hashkey = HASH_KEY(data, size);
|
if (!copy) {
|
||||||
ScopedLock lock(key);
|
loader->hashkey = HASH_KEY(data);
|
||||||
_activeLoaders.back(loader);
|
ScopedLock lock(key);
|
||||||
|
_activeLoaders.back(loader);
|
||||||
|
}
|
||||||
return loader;
|
return loader;
|
||||||
} else {
|
} else {
|
||||||
TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str());
|
TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str());
|
||||||
@@ -371,8 +379,8 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
|
|||||||
auto loader = _find(static_cast<FileType>(i));
|
auto loader = _find(static_cast<FileType>(i));
|
||||||
if (loader) {
|
if (loader) {
|
||||||
if (loader->open(data, size, copy)) {
|
if (loader->open(data, size, copy)) {
|
||||||
loader->hashkey = HASH_KEY(data, size);
|
if (!copy) {
|
||||||
{
|
loader->hashkey = HASH_KEY(data);
|
||||||
ScopedLock lock(key);
|
ScopedLock lock(key);
|
||||||
_activeLoaders.back(loader);
|
_activeLoaders.back(loader);
|
||||||
}
|
}
|
||||||
@@ -387,14 +395,18 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
|
|||||||
|
|
||||||
LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy)
|
LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy)
|
||||||
{
|
{
|
||||||
//TODO: should we check premultiplied??
|
//Note that users could use the same data pointer with the different content.
|
||||||
if (auto loader = _findFromCache((const char*)(data), w * h, "raw")) return loader;
|
//Thus caching is only valid for shareable.
|
||||||
|
if (!copy) {
|
||||||
|
//TODO: should we check premultiplied??
|
||||||
|
if (auto loader = _findFromCache((const char*)(data), w * h, "raw")) return loader;
|
||||||
|
}
|
||||||
|
|
||||||
//function is dedicated for raw images only
|
//function is dedicated for raw images only
|
||||||
auto loader = new RawLoader;
|
auto loader = new RawLoader;
|
||||||
if (loader->open(data, w, h, copy)) {
|
if (loader->open(data, w, h, copy)) {
|
||||||
loader->hashkey = HASH_KEY((const char*)data, w * h);
|
if (!copy) {
|
||||||
{
|
loader->hashkey = HASH_KEY((const char*)data);
|
||||||
ScopedLock lock(key);
|
ScopedLock lock(key);
|
||||||
_activeLoaders.back(loader);
|
_activeLoaders.back(loader);
|
||||||
}
|
}
|
||||||
|
|||||||
2
thirdparty/thorvg/src/renderer/tvgRender.h
vendored
2
thirdparty/thorvg/src/renderer/tvgRender.h
vendored
@@ -59,7 +59,7 @@ struct Surface
|
|||||||
uint32_t w = 0, h = 0;
|
uint32_t w = 0, h = 0;
|
||||||
ColorSpace cs = ColorSpace::Unsupported;
|
ColorSpace cs = ColorSpace::Unsupported;
|
||||||
uint8_t channelSize = 0;
|
uint8_t channelSize = 0;
|
||||||
bool premultiplied = 0; //Alpha-premultiplied
|
bool premultiplied = false; //Alpha-premultiplied
|
||||||
|
|
||||||
Surface()
|
Surface()
|
||||||
{
|
{
|
||||||
|
|||||||
7
thirdparty/thorvg/src/renderer/tvgSaver.cpp
vendored
7
thirdparty/thorvg/src/renderer/tvgSaver.cpp
vendored
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
#include "tvgSaveModule.h"
|
#include "tvgSaveModule.h"
|
||||||
|
#include "tvgPaint.h"
|
||||||
|
|
||||||
#ifdef THORVG_TVG_SAVER_SUPPORT
|
#ifdef THORVG_TVG_SAVER_SUPPORT
|
||||||
#include "tvgTvgSaver.h"
|
#include "tvgTvgSaver.h"
|
||||||
@@ -123,7 +124,7 @@ Result Saver::save(std::unique_ptr<Paint> paint, const string& path, bool compre
|
|||||||
|
|
||||||
//Already on saving an other resource.
|
//Already on saving an other resource.
|
||||||
if (pImpl->saveModule) {
|
if (pImpl->saveModule) {
|
||||||
delete(p);
|
if (P(p)->refCnt == 0) delete(p);
|
||||||
return Result::InsufficientCondition;
|
return Result::InsufficientCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ Result Saver::save(std::unique_ptr<Paint> paint, const string& path, bool compre
|
|||||||
pImpl->saveModule = saveModule;
|
pImpl->saveModule = saveModule;
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
} else {
|
} else {
|
||||||
delete(p);
|
if (P(p)->refCnt == 0) delete(p);
|
||||||
delete(saveModule);
|
delete(saveModule);
|
||||||
return Result::Unknown;
|
return Result::Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete(p);
|
if (P(p)->refCnt == 0) delete(p);
|
||||||
return Result::NonSupport;
|
return Result::NonSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
thirdparty/thorvg/src/renderer/tvgShape.cpp
vendored
14
thirdparty/thorvg/src/renderer/tvgShape.cpp
vendored
@@ -26,7 +26,7 @@
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Internal Class Implementation */
|
/* Internal Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
constexpr auto PATH_KAPPA = 0.552284f;
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
@@ -130,11 +130,11 @@ Result Shape::appendCircle(float cx, float cy, float rx, float ry) noexcept
|
|||||||
auto ryKappa = ry * PATH_KAPPA;
|
auto ryKappa = ry * PATH_KAPPA;
|
||||||
|
|
||||||
pImpl->grow(6, 13);
|
pImpl->grow(6, 13);
|
||||||
pImpl->moveTo(cx, cy - ry);
|
pImpl->moveTo(cx + rx, cy);
|
||||||
pImpl->cubicTo(cx + rxKappa, cy - ry, cx + rx, cy - ryKappa, cx + rx, cy);
|
|
||||||
pImpl->cubicTo(cx + rx, cy + ryKappa, cx + rxKappa, cy + ry, cx, cy + ry);
|
pImpl->cubicTo(cx + rx, cy + ryKappa, cx + rxKappa, cy + ry, cx, cy + ry);
|
||||||
pImpl->cubicTo(cx - rxKappa, cy + ry, cx - rx, cy + ryKappa, cx - rx, cy);
|
pImpl->cubicTo(cx - rxKappa, cy + ry, cx - rx, cy + ryKappa, cx - rx, cy);
|
||||||
pImpl->cubicTo(cx - rx, cy - ryKappa, cx - rxKappa, cy - ry, cx, cy - ry);
|
pImpl->cubicTo(cx - rx, cy - ryKappa, cx - rxKappa, cy - ry, cx, cy - ry);
|
||||||
|
pImpl->cubicTo(cx + rxKappa, cy - ry, cx + rx, cy - ryKappa, cx + rx, cy);
|
||||||
pImpl->close();
|
pImpl->close();
|
||||||
|
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
@@ -215,20 +215,20 @@ Result Shape::appendRect(float x, float y, float w, float h, float rx, float ry)
|
|||||||
pImpl->lineTo(x + w, y + h);
|
pImpl->lineTo(x + w, y + h);
|
||||||
pImpl->lineTo(x, y + h);
|
pImpl->lineTo(x, y + h);
|
||||||
pImpl->close();
|
pImpl->close();
|
||||||
//circle
|
//rounded rectangle or circle
|
||||||
} else {
|
} else {
|
||||||
auto hrx = rx * PATH_KAPPA;
|
auto hrx = rx * PATH_KAPPA;
|
||||||
auto hry = ry * PATH_KAPPA;
|
auto hry = ry * PATH_KAPPA;
|
||||||
pImpl->grow(10, 17);
|
pImpl->grow(10, 17);
|
||||||
pImpl->moveTo(x + w, y + ry);
|
pImpl->moveTo(x + rx, y);
|
||||||
|
pImpl->lineTo(x + w - rx, y);
|
||||||
|
pImpl->cubicTo(x + w - rx + hrx, y, x + w, y + ry - hry, x + w, y + ry);
|
||||||
pImpl->lineTo(x + w, y + h - ry);
|
pImpl->lineTo(x + w, y + h - ry);
|
||||||
pImpl->cubicTo(x + w, y + h - ry + hry, x + w - rx + hrx, y + h, x + w - rx, y + h);
|
pImpl->cubicTo(x + w, y + h - ry + hry, x + w - rx + hrx, y + h, x + w - rx, y + h);
|
||||||
pImpl->lineTo(x + rx, y + h);
|
pImpl->lineTo(x + rx, y + h);
|
||||||
pImpl->cubicTo(x + rx - hrx, y + h, x, y + h - ry + hry, x, y + h - ry);
|
pImpl->cubicTo(x + rx - hrx, y + h, x, y + h - ry + hry, x, y + h - ry);
|
||||||
pImpl->lineTo(x, y + ry);
|
pImpl->lineTo(x, y + ry);
|
||||||
pImpl->cubicTo(x, y + ry - hry, x + rx - hrx, y, x + rx, y);
|
pImpl->cubicTo(x, y + ry - hry, x + rx - hrx, y, x + rx, y);
|
||||||
pImpl->lineTo(x + w - rx, y);
|
|
||||||
pImpl->cubicTo(x + w - rx + hrx, y, x + w, y + ry - hry, x + w, y + ry);
|
|
||||||
pImpl->close();
|
pImpl->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
thirdparty/thorvg/src/renderer/tvgShape.h
vendored
2
thirdparty/thorvg/src/renderer/tvgShape.h
vendored
@@ -106,7 +106,7 @@ struct Shape::Impl
|
|||||||
{
|
{
|
||||||
//Path bounding size
|
//Path bounding size
|
||||||
if (rs.path.pts.count > 0 ) {
|
if (rs.path.pts.count > 0 ) {
|
||||||
auto pts = rs.path.pts.data;
|
auto pts = rs.path.pts.begin();
|
||||||
Point min = { pts->x, pts->y };
|
Point min = { pts->x, pts->y };
|
||||||
Point max = { pts->x, pts->y };
|
Point max = { pts->x, pts->y };
|
||||||
|
|
||||||
|
|||||||
@@ -123,14 +123,14 @@ struct TaskSchedulerImpl
|
|||||||
|
|
||||||
~TaskSchedulerImpl()
|
~TaskSchedulerImpl()
|
||||||
{
|
{
|
||||||
for (auto tq = taskQueues.data; tq < taskQueues.end(); ++tq) {
|
for (auto tq = taskQueues.begin(); tq < taskQueues.end(); ++tq) {
|
||||||
(*tq)->complete();
|
(*tq)->complete();
|
||||||
}
|
}
|
||||||
for (auto thread = threads.data; thread < threads.end(); ++thread) {
|
for (auto thread = threads.begin(); thread < threads.end(); ++thread) {
|
||||||
(*thread)->join();
|
(*thread)->join();
|
||||||
delete(*thread);
|
delete(*thread);
|
||||||
}
|
}
|
||||||
for (auto tq = taskQueues.data; tq < taskQueues.end(); ++tq) {
|
for (auto tq = taskQueues.begin(); tq < taskQueues.end(); ++tq) {
|
||||||
delete(*tq);
|
delete(*tq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
thirdparty/thorvg/update-thorvg.sh
vendored
2
thirdparty/thorvg/update-thorvg.sh
vendored
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
VERSION=0.12.5
|
VERSION=0.12.7
|
||||||
|
|
||||||
cd thirdparty/thorvg/ || true
|
cd thirdparty/thorvg/ || true
|
||||||
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/
|
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/
|
||||||
|
|||||||
Reference in New Issue
Block a user