Browse Source

Merge pull request #96658 from akien-mga/thorvg-0.14.9

thorvg: Update to 0.14.9
Rémi Verschelde 11 months ago
parent
commit
5675c76461

+ 1 - 1
thirdparty/README.md

@@ -907,7 +907,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:

+ 1 - 1
thirdparty/thorvg/inc/config.h

@@ -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

+ 0 - 96
thirdparty/thorvg/patches/pr2702-sw_engine-handle-small-cubics.patch

@@ -1,96 +0,0 @@
-From ac7d208ed8e4651c93ce1b2384070fccac9b6cb6 Mon Sep 17 00:00:00 2001
-From: Mira Grudzinska <[email protected]>
-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) {

+ 25 - 0
thirdparty/thorvg/patches/pr2716-text-drawing-reliability.patch

@@ -0,0 +1,25 @@
+From 41d67213607e7ff20b7a3ca833f1cfde9780da65 Mon Sep 17 00:00:00 2001
+From: Hermet Park <[email protected]>
+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);
+     }

+ 13 - 0
thirdparty/thorvg/patches/revert-tvgLines-bezier-precision-change.patch

@@ -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) {

+ 1 - 1
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) {

+ 3 - 5
thirdparty/thorvg/src/common/tvgMath.cpp

@@ -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);
 }

+ 8 - 1
thirdparty/thorvg/src/common/tvgMath.h

@@ -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                                                     */
 /************************************************************************/

+ 4 - 6
thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp

@@ -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;
 }
 
 

+ 1 - 2
thirdparty/thorvg/src/renderer/sw_engine/tvgSwCommon.h

@@ -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);

+ 7 - 12
thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp

@@ -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);

+ 1 - 1
thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp

@@ -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];

+ 5 - 11
thirdparty/thorvg/src/renderer/sw_engine/tvgSwStroke.cpp

@@ -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) {

+ 1 - 0
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);
     }

+ 1 - 1
thirdparty/thorvg/update-thorvg.sh

@@ -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=