basegfx/source/polygon/b2dpolygontools.cxx | 51 +++++++++++++++++++++------- include/basegfx/polygon/b2dpolygontools.hxx | 2 - 2 files changed, 40 insertions(+), 13 deletions(-)
New commits: commit 9f4ccc63346b26d8d774b22124da0842ef18e0bc Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Wed Sep 13 14:27:02 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Wed Sep 13 15:42:37 2023 +0200 tdf#156995 speed up dragging complex group objects These shaves 20% of the time of the construction of the "drag view" object. Of course, it is still heinously slow. Change-Id: I4c6ee2d7e0cc2030a9966a281d2fdbe7f6859289 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156896 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx index 04a22df578a6..56b286403671 100644 --- a/basegfx/source/polygon/b2dpolygontools.cxx +++ b/basegfx/source/polygon/b2dpolygontools.cxx @@ -475,7 +475,7 @@ namespace basegfx::utils return fRetval; } - double getLength(const B2DPolygon& rCandidate) + double getLength(const B2DPolygon& rCandidate, bool bApproximateBezierLength) { double fRetval(0.0); const sal_uInt32 nPointCount(rCandidate.count()); @@ -486,18 +486,45 @@ namespace basegfx::utils if(rCandidate.areControlPointsUsed()) { - B2DCubicBezier aEdge; - aEdge.setStartPoint(rCandidate.getB2DPoint(0)); + if (bApproximateBezierLength) + { + B2DPoint aStartPoint = rCandidate.getB2DPoint(0); - for(sal_uInt32 a(0); a < nEdgeCount; a++) + for(sal_uInt32 a(0); a < nEdgeCount; a++) + { + // An approximate length of a cubic Bezier curve is the average + // of its chord length and the sum of the lengths of its control net sides. + const sal_uInt32 nNextIndex((a + 1) % nPointCount); + const B2DPoint& aControlPoint1 = rCandidate.getNextControlPoint(a); + const B2DPoint& aControlPoint2 = rCandidate.getPrevControlPoint(nNextIndex); + const B2DPoint& aEndPoint = rCandidate.getB2DPoint(nNextIndex); + + double chord_length = B2DVector(aEndPoint - aStartPoint).getLength(); + double control_net_length = B2DVector(aStartPoint - aControlPoint1).getLength() + + B2DVector(aControlPoint2 - aControlPoint1).getLength() + + B2DVector(aEndPoint - aControlPoint2).getLength(); + double approximate_arc_length = (control_net_length + chord_length) / 2; + + fRetval += approximate_arc_length; + aStartPoint = aEndPoint; + } + + } + else { - const sal_uInt32 nNextIndex((a + 1) % nPointCount); - aEdge.setControlPointA(rCandidate.getNextControlPoint(a)); - aEdge.setControlPointB(rCandidate.getPrevControlPoint(nNextIndex)); - aEdge.setEndPoint(rCandidate.getB2DPoint(nNextIndex)); + B2DCubicBezier aEdge; + aEdge.setStartPoint(rCandidate.getB2DPoint(0)); - fRetval += aEdge.getLength(); - aEdge.setStartPoint(aEdge.getEndPoint()); + for(sal_uInt32 a(0); a < nEdgeCount; a++) + { + const sal_uInt32 nNextIndex((a + 1) % nPointCount); + aEdge.setControlPointA(rCandidate.getNextControlPoint(a)); + aEdge.setControlPointB(rCandidate.getPrevControlPoint(nNextIndex)); + aEdge.setEndPoint(rCandidate.getB2DPoint(nNextIndex)); + + fRetval += aEdge.getLength(); + aEdge.setStartPoint(aEdge.getEndPoint()); + } } } else @@ -1236,9 +1263,9 @@ namespace basegfx::utils // precalculate maximal acceptable length of candidate polygon assuming // we want to create a maximum of fNumberOfAllowedSnippets. For // fNumberOfAllowedSnippets use ca. 65536, double due to line & gap. - static const double fNumberOfAllowedSnippets(65535.0 * 2.0); + static const double fNumberOfAllowedSnippets(100.0 * 2.0); const double fAllowedLength((fNumberOfAllowedSnippets * fDotDashLength) / double(rDotDashArray.size())); - const double fCandidateLength(basegfx::utils::getLength(rCandidate)); + const double fCandidateLength(basegfx::utils::getLength(rCandidate, /*bApproximateBezierLength*/true)); std::vector<double> aDotDashArray(rDotDashArray); if(fCandidateLength > fAllowedLength) diff --git a/include/basegfx/polygon/b2dpolygontools.hxx b/include/basegfx/polygon/b2dpolygontools.hxx index 2f73b76d33c6..eff5f06a9cff 100644 --- a/include/basegfx/polygon/b2dpolygontools.hxx +++ b/include/basegfx/polygon/b2dpolygontools.hxx @@ -113,7 +113,7 @@ namespace basegfx::utils BASEGFX_DLLPUBLIC double getEdgeLength(const B2DPolygon& rCandidate, sal_uInt32 nIndex); /** get length of polygon */ - BASEGFX_DLLPUBLIC double getLength(const B2DPolygon& rCandidate); + BASEGFX_DLLPUBLIC double getLength(const B2DPolygon& rCandidate, bool bApproximateBezierLength = false); // get position on polygon for absolute given distance. If // length is given, it is assumed the correct polygon length, if 0.0 it is calculated