tdf#94699: freehand drawing tool, ignore extremely offsetted control points

Now with the /org.openoffice.Office.Common/Misc/FreehandThresholdPixels config
option, when using low threshold pixels like 1px it is more apparent that
XPolygon::PointsToBezier will sometimes make the curve shoot off.

Try to counteract by ignoring control points offsetted more then the segment
length.

Better fix would be changing the PointsToBezier algorithm, but this seems to
hold OK for now.

Change-Id: I7ab0a67a33e25874ff55af932b3e087bbaad98fb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181841
Tested-by: Jenkins
Reviewed-by: Sarper Akdemir <sarper.akdemir@allotropia.de>
This commit is contained in:
Sarper Akdemir
2025-03-31 09:33:50 +02:00
parent c976458eb2
commit dc468362e4
+15 -2
View File
@@ -729,8 +729,21 @@ void XPolygon::PointsToBezier(sal_uInt16 nFirst)
fY2 -= fY1 * fU2 / fT2;
fY2 -= fY3 * fT2 / (fU2 * 3);
pPoints[nFirst+1] = Point(static_cast<tools::Long>(fX1), static_cast<tools::Long>(fY1));
pPoints[nFirst+2] = Point(static_cast<tools::Long>(fX2), static_cast<tools::Long>(fY2));
Point aControlPoint1(static_cast<tools::Long>(fX1), static_cast<tools::Long>(fY1));
Point aControlPoint2(static_cast<tools::Long>(fX2), static_cast<tools::Long>(fY2));
auto fPointOffset1 = std::hypot(aControlPoint1.X() - pPoints[nFirst + 1].X(), aControlPoint1.Y() - pPoints[nFirst + 1].Y());
auto fPointOffset2 = std::hypot(aControlPoint2.X() - pPoints[nFirst + 2].X(), aControlPoint2.Y() - pPoints[nFirst + 2].Y());
// To prevent the curve from overshooting due to sharp direction changes in the given sequence of points,
// compare the control point offsets against the full segment length.
// Apply the calculated ControlPoints only if their offsets are within a reasonable range.
if( fPointOffset1 < nFullLength && fPointOffset2 < nFullLength )
{
pPoints[nFirst + 1] = aControlPoint1;
pPoints[nFirst + 2] = aControlPoint2;
}
SetFlags(nFirst+1, PolyFlags::Control);
SetFlags(nFirst+2, PolyFlags::Control);
}