Procházet zdrojové kódy

LibGfx: Put the Midpoint Ellipse Algorithm in its own function

Lucas CHOLLET před 2 roky
rodič
revize
d2372464a2
1 změnil soubory, kde provedl 41 přidání a 36 odebrání
  1. 41 36
      Userland/Libraries/LibGfx/Painter.cpp

+ 41 - 36
Userland/Libraries/LibGfx/Painter.cpp

@@ -472,41 +472,11 @@ void Painter::draw_circle_arc_intersecting(IntRect const& a_rect, IntPoint cente
     return draw_circle_arc_intersecting(a_rect, center, radius - 1, color, thickness - 1);
 }
 
-void Painter::fill_ellipse(IntRect const& a_rect, Color color)
+// The callback will only be called for a quarter of the ellipse, the user is intended to deduce other points.
+// As the coordinate space is relative to the center of the rectangle, it's simply (x, y), (x, -y), (-x, y) and (-x, -y).
+static void on_each_ellipse_point(IntRect const& rect, Function<void(IntPoint)>&& callback)
 {
-    VERIFY(scale() == 1); // FIXME: Add scaling support.
-
-    auto rect = a_rect.translated(translation()).intersected(clip_rect());
-    if (rect.is_empty())
-        return;
-
-    VERIFY(m_target->rect().contains(rect));
-
-    for (int i = 1; i < a_rect.height(); i++) {
-        float y = a_rect.height() * 0.5 - i;
-        float x = a_rect.width() * AK::sqrt(0.25f - y * y / a_rect.height() / a_rect.height());
-        draw_line({ a_rect.x() + a_rect.width() / 2 - (int)x, a_rect.y() + i }, { a_rect.x() + a_rect.width() / 2 + (int)x - 1, a_rect.y() + i }, color);
-    }
-}
-
-void Painter::draw_ellipse_intersecting(IntRect const& rect, Color color, int thickness)
-{
-    VERIFY(scale() == 1); // FIXME: Add scaling support.
-
-    if (thickness <= 0)
-        return;
-
-    auto const center = rect.center();
-
-    auto const draw_real_world_x4 = [this, &color, thickness, center](int x, int y) {
-        IntPoint const directions[4] = { { x, y }, { x, -y }, { -x, y }, { -x, -y } };
-        for (auto const& delta : directions) {
-            auto const point = center + delta;
-            draw_line(point, point, color, thickness);
-        }
-    };
-
-    // Note: This is an implementation of the Midpoint Ellipse Algorithm:
+    // Note: This is an implementation of the Midpoint Ellipse Algorithm.
     double const a = rect.width() / 2;
     double const a_square = a * a;
     double const b = rect.height() / 2;
@@ -522,7 +492,7 @@ void Painter::draw_ellipse_intersecting(IntRect const& rect, Color color, int th
     auto decision_parameter = b_square - a_square * b + .25 * a_square;
 
     while (dx < dy) {
-        draw_real_world_x4(x, y);
+        callback({ x, y });
 
         if (decision_parameter >= 0) {
             y--;
@@ -538,7 +508,7 @@ void Painter::draw_ellipse_intersecting(IntRect const& rect, Color color, int th
     decision_parameter = b_square * ((x + 0.5) * (x + 0.5)) + a_square * ((y - 1) * (y - 1)) - a_square * b_square;
 
     while (y >= 0) {
-        draw_real_world_x4(x, y);
+        callback({ x, y });
 
         if (decision_parameter <= 0) {
             x++;
@@ -551,6 +521,41 @@ void Painter::draw_ellipse_intersecting(IntRect const& rect, Color color, int th
     }
 }
 
+void Painter::fill_ellipse(IntRect const& a_rect, Color color)
+{
+    VERIFY(scale() == 1); // FIXME: Add scaling support.
+
+    auto rect = a_rect.translated(translation()).intersected(clip_rect());
+    if (rect.is_empty())
+        return;
+
+    VERIFY(m_target->rect().contains(rect));
+
+    for (int i = 1; i < a_rect.height(); i++) {
+        float y = a_rect.height() * 0.5 - i;
+        float x = a_rect.width() * AK::sqrt(0.25f - y * y / a_rect.height() / a_rect.height());
+        draw_line({ a_rect.x() + a_rect.width() / 2 - (int)x, a_rect.y() + i }, { a_rect.x() + a_rect.width() / 2 + (int)x - 1, a_rect.y() + i }, color);
+    }
+}
+
+void Painter::draw_ellipse_intersecting(IntRect const& rect, Color color, int thickness)
+{
+    VERIFY(scale() == 1); // FIXME: Add scaling support.
+
+    if (thickness <= 0)
+        return;
+
+    auto const center = rect.center();
+
+    on_each_ellipse_point(rect, [this, &color, thickness, center](IntPoint position) {
+        IntPoint const directions[4] = { { position.x(), position.y() }, { position.x(), -position.y() }, { -position.x(), position.y() }, { -position.x(), -position.y() } };
+        for (auto const delta : directions) {
+            auto const point = center + delta;
+            draw_line(point, point, color, thickness);
+        }
+    });
+}
+
 template<typename RectType, typename Callback>
 static void for_each_pixel_around_rect_clockwise(RectType const& rect, Callback callback)
 {