1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:17:45 +00:00

LibGfx+PixelPaint: Add Point::end_point_for_aspect_ratio method

Previously we only had `Point::end_point_for_square_aspect_ratio`,
which was convenient for PixelPaint but assumed the aspect ratio
was always fixed at 1. This patch replaces it with a new mthod that
takes in an arbitrary aspect ratio and computes the end point based
off that.

There's some explicit casting going on in `Point.cpp` to ensure that
the types line up, since we're templating Point based on `T`.`
This commit is contained in:
Mustafa Quraish 2021-09-15 19:34:50 -04:00 committed by Andreas Kling
parent 5c244a7893
commit f14c891ba5
4 changed files with 15 additions and 10 deletions

View file

@ -90,7 +90,7 @@ void EllipseTool::on_mousemove(Layer*, MouseEvent& event)
m_draw_mode = event.layer_event().alt() ? DrawMode::FromCenter : DrawMode::FromCorner; m_draw_mode = event.layer_event().alt() ? DrawMode::FromCenter : DrawMode::FromCorner;
if (event.layer_event().shift()) if (event.layer_event().shift())
m_ellipse_end_position = m_ellipse_start_position.end_point_for_square_aspect_ratio(event.layer_event().position()); m_ellipse_end_position = m_ellipse_start_position.end_point_for_aspect_ratio(event.layer_event().position(), 1.0);
else else
m_ellipse_end_position = event.layer_event().position(); m_ellipse_end_position = event.layer_event().position();

View file

@ -96,7 +96,7 @@ void RectangleTool::on_mousemove(Layer* layer, MouseEvent& event)
m_draw_mode = event.layer_event().alt() ? DrawMode::FromCenter : DrawMode::FromCorner; m_draw_mode = event.layer_event().alt() ? DrawMode::FromCenter : DrawMode::FromCorner;
if (event.layer_event().shift()) if (event.layer_event().shift())
m_rectangle_end_position = m_rectangle_start_position.end_point_for_square_aspect_ratio(event.layer_event().position()); m_rectangle_end_position = m_rectangle_start_position.end_point_for_aspect_ratio(event.layer_event().position(), 1.0);
else else
m_rectangle_end_position = event.layer_event().position(); m_rectangle_end_position = event.layer_event().position();

View file

@ -20,14 +20,19 @@ void Point<T>::constrain(Rect<T> const& rect)
} }
template<typename T> template<typename T>
[[nodiscard]] Point<T> Point<T>::end_point_for_square_aspect_ratio(Point<T> const& previous_end_point) const [[nodiscard]] Point<T> Point<T>::end_point_for_aspect_ratio(Point<T> const& previous_end_point, float aspect_ratio) const
{ {
const T dx = previous_end_point.x() - x(); VERIFY(aspect_ratio > 0);
const T dy = previous_end_point.y() - y(); const T x_sign = previous_end_point.x() >= x() ? 1 : -1;
const T x_sign = dx >= 0 ? 1 : -1; const T y_sign = previous_end_point.y() >= y() ? 1 : -1;
const T y_sign = dy >= 0 ? 1 : -1; T dx = AK::abs(previous_end_point.x() - x());
const T abs_size = AK::max(AK::abs(dx), AK::abs(dy)); T dy = AK::abs(previous_end_point.y() - y());
return { x() + x_sign * abs_size, y() + y_sign * abs_size }; if (dx > dy) {
dy = (T)((float)dx / aspect_ratio);
} else {
dx = (T)((float)dy * aspect_ratio);
}
return { x() + x_sign * dx, y() + y_sign * dy };
} }
template<> template<>

View file

@ -231,7 +231,7 @@ public:
return { AK::abs(dx_relative_to(other)), AK::abs(dy_relative_to(other)) }; return { AK::abs(dx_relative_to(other)), AK::abs(dy_relative_to(other)) };
} }
[[nodiscard]] Point end_point_for_square_aspect_ratio(Point const&) const; [[nodiscard]] Point end_point_for_aspect_ratio(Point const& previous_end_point, float aspect_ratio) const;
template<typename U> template<typename U>
[[nodiscard]] Point<U> to_type() const [[nodiscard]] Point<U> to_type() const