summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGfx
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2021-04-15 18:41:13 +0430
committerAndreas Kling <kling@serenityos.org>2021-04-15 17:50:16 +0200
commit801daf47f04ef8a353783f8331ef260336670d72 (patch)
tree234455e3410963c7f741d8168c539ba569b7cd9f /Userland/Libraries/LibGfx
parent6c05d6d3706bc2d3ebda1fed641dfa9c903100f3 (diff)
downloadserenity-801daf47f04ef8a353783f8331ef260336670d72.zip
LibGfx+LibWeb: Wire up CanvasRenderingContext2D.ellipse()
Note that this is *extremely* naive, and not very good at being correct.
Diffstat (limited to 'Userland/Libraries/LibGfx')
-rw-r--r--Userland/Libraries/LibGfx/Painter.cpp2
-rw-r--r--Userland/Libraries/LibGfx/Path.cpp35
-rw-r--r--Userland/Libraries/LibGfx/Path.h14
3 files changed, 39 insertions, 12 deletions
diff --git a/Userland/Libraries/LibGfx/Painter.cpp b/Userland/Libraries/LibGfx/Painter.cpp
index b3a383dc3d..e16792f716 100644
--- a/Userland/Libraries/LibGfx/Painter.cpp
+++ b/Userland/Libraries/LibGfx/Painter.cpp
@@ -1492,7 +1492,7 @@ void Painter::for_each_line_segment_on_bezier_curve(const FloatPoint& control_po
static bool can_approximate_elliptical_arc(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& center, const FloatPoint radii, float x_axis_rotation, float theta_1, float theta_delta)
{
- constexpr static float tolerance = 0.5f;
+ constexpr static float tolerance = 0.3f;
auto half_theta_delta = theta_delta / 2.0f;
diff --git a/Userland/Libraries/LibGfx/Path.cpp b/Userland/Libraries/LibGfx/Path.cpp
index f7d758a794..9bb4e7fa53 100644
--- a/Userland/Libraries/LibGfx/Path.cpp
+++ b/Userland/Libraries/LibGfx/Path.cpp
@@ -30,11 +30,14 @@
#include <AK/StringBuilder.h>
#include <LibGfx/Painter.h>
#include <LibGfx/Path.h>
+#include <math.h>
namespace Gfx {
-void Path::elliptical_arc_to(const FloatPoint& next_point, const FloatPoint& radii, double x_axis_rotation, bool large_arc, bool sweep)
+void Path::elliptical_arc_to(const FloatPoint& point, const FloatPoint& radii, double x_axis_rotation, bool large_arc, bool sweep)
{
+ auto next_point = point;
+
double rx = radii.x();
double ry = radii.y();
@@ -58,6 +61,18 @@ void Path::elliptical_arc_to(const FloatPoint& next_point, const FloatPoint& rad
if (ry < 0)
ry *= -1.0;
+ // POSSIBLY HACK: Handle the case where both points are the same.
+ auto same_endpoints = next_point == last_point;
+ if (same_endpoints) {
+ if (!large_arc) {
+ // Nothing is going to be drawn anyway.
+ return;
+ }
+
+ // Move the endpoint by a small amount to avoid division by zero.
+ next_point.move_by(0.01f, 0.01f);
+ }
+
// Find (cx, cy), theta_1, theta_delta
// Step 1: Compute (x1', y1')
auto x_avg = (last_point.x() - next_point.x()) / 2.0f;
@@ -104,20 +119,18 @@ void Path::elliptical_arc_to(const FloatPoint& next_point, const FloatPoint& rad
auto theta_delta = theta_2 - theta_1;
if (!sweep && theta_delta > 0.0f) {
- theta_delta -= M_TAU;
+ theta_delta -= 2 * M_PI;
} else if (sweep && theta_delta < 0) {
- theta_delta += M_TAU;
+ theta_delta += 2 * M_PI;
}
- append_segment<EllipticalArcSegment>(
+ elliptical_arc_to(
next_point,
- FloatPoint(cx, cy),
- FloatPoint(rx, ry),
- static_cast<float>(x_axis_rotation),
- static_cast<float>(theta_1),
- static_cast<float>(theta_delta));
-
- invalidate_split_lines();
+ { cx, cy },
+ { rx, ry },
+ x_axis_rotation,
+ theta_1,
+ theta_delta);
}
void Path::close()
diff --git a/Userland/Libraries/LibGfx/Path.h b/Userland/Libraries/LibGfx/Path.h
index 52013ce7ff..b1691bf5de 100644
--- a/Userland/Libraries/LibGfx/Path.h
+++ b/Userland/Libraries/LibGfx/Path.h
@@ -160,6 +160,20 @@ public:
elliptical_arc_to(point, { radius, radius }, 0, large_arc, sweep);
}
+ // Note: This does not do any sanity checks!
+ void elliptical_arc_to(const FloatPoint& endpoint, const FloatPoint& center, const FloatPoint& radii, double x_axis_rotation, double theta, double theta_delta)
+ {
+ append_segment<EllipticalArcSegment>(
+ endpoint,
+ center,
+ radii,
+ x_axis_rotation,
+ theta,
+ theta_delta);
+
+ invalidate_split_lines();
+ }
+
void close();
void close_all_subpaths();