Skip to content

Commit 746756d

Browse files
committed
Merge pull request godotengine#90243 from akien-mga/thorvg-0.12.10
thorvg: Update to 0.12.10
2 parents d3e8b6c + 8de1cf5 commit 746756d

File tree

9 files changed

+90
-51
lines changed

9 files changed

+90
-51
lines changed

thirdparty/thorvg/inc/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
// For internal debugging:
1111
//#define THORVG_LOG_ENABLED
1212

13-
#define THORVG_VERSION_STRING "0.12.9"
13+
#define THORVG_VERSION_STRING "0.12.10"
1414
#endif

thirdparty/thorvg/src/common/tvgMath.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void mathRotate(Matrix* m, float degree)
7171
{
7272
if (degree == 0.0f) return;
7373

74-
auto radian = degree / 180.0f * M_PI;
74+
auto radian = degree / 180.0f * MATH_PI;
7575
auto cosVal = cosf(radian);
7676
auto sinVal = sinf(radian);
7777

thirdparty/thorvg/src/common/tvgMath.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ static inline bool mathEqual(const Matrix& a, const Matrix& b)
7070
static inline bool mathRightAngle(const Matrix* m)
7171
{
7272
auto radian = fabsf(atan2f(m->e21, m->e11));
73-
if (radian < FLT_EPSILON || mathEqual(radian, float(M_PI_2)) || mathEqual(radian, float(M_PI))) return true;
73+
if (radian < FLT_EPSILON || mathEqual(radian, MATH_PI2) || mathEqual(radian, MATH_PI)) return true;
7474
return false;
7575
}
7676

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

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -743,10 +743,10 @@ static Matrix* _parseTransformationMatrix(const char* value)
743743
} else goto error;
744744
} else if (state == MatrixState::Rotate) {
745745
//Transform to signed.
746-
points[0] = fmod(points[0], 360);
747-
if (points[0] < 0) points[0] += 360;
748-
auto c = cosf(points[0] * (M_PI / 180.0));
749-
auto s = sinf(points[0] * (M_PI / 180.0));
746+
points[0] = fmodf(points[0], 360.0f);
747+
if (points[0] < 0) points[0] += 360.0f;
748+
auto c = cosf(points[0] * (MATH_PI / 180.0f));
749+
auto s = sinf(points[0] * (MATH_PI / 180.0f));
750750
if (ptCount == 1) {
751751
Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 };
752752
*matrix = mathMultiply(matrix, &tmp);
@@ -769,12 +769,12 @@ static Matrix* _parseTransformationMatrix(const char* value)
769769
*matrix = mathMultiply(matrix, &tmp);
770770
} else if (state == MatrixState::SkewX) {
771771
if (ptCount != 1) goto error;
772-
auto deg = tanf(points[0] * (M_PI / 180.0));
772+
auto deg = tanf(points[0] * (MATH_PI / 180.0f));
773773
Matrix tmp = { 1, deg, 0, 0, 1, 0, 0, 0, 1 };
774774
*matrix = mathMultiply(matrix, &tmp);
775775
} else if (state == MatrixState::SkewY) {
776776
if (ptCount != 1) goto error;
777-
auto deg = tanf(points[0] * (M_PI / 180.0));
777+
auto deg = tanf(points[0] * (MATH_PI / 180.0f));
778778
Matrix tmp = { 1, 0, 0, deg, 1, 0, 0, 0, 1 };
779779
*matrix = mathMultiply(matrix, &tmp);
780780
}
@@ -1919,6 +1919,19 @@ static SvgNode* _findNodeById(SvgNode *node, const char* id)
19191919
}
19201920

19211921

