From 73880c92ea3dfa38d02fe0e80ae964615c84f943 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 7 Aug 2023 10:23:41 +0200 Subject: [PATCH] Revert "Add QBezier methods for computing a quadratic curves approximation" Were added for 6.6, but turns out they were not quite ready, and also live better together with the quadpath class in the curve renderer. This reverts commit aaccd50224f9a5b22b717ac743634be77c5bc678. Change-Id: I58399f8e280d5353cb9c3102e8a8e15dcfa4484a Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Paul Olav Tvete (cherry picked from commit 3cc693d2565c5633382517145822bb5edc3106cd) Reviewed-by: Qt Cherry-pick Bot --- src/gui/painting/qbezier.cpp | 102 ----------------------------------- src/gui/painting/qbezier_p.h | 4 -- 2 files changed, 106 deletions(-) diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp index 35d4a3a6649..5b2a962661c 100644 --- a/src/gui/painting/qbezier.cpp +++ b/src/gui/painting/qbezier.cpp @@ -134,108 +134,6 @@ void QBezier::addToPolygon(QDataBuffer &polygon, qreal bezier_flattenin } } -QPolygonF QBezier::toQuadratics(qreal errorLimit) const -{ - qreal infPoints[2]; - int numInfPoints = inflectionPoints(infPoints); - QPolygonF res; - res.reserve((numInfPoints + 1) * 3 * 2); - res.append(pt1()); - qreal t0 = 0; - for (int i = 0; i < numInfPoints + 1; i++) { // #segments == #inflectionpoints + 1 - qreal t1 = (i < numInfPoints) ? infPoints[i] : 1; - QBezier segment = bezierOnInterval(t0, t1); - segment.addToQuadratics(&res, t1 - t0, errorLimit); - t0 = t1; - } - return res; -} - -static inline qreal scoreQuadratic(const QBezier &b, QPointF qcp) -{ - // Construct a cubic from the quadratic, and compare its control points to the originals' - const QRectF bounds = b.bounds(); - qreal dim = QLineF(bounds.topLeft(), bounds.bottomRight()).length(); - if (qFuzzyIsNull(dim)) - return 1; - const qreal f = 2.0 / 3; - const QPointF cp1 = b.pt1() + f * (qcp - b.pt1()); - const QPointF cp2 = b.pt4() + f * (qcp - b.pt4()); - const QLineF d1(b.pt2(), cp1); - const QLineF d2(b.pt3(), cp2); - return qMax(d1.length(), d2.length()) / dim; -} - -static inline QPointF quadraticForCubic(const QBezier &b) -{ - QPointF qcp; - const QLineF st = b.startTangent(); - const QLineF et = b.endTangent(); - if (st.intersects(et, &qcp) == QLineF::NoIntersection) - qcp = b.midPoint(); - return qcp; -} - -void QBezier::addToQuadratics(QPolygonF *p, qreal tspan, qreal errorLimit) const -{ - Q_ASSERT((tspan > 0) && !(tspan > 1)); - static constexpr qreal MinimumTSpan = 0.1; - - QPointF qcp = quadraticForCubic(*this); - if (tspan < MinimumTSpan || scoreQuadratic(*this, qcp) < errorLimit) { - p->append(qcp); - p->append(pt4()); - } else { - std::pair halves = split(); - halves.first.addToQuadratics(p, tspan / 2, errorLimit); - halves.second.addToQuadratics(p, tspan / 2, errorLimit); - } -} - -int QBezier::inflectionPoints(qreal *tpoints) const -{ - auto isValidRoot = [](qreal r) { - return qIsFinite(r) && (r > 0) && (!qFuzzyIsNull(float(r))) && (r < 1) - && (!qFuzzyIsNull(float(r - 1))); - }; - - // normalize so pt1.x,pt1.y,pt4.y == 0 - QTransform xf; - const QLineF l(pt1(), pt4()); - xf.rotate(l.angle()); - xf.translate(-pt1().x(), -pt1().y()); - const QBezier n = mapBy(xf); - Q_ASSERT(n.pt1() == QPoint() && qFuzzyIsNull(float(n.pt4().y()))); - - const qreal p = n.pt3().x() * n.pt2().y(); - const qreal q = n.pt4().x() * n.pt2().y(); - const qreal r = n.pt2().x() * n.pt3().y(); - const qreal s = n.pt4().x() * n.pt3().y(); - - const qreal a = 36 * ((-3 * p) + (2 * q) + (3 * r) - s); - if (!a) - return 0; - const qreal b = -18 * (((3 * p) - q) - (3 * r)); - const qreal c = 18 * (r - p); - const qreal rad = (b * b) - (2 * a * c); - if (rad < 0) - return 0; - const qreal sqr = qSqrt(rad); - const qreal root1 = (b + sqr) / a; - const qreal root2 = (b - sqr) / a; - - int res = 0; - if (isValidRoot(root1)) - tpoints[res++] = root1; - if (!qFuzzyCompare(root2, root1) && isValidRoot(root2)) - tpoints[res++] = root2; - - if (res == 2 && tpoints[0] > tpoints[1]) - qSwap(tpoints[0], tpoints[1]); - - return res; -} - QRectF QBezier::bounds() const { qreal xmin = x1; diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h index c1b868263a9..373a35b2beb 100644 --- a/src/gui/painting/qbezier_p.h +++ b/src/gui/painting/qbezier_p.h @@ -47,10 +47,6 @@ public: void addToPolygon(QPolygonF *p, qreal bezier_flattening_threshold = 0.5) const; void addToPolygon(QDataBuffer &polygon, qreal bezier_flattening_threshold) const; - QPolygonF toQuadratics(qreal errorLimit = 0.2) const; - void addToQuadratics(QPolygonF *p, qreal tspan = 1.0, qreal errorLimit = 0.2) const; - int inflectionPoints(qreal *tpoints) const; - QRectF bounds() const; qreal length(qreal error = 0.01) const; void addIfClose(qreal *length, qreal error) const;