Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

thorvg: Update to 0.14.8, and backport upstream fix for Bezier precision regression #96320

Merged
merged 1 commit into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion thirdparty/thorvg/inc/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
// For internal debugging:
//#define THORVG_LOG_ENABLED

#define THORVG_VERSION_STRING "0.14.7"
#define THORVG_VERSION_STRING "0.14.8"
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
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) {
8 changes: 8 additions & 0 deletions thirdparty/thorvg/src/common/tvgMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,11 @@ Point operator*(const Point& pt, const Matrix& m)
auto ty = pt.x * m.e21 + pt.y * m.e22 + m.e23;
return {tx, ty};
}

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;
return static_cast<uint8_t>(result);
}
1 change: 1 addition & 0 deletions thirdparty/thorvg/src/common/tvgMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,5 +259,6 @@ static inline T mathLerp(const T &start, const T &end, float t)
return static_cast<T>(start + (end - start) * t);
}

uint8_t mathLerp(const uint8_t &start, const uint8_t &end, float t);

#endif //_TVG_MATH_H_
6 changes: 5 additions & 1 deletion thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,11 @@ static bool _hslToRgb(float hue, float saturation, float brightness, uint8_t* re
float _red = 0, _green = 0, _blue = 0;
uint32_t i = 0;

while (hue < 0) hue += 360.0f;
hue = fmod(hue, 360.0f);
saturation = saturation > 0 ? std::min(saturation, 1.0f) : 0.0f;
brightness = brightness > 0 ? std::min(brightness, 1.0f) : 0.0f;

if (mathZero(saturation)) _red = _green = _blue = brightness;
else {
if (mathEqual(hue, 360.0)) hue = 0.0f;
Expand Down Expand Up @@ -714,7 +719,6 @@ static bool _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char**
const char* hue = nullptr;
if (_parseNumber(&content, &hue, &th) && hue) {
const char* saturation = nullptr;
th = float(uint32_t(th) % 360);
hue = _skipSpace(hue, nullptr);
hue = (char*)_skipComma(hue);
hue = _skipSpace(hue, nullptr);
Expand Down
12 changes: 8 additions & 4 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNU
}

//TODO: BlendMethod could remove the alpha parameter.
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, uint8_t a)
{
//if (s > d) => s - d
//else => d - s
Expand Down Expand Up @@ -404,8 +404,7 @@ static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t
return JOIN(255, c1, c2, c3);
}


static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
static inline uint32_t opBlendDirectMultiply(uint32_t s, uint32_t d, uint8_t a)
{
// s * d
auto c1 = MULTIPLY(C1(s), C1(d));
Expand All @@ -414,6 +413,10 @@ static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_
return JOIN(255, c1, c2, c3);
}

static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, uint8_t a)
{
return opBlendDirectMultiply(s, d, a) + ALPHA_BLEND(d, IA(s));
}

static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
{
Expand Down Expand Up @@ -492,7 +495,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);
Expand Down
19 changes: 12 additions & 7 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,25 @@ 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];
auto d3 = base[0] - base[1];

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);
Expand Down
2 changes: 1 addition & 1 deletion thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1383,7 +1383,7 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image,
*dst = INTERPOLATE(tmp, *dst, A(*src));
}
} else {
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) {
for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) {
auto tmp = ALPHA_BLEND(*src, opacity);
auto tmp2 = surface->blender(tmp, *dst, 255);
*dst = INTERPOLATE(tmp2, *dst, A(tmp));
Expand Down
5 changes: 2 additions & 3 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ struct SwShapeTask : SwTask
return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12));
}


bool clip(SwRleData* target) override
{
if (shape.fastTrack) rleClipRect(target, &bbox);
Expand Down Expand Up @@ -447,7 +446,7 @@ bool SwRenderer::renderShape(RenderData data)
}


bool SwRenderer::blend(BlendMethod method)
bool SwRenderer::blend(BlendMethod method, bool direct)
{
if (surface->blendMethod == method) return true;
surface->blendMethod = method;
Expand All @@ -460,7 +459,7 @@ bool SwRenderer::blend(BlendMethod method)
surface->blender = opBlendScreen;
break;
case BlendMethod::Multiply:
surface->blender = opBlendMultiply;
surface->blender = direct ? opBlendDirectMultiply : opBlendMultiply;
break;
case BlendMethod::Overlay:
surface->blender = opBlendOverlay;
Expand Down
2 changes: 1 addition & 1 deletion thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class SwRenderer : public RenderMethod
RenderRegion region(RenderData data) override;
RenderRegion viewport() override;
bool viewport(const RenderRegion& vp) override;
bool blend(BlendMethod method) override;
bool blend(BlendMethod method, bool direct) override;
ColorSpace colorSpace() override;
const Surface* mainSurface() override;

Expand Down
16 changes: 11 additions & 5 deletions thirdparty/thorvg/src/renderer/sw_engine/tvgSwStroke.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion thirdparty/thorvg/src/renderer/tvgLoadModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ struct FontLoader : LoadModule

FontLoader(FileType type) : LoadModule(type) {}

virtual bool request(Shape* shape, char* text, bool italic = false) = 0;
virtual bool request(Shape* shape, char* text) = 0;
virtual bool transform(Paint* paint, float fontSize, bool italic) = 0;
};

#endif //_TVG_LOAD_MODULE_H_
2 changes: 0 additions & 2 deletions thirdparty/thorvg/src/renderer/tvgPaint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ bool Paint::Impl::render(RenderMethod* renderer)

if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity);

renderer->blend(blendMethod);

bool ret;
PAINT_METHOD(ret, render(renderer));

Expand Down
2 changes: 2 additions & 0 deletions thirdparty/thorvg/src/renderer/tvgPicture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ bool Picture::Impl::needComposition(uint8_t opacity)
bool Picture::Impl::render(RenderMethod* renderer)
{
bool ret = false;
renderer->blend(picture->blend(), true);

if (surface) return renderer->renderImage(rd);
else if (paint) {
Compositor* cmp = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion thirdparty/thorvg/src/renderer/tvgRender.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ class RenderMethod
virtual RenderRegion region(RenderData data) = 0;
virtual RenderRegion viewport() = 0;
virtual bool viewport(const RenderRegion& vp) = 0;
virtual bool blend(BlendMethod method) = 0;
virtual bool blend(BlendMethod method, bool direct = false) = 0;
virtual ColorSpace colorSpace() = 0;
virtual const Surface* mainSurface() = 0;

Expand Down
2 changes: 2 additions & 0 deletions thirdparty/thorvg/src/renderer/tvgScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ struct Scene::Impl
Compositor* cmp = nullptr;
auto ret = true;

renderer->blend(scene->blend());

if (needComp) {
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
Expand Down
3 changes: 3 additions & 0 deletions thirdparty/thorvg/src/renderer/tvgShape.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,13 @@ struct Shape::Impl
Compositor* cmp = nullptr;
bool ret;

renderer->blend(shape->blend(), !needComp);

if (needComp) {
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
}

ret = renderer->renderShape(rd);
if (cmp) renderer->endComposite(cmp);
return ret;
Expand Down
Loading
Loading