thorvg: Update to 0.14.9
Fixes #96491.
Update fix for #96262 to a simple revert of the problematic commit,
as the upstream fix is still being debated and caused other issues.
Also include fix for upstream regression 2715 added in 0.14.9.
(cherry picked from commit a6ab039f2b
)
This commit is contained in:
parent
7a7e4129bd
commit
99a8821a71
|
@ -882,7 +882,7 @@ instead of `miniz.h` as an external dependency.
|
|||
## thorvg
|
||||
|
||||
- Upstream: https://github.com/thorvg/thorvg
|
||||
- Version: 0.14.7 (e3a6bf5229a9671c385ee78bc33e6e6b611a9729, 2024)
|
||||
- Version: 0.14.9 (81a0fbfd590873b21e53c3af77969c71d3d9b586, 2024)
|
||||
- License: MIT
|
||||
|
||||
Files extracted from upstream source:
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
// For internal debugging:
|
||||
//#define THORVG_LOG_ENABLED
|
||||
|
||||
#define THORVG_VERSION_STRING "0.14.8"
|
||||
#define THORVG_VERSION_STRING "0.14.9"
|
||||
#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;
|
||||
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) {
|
||||
|
|
|
@ -43,9 +43,8 @@ bool mathInverse(const Matrix* m, Matrix* out)
|
|||
m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) +
|
||||
m->e13 * (m->e21 * m->e32 - m->e22 * m->e31);
|
||||
|
||||
if (mathZero(det)) return false;
|
||||
|
||||
auto invDet = 1 / det;
|
||||
auto invDet = 1.0f / det;
|
||||
if (std::isinf(invDet)) return false;
|
||||
|
||||
out->e11 = (m->e22 * m->e33 - m->e32 * m->e23) * 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)
|
||||
{
|
||||
auto result = static_cast<int>(start + (end - start) * t);
|
||||
if (result > 255) result = 255;
|
||||
else if (result < 0) result = 0;
|
||||
mathClamp(result, 0, 255);
|
||||
return static_cast<uint8_t>(result);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include "tvgCommon.h"
|
||||
|
||||
#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 */
|
||||
/************************************************************************/
|
||||
|
|
|
@ -3288,6 +3288,7 @@ static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content,
|
|||
for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) {
|
||||
if (!strncmp(tagName, graphicsTags[i].tag, sz)) {
|
||||
loader->currentGraphicsNode = nullptr;
|
||||
if (!strncmp(tagName, "text", 4)) loader->openedTag = OpenedTagType::Other;
|
||||
loader->stack.pop();
|
||||
break;
|
||||
}
|
||||
|
@ -3361,11 +3362,9 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
|
|||
node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes);
|
||||
if (node && !empty) {
|
||||
if (!strcmp(tagName, "text")) loader->openedTag = OpenedTagType::Text;
|
||||
else {
|
||||
auto defs = _createDefsNode(loader, nullptr, nullptr, 0, nullptr);
|
||||
loader->stack.push(defs);
|
||||
loader->currentGraphicsNode = node;
|
||||
}
|
||||
auto defs = _createDefsNode(loader, nullptr, nullptr, 0, nullptr);
|
||||
loader->stack.push(defs);
|
||||
loader->currentGraphicsNode = node;
|
||||
}
|
||||
} else if ((gradientMethod = _findGradientFactory(tagName))) {
|
||||
SvgStyleGradient* gradient;
|
||||
|
@ -3403,7 +3402,6 @@ static void _svgLoaderParserText(SvgLoaderData* loader, const char* content, uns
|
|||
auto text = &loader->svgParse->node->node.text;
|
||||
if (text->text) free(text->text);
|
||||
text->text = strDuplicate(content, length);
|
||||
loader->openedTag = OpenedTagType::Other;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -495,8 +495,7 @@ SwFixed mathSin(SwFixed angle);
|
|||
void mathSplitCubic(SwPoint* base);
|
||||
SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
|
||||
SwFixed mathLength(const SwPoint& pt);
|
||||
bool mathSmallCubic(const SwPoint* base);
|
||||
bool mathFlatCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
|
||||
bool mathSmallCubic(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);
|
||||
|
|
|
@ -44,17 +44,7 @@ SwFixed mathMean(SwFixed angle1, SwFixed angle2)
|
|||
}
|
||||
|
||||
|
||||
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)
|
||||
bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut)
|
||||
{
|
||||
auto d1 = base[2] - base[3];
|
||||
auto d2 = base[1] - base[2];
|
||||
|
@ -62,7 +52,12 @@ bool mathFlatCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwF
|
|||
|
||||
if (d1.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 {
|
||||
if (d3.small()) {
|
||||
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);
|
||||
}
|
||||
if (dash.curLen < 1 && TO_SWCOORD(len) > 1) {
|
||||
if (dash.curLen < 0.1f && TO_SWCOORD(len) > 1) {
|
||||
//move to next dash
|
||||
dash.curIdx = (dash.curIdx + 1) % dash.cnt;
|
||||
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
|
||||
angleIn = angleOut = angleMid = stroke.angleIn;
|
||||
|
||||
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 (arc < limit && !mathSmallCubic(arc, angleIn, angleMid, angleOut)) {
|
||||
if (stroke.firstPt) stroke.angleIn = angleIn;
|
||||
mathSplitCubic(arc);
|
||||
arc += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (firstArc) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
VERSION=0.14.8
|
||||
VERSION=0.14.9
|
||||
# Uncomment and set a git hash to use specific commit instead of tag.
|
||||
#GIT_COMMIT=
|
||||
|
||||
|
|
Loading…
Reference in New Issue