diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.cpp b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.cpp index a8ffab9ae8..2577583f68 100644 --- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.cpp +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPath.cpp @@ -53,7 +53,9 @@ WebIDL::ExceptionOr CanvasPath::ellipse(float x, float y, float radius_x, if (constexpr float tau = M_TAU; (!counter_clockwise && (end_angle - start_angle) >= tau) || (counter_clockwise && (start_angle - end_angle) >= tau)) { start_angle = 0; - end_angle = tau; + // FIXME: elliptical_arc_to() incorrectly handles the case where the start/end points are very close. + // So we slightly fudge the numbers here to correct for that. + end_angle = tau * 0.9999f; } else { start_angle = fmodf(start_angle, tau); end_angle = fmodf(end_angle, tau); @@ -63,8 +65,9 @@ WebIDL::ExceptionOr CanvasPath::ellipse(float x, float y, float radius_x, // To do so, we can pretend that the center of this ellipse is at (0, 0), // and the whole coordinate system is rotated `rotation` radians around the x axis, centered on `center`. // The sign of the resulting relative positions is just whether our angle is on one of the left quadrants. - auto sin_rotation = sinf(rotation); - auto cos_rotation = cosf(rotation); + float sin_rotation; + float cos_rotation; + AK::sincos(rotation, sin_rotation, cos_rotation); auto resolve_point_with_angle = [&](float angle) { auto tan_relative = tanf(angle); @@ -79,7 +82,9 @@ WebIDL::ExceptionOr CanvasPath::ellipse(float x, float y, float radius_x, auto relative_y_position = ab * tan_relative / sqrt; // Make sure to set the correct sign - float sn = sinf(angle) >= 0 ? 1 : -1; + // -1 if 0 ≤ θ < 90° or 270°< θ ≤ 360° + // 1 if 90° < θ< 270° + float sn = cosf(angle) >= 0 ? 1 : -1; relative_x_position *= sn; relative_y_position *= sn; @@ -94,12 +99,10 @@ WebIDL::ExceptionOr CanvasPath::ellipse(float x, float y, float radius_x, m_path.move_to(start_point); - double delta_theta = end_angle - start_angle; + auto delta_theta = end_angle - start_angle; - // FIXME: This is still goofy for some values. - m_path.elliptical_arc_to(end_point, { radius_x, radius_y }, rotation, delta_theta > M_PI, !counter_clockwise); + m_path.elliptical_arc_to(end_point, { radius_x, radius_y }, rotation, delta_theta > AK::Pi, !counter_clockwise); - m_path.close(); return {}; }