summaryrefslogtreecommitdiffstats
path: root/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
diff options
context:
space:
mode:
authorMartin Capitanio <capnm@capitanio.org>2024-06-08 19:42:09 +0200
committerMartin Capitanio <capnm@capitanio.org>2024-06-08 20:19:53 +0200
commit18650de06a8500ad553ce00a7a573f623682dfa7 (patch)
tree5b2db496c76d4fe6f58751c67321b46e547d4b6c /thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
parent5833f597865c773fae3ee09fc4e31d4a243f812d (diff)
downloadredot-engine-18650de06a8500ad553ce00a7a573f623682dfa7.tar.gz
ThorVG: Update to 0.13.7
Diffstat (limited to 'thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp')
-rw-r--r--thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp197
1 files changed, 102 insertions, 95 deletions
diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
index b9327374b6..d8dd40d45b 100644
--- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
+++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp
@@ -107,7 +107,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
if (mathZero(len)) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
//draw the current line fully
- } else if (len < dash.curLen) {
+ } else if (len <= dash.curLen) {
dash.curLen -= len;
if (!dash.curOpGap) {
if (dash.move) {
@@ -168,7 +168,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
//draw the current line fully
if (mathZero(len)) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
- } else if (len < dash.curLen) {
+ } else if (len <= dash.curLen) {
dash.curLen -= len;
if (!dash.curOpGap) {
if (dash.move) {
@@ -245,7 +245,86 @@ static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const
}
-static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* transform, float length, SwMpool* mpool, unsigned tid)
+static void _trimPattern(SwDashStroke* dash, const RenderShape* rshape, float length)
+{
+ auto begin = length * rshape->stroke->trim.begin;
+ auto end = length * rshape->stroke->trim.end;
+
+ //default
+ if (end > begin) {
+ if (begin > 0.0f) dash->cnt = 4;
+ else dash->cnt = 2;
+ //looping
+ } else dash->cnt = 3;
+
+ if (dash->cnt == 2) {
+ dash->pattern[0] = end - begin;
+ dash->pattern[1] = length - (end - begin);
+ } else if (dash->cnt == 3) {
+ dash->pattern[0] = end;
+ dash->pattern[1] = (begin - end);
+ dash->pattern[2] = length - begin;
+ } else {
+ 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;
+ }
+}
+
+
+static float _outlineLength(const RenderShape* rshape, uint32_t shiftPts, uint32_t shiftCmds, bool subpath)
+{
+ const PathCommand* cmds = rshape->path.cmds.data + shiftCmds;
+ auto cmdCnt = rshape->path.cmds.count - shiftCmds;
+ const Point* pts = rshape->path.pts.data + shiftPts;
+ auto ptsCnt = rshape->path.pts.count - shiftPts;
+
+ //No actual shape data
+ if (cmdCnt <= 0 || ptsCnt <= 0) return 0.0f;
+
+ const Point* close = nullptr;
+ auto length = 0.0f;
+
+ //must begin with moveTo
+ if (cmds[0] == PathCommand::MoveTo) {
+ close = pts;
+ cmds++;
+ pts++;
+ cmdCnt--;
+ }
+
+ while (cmdCnt-- > 0) {
+ switch (*cmds) {
+ case PathCommand::Close: {
+ length += mathLength(pts - 1, close);
+ if (subpath) return length;
+ break;
+ }
+ case PathCommand::MoveTo: {
+ if (subpath) return length;
+ close = pts;
+ ++pts;
+ break;
+ }
+ case PathCommand::LineTo: {
+ length += mathLength(pts - 1, pts);
+ ++pts;
+ break;
+ }
+ case PathCommand::CubicTo: {
+ length += bezLength({*(pts - 1), *pts, *(pts + 1), *(pts + 2)});
+ pts += 3;
+ break;
+ }
+ }
+ ++cmds;
+ }
+ return length;
+}
+
+
+static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* transform, bool trimmed, SwMpool* mpool, unsigned tid)
{
const PathCommand* cmds = rshape->path.cmds.data;
auto cmdCnt = rshape->path.cmds.count;
@@ -255,49 +334,23 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
//No actual shape data
if (cmdCnt == 0 || ptsCnt == 0) return nullptr;
+ auto startPts = pts;
+ auto startCmds = cmds;
+
SwDashStroke dash;
auto offset = 0.0f;
- auto trimmed = false;
-
dash.cnt = rshape->strokeDash((const float**)&dash.pattern, &offset);
+ auto simultaneous = rshape->stroke->trim.simultaneous;
- //dash by trimming.
- if (length > 0.0f && dash.cnt == 0) {
- auto begin = length * rshape->stroke->trim.begin;
- auto end = length * rshape->stroke->trim.end;
-
- //TODO: mix trimming + dash style
-
- //default
- if (end > begin) {
- if (begin > 0.0f) dash.cnt += 4;
- else dash.cnt += 2;
- //looping
- } else dash.cnt += 3;
-
- dash.pattern = (float*)malloc(sizeof(float) * dash.cnt);
-
- if (dash.cnt == 2) {
- dash.pattern[0] = end - begin;
- dash.pattern[1] = length - (end - begin);
- } else if (dash.cnt == 3) {
- dash.pattern[0] = end;
- dash.pattern[1] = (begin - end);
- dash.pattern[2] = length - begin;
- } else {
- 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;
- }
-
- trimmed = true;
- //just a dasy style.
+ if (dash.cnt == 0) {
+ if (trimmed) dash.pattern = (float*)malloc(sizeof(float) * 4);
+ else return nullptr;
} else {
- if (dash.cnt == 0) return nullptr;
+ //TODO: handle dash + trim - for now trimming ignoring is forced
+ trimmed = false;
}
- //offset?
+ //offset
auto patternLength = 0.0f;
uint32_t offIdx = 0;
if (!mathZero(offset)) {
@@ -319,6 +372,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
//must begin with moveTo
if (cmds[0] == PathCommand::MoveTo) {
+ if (trimmed) _trimPattern(&dash, rshape, _outlineLength(rshape, 0, 0, simultaneous));
_dashMoveTo(dash, offIdx, offset, pts);
cmds++;
pts++;
@@ -331,8 +385,12 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
break;
}
case PathCommand::MoveTo: {
- if (rshape->stroke->trim.individual) _dashMoveTo(dash, pts);
- else _dashMoveTo(dash, offIdx, offset, pts);
+ if (trimmed) {
+ if (simultaneous) {
+ _trimPattern(&dash, rshape, _outlineLength(rshape, pts - startPts, cmds - startCmds, true));
+ _dashMoveTo(dash, offIdx, offset, pts);
+ } else _dashMoveTo(dash, pts);
+ } else _dashMoveTo(dash, offIdx, offset, pts);
++pts;
break;
}
@@ -358,56 +416,6 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
}
-static float _outlineLength(const RenderShape* rshape)
-{
- const PathCommand* cmds = rshape->path.cmds.data;
- auto cmdCnt = rshape->path.cmds.count;
- const Point* pts = rshape->path.pts.data;
- auto ptsCnt = rshape->path.pts.count;
-
- //No actual shape data
- if (cmdCnt == 0 || ptsCnt == 0) return 0.0f;
-
- 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);
- //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: {
- close = pts;
- ++pts;
- break;
- }
- case PathCommand::LineTo: {
- length += mathLength(pts - 1, pts);
- ++pts;
- break;
- }
- case PathCommand::CubicTo: {
- length += bezLength({*(pts - 1), *pts, *(pts + 1), *(pts + 2)});
- pts += 3;
- break;
- }
- }
- ++cmds;
- }
- if (simultaneous && slength > length) return slength;
- else return length;
-}
-
-
static bool _axisAlignedRect(const SwOutline* outline)
{
//Fast Track: axis-aligned rectangle?
@@ -584,11 +592,10 @@ bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix*
auto dashStroking = false;
auto ret = true;
- auto length = rshape->strokeTrim() ? _outlineLength(rshape) : 0.0f;
-
//Dash style (+trimming)
- if (rshape->stroke->dashCnt > 0 || length > 0) {
- shapeOutline = _genDashOutline(rshape, transform, length, mpool, tid);
+ auto trimmed = rshape->strokeTrim();
+ if (rshape->stroke->dashCnt > 0 || trimmed) {
+ shapeOutline = _genDashOutline(rshape, transform, trimmed, mpool, tid);
if (!shapeOutline) return false;
dashStroking = true;
//Normal style