From 11a029c99d080453c852ea077d7f8c7fd56aa73e Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Wed, 15 Jan 2025 01:34:15 +0100 Subject: [PATCH] gl_engine: apply common trimming logic The trim-related implementation has been removed and replaced with the one available in common. @Issue: https://github.com/thorvg/thorvg/issues/2854 --- src/renderer/gl_engine/tvgGlTessellator.cpp | 314 +------------------- src/renderer/gl_engine/tvgGlTessellator.h | 18 -- 2 files changed, 9 insertions(+), 323 deletions(-) diff --git a/src/renderer/gl_engine/tvgGlTessellator.cpp b/src/renderer/gl_engine/tvgGlTessellator.cpp index e528f4a1..2e04265d 100644 --- a/src/renderer/gl_engine/tvgGlTessellator.cpp +++ b/src/renderer/gl_engine/tvgGlTessellator.cpp @@ -1541,26 +1541,16 @@ void Stroker::stroke(const RenderShape *rshape) mStrokeWidth = strokeWidth / mMatrix.e11; } - auto cmds = rshape->path.cmds.data; - auto cmdCnt = rshape->path.cmds.count; - auto pts = rshape->path.pts.data; - auto ptsCnt = rshape->path.pts.count; + PathCommand* cmds = nullptr; + Point* pts = nullptr; + uint32_t cmdCnt, ptsCnt; - if (rshape->strokeTrim()) { - auto begin = 0.0f; - auto end = 0.0f; - rshape->stroke->trim.get(begin, end); - - if (begin == end) return; - - if (begin > end) { - doTrimStroke(cmds, cmdCnt, pts, ptsCnt, rshape->stroke->trim.simultaneous, begin, 1.0f); - doTrimStroke(cmds, cmdCnt, pts, ptsCnt, rshape->stroke->trim.simultaneous, 0.0f, end); - } else { - doTrimStroke(cmds, cmdCnt, pts, ptsCnt, rshape->stroke->trim.simultaneous, begin, end); - } - - return; + if (rshape->strokeTrim()) rshape->stroke->trim.trim(rshape->path.cmds, rshape->path.pts, cmds, cmdCnt, pts, ptsCnt); + else { + cmds = rshape->path.cmds.data; + cmdCnt = rshape->path.cmds.count; + pts = rshape->path.pts.data; + ptsCnt = rshape->path.pts.count; } const float *dash_pattern = nullptr; @@ -1581,76 +1571,6 @@ RenderRegion Stroker::bounds() const }; } -void Stroker::doTrimStroke(const PathCommand* cmds, uint32_t cmdCnt, const Point* pts, uint32_t ptsCnt, bool simultaneous, float start, float end) -{ - if (simultaneous) { - auto startCmds = cmds; - auto currCmds = cmds; - int ptsNum = 0; - for (uint32_t i = 0; i < cmdCnt; i++) { - switch (*currCmds) { - case PathCommand::MoveTo: { - if (currCmds != startCmds) { - PathTrim trim{}; - if (trim.trim(startCmds, currCmds - startCmds, pts, ptsNum, start, end)) { - const auto& sCmds = trim.cmds(); - const auto& sPts = trim.pts(); - doStroke(sCmds.data, sCmds.count, sPts.data, sPts.count); - } - startCmds = currCmds; - pts += ptsNum; - ptsNum = 0; - } - currCmds++; - ptsNum++; - break; - } - case PathCommand::LineTo: - currCmds++; - ptsNum++; - break; - case PathCommand::CubicTo: - currCmds++; - ptsNum += 3; - break; - case PathCommand::Close: { - PathTrim trim{}; - currCmds++; - if (trim.trim(startCmds, currCmds - startCmds, pts, ptsNum, start, end)) { - const auto& sCmds = trim.cmds(); - const auto& sPts = trim.pts(); - doStroke(sCmds.data, sCmds.count, sPts.data, sPts.count); - } - startCmds = currCmds; - pts += ptsNum; - ptsNum = 0; - break; - } - } - } - - if (startCmds != currCmds && ptsNum > 0) { - PathTrim trim{}; - - if (trim.trim(startCmds, currCmds - startCmds, pts, ptsNum, start, end)) { - const auto& sCmds = trim.cmds(); - const auto& sPts = trim.pts(); - doStroke(sCmds.data, sCmds.count, sPts.data, sPts.count); - } - startCmds = currCmds; - pts += ptsNum; - ptsNum = 0; - } - } else { - PathTrim trim{}; - if (trim.trim(cmds, cmdCnt, pts, ptsCnt, start, end)) { - const auto& sCmds = trim.cmds(); - const auto& sPts = trim.pts(); - doStroke(sCmds.data, sCmds.count, sPts.data, sPts.count); - } - } -} - void Stroker::doStroke(const PathCommand *cmds, uint32_t cmd_count, const Point *pts, uint32_t pts_count) { @@ -2209,222 +2129,6 @@ void DashStroke::cubicTo(const Point& cnt1, const Point& cnt2, const Point& end) } -bool PathTrim::trim(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count, float start, float end) -{ - if (end - start < 0.0001f) return false; - - auto len = pathLength(cmds, cmd_count, pts, pts_count); - if (len < 0.001f) return false; - - auto startLength = len * start; - auto endLength = len * end; - if (startLength >= endLength) return false; - - trimPath(cmds, cmd_count, pts, pts_count, startLength, endLength); - - return true; -} - - -float PathTrim::pathLength(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count) -{ - auto len = 0.0f; - Point zero = {0.0f, 0.0f}; - const Point* prev = nullptr; - const Point* begin = nullptr; - - for (uint32_t i = 0; i < cmd_count; i++) { - switch (cmds[i]) { - case PathCommand::MoveTo: { - prev = pts; - begin = pts; - pts++; - break; - } - case PathCommand::LineTo: { - if (prev != nullptr) len += length(prev, pts); - if (begin == nullptr) begin = pts; - prev = pts; - pts++; - break; - } - case PathCommand::CubicTo: { - if (prev == nullptr || begin == nullptr) { - prev = begin = &zero; - } - Bezier b{ *prev, pts[0], pts[1], pts[2]}; - len += b.length(); - prev = pts + 2; - pts += 3; - break; - } - case PathCommand::Close: { - if (prev != nullptr && begin != nullptr && prev != begin) { - len += length(prev, begin); - } - prev = begin = nullptr; - break; - } - } - } - return len; -} - - -void PathTrim::trimPath(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count, float start, float end) -{ - auto pos = 0.0f; - Point zero = {0.0f, 0.0f}; - Point prev = {}; - Point begin = {}; - auto closed = true; - auto pushedMoveTo = false; - auto hasLineTo = false; - - auto handle_line_to = [&](const Point* p1, const Point* p2) { - auto currLen = length(p1, p2); - if (pos + currLen <= start) { - pos += currLen; - prev = *p2; - return; - } - - if (pos >= end) { - prev = *p2; - return; - } - - Line line{*p1, *p2}; - - if (pos < start) { - Line left, right; - line.split(start - pos, left, right); - - pos += left.length(); - line = right; - } - - if (pos + currLen > end) { - Line left, right; - line.split(end - pos, left, right); - pos += left.length(); - line = left; - } - - if (!pushedMoveTo) { - mCmds.push(PathCommand::MoveTo); - mPts.push(line.pt1); - pushedMoveTo = true; - begin = line.pt1; - } - - pos += line.length(); - - mCmds.push(PathCommand::LineTo); - mPts.push(line.pt2); - prev = line.pt2; - hasLineTo = true; - closed = false; - }; - - for (uint32_t i = 0; i < cmd_count; i++) { - if (pos - end > 0.001f) return; // we are done - - if (pos >= end) return; - - switch (cmds[i]) { - case PathCommand::MoveTo: { - prev = *pts; - begin = *pts; - pts++; - closed = false; - break; - } - case PathCommand::LineTo: { - handle_line_to(&prev, pts); - hasLineTo = true; - pts++; - break; - } - case PathCommand::CubicTo: { - Bezier b{ prev, pts[0], pts[1], pts[2]}; - - auto currLen = b.length(); - if (pos + currLen <= start) { - pos += currLen; - prev = pts[2]; - pts += 3; - break; - } - - if (pos < start) { - Bezier left, right; - b.split(start - pos, left, right); - pos += left.length(); - b = right; - } - - if (pos + currLen > end) { - Bezier left, right; - b.split(end - pos, left, right); - pos += left.length(); - b = left; - } - - if (!pushedMoveTo) { - mCmds.push(PathCommand::MoveTo); - mPts.push(b.start); - pushedMoveTo = true; - } - - - pos += b.length(); - mCmds.push(PathCommand::CubicTo); - mPts.push(b.ctrl1); - mPts.push(b.ctrl2); - mPts.push(b.end); - prev = b.end; - hasLineTo = true; - closed = false; - pts += 3; - break; - } - case PathCommand::Close: { - if (closed) break; - if (!hasLineTo) { - closed = true; - pushedMoveTo = false; - prev = begin = zero; - break; - } - if (prev == begin) { - prev = begin = zero; - closed = true; - pushedMoveTo = false; - break; - } - auto currLen = length(&prev, &begin); - if (currLen + pos < start) { - pos += currLen; - break; - } - if (pos + currLen <= end) { - mCmds.push(PathCommand::Close); - pos += currLen; - break; - } - // handle_line_to(&prev, &begin); - closed = true; - pushedMoveTo = false; - prev = begin = zero; - pos += currLen; - break; - } - } - } -} - - BWTessellator::BWTessellator(Array* points, Array* indices): mResPoints(points), mResIndices(indices) { } diff --git a/src/renderer/gl_engine/tvgGlTessellator.h b/src/renderer/gl_engine/tvgGlTessellator.h index d047c5fa..b8d0ca1d 100644 --- a/src/renderer/gl_engine/tvgGlTessellator.h +++ b/src/renderer/gl_engine/tvgGlTessellator.h @@ -86,7 +86,6 @@ public: RenderRegion bounds() const; private: - void doTrimStroke(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count, bool simultaneous, float start, float end); void doStroke(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count); void doDashStroke(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count, uint32_t dash_count, const float* dash_pattern); @@ -145,23 +144,6 @@ private: Point mPtCur; }; -class PathTrim -{ -public: - PathTrim(): mCmds(), mPts() {} - ~PathTrim() = default; - bool trim(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count, float start, float end); - const Array& cmds() const { return mCmds; } - const Array& pts() const { return mPts; } - -private: - float pathLength(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count); - void trimPath(const PathCommand* cmds, uint32_t cmd_count, const Point* pts, uint32_t pts_count, float start, float end); - - Array mCmds; - Array mPts; -}; - class BWTessellator { public: