Skip to content

Commit bb0b5f1

Browse files
committed
Merge pull request #106885 from Chubercik/thorvg-0.15.13
thorvg: Update to 0.15.13
2 parents eef13d5 + 5c94127 commit bb0b5f1

File tree

14 files changed

+71
-69
lines changed

14 files changed

+71
-69
lines changed

thirdparty/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ Patches:
970970
## thorvg
971971

972972
- Upstream: https://github.com/thorvg/thorvg
973-
- Version: 0.15.12 (91bd6f35b94e92abfc1a320632e66cd124943524, 2025)
973+
- Version: 0.15.13 (c597365b99f27cb46e2a5ac2942da45bb73d5a55, 2025)
974974
- License: MIT
975975

976976
Files extracted from upstream source:
@@ -981,7 +981,6 @@ Files extracted from upstream source:
981981
Patches:
982982

983983
- `0001-revert-tvglines-bezier-precision.patch` (GH-96658)
984-
- `0002-png-explicit-variable-scope.patch` (GH-105093)
985984

986985

987986
## tinyexr

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.15.12"
18+
#define THORVG_VERSION_STRING "0.15.13"
1919
#endif

thirdparty/thorvg/patches/0002-png-explicit-variable-scope.patch

Lines changed: 0 additions & 13 deletions
This file was deleted.

thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ bool JpgLoader::read()
132132

133133
//determine the image format
134134
TJPF format;
135-
if (cs == ColorSpace::ARGB8888 || cs == ColorSpace::ARGB8888S) {
135+
if (ImageLoader::cs == ColorSpace::ARGB8888 || ImageLoader::cs == ColorSpace::ARGB8888S) {
136136
format = TJPF_BGRX;
137137
surface.cs = ColorSpace::ARGB8888;
138138
} else {

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

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3368,6 +3368,13 @@ static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content,
33683368
}
33693369
}
33703370

3371+
for (unsigned int i = 0; i < sizeof(gradientTags) / sizeof(gradientTags[0]); i++) {
3372+
if (!strncmp(tagName, gradientTags[i].tag, sz)) {
3373+
loader->gradientStack.pop();
3374+
break;
3375+
}
3376+
}
3377+
33713378
for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) {
33723379
if (!strncmp(tagName, graphicsTags[i].tag, sz)) {
33733380
loader->currentGraphicsNode = nullptr;
@@ -3439,7 +3446,6 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
34393446
if (node->type != SvgNodeType::Defs || !empty) {
34403447
loader->stack.push(node);
34413448
}
3442-
loader->latestGradient = nullptr;
34433449
} else if ((method = _findGraphicsFactory(tagName))) {
34443450
if (loader->stack.count > 0) parent = loader->stack.last();
34453451
else parent = loader->doc;
@@ -3450,34 +3456,35 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
34503456
loader->stack.push(defs);
34513457
loader->currentGraphicsNode = node;
34523458
}
3453-
loader->latestGradient = nullptr;
34543459
} else if ((gradientMethod = _findGradientFactory(tagName))) {
34553460
SvgStyleGradient* gradient;
34563461
gradient = gradientMethod(loader, attrs, attrsLength);
3457-
//FIXME: The current parsing structure does not distinguish end tags.
3458-
// There is no way to know if the currently parsed gradient is in defs.
3459-
// If a gradient is declared outside of defs after defs is set, it is included in the gradients of defs.
3460-
// But finally, the loader has a gradient style list regardless of defs.
3461-
// This is only to support this when multiple gradients are declared, even if no defs are declared.
3462-
// refer to: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs
3463-
if (loader->def && loader->doc->node.doc.defs) {
3464-
loader->def->node.defs.gradients.push(gradient);
3465-
} else {
3466-
loader->gradients.push(gradient);
3462+
//Gradients do not allow nested declarations, so only the earliest declared Gradient is valid.
3463+
if (loader->gradientStack.count == 0) {
3464+
//FIXME: The current parsing structure does not distinguish end tags.
3465+
// There is no way to know if the currently parsed gradient is in defs.
3466+
// If a gradient is declared outside of defs after defs is set, it is included in the gradients of defs.
3467+
// But finally, the loader has a gradient style list regardless of defs.
3468+
// This is only to support this when multiple gradients are declared, even if no defs are declared.
3469+
// refer to: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs
3470+
if (loader->def && loader->doc->node.doc.defs) {
3471+
loader->def->node.defs.gradients.push(gradient);
3472+
} else {
3473+
loader->gradients.push(gradient);
3474+
}
34673475
}
3468-
loader->latestGradient = gradient;
3476+
if (!empty) loader->gradientStack.push(gradient);
34693477
} else if (!strcmp(tagName, "stop")) {
3470-
if (!loader->latestGradient) {
3478+
if (loader->gradientStack.count == 0) {
34713479
TVGLOG("SVG", "Stop element is used outside of the Gradient element");
34723480
return;
34733481
}
34743482
/* default value for opacity */
34753483
loader->svgParse->gradStop = {0.0f, 0, 0, 0, 255};
34763484
loader->svgParse->flags = SvgStopStyleFlags::StopDefault;
34773485
simpleXmlParseAttributes(attrs, attrsLength, _attrParseStops, loader);
3478-
loader->latestGradient->stops.push(loader->svgParse->gradStop);
3486+
loader->gradientStack.last()->stops.push(loader->svgParse->gradStop);
34793487
} else {
3480-
loader->latestGradient = nullptr;
34813488
if (!isIgnoreUnsupportedLogElements(tagName)) TVGLOG("SVG", "Unsupported elements used [Elements: %s]", tagName);
34823489
}
34833490
}

thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ struct SvgLoaderData
577577
SvgNode* def = nullptr; //also used to store nested graphic nodes
578578
SvgNode* cssStyle = nullptr;
579579
Array<SvgStyleGradient*> gradients;
580-
SvgStyleGradient* latestGradient = nullptr; //For stops
580+
Array<SvgStyleGradient*> gradientStack; //For stops
581581
SvgParser* svgParse = nullptr;
582582
Array<SvgNodeIdPair> cloneNodes;
583583
Array<SvgNodeIdPair> nodesToStyle;

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -752,12 +752,22 @@ static unique_ptr<Scene> _useBuildHelper(SvgLoaderData& loaderData, const SvgNod
752752
}
753753
viewBoxClip->transform(mClipTransform);
754754

755-
scene->clip(std::move(viewBoxClip));
755+
auto clippingLayer = Scene::gen();
756+
clippingLayer->clip(std::move(viewBoxClip));
757+
clippingLayer->push(std::move(scene));
758+
return clippingLayer;
756759
}
757-
} else {
758-
scene->transform(mUseTransform);
760+
return scene;
761+
}
762+
763+
if (auto clipper = scene->Paint::pImpl->clipper) {
764+
auto clipTransform = clipper->transform();
765+
Matrix inv;
766+
if (node->transform && inverse(node->transform, &inv)) clipTransform = inv * clipTransform;
767+
clipper->transform(mUseTransform * clipTransform);
759768
}
760769

