thorvg: Update to 0.14.8, and workaround Bezier precision regression
Fixes #96262 by backporting https://github.com/thorvg/thorvg/pull/2702.
This commit is contained in:
parent
7f86ca057a
commit
7375f9b923
|
@ -15,5 +15,5 @@
|
||||||
// For internal debugging:
|
// For internal debugging:
|
||||||
//#define THORVG_LOG_ENABLED
|
//#define THORVG_LOG_ENABLED
|
||||||
|
|
||||||
#define THORVG_VERSION_STRING "0.14.7"
|
#define THORVG_VERSION_STRING "0.14.8"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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) {
|
|
@ -133,3 +133,11 @@ Point operator*(const Point& pt, const Matrix& m)
|
||||||
auto ty = pt.x * m.e21 + pt.y * m.e22 + m.e23;
|
auto ty = pt.x * m.e21 + pt.y * m.e22 + m.e23;
|
||||||
return {tx, ty};
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -259,5 +259,6 @@ static inline T mathLerp(const T &start, const T &end, float t)
|
||||||
return static_cast<T>(start + (end - start) * 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_
|
#endif //_TVG_MATH_H_
|
||||||
|
|
|
@ -588,6 +588,11 @@ static bool _hslToRgb(float hue, float saturation, float brightness, uint8_t* re
|
||||||
float _red = 0, _green = 0, _blue = 0;
|
float _red = 0, _green = 0, _blue = 0;
|
||||||
uint32_t i = 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;
|
if (mathZero(saturation)) _red = _green = _blue = brightness;
|
||||||
else {
|
else {
|
||||||
if (mathEqual(hue, 360.0)) hue = 0.0f;
|
if (mathEqual(hue, 360.0)) hue = 0.0f;
|
||||||
|
@ -714,7 +719,6 @@ static bool _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char**
|
||||||
const char* hue = nullptr;
|
const char* hue = nullptr;
|
||||||
if (_parseNumber(&content, &hue, &th) && hue) {
|
if (_parseNumber(&content, &hue, &th) && hue) {
|
||||||
const char* saturation = nullptr;
|
const char* saturation = nullptr;
|
||||||
th = float(uint32_t(th) % 360);
|
|
||||||
hue = _skipSpace(hue, nullptr);
|
hue = _skipSpace(hue, nullptr);
|
||||||
hue = (char*)_skipComma(hue);
|
hue = (char*)_skipComma(hue);
|
||||||
hue = _skipSpace(hue, nullptr);
|
hue = _skipSpace(hue, nullptr);
|
||||||
|
|
|
@ -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.
|
//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
|
//if (s > d) => s - d
|
||||||
//else => d - s
|
//else => d - s
|
||||||
|
@ -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);
|
return JOIN(255, c1, c2, c3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t opBlendDirectMultiply(uint32_t s, uint32_t d, uint8_t a)
|
||||||
static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
|
||||||
{
|
{
|
||||||
// s * d
|
// s * d
|
||||||
auto c1 = MULTIPLY(C1(s), C1(d));
|
auto c1 = MULTIPLY(C1(s), C1(d));
|
||||||
|
@ -414,6 +413,10 @@ static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_
|
||||||
return JOIN(255, c1, c2, c3);
|
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)
|
static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||||
{
|
{
|
||||||
|
@ -492,7 +495,8 @@ 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, 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);
|
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,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 d1 = base[2] - base[3];
|
||||||
auto d2 = base[1] - base[2];
|
auto d2 = base[1] - base[2];
|
||||||
|
@ -52,12 +62,7 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw
|
||||||
|
|
||||||
if (d1.small()) {
|
if (d1.small()) {
|
||||||
if (d2.small()) {
|
if (d2.small()) {
|
||||||
if (d3.small()) {
|
angleIn = angleMid = angleOut = mathAtan(d3);
|
||||||
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);
|
||||||
|
|
|
@ -1383,7 +1383,7 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image,
|
||||||
*dst = INTERPOLATE(tmp, *dst, A(*src));
|
*dst = INTERPOLATE(tmp, *dst, A(*src));
|
||||||
}
|
}
|
||||||
} else {
|
} 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 tmp = ALPHA_BLEND(*src, opacity);
|
||||||
auto tmp2 = surface->blender(tmp, *dst, 255);
|
auto tmp2 = surface->blender(tmp, *dst, 255);
|
||||||
*dst = INTERPOLATE(tmp2, *dst, A(tmp));
|
*dst = INTERPOLATE(tmp2, *dst, A(tmp));
|
||||||
|
|
|
@ -100,7 +100,6 @@ struct SwShapeTask : SwTask
|
||||||
return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12));
|
return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool clip(SwRleData* target) override
|
bool clip(SwRleData* target) override
|
||||||
{
|
{
|
||||||
if (shape.fastTrack) rleClipRect(target, &bbox);
|
if (shape.fastTrack) rleClipRect(target, &bbox);
|
||||||
|
@ -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;
|
if (surface->blendMethod == method) return true;
|
||||||
surface->blendMethod = method;
|
surface->blendMethod = method;
|
||||||
|
@ -460,7 +459,7 @@ bool SwRenderer::blend(BlendMethod method)
|
||||||
surface->blender = opBlendScreen;
|
surface->blender = opBlendScreen;
|
||||||
break;
|
break;
|
||||||
case BlendMethod::Multiply:
|
case BlendMethod::Multiply:
|
||||||
surface->blender = opBlendMultiply;
|
surface->blender = direct ? opBlendDirectMultiply : opBlendMultiply;
|
||||||
break;
|
break;
|
||||||
case BlendMethod::Overlay:
|
case BlendMethod::Overlay:
|
||||||
surface->blender = opBlendOverlay;
|
surface->blender = opBlendOverlay;
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
RenderRegion region(RenderData data) override;
|
RenderRegion region(RenderData data) override;
|
||||||
RenderRegion viewport() override;
|
RenderRegion viewport() override;
|
||||||
bool viewport(const RenderRegion& vp) override;
|
bool viewport(const RenderRegion& vp) override;
|
||||||
bool blend(BlendMethod method) override;
|
bool blend(BlendMethod method, bool direct) override;
|
||||||
ColorSpace colorSpace() override;
|
ColorSpace colorSpace() override;
|
||||||
const Surface* mainSurface() override;
|
const Surface* mainSurface() override;
|
||||||
|
|
||||||
|
|
|
@ -441,11 +441,17 @@ 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 && !mathSmallCubic(arc, angleIn, angleMid, angleOut)) {
|
if (arc < limit) {
|
||||||
if (stroke.firstPt) stroke.angleIn = angleIn;
|
if (mathSmallCubic(arc)) {
|
||||||
mathSplitCubic(arc);
|
arc -= 3;
|
||||||
arc += 3;
|
continue;
|
||||||
continue;
|
}
|
||||||
|
if (!mathFlatCubic(arc, angleIn, angleMid, angleOut)) {
|
||||||
|
if (stroke.firstPt) stroke.angleIn = angleIn;
|
||||||
|
mathSplitCubic(arc);
|
||||||
|
arc += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstArc) {
|
if (firstArc) {
|
||||||
|
|
|
@ -101,7 +101,8 @@ struct FontLoader : LoadModule
|
||||||
|
|
||||||
FontLoader(FileType type) : LoadModule(type) {}
|
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_
|
#endif //_TVG_LOAD_MODULE_H_
|
||||||
|
|
|
@ -225,8 +225,6 @@ bool Paint::Impl::render(RenderMethod* renderer)
|
||||||
|
|
||||||
if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity);
|
if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity);
|
||||||
|
|
||||||
renderer->blend(blendMethod);
|
|
||||||
|
|
||||||
bool ret;
|
bool ret;
|
||||||
PAINT_METHOD(ret, render(renderer));
|
PAINT_METHOD(ret, render(renderer));
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,8 @@ bool Picture::Impl::needComposition(uint8_t opacity)
|
||||||
bool Picture::Impl::render(RenderMethod* renderer)
|
bool Picture::Impl::render(RenderMethod* renderer)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
renderer->blend(picture->blend(), true);
|
||||||
|
|
||||||
if (surface) return renderer->renderImage(rd);
|
if (surface) return renderer->renderImage(rd);
|
||||||
else if (paint) {
|
else if (paint) {
|
||||||
Compositor* cmp = nullptr;
|
Compositor* cmp = nullptr;
|
||||||
|
|
|
@ -296,7 +296,7 @@ public:
|
||||||
virtual RenderRegion region(RenderData data) = 0;
|
virtual RenderRegion region(RenderData data) = 0;
|
||||||
virtual RenderRegion viewport() = 0;
|
virtual RenderRegion viewport() = 0;
|
||||||
virtual bool viewport(const RenderRegion& vp) = 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 ColorSpace colorSpace() = 0;
|
||||||
virtual const Surface* mainSurface() = 0;
|
virtual const Surface* mainSurface() = 0;
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,8 @@ struct Scene::Impl
|
||||||
Compositor* cmp = nullptr;
|
Compositor* cmp = nullptr;
|
||||||
auto ret = true;
|
auto ret = true;
|
||||||
|
|
||||||
|
renderer->blend(scene->blend());
|
||||||
|
|
||||||
if (needComp) {
|
if (needComp) {
|
||||||
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
|
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
|
||||||
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
|
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
|
||||||
|
|
|
@ -54,10 +54,13 @@ struct Shape::Impl
|
||||||
Compositor* cmp = nullptr;
|
Compositor* cmp = nullptr;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
|
renderer->blend(shape->blend(), !needComp);
|
||||||
|
|
||||||
if (needComp) {
|
if (needComp) {
|
||||||
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
|
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
|
||||||
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
|
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = renderer->renderShape(rd);
|
ret = renderer->renderShape(rd);
|
||||||
if (cmp) renderer->endComposite(cmp);
|
if (cmp) renderer->endComposite(cmp);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -26,12 +26,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "tvgShape.h"
|
#include "tvgShape.h"
|
||||||
#include "tvgFill.h"
|
#include "tvgFill.h"
|
||||||
|
#include "tvgLoader.h"
|
||||||
#ifdef THORVG_TTF_LOADER_SUPPORT
|
|
||||||
#include "tvgTtfLoader.h"
|
|
||||||
#else
|
|
||||||
#include "tvgLoader.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct Text::Impl
|
struct Text::Impl
|
||||||
{
|
{
|
||||||
|
@ -69,6 +64,11 @@ struct Text::Impl
|
||||||
auto loader = LoaderMgr::loader(name);
|
auto loader = LoaderMgr::loader(name);
|
||||||
if (!loader) return Result::InsufficientCondition;
|
if (!loader) return Result::InsufficientCondition;
|
||||||
|
|
||||||
|
if (style && strstr(style, "italic")) italic = true;
|
||||||
|
else italic = false;
|
||||||
|
|
||||||
|
fontSize = size;
|
||||||
|
|
||||||
//Same resource has been loaded.
|
//Same resource has been loaded.
|
||||||
if (this->loader == loader) {
|
if (this->loader == loader) {
|
||||||
this->loader->sharing--; //make it sure the reference counting.
|
this->loader->sharing--; //make it sure the reference counting.
|
||||||
|
@ -78,8 +78,6 @@ struct Text::Impl
|
||||||
}
|
}
|
||||||
this->loader = static_cast<FontLoader*>(loader);
|
this->loader = static_cast<FontLoader*>(loader);
|
||||||
|
|
||||||
fontSize = size;
|
|
||||||
if (style && strstr(style, "italic")) italic = true;
|
|
||||||
changed = true;
|
changed = true;
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +89,7 @@ struct Text::Impl
|
||||||
|
|
||||||
bool render(RenderMethod* renderer)
|
bool render(RenderMethod* renderer)
|
||||||
{
|
{
|
||||||
|
renderer->blend(paint->blend(), true);
|
||||||
return PP(shape)->render(renderer);
|
return PP(shape)->render(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,13 +97,13 @@ struct Text::Impl
|
||||||
{
|
{
|
||||||
if (!loader) return false;
|
if (!loader) return false;
|
||||||
|
|
||||||
|
loader->request(shape, utf8);
|
||||||
//reload
|
//reload
|
||||||
if (changed) {
|
if (changed) {
|
||||||
loader->request(shape, utf8, italic);
|
|
||||||
loader->read();
|
loader->read();
|
||||||
changed = false;
|
changed = false;
|
||||||
}
|
}
|
||||||
return loader->resize(shape, fontSize, fontSize);
|
return loader->transform(shape, fontSize, italic);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, TVG_UNUSED bool clipper)
|
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, TVG_UNUSED bool clipper)
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
VERSION=0.14.7
|
VERSION=0.14.8
|
||||||
|
# Uncomment and set a git hash to use specific commit instead of tag.
|
||||||
|
#GIT_COMMIT=
|
||||||
|
|
||||||
cd thirdparty/thorvg/ || true
|
pushd "$(dirname "$0")"
|
||||||
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/
|
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/
|
||||||
|
|
||||||
mkdir tmp/ && pushd tmp/
|
mkdir tmp/ && pushd tmp/
|
||||||
|
|
||||||
# Release
|
# Release
|
||||||
curl -L -O https://github.com/thorvg/thorvg/archive/v$VERSION.tar.gz
|
if [ ! -z "$GIT_COMMIT" ]; then
|
||||||
# Current Github main branch tip
|
echo "Updating ThorVG to commit:" $GIT_COMMIT
|
||||||
#curl -L -O https://github.com/thorvg/thorvg/archive/refs/heads/main.tar.gz
|
curl -L -O https://github.com/thorvg/thorvg/archive/$GIT_COMMIT.tar.gz
|
||||||
|
else
|
||||||
|
echo "Updating ThorVG to tagged release:" $VERSION
|
||||||
|
curl -L -O https://github.com/thorvg/thorvg/archive/v$VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
|
||||||
tar --strip-components=1 -xvf *.tar.gz
|
tar --strip-components=1 -xvf *.tar.gz
|
||||||
rm *.tar.gz
|
rm *.tar.gz
|
||||||
|
@ -70,4 +76,4 @@ cp -rv src/loaders/jpg ../src/loaders/
|
||||||
|
|
||||||
popd
|
popd
|
||||||
rm -rf tmp
|
rm -rf tmp
|
||||||
|
popd
|
||||||
|
|
Loading…
Reference in New Issue