Bug 1847149. Make PathBuilderD2D::Arc handle all start and end angles properly. r=lsalzman

This steals some code from ArcToBezier https://searchfox.org/mozilla-central/rev/fb43eb3bdf5b51000bc7dfe3474cbe56ca2ab63c/gfx/2d/PathHelpers.h#127 so that the start and end angle are within 2*Pi and so that they are in the correct numerical order depending if we are sweeping clockwise or anticlockwise. This makes calculations easier. Specifically it makes the determination of arc size (more or less than Pi) work below. This replaces some code which tried to do something similar but did not account for all cases.

Differential Revision: https://phabricator.services.mozilla.com/D185517
This commit is contained in:
Timothy Nikkel 2023-08-07 02:05:30 +00:00
Родитель f68eec7bff
Коммит 1a15b46e51
1 изменённых файлов: 12 добавлений и 13 удалений

Просмотреть файл

@ -169,20 +169,20 @@ void PathBuilderD2D::Close() {
void PathBuilderD2D::Arc(const Point& aOrigin, Float aRadius, Float aStartAngle,
Float aEndAngle, bool aAntiClockwise) {
ArcToBezier(this, aOrigin, Size(aRadius, aRadius), aStartAngle, aEndAngle,
aAntiClockwise);
#if 0
MOZ_ASSERT(aRadius >= 0);
if (aAntiClockwise && aStartAngle < aEndAngle) {
// D2D does things a little differently, and draws the arc by specifying an
// beginning and an end point. This means the circle will be the wrong way
// around if the start angle is smaller than the end angle. It might seem
// tempting to invert aAntiClockwise but that would change the sweeping
// direction of the arc so instead we exchange start/begin.
Float oldStart = aStartAngle;
aStartAngle = aEndAngle;
aEndAngle = oldStart;
// We want aEndAngle to come numerically after aStartAngle when taking into
// account the sweep direction so that our calculation of the arcSize below
// (large or small) works.
Float sweepDirection = aAntiClockwise ? -1.0f : 1.0f;
Float arcSweepLeft = (aEndAngle - aStartAngle) * sweepDirection;
if (arcSweepLeft < 0) {
// This calculation moves aStartAngle by a multiple of 2*Pi so that it is
// the closest it can be to aEndAngle and still be numerically before
// aEndAngle when taking into account sweepDirection.
arcSweepLeft = Float(2.0f * M_PI) + fmodf(arcSweepLeft, Float(2.0f * M_PI));
aStartAngle = aEndAngle - arcSweepLeft * sweepDirection;
}
// XXX - Workaround for now, D2D does not appear to do the desired thing when
@ -256,7 +256,6 @@ void PathBuilderD2D::Arc(const Point& aOrigin, Float aRadius, Float aStartAngle,
mCurrentPoint = endPoint;
mFigureEmpty = false;
#endif
}
void PathBuilderD2D::EnsureActive(const Point& aPoint) {