1922+
static SvgNode* _findParentById(SvgNode* node, char* id, SvgNode* doc)
1923+
{
1924+
SvgNode *parent = node->parent;
1925+
while (parent != nullptr && parent != doc) {
1926+
if (parent->id && !strcmp(parent->id, id)) {
1927+
return parent;
1928+
}
1929+
parent = parent->parent;
1930+
}
1931+
return nullptr;
1932+
}
1933+
1934+
19221935
static constexpr struct
19231936
{
19241937
const char* tag;
@@ -1959,8 +1972,12 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
19591972
defs = _getDefsNode(node);
19601973
nodeFrom = _findNodeById(defs, id);
19611974
if (nodeFrom) {
1962-
_cloneNode(nodeFrom, node, 0);
1963-
if (nodeFrom->type == SvgNodeType::Symbol) use->symbol = nodeFrom;
1975+
if (!_findParentById(node, id, loader->doc)) {
1976+
_cloneNode(nodeFrom, node, 0);
1977+
if (nodeFrom->type == SvgNodeType::Symbol) use->symbol = nodeFrom;
1978+
} else {
1979+
TVGLOG("SVG", "%s is ancestor element. This reference is invalid.", id);
1980+
}
19641981
free(id);
19651982
} else {
19661983
//some svg export software include <defs> element at the end of the file
@@ -2669,7 +2686,7 @@ static void _inheritGradient(SvgLoaderData* loader, SvgStyleGradient* to, SvgSty
26692686
if (to->transform) memcpy(to->transform, from->transform, sizeof(Matrix));
26702687
}
26712688

2672-
if (to->type == SvgGradientType::Linear && from->type == SvgGradientType::Linear) {
2689+
if (to->type == SvgGradientType::Linear) {
26732690
for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) {
26742691
bool coordSet = to->flags & linear_tags[i].flag;
26752692
if (!(to->flags & linear_tags[i].flag) && (from->flags & linear_tags[i].flag)) {
@@ -2686,7 +2703,7 @@ static void _inheritGradient(SvgLoaderData* loader, SvgStyleGradient* to, SvgSty
26862703
linear_tags[i].tagInheritedRecalc(loader, to->linear, to->userSpace);
26872704
}
26882705
}
2689-
} else if (to->type == SvgGradientType::Radial && from->type == SvgGradientType::Radial) {
2706+
} else if (to->type == SvgGradientType::Radial) {
26902707
for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) {
26912708
bool coordSet = (to->flags & radialTags[i].flag);
26922709
if (!(to->flags & radialTags[i].flag) && (from->flags & radialTags[i].flag)) {
@@ -2696,10 +2713,16 @@ static void _inheritGradient(SvgLoaderData* loader, SvgStyleGradient* to, SvgSty
26962713
//GradUnits not set directly, coord set
26972714
if (!gradUnitSet && coordSet) {
26982715
radialTags[i].tagRecalc(loader, to->radial, to->userSpace);
2716+
//If fx and fy are not set, set cx and cy.
2717+
if (!strcmp(radialTags[i].tag, "cx") && !(to->flags & SvgGradientFlags::Fx)) to->radial->fx = to->radial->cx;
2718+
if (!strcmp(radialTags[i].tag, "cy") && !(to->flags & SvgGradientFlags::Fy)) to->radial->fy = to->radial->cy;
26992719
}
27002720
//GradUnits set, coord not set directly
27012721
if (to->userSpace == from->userSpace) continue;
27022722
if (gradUnitSet && !coordSet) {
2723+
//If fx and fx are not set, do not call recalc.
2724+
if (!strcmp(radialTags[i].tag, "fx") && !(to->flags & SvgGradientFlags::Fx)) continue;
2725+
if (!strcmp(radialTags[i].tag, "fy") && !(to->flags & SvgGradientFlags::Fy)) continue;
27032726
radialTags[i].tagInheritedRecalc(loader, to->radial, to->userSpace);
27042727
}
27052728
}
@@ -3018,9 +3041,13 @@ static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc)
30183041
auto defs = _getDefsNode(nodeIdPair.node);
30193042
auto nodeFrom = _findNodeById(defs, nodeIdPair.id);
30203043
if (!nodeFrom) nodeFrom = _findNodeById(doc, nodeIdPair.id);
3021-
_cloneNode(nodeFrom, nodeIdPair.node, 0);
3022-
if (nodeFrom && nodeFrom->type == SvgNodeType::Symbol && nodeIdPair.node->type == SvgNodeType::Use) {
3023-
nodeIdPair.node->node.use.symbol = nodeFrom;
3044+
if (!_findParentById(nodeIdPair.node, nodeIdPair.id, doc)) {
3045+
_cloneNode(nodeFrom, nodeIdPair.node, 0);
3046+
if (nodeFrom && nodeFrom->type == SvgNodeType::Symbol && nodeIdPair.node->type == SvgNodeType::Use) {
3047+
nodeIdPair.node->node.use.symbol = nodeFrom;
3048+
}
3049+
} else {
3050+
TVGLOG("SVG", "%s is ancestor element. This reference is invalid.", nodeIdPair.id);
30243051
}
30253052
free(nodeIdPair.id);
30263053
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void _pathAppendArcTo(Array<PathCommand>* cmds, Array<Point>* pts, Point* cur, P
126126
rx = fabsf(rx);
127127
ry = fabsf(ry);
128128

129-
angle = angle * M_PI / 180.0f;
129+
angle = angle * MATH_PI / 180.0f;
130130
cosPhi = cosf(angle);
131131
sinPhi = sinf(angle);
132132
dx2 = (sx - x) / 2.0f;
@@ -195,24 +195,24 @@ void _pathAppendArcTo(Array<PathCommand>* cmds, Array<Point>* pts, Point* cur, P
195195
//http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm
196196
//Note: atan2 (0.0, 1.0) == 0.0
197197
at = atan2(((y1p - cyp) / ry), ((x1p - cxp) / rx));
198-
theta1 = (at < 0.0f) ? 2.0f * M_PI + at : at;
198+
theta1 = (at < 0.0f) ? 2.0f * MATH_PI + at : at;
199199

200200
nat = atan2(((-y1p - cyp) / ry), ((-x1p - cxp) / rx));
201-
deltaTheta = (nat < at) ? 2.0f * M_PI - at + nat : nat - at;
201+
deltaTheta = (nat < at) ? 2.0f * MATH_PI - at + nat : nat - at;
202202

203203
if (sweep) {
204204
//Ensure delta theta < 0 or else add 360 degrees
205-
if (deltaTheta < 0.0f) deltaTheta += (float)(2.0f * M_PI);
205+
if (deltaTheta < 0.0f) deltaTheta += 2.0f * MATH_PI;
206206
} else {
207207
//Ensure delta theta > 0 or else substract 360 degrees
208-
if (deltaTheta > 0.0f) deltaTheta -= (float)(2.0f * M_PI);
208+
if (deltaTheta > 0.0f) deltaTheta -= 2.0f * MATH_PI;
209209
}
210210

211211
//Add several cubic bezier to approximate the arc
212212
//(smaller than 90 degrees)
213213
//We add one extra segment because we want something
214214
//Smaller than 90deg (i.e. not 90 itself)
215-
segments = static_cast<int>(fabsf(deltaTheta / float(M_PI_2)) + 1.0f);
215+
segments = static_cast<int>(fabsf(deltaTheta / MATH_PI2) + 1.0f);
216216
delta = deltaTheta / segments;
217217

218218
//http://www.stillhq.com/ctpfaq/2001/comp.text.pdf-faq-2001-04.txt (section 2.13)

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

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
/* Internal Class Implementation */
2929
/************************************************************************/
3030

31+
3132
struct Line
3233
{
3334
Point pt1;
@@ -55,23 +56,24 @@ static void _lineSplitAt(const Line& cur, float at, Line& left, Line& right)
5556
}
5657

5758

58-
static void _outlineEnd(SwOutline& outline)
59+
static bool _outlineEnd(SwOutline& outline)
5960
{
60-
if (outline.pts.empty()) return;
61+
//Make a contour if lineTo/curveTo without calling close/moveTo beforehand.
62+
if (outline.pts.empty()) return false;
6163
outline.cntrs.push(outline.pts.count - 1);
6264
outline.closed.push(false);
65+
return false;
6366
}
6467

6568

66-
static void _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform)
69+
static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform, bool closed = false)
6770
{
68-
if (outline.pts.count > 0) {
69-
outline.cntrs.push(outline.pts.count - 1);
70-
outline.closed.push(false);
71-
}
71+
//make it a contour, if the last contour is not closed yet.
72+
if (!closed) _outlineEnd(outline);
7273

7374
outline.pts.push(mathTransform(to, transform));
7475
outline.types.push(SW_CURVE_TYPE_POINT);
76+
return false;
7577
}
7678

7779

@@ -95,20 +97,22 @@ static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point*
9597
}
9698

9799

98-
static void _outlineClose(SwOutline& outline)
100+
static bool _outlineClose(SwOutline& outline)
99101
{
100-
uint32_t i = 0;
101-
102+
uint32_t i;
102103
if (outline.cntrs.count > 0) i = outline.cntrs.last() + 1;
103-
else i = 0; //First Path
104+
else i = 0;
104105

105106
//Make sure there is at least one point in the current path
106-
if (outline.pts.count == i) return;
107+
if (outline.pts.count == i) return false;
107108

108109
//Close the path
109110
outline.pts.push(outline.pts[i]);
111+
outline.cntrs.push(outline.pts.count - 1);
110112
outline.types.push(SW_CURVE_TYPE_POINT);
111113
outline.closed.push(true);
114+
115+
return true;
112116
}
113117

114118

@@ -306,7 +310,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
306310
bool isOdd = dash.cnt % 2;
307311
if (isOdd) patternLength *= 2;
308312

309-
offset = fmod(offset, patternLength);
313+
offset = fmodf(offset, patternLength);
310314
if (offset < 0) offset += patternLength;
311315

312316
for (size_t i = 0; i < dash.cnt * (1 + (size_t)isOdd); ++i, ++offIdx) {
@@ -425,25 +429,28 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
425429

426430
shape->outline = mpoolReqOutline(mpool, tid);
427431
auto outline = shape->outline;
432+
bool closed = false;
428433

429434
//Generate Outlines
430435
while (cmdCnt-- > 0) {
431436
switch (*cmds) {
432437
case PathCommand::Close: {
433-
_outlineClose(*outline);
438+
if (!closed) closed = _outlineClose(*outline);
434439
break;
435440
}
436441
case PathCommand::MoveTo: {
437-
_outlineMoveTo(*outline, pts, transform);
442+
closed = _outlineMoveTo(*outline, pts, transform, closed);
438443
++pts;
439444
break;
440445
}
441446
case PathCommand::LineTo: {
447+
if (closed) closed = _outlineEnd(*outline);
442448
_outlineLineTo(*outline, pts, transform);
443449
++pts;
444450
break;
445451
}
446452
case PathCommand::CubicTo: {
453+
if (closed) closed = _outlineEnd(*outline);
447454
_outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform);
448455
pts += 3;
449456
break;
@@ -452,7 +459,7 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
452459
++cmds;
453460
}
454461

455-
_outlineEnd(*outline);
462+
if (!closed) _outlineEnd(*outline);
456463

457464
outline->fillRule = rshape->rule;
458465
shape->outline = outline;

thirdparty/thorvg/src/renderer/tvgPaint.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,26 @@
4141
}
4242

4343

44-
static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport)
44+
45+
static Result _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport)
4546
{
4647
/* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */
4748
auto shape = static_cast<Shape*>(cmpTarget);
4849

4950
//Rectangle Candidates?
5051
const Point* pts;
51-
if (shape->pathCoords(&pts) != 4) return false;
52+
auto ptsCnt = shape->pathCoords(&pts);
53+
54+
//nothing to clip
55+
if (ptsCnt == 0) return Result::InvalidArguments;
56+
57+
if (ptsCnt != 4) return Result::InsufficientCondition;
5258

5359
if (rTransform) rTransform->update();
5460

5561
//No rotation and no skewing
56-
if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) return false;
57-
if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) return false;
62+
if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) return Result::InsufficientCondition;
63+
if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) return Result::InsufficientCondition;
5864

