|
@@ -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)
|
|
|
{
|