770+
scene->transform(mUseTransform);
761771
return scene;
762772
}
763773

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

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -118,50 +118,41 @@ struct SwShapeTask : SwTask
118118

119119
auto strokeWidth = validStrokeWidth();
120120
SwBBox renderRegion{};
121-
auto visibleFill = false;
122-
123-
//This checks also for the case, if the invisible shape turned to visible by alpha.
124-
auto prepareShape = !shapePrepared(&shape) && flags & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient);
121+
auto updateShape = flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform | RenderUpdateFlag::Clip);
122+
auto updateFill = false;
125123

126124
//Shape
127-
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) {
125+
if (updateShape || flags & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient)) {
128126
uint8_t alpha = 0;
129127
rshape->fillColor(nullptr, nullptr, nullptr, &alpha);
130-
alpha = MULTIPLY(alpha, opacity);
131-
visibleFill = (alpha > 0 || rshape->fill);
132-
shapeReset(&shape);
133-
if (visibleFill || clipper) {
134-
if (!shapePrepare(&shape, rshape, transform, bbox, renderRegion, mpool, tid, clips.count > 0 ? true : false)) {
135-
visibleFill = false;
128+
updateFill = (MULTIPLY(alpha, opacity) || rshape->fill);
129+
if (updateShape) shapeReset(&shape);
130+
if (updateFill || clipper) {
131+
if (shapePrepare(&shape, rshape, transform, bbox, renderRegion, mpool, tid, clips.count > 0 ? true : false)) {
132+
if (!shapeGenRle(&shape, rshape, antialiasing(strokeWidth))) goto err;
133+
} else {
134+
updateFill = false;
136135
renderRegion.reset();
137136
}
138137
}
139138
}
140139
//Fill
141-
if (flags & (RenderUpdateFlag::Path |RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
142-
if (visibleFill || clipper) {
143-
if (!shapeGenRle(&shape, rshape, antialiasing(strokeWidth))) goto err;
144-
}
140+
if (updateFill) {
145141
if (auto fill = rshape->fill) {
146142
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
147143
if (ctable) shapeResetFill(&shape);
148144
if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
149-
} else {
150-
shapeDelFill(&shape);
151145
}
152146
}
153147
//Stroke
154-
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
148+
if (updateShape || flags & RenderUpdateFlag::Stroke) {
155149
if (strokeWidth > 0.0f) {
156150
shapeResetStroke(&shape, rshape, transform);
157-
158151
if (!shapeGenStrokeRle(&shape, rshape, transform, bbox, renderRegion, mpool, tid)) goto err;
159152
if (auto fill = rshape->strokeFill()) {
160153
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
161154
if (ctable) shapeResetStrokeFill(&shape);
162155
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
163-
} else {
164-
shapeDelStrokeFill(&shape);
165156
}
166157
} else {
167158
shapeDelStroke(&shape);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ void rleFree(SwRle* rle)
10251025
bool rleClip(SwRle *rle, const SwRle *clip)
10261026
{
10271027
if (rle->size == 0 || clip->size == 0) return false;
1028-
auto spanCnt = rle->size > clip->size ? rle->size : clip->size;
1028+
auto spanCnt = 2 * (rle->size > clip->size ? rle->size : clip->size); //factor 2 added for safety (no real cases observed where the factor exceeded 1.4)
10291029
auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * (spanCnt)));
10301030
auto spansEnd = _intersectSpansRegion(clip, rle, spans, spanCnt);
10311031

thirdparty/thorvg/src/renderer/tvgPaint.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,19 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix& pm, Array<R
276276

277277
/* 2. Clipping */
278278
if (this->clipper) {
279-
P(this->clipper)->ctxFlag &= ~ContextFlag::FastTrack; //reset
279+
auto pclip = P(this->clipper);
280+
if (pclip->renderFlag | static_cast<Shape*>(this->clipper)->pImpl->rFlag) renderFlag |= RenderUpdateFlag::Clip;
281+
pclip->ctxFlag &= ~ContextFlag::FastTrack; //reset
280282
viewport = renderer->viewport();
281283
/* TODO: Intersect the clipper's clipper, if both are FastTrack.
282284
Update the subsequent clipper first and check its ctxFlag. */
283-
if (!P(this->clipper)->clipper && (compFastTrack = _compFastTrack(renderer, this->clipper, pm, viewport)) == Result::Success) {
284-
P(this->clipper)->ctxFlag |= ContextFlag::FastTrack;
285-
}
286-
if (compFastTrack == Result::InsufficientCondition) {
287-
trd = P(this->clipper)->update(renderer, pm, clips, 255, pFlag, true);
285+
if (!pclip->clipper && _compFastTrack(renderer, this->clipper, pm, viewport) == Result::Success) {
286+
pclip->ctxFlag |= ContextFlag::FastTrack;
287+
compFastTrack = Result::Success;
288+
} else {
289+
trd = pclip->update(renderer, pm, clips, 255, pFlag, true);
288290
clips.push(trd);
291+
compFastTrack = Result::InsufficientCondition;
289292
}
290293
}
291294

thirdparty/thorvg/src/renderer/tvgPaint.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ namespace tvg
7272
tvg::rotate(&m, degree);
7373
}
7474
} tr;
75+
RenderUpdateFlag renderFlag = RenderUpdateFlag::None;
7576
BlendMethod blendMethod;
76-
uint8_t renderFlag;
7777
uint8_t ctxFlag;
7878
uint8_t opacity;
7979
uint8_t refCnt = 0; //reference count

thirdparty/thorvg/src/renderer/tvgRender.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,14 @@ using pixel_t = uint32_t;
3737

3838
#define DASH_PATTERN_THRESHOLD 0.001f
3939

40-
enum RenderUpdateFlag : uint8_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, All = 255};
40+
enum RenderUpdateFlag : uint16_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, Clip = 256, All = 0xffff};
4141
enum CompositionFlag : uint8_t {Invalid = 0, Opacity = 1, Blending = 2, Masking = 4, PostProcessing = 8}; //Composition Purpose
4242

43+
static inline void operator|=(RenderUpdateFlag& a, const RenderUpdateFlag b)
44+
{
45+
a = RenderUpdateFlag(uint16_t(a) | uint16_t(b));
46+
}
47+
4348
//TODO: Move this in public header unifying with SwCanvas::Colorspace
4449
enum ColorSpace : uint8_t
4550
{

thirdparty/thorvg/src/renderer/tvgShape.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct Shape::Impl
3333
RenderShape rs; //shape data
3434
RenderData rd = nullptr; //engine data
3535
Shape* shape;
36-
uint8_t rFlag = RenderUpdateFlag::None;
36+
RenderUpdateFlag rFlag = RenderUpdateFlag::None;
3737
uint8_t cFlag = CompositionFlag::Invalid;
3838
uint8_t opacity; //for composition
3939

thirdparty/thorvg/update-thorvg.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash -e
22

3-
VERSION=0.15.12
3+
VERSION=0.15.13
44
# Uncomment and set a git hash to use specific commit instead of tag.
55
#GIT_COMMIT=
66

0 commit comments

Comments
 (0)