diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2024-03-27 18:18:02 +0100 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2024-04-03 21:08:44 +0000 |
commit | 076711dbaab97e93348d4a1579cfcc9435359689 (patch) | |
tree | 44fc1da6e90a208fb8a53dfe0e8fb709939f9b73 /src/quick | |
parent | 1314d046f043bfcb29c44163e113b810c7764aed (diff) |
Curve renderer: Use a common QQuadPath iterator function
For code simplification, replace a couple of ad-hoc QQuadPath
iteration implementations with calls to QQuadPath's own
iterateElements() function.
To make that possible, extend iterateElements() to pass the element
index too to the lambda function.
Pick-to: 6.7
Change-Id: I2e6697b5d1404c7ed4fa1c247e18f93856394fa1
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/scenegraph/qsgcurveprocessor.cpp | 85 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qquadpath.cpp | 6 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qquadpath_p.h | 14 |
3 files changed, 45 insertions, 60 deletions
diff --git a/src/quick/scenegraph/qsgcurveprocessor.cpp b/src/quick/scenegraph/qsgcurveprocessor.cpp index 801cf32826..3cefb8c39c 100644 --- a/src/quick/scenegraph/qsgcurveprocessor.cpp +++ b/src/quick/scenegraph/qsgcurveprocessor.cpp @@ -56,18 +56,6 @@ static inline float testSideOfLineByNormal(QVector2D a, QVector2D n, QVector2D p return dot; }; -template<typename Func> -void iteratePath(const QQuadPath &path, int index, Func &&lambda) -{ - const auto &element = path.elementAt(index); - if (element.childCount() == 0) { - lambda(element, index); - } else { - for (int i = 0; i < element.childCount(); ++i) - iteratePath(path, element.indexOfChild(i), lambda); - } -} - static inline float determinant(const QVector2D &p1, const QVector2D &p2, const QVector2D &p3) { return p1.x() * (p2.y() - p3.y()) @@ -438,7 +426,8 @@ QList<TriangleData> simplePointTriangulator(const QList<QVector2D> &pts, const Q return ret; } -static bool needsSplit(const QQuadPath::Element &el) + +inline bool needsSplit(const QQuadPath::Element &el) { Q_ASSERT(!el.isLine()); const auto v1 = el.controlPoint() - el.startPoint(); @@ -446,28 +435,24 @@ static bool needsSplit(const QQuadPath::Element &el) float cos = QVector2D::dotProduct(v1, v2) / (v1.length() * v2.length()); return cos < 0.9; } -static void splitElementIfNecessary(QQuadPath &path, int index) -{ - auto &e = path.elementAt(index); - if (e.isLine()) - return; - if (e.childCount() == 0) { - if (needsSplit(e)) - path.splitElementAt(index); - } else { - const int childCount = e.childCount(); - for (int i = 0; i < childCount; ++i) - splitElementIfNecessary(path, path.indexOfChildAt(index, i)); + + +inline void splitElementIfNecessary(QQuadPath *path, int index, int level) { + if (level > 0 && needsSplit(path->elementAt(index))) { + path->splitElementAt(index); + splitElementIfNecessary(path, path->indexOfChildAt(index, 0), level - 1); + splitElementIfNecessary(path, path->indexOfChildAt(index, 1), level - 1); } } static QQuadPath subdivide(const QQuadPath &path, int subdivisions) { QQuadPath newPath = path; + newPath.iterateElements([&](QQuadPath::Element &e, int index) { + if (!e.isLine()) + splitElementIfNecessary(&newPath, index, subdivisions); + }); - for (int i = 0; i < subdivisions; ++i) - for (int j = 0; j < newPath.elementCount(); j++) - splitElementIfNecessary(newPath, j); return newPath; } @@ -1692,34 +1677,32 @@ void QSGCurveProcessor::processFill(const QQuadPath &fillPath, [&uv](QVector2D) { return uv; }); }; - for (int i = 0; i < fillPath.elementCount(); ++i) { - iteratePath(fillPath, i, [&](const QQuadPath::Element &element, int index) { - QVector2D sp(element.startPoint()); - QVector2D cp(element.controlPoint()); - QVector2D ep(element.endPoint()); - QVector2D rsp = roundVec2D(sp); - - if (element.isSubpathStart()) - internalHull.moveTo(sp.toPointF()); - if (element.isLine()) { + fillPath.iterateElements([&](const QQuadPath::Element &element, int index) { + QVector2D sp(element.startPoint()); + QVector2D cp(element.controlPoint()); + QVector2D ep(element.endPoint()); + QVector2D rsp = roundVec2D(sp); + + if (element.isSubpathStart()) + internalHull.moveTo(sp.toPointF()); + if (element.isLine()) { + internalHull.lineTo(ep.toPointF()); + pointHash.insert(rsp, index); + } else { + QVector2D rep = roundVec2D(ep); + QVector2D rcp = roundVec2D(cp); + if (element.isConvex()) { internalHull.lineTo(ep.toPointF()); + addTriangleForConvex(element, rsp, rep, rcp); pointHash.insert(rsp, index); } else { - QVector2D rep = roundVec2D(ep); - QVector2D rcp = roundVec2D(cp); - if (element.isConvex()) { - internalHull.lineTo(ep.toPointF()); - addTriangleForConvex(element, rsp, rep, rcp); - pointHash.insert(rsp, index); - } else { - internalHull.lineTo(cp.toPointF()); - internalHull.lineTo(ep.toPointF()); + internalHull.lineTo(cp.toPointF()); + internalHull.lineTo(ep.toPointF()); addTriangleForConcave(element, rsp, rep, rcp); - pointHash.insert(rcp, index); - } + pointHash.insert(rcp, index); } - }); - } + } + }); // Points in p are already rounded do 1/32 // Returns false if the triangle needs to be split. Adds the triangle to the graphics buffers and returns true otherwise. diff --git a/src/quick/scenegraph/util/qquadpath.cpp b/src/quick/scenegraph/util/qquadpath.cpp index 1f77cd0185..8c9986c2ac 100644 --- a/src/quick/scenegraph/util/qquadpath.cpp +++ b/src/quick/scenegraph/util/qquadpath.cpp @@ -611,7 +611,7 @@ QRectF QQuadPath::controlPointRect() const int QQuadPath::elementCountRecursive() const { int count = 0; - iterateElements([&](const QQuadPath::Element &) { count++; }); + iterateElements([&](const QQuadPath::Element &, int) { count++; }); return count; } @@ -704,7 +704,7 @@ QQuadPath QQuadPath::flattened() const { QQuadPath res; res.reserve(elementCountRecursive()); - iterateElements([&](const QQuadPath::Element &element) { res.m_elements.append(element); }); + iterateElements([&](const QQuadPath::Element &elem, int) { res.m_elements.append(elem); }); res.setPathHints(pathHints()); res.setFillRule(fillRule()); return res; @@ -941,7 +941,7 @@ QDebug operator<<(QDebug stream, const QQuadPath &path) << path.elementCountRecursive() << " leaf elements, " << (path.fillRule() == Qt::OddEvenFill ? "OddEven" : "Winding") << Qt::endl; int count = 0; - path.iterateElements([&](const QQuadPath::Element &e) { + path.iterateElements([&](const QQuadPath::Element &e, int) { stream << " " << count++ << (e.isSubpathStart() ? " >" : " "); printElement(stream, e); stream << Qt::endl; diff --git a/src/quick/scenegraph/util/qquadpath_p.h b/src/quick/scenegraph/util/qquadpath_p.h index 6037c6e736..98ef5b664c 100644 --- a/src/quick/scenegraph/util/qquadpath_p.h +++ b/src/quick/scenegraph/util/qquadpath_p.h @@ -248,7 +248,7 @@ public: if (c.childCount() > 0) iterateChildrenOf(c, lambda); else - lambda(c); + lambda(c, -(i + 1)); } } @@ -261,29 +261,31 @@ public: if (c.childCount() > 0) iterateChildrenOf(c, lambda); else - lambda(c); + lambda(c, -(i + 1)); } } template<typename Func> void iterateElements(Func &&lambda) { - for (auto &e : m_elements) { + for (int i = 0; i < m_elements.size(); i++) { + Element &e = m_elements[i]; if (e.childCount() > 0) iterateChildrenOf(e, lambda); else - lambda(e); + lambda(e, i); } } template<typename Func> void iterateElements(Func &&lambda) const { - for (auto &e : m_elements) { + for (int i = 0; i < m_elements.size(); i++) { + const Element &e = m_elements[i]; if (e.childCount() > 0) iterateChildrenOf(e, lambda); else - lambda(e); + lambda(e, i); } } |