Merge pull request #96658 from akien-mga/thorvg-0.14.9
thorvg: Update to 0.14.9
This commit is contained in:
commit
5675c76461
|
@ -907,7 +907,7 @@ instead of `miniz.h` as an external dependency.
|
||||||
## thorvg
|
## thorvg
|
||||||
|
|
||||||
- Upstream: https://github.com/thorvg/thorvg
|
- Upstream: https://github.com/thorvg/thorvg
|
||||||
- Version: 0.14.7 (e3a6bf5229a9671c385ee78bc33e6e6b611a9729, 2024)
|
- Version: 0.14.9 (81a0fbfd590873b21e53c3af77969c71d3d9b586, 2024)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|
|
@ -15,5 +15,5 @@
|
||||||
// For internal debugging:
|
// For internal debugging:
|
||||||
//#define THORVG_LOG_ENABLED
|
//#define THORVG_LOG_ENABLED
|
||||||
|
|
||||||
#define THORVG_VERSION_STRING "0.14.8"
|
#define THORVG_VERSION_STRING "0.14.9"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
From ac7d208ed8e4651c93ce1b2384070fccac9b6cb6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mira Grudzinska <mira@lottiefiles.com>
|
|
||||||
Date: Sun, 1 Sep 2024 22:36:18 +0200
|
|
||||||
Subject: [PATCH] sw_engine: handle small cubics
|
|
||||||
|
|
||||||
During the stroke's outline calculation, the function
|
|
||||||
handling small cubics set all angles to zero. Such cases
|
|
||||||
should be ignored, as further processing caused errors -
|
|
||||||
when the cubic was small but not zero, setting the angles
|
|
||||||
to zero resulted in incorrect outlines.
|
|
||||||
|
|
||||||
@Issue: https://github.com/godotengine/godot/issues/96262
|
|
||||||
---
|
|
||||||
src/renderer/sw_engine/tvgSwCommon.h | 3 ++-
|
|
||||||
src/renderer/sw_engine/tvgSwMath.cpp | 19 ++++++++++++-------
|
|
||||||
src/renderer/sw_engine/tvgSwStroke.cpp | 16 +++++++++++-----
|
|
||||||
3 files changed, 25 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/renderer/sw_engine/tvgSwCommon.h b/src/renderer/sw_engine/tvgSwCommon.h
|
|
||||||
index 893e9beca..158fe8ecd 100644
|
|
||||||
--- a/src/renderer/sw_engine/tvgSwCommon.h
|
|
||||||
+++ b/src/renderer/sw_engine/tvgSwCommon.h
|
|
||||||
@@ -491,7 +491,8 @@ SwFixed mathSin(SwFixed angle);
|
|
||||||
void mathSplitCubic(SwPoint* base);
|
|
||||||
SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
|
|
||||||
SwFixed mathLength(const SwPoint& pt);
|
|
||||||
-bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
|
|
||||||
+bool mathSmallCubic(const SwPoint* base);
|
|
||||||
+bool mathFlatCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
|
|
||||||
SwFixed mathMean(SwFixed angle1, SwFixed angle2);
|
|
||||||
SwPoint mathTransform(const Point* to, const Matrix& transform);
|
|
||||||
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
|
|
||||||
diff --git a/src/renderer/sw_engine/tvgSwMath.cpp b/src/renderer/sw_engine/tvgSwMath.cpp
|
|
||||||
index 1093edd62..b311be05f 100644
|
|
||||||
--- a/src/renderer/sw_engine/tvgSwMath.cpp
|
|
||||||
+++ b/src/renderer/sw_engine/tvgSwMath.cpp
|
|
||||||
@@ -44,7 +44,17 @@ SwFixed mathMean(SwFixed angle1, SwFixed angle2)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut)
|
|
||||||
+bool mathSmallCubic(const SwPoint* base)
|
|
||||||
+{
|
|
||||||
+ auto d1 = base[2] - base[3];
|
|
||||||
+ auto d2 = base[1] - base[2];
|
|
||||||
+ auto d3 = base[0] - base[1];
|
|
||||||
+
|
|
||||||
+ return d1.small() && d2.small() && d3.small();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+bool mathFlatCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut)
|
|
||||||
{
|
|
||||||
auto d1 = base[2] - base[3];
|
|
||||||
auto d2 = base[1] - base[2];
|
|
||||||
@@ -52,12 +62,7 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw
|
|
||||||
|
|
||||||
if (d1.small()) {
|
|
||||||
if (d2.small()) {
|
|
||||||
- if (d3.small()) {
|
|
||||||
- angleIn = angleMid = angleOut = 0;
|
|
||||||
- return true;
|
|
||||||
- } else {
|
|
||||||
- angleIn = angleMid = angleOut = mathAtan(d3);
|
|
||||||
- }
|
|
||||||
+ angleIn = angleMid = angleOut = mathAtan(d3);
|
|
||||||
} else {
|
|
||||||
if (d3.small()) {
|
|
||||||
angleIn = angleMid = angleOut = mathAtan(d2);
|
|
||||||
diff --git a/src/renderer/sw_engine/tvgSwStroke.cpp b/src/renderer/sw_engine/tvgSwStroke.cpp
|
|
||||||
index 575d12951..4679b72cc 100644
|
|
||||||
--- a/src/renderer/sw_engine/tvgSwStroke.cpp
|
|
||||||
+++ b/src/renderer/sw_engine/tvgSwStroke.cpp
|
|
||||||
@@ -441,11 +441,17 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl
|
|
||||||
//initialize with current direction
|
|
||||||
angleIn = angleOut = angleMid = stroke.angleIn;
|
|
||||||
|
|
||||||
- if (arc < limit && !mathSmallCubic(arc, angleIn, angleMid, angleOut)) {
|
|
||||||
- if (stroke.firstPt) stroke.angleIn = angleIn;
|
|
||||||
- mathSplitCubic(arc);
|
|
||||||
- arc += 3;
|
|
||||||
- continue;
|
|
||||||
+ if (arc < limit) {
|
|
||||||
+ if (mathSmallCubic(arc)) {
|
|
||||||
+ arc -= 3;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ if (!mathFlatCubic(arc, angleIn, angleMid, angleOut)) {
|
|
||||||
+ if (stroke.firstPt) stroke.angleIn = angleIn;
|
|
||||||
+ mathSplitCubic(arc);
|
|
||||||
+ arc += 3;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstArc) {
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
From 41d67213607e7ff20b7a3ca833f1cfde9780da65 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hermet Park <hermet@lottiefiles.com>
|
||||||
|
Date: Sat, 7 Sep 2024 01:35:09 +0900
|
||||||
|
Subject: [PATCH] renderer: ++reliability in text drawing
|
||||||
|
|
||||||
|
Allow the canvas to pass through
|
||||||
|
even if text elements are not properly supported.
|
||||||
|
|
||||||
|
issue: https://github.com/thorvg/thorvg/issues/2715
|
||||||
|
---
|
||||||
|
src/renderer/tvgText.h | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/thirdparty/thorvg/src/renderer/tvgText.h b/thirdparty/thorvg/src/renderer/tvgText.h
|
||||||
|
index 746b85bea6..55d33ffd4b 100644
|
||||||
|
--- a/thirdparty/thorvg/src/renderer/tvgText.h
|
||||||
|
+++ b/thirdparty/thorvg/src/renderer/tvgText.h
|
||||||
|
@@ -89,6 +89,7 @@ struct Text::Impl
|
||||||
|
|
||||||
|
bool render(RenderMethod* renderer)
|
||||||
|
{
|
||||||
|
+ if (!loader) return true;
|
||||||
|
renderer->blend(paint->blend(), true);
|
||||||
|
return PP(shape)->render(renderer);
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
diff --git a/thirdparty/thorvg/src/common/tvgLines.cpp b/thirdparty/thorvg/src/common/tvgLines.cpp
|
||||||
|
index 49d992f127..9d704900a5 100644
|
||||||
|
--- a/thirdparty/thorvg/src/common/tvgLines.cpp
|
||||||
|
+++ b/thirdparty/thorvg/src/common/tvgLines.cpp
|
||||||
|
@@ -79,7 +79,7 @@ float _bezAt(const Bezier& bz, float at, float length, LengthFunc lineLengthFunc
|
||||||
|
Bezier left;
|
||||||
|
bezSplitLeft(right, t, left);
|
||||||
|
length = _bezLength(left, lineLengthFunc);
|
||||||
|
- if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < 1e-3f) {
|
||||||
|
+ if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (length < at) {
|
|
@ -79,7 +79,7 @@ float _bezAt(const Bezier& bz, float at, float length, LengthFunc lineLengthFunc
|
||||||
Bezier left;
|
Bezier left;
|
||||||
bezSplitLeft(right, t, left);
|
bezSplitLeft(right, t, left);
|
||||||
length = _bezLength(left, lineLengthFunc);
|
length = _bezLength(left, lineLengthFunc);
|
||||||
if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < 1e-3f) {
|
if (fabsf(length - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (length < at) {
|
if (length < at) {
|
||||||
|
|
|
@ -43,9 +43,8 @@ bool mathInverse(const Matrix* m, Matrix* out)
|
||||||
m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) +
|
m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) +
|
||||||
m->e13 * (m->e21 * m->e32 - m->e22 * m->e31);
|
m->e13 * (m->e21 * m->e32 - m->e22 * m->e31);
|
||||||
|
|
||||||
if (mathZero(det)) return false;
|
auto invDet = 1.0f / det;
|
||||||
|
if (std::isinf(invDet)) return false;
|
||||||
auto invDet = 1 / det;
|
|
||||||
|
|
||||||
out->e11 = (m->e22 * m->e33 - m->e32 * m->e23) * invDet;
|
out->e11 = (m->e22 * m->e33 - m->e32 * m->e23) * invDet;
|
||||||
out->e12 = (m->e13 * m->e32 - m->e12 * m->e33) * invDet;
|
out->e12 = (m->e13 * m->e32 - m->e12 * m->e33) * invDet;
|
||||||
|
@ -137,7 +136,6 @@ Point operator*(const Point& pt, const Matrix& m)
|
||||||
uint8_t mathLerp(const uint8_t &start, const uint8_t &end, float t)
|
uint8_t mathLerp(const uint8_t &start, const uint8_t &end, float t)
|
||||||
{
|
{
|
||||||
auto result = static_cast<int>(start + (end - start) * t);
|
auto result = static_cast<int>(start + (end - start) * t);
|
||||||
if (result > 255) result = 255;
|
mathClamp(result, 0, 255);
|
||||||
else if (result < 0) result = 0;
|
|
||||||
return static_cast<uint8_t>(result);
|
return static_cast<uint8_t>(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
|
|
||||||
#define MATH_PI 3.14159265358979323846f
|
#define MATH_PI 3.14159265358979323846f
|
||||||
|
@ -68,6 +68,13 @@ static inline bool mathEqual(float a, float b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline void mathClamp(T& v, const T& min, const T& max)
|
||||||
|
{
|
||||||
|
if (v < min) v = min;
|
||||||
|
else if (v > max) v = max;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Matrix functions */
|
/* Matrix functions */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
|
@ -3288,6 +3288,7 @@ static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content,
|
||||||
for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) {
|
for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) {
|
||||||
if (!strncmp(tagName, graphicsTags[i].tag, sz)) {
|
if (!strncmp(tagName, graphicsTags[i].tag, sz)) {
|
||||||
loader->currentGraphicsNode = nullptr;
|
loader->currentGraphicsNode = nullptr;
|
||||||
|
if (!strncmp(tagName, "text", 4)) loader->openedTag = OpenedTagType::Other;
|
||||||
loader->stack.pop();
|
loader->stack.pop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3361,11 +3362,9 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
||||||
node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes);
|
node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes);
|
||||||
if (node && !empty) {
|
if (node && !empty) {
|
||||||
if (!strcmp(tagName, "text")) loader->openedTag = OpenedTagType::Text;
|
if (!strcmp(tagName, "text")) loader->openedTag = OpenedTagType::Text;
|
||||||
else {
|
auto defs = _createDefsNode(loader, nullptr, nullptr, 0, nullptr);
|
||||||
auto defs = _createDefsNode(loader, nullptr, nullptr, 0, nullptr);
|
loader->stack.push(defs);
|
||||||
loader->stack.push(defs);
|
loader->currentGraphicsNode = node;
|
||||||
loader->currentGraphicsNode = node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if ((gradientMethod = _findGradientFactory(tagName))) {
|
} else if ((gradientMethod = _findGradientFactory(tagName))) {
|
||||||
SvgStyleGradient* gradient;
|
SvgStyleGradient* gradient;
|
||||||
|
@ -3403,7 +3402,6 @@ static void _svgLoaderParserText(SvgLoaderData* loader, const char* content, uns
|
||||||
auto text = &loader->svgParse->node->node.text;
|
auto text = &loader->svgParse->node->node.text;
|
||||||
if (text->text) free(text->text);
|
if (text->text) free(text->text);
|
||||||
text->text = strDuplicate(content, length);
|
text->text = strDuplicate(content, length);
|
||||||
loader->openedTag = OpenedTagType::Other;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -495,8 +495,7 @@ SwFixed mathSin(SwFixed angle);
|
||||||
void mathSplitCubic(SwPoint* base);
|
void mathSplitCubic(SwPoint* base);
|
||||||
SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
|
SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
|
||||||
SwFixed mathLength(const SwPoint& pt);
|
SwFixed mathLength(const SwPoint& pt);
|
||||||
bool mathSmallCubic(const SwPoint* base);
|
bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
|
||||||
bool mathFlatCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
|
|
||||||
SwFixed mathMean(SwFixed angle1, SwFixed angle2);
|
SwFixed mathMean(SwFixed angle1, SwFixed angle2);
|
||||||
SwPoint mathTransform(const Point* to, const Matrix& transform);
|
SwPoint mathTransform(const Point* to, const Matrix& transform);
|
||||||
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
|
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
|
||||||
|
|
|
@ -44,17 +44,7 @@ SwFixed mathMean(SwFixed angle1, SwFixed angle2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool mathSmallCubic(const SwPoint* base)
|
bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut)
|
||||||
{
|
|
||||||
auto d1 = base[2] - base[3];
|
|
||||||
auto d2 = base[1] - base[2];
|
|
||||||
auto d3 = base[0] - base[1];
|
|
||||||
|
|
||||||
return d1.small() && d2.small() && d3.small();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool mathFlatCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut)
|
|
||||||
{
|
{
|
||||||
auto d1 = base[2] - base[3];
|
auto d1 = base[2] - base[3];
|
||||||
auto d2 = base[1] - base[2];
|
auto d2 = base[1] - base[2];
|
||||||
|
@ -62,7 +52,12 @@ bool mathFlatCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwF
|
||||||
|
|
||||||
if (d1.small()) {
|
if (d1.small()) {
|
||||||
if (d2.small()) {
|
if (d2.small()) {
|
||||||
angleIn = angleMid = angleOut = mathAtan(d3);
|
if (d3.small()) {
|
||||||
|
angleIn = angleMid = angleOut = 0;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
angleIn = angleMid = angleOut = mathAtan(d3);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (d3.small()) {
|
if (d3.small()) {
|
||||||
angleIn = angleMid = angleOut = mathAtan(d2);
|
angleIn = angleMid = angleOut = mathAtan(d2);
|
||||||
|
|
|
@ -210,7 +210,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
|
||||||
}
|
}
|
||||||
_outlineCubicTo(*dash.outline, &cur.ctrl1, &cur.ctrl2, &cur.end, transform);
|
_outlineCubicTo(*dash.outline, &cur.ctrl1, &cur.ctrl2, &cur.end, transform);
|
||||||
}
|
}
|
||||||
if (dash.curLen < 1 && TO_SWCOORD(len) > 1) {
|
if (dash.curLen < 0.1f && TO_SWCOORD(len) > 1) {
|
||||||
//move to next dash
|
//move to next dash
|
||||||
dash.curIdx = (dash.curIdx + 1) % dash.cnt;
|
dash.curIdx = (dash.curIdx + 1) % dash.cnt;
|
||||||
dash.curLen = dash.pattern[dash.curIdx];
|
dash.curLen = dash.pattern[dash.curIdx];
|
||||||
|
|
|
@ -441,17 +441,11 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl
|
||||||
//initialize with current direction
|
//initialize with current direction
|
||||||
angleIn = angleOut = angleMid = stroke.angleIn;
|
angleIn = angleOut = angleMid = stroke.angleIn;
|
||||||
|
|
||||||
if (arc < limit) {
|
if (arc < limit && !mathSmallCubic(arc, angleIn, angleMid, angleOut)) {
|
||||||
if (mathSmallCubic(arc)) {
|
if (stroke.firstPt) stroke.angleIn = angleIn;
|
||||||
arc -= 3;
|
mathSplitCubic(arc);
|
||||||
continue;
|
arc += 3;
|
||||||
}
|
continue;
|
||||||
if (!mathFlatCubic(arc, angleIn, angleMid, angleOut)) {
|
|
||||||
if (stroke.firstPt) stroke.angleIn = angleIn;
|
|
||||||
mathSplitCubic(arc);
|
|
||||||
arc += 3;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstArc) {
|
if (firstArc) {
|
||||||
|
|
|
@ -89,6 +89,7 @@ struct Text::Impl
|
||||||
|
|
||||||
bool render(RenderMethod* renderer)
|
bool render(RenderMethod* renderer)
|
||||||
{
|
{
|
||||||
|
if (!loader) return true;
|
||||||
renderer->blend(paint->blend(), true);
|
renderer->blend(paint->blend(), true);
|
||||||
return PP(shape)->render(renderer);
|
return PP(shape)->render(renderer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
VERSION=0.14.8
|
VERSION=0.14.9
|
||||||
# Uncomment and set a git hash to use specific commit instead of tag.
|
# Uncomment and set a git hash to use specific commit instead of tag.
|
||||||
#GIT_COMMIT=
|
#GIT_COMMIT=
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue