Skip to content

Commit 20be397

Browse files
committed
Merge pull request #97079 from akien-mga/thorvg-0.14.10
thorvg: Update to 0.14.10
2 parents 8a7555a + 0c0336f commit 20be397

File tree

16 files changed

+136
-76
lines changed

16 files changed

+136
-76
lines changed

thirdparty/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ instead of `miniz.h` as an external dependency.
907907
## thorvg
908908

909909
- Upstream: https://github.com/thorvg/thorvg
910-
- Version: 0.14.9 (81a0fbfd590873b21e53c3af77969c71d3d9b586, 2024)
910+
- Version: 0.14.10 (366dcd72850c360b49e841e568fc5a154d7cce9e, 2024)
911911
- License: MIT
912912

913913
Files extracted from upstream source:

thirdparty/thorvg/inc/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
// For internal debugging:
1616
//#define THORVG_LOG_ENABLED
1717

18-
#define THORVG_VERSION_STRING "0.14.9"
18+
#define THORVG_VERSION_STRING "0.14.10"
1919
#endif

thirdparty/thorvg/patches/pr2716-text-drawing-reliability.patch

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
From 8009c75465e5b35da2d5f53532bc65f6df202a3a Mon Sep 17 00:00:00 2001
2+
From: Hermet Park <[email protected]>
3+
Date: Tue, 17 Sep 2024 11:35:48 +0900
4+
Subject: [PATCH] renderer: hotfix a crash
5+
6+
prevent a nullptr memory access
7+
regression by f5337015e971d24379d2ee664895503ab8945e13
8+
9+
issue: https://github.com/godotengine/godot/issues/97078
10+
---
11+
src/renderer/tvgShape.h | 6 ++++--
12+
2 files changed, 4 insertions(+), 4 deletions(-)
13+
14+
diff --git a/src/renderer/tvgShape.h b/src/renderer/tvgShape.h
15+
index 221931dee..e120a85c6 100644
16+
--- a/src/renderer/tvgShape.h
17+
+++ b/src/renderer/tvgShape.h
18+
@@ -51,8 +51,9 @@ struct Shape::Impl
19+
20+
bool render(RenderMethod* renderer)
21+
{
22+
+ if (!rd) return false;
23+
+
24+
Compositor* cmp = nullptr;
25+
- bool ret;
26+
27+
renderer->blend(shape->blend());
28+
29+
@@ -61,7 +62,7 @@ struct Shape::Impl
30+
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
31+
}
32+
33+
- ret = renderer->renderShape(rd);
34+
+ auto ret = renderer->renderShape(rd);
35+
if (cmp) renderer->endComposite(cmp);
36+
return ret;
37+
}
38+
@@ -117,6 +118,7 @@ struct Shape::Impl
39+
40+
RenderRegion bounds(RenderMethod* renderer)
41+
{
42+
+ if (!rd) return {0, 0, 0, 0};
43+
return renderer->region(rd);
44+
}
45+

thirdparty/thorvg/src/common/tvgStr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,14 @@ char* strDuplicate(const char *str, size_t n)
229229
return (char *) memcpy(ret, str, n);
230230
}
231231

232+
char* strAppend(char* lhs, const char* rhs, size_t n)
233+
{
234+
if (!rhs) return lhs;
235+
if (!lhs) return strDuplicate(rhs, n);
236+
lhs = (char*)realloc(lhs, strlen(lhs) + n + 1);
237+
return strncat(lhs, rhs, n);
238+
}
239+
232240
char* strDirname(const char* path)
233241
{
234242
const char *ptr = strrchr(path, '/');

thirdparty/thorvg/src/common/tvgStr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace tvg
3131
float strToFloat(const char *nPtr, char **endPtr); //convert to float
3232
int str2int(const char* str, size_t n); //convert to integer
3333
char* strDuplicate(const char *str, size_t n); //copy the string
34+
char* strAppend(char* lhs, const char* rhs, size_t n); //append the rhs to the lhs
3435
char* strDirname(const char* path); //return the full directory name
3536

3637
}

thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,6 +2183,7 @@ static SvgNode* _createTextNode(SvgLoaderData* loader, SvgNode* parent, const ch
21832183
//TODO: support the def font and size as used in a system?
21842184
loader->svgParse->node->node.text.fontSize = 10.0f;
21852185
loader->svgParse->node->node.text.fontFamily = nullptr;
2186+
loader->svgParse->node->node.text.text = nullptr;
21862187

21872188
func(buf, bufLength, _attrParseTextNode, loader);
21882189

@@ -3400,8 +3401,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
34003401
static void _svgLoaderParserText(SvgLoaderData* loader, const char* content, unsigned int length)
34013402
{
34023403
auto text = &loader->svgParse->node->node.text;
3403-
if (text->text) free(text->text);
3404-
text->text = strDuplicate(content, length);
3404+
text->text = strAppend(text->text, content, length);
34053405
}
34063406

34073407

thirdparty/thorvg/src/renderer/sw_engine/tvgSwCommon.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNU
367367
}
368368

369369
//TODO: BlendMethod could remove the alpha parameter.
370-
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, uint8_t a)
370+
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
371371
{
372372
//if (s > d) => s - d
373373
//else => d - s
@@ -404,7 +404,7 @@ static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t
404404
return JOIN(255, c1, c2, c3);
405405
}
406406

407-
static inline uint32_t opBlendDirectMultiply(uint32_t s, uint32_t d, uint8_t a)
407+
static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
408408
{
409409
// s * d
410410
auto c1 = MULTIPLY(C1(s), C1(d));
@@ -413,11 +413,6 @@ static inline uint32_t opBlendDirectMultiply(uint32_t s, uint32_t d, uint8_t a)
413413
return JOIN(255, c1, c2, c3);
414414
}
415415

416-
static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, uint8_t a)
417-
{
418-
return opBlendDirectMultiply(s, d, a) + ALPHA_BLEND(d, IA(s));
419-
}
420-
421416
static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
422417
{
423418
// if (2 * d < da) => 2 * s * d,
@@ -570,7 +565,7 @@ bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8
570565
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& bbox, uint8_t opacity);
571566
bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
572567
bool rasterGradientStroke(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity);
573-
bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
568+
bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h, pixel_t val = 0);
574569
void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len);
575570
void rasterGrayscale8(uint8_t *dst, uint8_t val, uint32_t offset, int32_t len);
576571
void rasterUnpremultiply(Surface* surface);

thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -423,12 +423,11 @@ static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, uint8_
423423
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
424424
auto color = surface->join(r, g, b, a);
425425
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
426-
auto ialpha = 255 - a;
427426

428427
for (uint32_t y = 0; y < h; ++y) {
429428
auto dst = &buffer[y * surface->stride];
430429
for (uint32_t x = 0; x < w; ++x, ++dst) {
431-
*dst = surface->blender(color, *dst, ialpha);
430+
*dst = surface->blender(color, *dst, 255);
432431
}
433432
}
434433
return true;
@@ -595,17 +594,16 @@ static bool _rasterBlendingRle(SwSurface* surface, const SwRleData* rle, uint8_t
595594

596595
auto span = rle->spans;
597596
auto color = surface->join(r, g, b, a);
598-
auto ialpha = 255 - a;
599597

600598
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
601599
auto dst = &surface->buf32[span->y * surface->stride + span->x];
602600
if (span->coverage == 255) {
603601
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
604-
*dst = surface->blender(color, *dst, ialpha);
602+
*dst = surface->blender(color, *dst, 255);
605603
}
606604
} else {
607605
for (uint32_t x = 0; x < span->len; ++x, ++dst) {
608-
auto tmp = surface->blender(color, *dst, ialpha);
606+
auto tmp = surface->blender(color, *dst, 255);
609607
*dst = INTERPOLATE(tmp, *dst, span->coverage);
610608
}
611609
}
@@ -813,9 +811,8 @@ static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage* ima
813811
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++dst) {
814812
SCALED_IMAGE_RANGE_X
815813
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
816-
if (opacity < 255) src = ALPHA_BLEND(src, opacity);
817814
auto tmp = surface->blender(src, *dst, 255);
818-
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src)));
815+
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(alpha, A(src)));
819816
}
820817
}
821818
}
@@ -981,18 +978,12 @@ static bool _rasterDirectBlendingRleImage(SwSurface* surface, const SwImage* ima
981978
auto alpha = MULTIPLY(span->coverage, opacity);
982979
if (alpha == 255) {
983980
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) {
984-
*dst = surface->blender(*img, *dst, IA(*img));
985-
}
986-
} else if (opacity == 255) {
987-
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) {
988-
auto tmp = surface->blender(*img, *dst, 255);
989-
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(*img)));
981+
*dst = surface->blender(*img, *dst, 255);
990982
}
991983
} else {
992984
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) {
993-
auto src = ALPHA_BLEND(*img, opacity);
994-
auto tmp = surface->blender(src, *dst, IA(src));
995-
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src)));
985+
auto tmp = surface->blender(*img, *dst, 255);
986+
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(alpha, A(*img)));
996987
}
997988
}
998989
}
@@ -1164,9 +1155,8 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image,
11641155
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
11651156
SCALED_IMAGE_RANGE_X
11661157
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
1167-
if (opacity < 255) ALPHA_BLEND(src, opacity);
11681158
auto tmp = surface->blender(src, *dst, 255);
1169-
*dst = INTERPOLATE(tmp, *dst, A(src));
1159+
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(opacity, A(src)));
11701160
}
11711161
}
11721162
return true;
@@ -1348,11 +1338,13 @@ static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, c
13481338
auto src = sbuffer;
13491339
if (opacity == 255) {
13501340
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
1351-
*dst = MULTIPLY(A(*src), alpha(cmp));
1341+
auto tmp = MULTIPLY(A(*src), alpha(cmp));
1342+
*dst = tmp + MULTIPLY(*dst, 255 - tmp);
13521343
}
13531344
} else {
13541345
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
1355-
*dst = MULTIPLY(A(*src), MULTIPLY(opacity, alpha(cmp)));
1346+
auto tmp = MULTIPLY(A(*src), MULTIPLY(opacity, alpha(cmp)));
1347+
*dst = tmp + MULTIPLY(*dst, 255 - tmp);
13561348
}
13571349
}
13581350
buffer += surface->stride;
@@ -1384,9 +1376,8 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image,
13841376
}
13851377
} else {
13861378
for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) {
1387-
auto tmp = ALPHA_BLEND(*src, opacity);
1388-
auto tmp2 = surface->blender(tmp, *dst, 255);
1389-
*dst = INTERPOLATE(tmp2, *dst, A(tmp));
1379+
auto tmp = surface->blender(*src, *dst, 255);
1380+
*dst = INTERPOLATE(tmp, *dst, MULTIPLY(opacity, A(*src)));
13901381
}
13911382
}
13921383
dbuffer += surface->stride;
@@ -1442,12 +1433,52 @@ static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const S
14421433
}
14431434

14441435

1436+
static bool _rasterDirectMattedBlendingImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
1437+
{
1438+
if (surface->channelSize == sizeof(uint8_t)) {
1439+
TVGERR("SW_ENGINE", "Not supported grayscale image!");
1440+
return false;
1441+
}
1442+
1443+
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
1444+
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
1445+
auto csize = surface->compositor->image.channelSize;
1446+
auto alpha = surface->alpha(surface->compositor->method);
1447+
auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
1448+
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; //compositor buffer
1449+
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
1450+
1451+
for (uint32_t y = 0; y < h; ++y) {
1452+
auto dst = buffer;
1453+
auto cmp = cbuffer;
1454+
auto src = sbuffer;
1455+
if (opacity == 255) {
1456+
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
1457+
auto tmp = ALPHA_BLEND(*src, alpha(cmp));
1458+
*dst = INTERPOLATE(surface->blender(tmp, *dst, 255), *dst, A(tmp));
1459+
}
1460+
} else {
1461+
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
1462+
auto tmp = ALPHA_BLEND(*src, alpha(cmp));
1463+
*dst = INTERPOLATE(surface->blender(tmp, *dst, 255), *dst, MULTIPLY(opacity, A(tmp)));
1464+
}
1465+
}
1466+
buffer += surface->stride;
1467+
cbuffer += surface->compositor->image.stride * csize;
1468+
sbuffer += image->stride;
1469+
}
1470+
return true;
1471+
}
1472+
1473+
14451474
//Blenders for the following scenarios: [Composition / Non-Composition] * [Opaque / Translucent]
14461475
static bool _directImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
14471476
{
14481477
if (_compositing(surface)) {
1449-
if (_matting(surface)) return _rasterDirectMattedImage(surface, image, region, opacity);
1450-
else return _rasterDirectMaskedImage(surface, image, region, opacity);
1478+
if (_matting(surface)) {
1479+
if (_blending(surface)) return _rasterDirectMattedBlendingImage(surface, image, region, opacity);
1480+
else return _rasterDirectMattedImage(surface, image, region, opacity);
1481+
} else return _rasterDirectMaskedImage(surface, image, region, opacity);
14511482
} else if (_blending(surface)) {
14521483
return _rasterDirectBlendingImage(surface, image, region, opacity);
14531484
} else {
@@ -1843,19 +1874,19 @@ bool rasterCompositor(SwSurface* surface)
18431874
}
18441875

18451876

1846-
bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
1877+
bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h, pixel_t val)
18471878
{
18481879
if (!surface || !surface->buf32 || surface->stride == 0 || surface->w == 0 || surface->h == 0) return false;
18491880

18501881
//32 bits
18511882
if (surface->channelSize == sizeof(uint32_t)) {
18521883
//full clear
18531884
if (w == surface->stride) {
1854-
rasterPixel32(surface->buf32, 0x00000000, surface->stride * y, w * h);
1885+
rasterPixel32(surface->buf32, val, surface->stride * y, w * h);
18551886
//partial clear
18561887
} else {
18571888
for (uint32_t i = 0; i < h; i++) {
1858-
rasterPixel32(surface->buf32, 0x00000000, (surface->stride * y + x) + (surface->stride * i), w);
1889+
rasterPixel32(surface->buf32, val, (surface->stride * y + x) + (surface->stride * i), w);
18591890
}
18601891
}
18611892
//8 bits

thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ bool SwRenderer::renderShape(RenderData data)
446446
}
447447

448448

449-
bool SwRenderer::blend(BlendMethod method, bool direct)
449+
bool SwRenderer::blend(BlendMethod method)
450450
{
451451
if (surface->blendMethod == method) return true;
452452
surface->blendMethod = method;
@@ -459,7 +459,7 @@ bool SwRenderer::blend(BlendMethod method, bool direct)
459459
surface->blender = opBlendScreen;
460460
break;
461461
case BlendMethod::Multiply:
462-
surface->blender = direct ? opBlendDirectMultiply : opBlendMultiply;
462+
surface->blender = opBlendMultiply;
463463
break;
464464
case BlendMethod::Overlay:
465465
surface->blender = opBlendOverlay;
@@ -606,7 +606,10 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs)
606606
cmp->w = cmp->compositor->image.w;
607607
cmp->h = cmp->compositor->image.h;
608608

609-
rasterClear(cmp, x, y, w, h);
609+
/* TODO: Currently, only blending might work.
610+
Blending and composition must be handled together. */
611+
auto color = (surface->blender && !surface->compositor) ? 0x00ffffff : 0x00000000;
612+
rasterClear(cmp, x, y, w, h, color);
610613

611614
//Switch render target
612615
surface = cmp;

0 commit comments

Comments
 (0)