summaryrefslogtreecommitdiffstats
path: root/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-05-10 09:30:57 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-05-10 09:30:57 +0200
commit1cf9f37589aad257653b5d038dfefa1283be381f (patch)
tree98e2f725e8eed411358db564450c7dd96b573866 /thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
parentc4279fe3e0b27d0f40857c00eece7324a967285f (diff)
downloadredot-engine-1cf9f37589aad257653b5d038dfefa1283be381f.tar.gz
thorvg: Update to 0.13.3, add webp loader
Remove embedded png loader, we use the external (libpng) one.
Diffstat (limited to 'thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp')
-rw-r--r--thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp86
1 files changed, 48 insertions, 38 deletions
diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
index 5e79bb6ffa..e38f13db25 100644
--- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
+++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
@@ -22,43 +22,26 @@
#include "tvgSwCommon.h"
#include "tvgMath.h"
-#include "tvgBezier.h"
+#include "tvgLines.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
-
-struct Line
-{
- Point pt1;
- Point pt2;
-};
-
-
-static float _lineLength(const Point& pt1, const Point& pt2)
-{
- Point diff = {pt2.x - pt1.x, pt2.y - pt1.y};
- return sqrtf(diff.x * diff.x + diff.y * diff.y);
-}
-
-
-static void _lineSplitAt(const Line& cur, float at, Line& left, Line& right)
+static bool _outlineBegin(SwOutline& outline)
{
- auto len = _lineLength(cur.pt1, cur.pt2);
- auto dx = ((cur.pt2.x - cur.pt1.x) / len) * at;
- auto dy = ((cur.pt2.y - cur.pt1.y) / len) * at;
- left.pt1 = cur.pt1;
- left.pt2.x = left.pt1.x + dx;
- left.pt2.y = left.pt1.y + dy;
- right.pt1 = left.pt2;
- right.pt2 = cur.pt2;
+ //Make a contour if lineTo/curveTo without calling close or moveTo beforehand.
+ if (outline.pts.empty()) return false;
+ outline.cntrs.push(outline.pts.count - 1);
+ outline.closed.push(false);
+ outline.pts.push(outline.pts[outline.cntrs.last()]);
+ outline.types.push(SW_CURVE_TYPE_POINT);
+ return false;
}
static bool _outlineEnd(SwOutline& outline)
{
- //Make a contour if lineTo/curveTo without calling close/moveTo beforehand.
if (outline.pts.empty()) return false;
outline.cntrs.push(outline.pts.count - 1);
outline.closed.push(false);
@@ -119,10 +102,11 @@ static bool _outlineClose(SwOutline& outline)
static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform)
{
Line cur = {dash.ptCur, *to};
- auto len = _lineLength(cur.pt1, cur.pt2);
+ auto len = lineLength(cur.pt1, cur.pt2);
if (mathZero(len)) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
+ //draw the current line fully
} else if (len < dash.curLen) {
dash.curLen -= len;
if (!dash.curOpGap) {
@@ -132,12 +116,13 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
}
_outlineLineTo(*dash.outline, to, transform);
}
+ //draw the current line partially
} else {
while (len - dash.curLen > 0.0001f) {
Line left, right;
if (dash.curLen > 0) {
len -= dash.curLen;
- _lineSplitAt(cur, dash.curLen, left, right);
+ lineSplitAt(cur, dash.curLen, left, right);
if (!dash.curOpGap) {
if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) {
_outlineMoveTo(*dash.outline, &left.pt1, transform);
@@ -180,6 +165,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to};
auto len = bezLength(cur);
+ //draw the current line fully
if (mathZero(len)) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
} else if (len < dash.curLen) {
@@ -191,6 +177,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
}
_outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform);
}
+ //draw the current line partially
} else {
while ((len - dash.curLen) > 0.0001f) {
Bezier left, right;
@@ -240,7 +227,15 @@ static void _dashClose(SwDashStroke& dash, const Matrix* transform)
}
-static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const Point* pts, const Matrix* transform)
+static void _dashMoveTo(SwDashStroke& dash, const Point* pts)
+{
+ dash.ptCur = *pts;
+ dash.ptStart = *pts;
+ dash.move = true;
+}
+
+
+static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const Point* pts)
{
dash.curIdx = offIdx % dash.cnt;
dash.curLen = dash.pattern[dash.curIdx] - offset;
@@ -275,7 +270,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
//default
if (end > begin) {
- if (begin > 0) dash.cnt += 4;
+ if (begin > 0.0f) dash.cnt += 4;
else dash.cnt += 2;
//looping
} else dash.cnt += 3;
@@ -293,7 +288,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
dash.pattern[0] = 0; //zero dash to start with a space.
dash.pattern[1] = begin;
dash.pattern[2] = end - begin;
- dash.pattern[3] = length - (end - begin);
+ dash.pattern[3] = length - end;
}
trimmed = true;
@@ -322,14 +317,22 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
dash.outline = mpoolReqDashOutline(mpool, tid);
- while (cmdCnt-- > 0) {
+ //must begin with moveTo
+ if (cmds[0] == PathCommand::MoveTo) {
+ _dashMoveTo(dash, offIdx, offset, pts);
+ cmds++;
+ pts++;
+ }
+
+ while (--cmdCnt > 0) {
switch (*cmds) {
case PathCommand::Close: {
_dashClose(dash, transform);
break;
}
case PathCommand::MoveTo: {
- _dashMoveTo(dash, offIdx, offset, pts, transform);
+ if (rshape->stroke->trim.individual) _dashMoveTo(dash, pts);
+ else _dashMoveTo(dash, offIdx, offset, pts);
++pts;
break;
}
@@ -367,13 +370,19 @@ static float _outlineLength(const RenderShape* rshape)
const Point* close = nullptr;
auto length = 0.0f;
+ auto slength = -1.0f;
+ auto simultaneous = !rshape->stroke->trim.individual;
//Compute the whole length
while (cmdCnt-- > 0) {
switch (*cmds) {
case PathCommand::Close: {
length += mathLength(pts - 1, close);
- ++pts;
+ //retrieve the max length of the shape if the simultaneous mode.
+ if (simultaneous) {
+ if (slength < length) slength = length;
+ length = 0.0f;
+ }
break;
}
case PathCommand::MoveTo: {
@@ -394,7 +403,8 @@ static float _outlineLength(const RenderShape* rshape)
}
++cmds;
}
- return length;
+ if (simultaneous && slength > length) return slength;
+ else return length;
}
@@ -429,7 +439,7 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
shape->outline = mpoolReqOutline(mpool, tid);
auto outline = shape->outline;
- bool closed = false;
+ auto closed = false;
//Generate Outlines
while (cmdCnt-- > 0) {
@@ -444,13 +454,13 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
break;
}
case PathCommand::LineTo: {
- if (closed) closed = _outlineEnd(*outline);
+ if (closed) closed = _outlineBegin(*outline);
_outlineLineTo(*outline, pts, transform);
++pts;
break;
}
case PathCommand::CubicTo: {
- if (closed) closed = _outlineEnd(*outline);
+ if (closed) closed = _outlineBegin(*outline);
_outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform);
pts += 3;
break;