5965
//Perpendicular Rectangle?
6066
auto pt1 = pts + 0;
@@ -99,10 +105,9 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform,
99105
if (viewport.w < 0) viewport.w = 0;
100106
if (viewport.h < 0) viewport.h = 0;
101107

102-
return true;
108+
return Result::Success;
103109
}
104-
105-
return false;
110+
return Result::InsufficientCondition;
106111
}
107112

108113

@@ -235,7 +240,7 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
235240
/* 1. Composition Pre Processing */
236241
RenderData trd = nullptr; //composite target render data
237242
RenderRegion viewport;
238-
bool compFastTrack = false;
243+
Result compFastTrack = Result::InsufficientCondition;
239244
bool childClipper = false;
240245

241246
if (compData) {
@@ -260,15 +265,15 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
260265
}
261266
if (tryFastTrack) {
262267
RenderRegion viewport2;
263-
if ((compFastTrack = _compFastTrack(target, pTransform, target->pImpl->rTransform, viewport2))) {
268+
if ((compFastTrack = _compFastTrack(target, pTransform, target->pImpl->rTransform, viewport2)) == Result::Success) {
264269
viewport = renderer->viewport();
265270
viewport2.intersect(viewport);
266271
renderer->viewport(viewport2);
267272
target->pImpl->ctxFlag |= ContextFlag::FastTrack;
268273
}
269274
}
270275
}
271-
if (!compFastTrack) {
276+
if (compFastTrack == Result::InsufficientCondition) {
272277
childClipper = compData->method == CompositeMethod::ClipPath ? true : false;
273278
trd = target->pImpl->update(renderer, pTransform, clips, 255, pFlag, childClipper);
274279
if (childClipper) clips.push(trd);
@@ -285,7 +290,7 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
285290
PAINT_METHOD(rd, update(renderer, &outTransform, clips, opacity, newFlag, clipper));
286291

287292
/* 3. Composition Post Processing */
288-
if (compFastTrack) renderer->viewport(viewport);
293+
if (compFastTrack == Result::Success) renderer->viewport(viewport);
289294
else if (childClipper) clips.pop();
290295

291296
return rd;

thirdparty/thorvg/src/renderer/tvgShape.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa
164164
}
165165

166166
for (int i = 0; i < nCurves; ++i) {
167-
auto endAngle = startAngle + ((i != nCurves - 1) ? float(M_PI_2) * sweepSign : fract);
167+
auto endAngle = startAngle + ((i != nCurves - 1) ? MATH_PI2 * sweepSign : fract);
168168
Point end = {radius * cosf(endAngle), radius * sinf(endAngle)};
169169

170170
//variables needed to calculate bezier control points

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.12.9
3+
VERSION=0.12.10
44

55
cd thirdparty/thorvg/ || true
66
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/

0 commit comments

Comments
 (0)