LibGfx+LibWeb: Store radii as FloatSize rather than FloatPoint

Radii are sizes, not points. This becomes important when mapping them
through a 2D transform.
This commit is contained in:
Andreas Kling 2023-02-10 10:52:14 +01:00
parent e9078e216d
commit 7c607462a4
Notes: sideshowbarker 2024-07-17 00:53:02 +09:00
10 changed files with 26 additions and 26 deletions

View file

@ -282,7 +282,7 @@ void AntiAliasingPainter::stroke_path(Path const& path, Color color, float thick
}
}
void AntiAliasingPainter::draw_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatPoint radii, float x_axis_rotation, float theta_1, float theta_delta, Color color, float thickness, Painter::LineStyle style)
void AntiAliasingPainter::draw_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, Color color, float thickness, Painter::LineStyle style)
{
Painter::for_each_line_segment_on_elliptical_arc(p1, p2, center, radii, x_axis_rotation, theta_1, theta_delta, [&](FloatPoint fp1, FloatPoint fp2) {
draw_line_for_path(fp1, fp2, color, thickness, style);

View file

@ -40,7 +40,7 @@ public:
void stroke_path(Path const&, Color, float thickness);
void draw_quadratic_bezier_curve(FloatPoint control_point, FloatPoint, FloatPoint, Color, float thickness = 1, Painter::LineStyle style = Painter::LineStyle::Solid);
void draw_cubic_bezier_curve(FloatPoint control_point_0, FloatPoint control_point_1, FloatPoint, FloatPoint, Color, float thickness = 1, Painter::LineStyle style = Painter::LineStyle::Solid);
void draw_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatPoint radii, float x_axis_rotation, float theta_1, float theta_delta, Color, float thickness = 1, Painter::LineStyle style = Painter::LineStyle::Solid);
void draw_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, Color, float thickness = 1, Painter::LineStyle style = Painter::LineStyle::Solid);
void translate(float dx, float dy) { m_transform.translate(dx, dy); }
void translate(FloatPoint delta) { m_transform.translate(delta); }

View file

@ -2254,9 +2254,9 @@ void Painter::draw_cubic_bezier_curve(IntPoint control_point_0, IntPoint control
}
// static
void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatPoint const radii, float x_axis_rotation, float theta_1, float theta_delta, Function<void(FloatPoint, FloatPoint)>& callback)
void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, Function<void(FloatPoint, FloatPoint)>& callback)
{
if (radii.x() <= 0 || radii.y() <= 0)
if (radii.width() <= 0 || radii.height() <= 0)
return;
auto start = p1;
@ -2270,8 +2270,8 @@ void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint
auto relative_start = start - center;
auto a = radii.x();
auto b = radii.y();
auto a = radii.width();
auto b = radii.height();
// The segments are at most 1 long
auto largest_radius = max(a, b);
@ -2306,12 +2306,12 @@ void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint
}
// static
void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatPoint const radii, float x_axis_rotation, float theta_1, float theta_delta, Function<void(FloatPoint, FloatPoint)>&& callback)
void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, Function<void(FloatPoint, FloatPoint)>&& callback)
{
for_each_line_segment_on_elliptical_arc(p1, p2, center, radii, x_axis_rotation, theta_1, theta_delta, callback);
}
void Painter::draw_elliptical_arc(IntPoint p1, IntPoint p2, IntPoint center, FloatPoint radii, float x_axis_rotation, float theta_1, float theta_delta, Color color, int thickness, LineStyle style)
void Painter::draw_elliptical_arc(IntPoint p1, IntPoint p2, IntPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, Color color, int thickness, LineStyle style)
{
VERIFY(scale() == 1); // FIXME: Add scaling support.

View file

@ -78,7 +78,7 @@ public:
void draw_triangle_wave(IntPoint, IntPoint, Color color, int amplitude, int thickness = 1);
void draw_quadratic_bezier_curve(IntPoint control_point, IntPoint, IntPoint, Color, int thickness = 1, LineStyle style = LineStyle::Solid);
void draw_cubic_bezier_curve(IntPoint control_point_0, IntPoint control_point_1, IntPoint, IntPoint, Color, int thickness = 1, LineStyle style = LineStyle::Solid);
void draw_elliptical_arc(IntPoint p1, IntPoint p2, IntPoint center, FloatPoint radii, float x_axis_rotation, float theta_1, float theta_delta, Color, int thickness = 1, LineStyle style = LineStyle::Solid);
void draw_elliptical_arc(IntPoint p1, IntPoint p2, IntPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, Color, int thickness = 1, LineStyle style = LineStyle::Solid);
void blit(IntPoint, Gfx::Bitmap const&, IntRect const& src_rect, float opacity = 1.0f, bool apply_alpha = true);
void blit_dimmed(IntPoint, Gfx::Bitmap const&, IntRect const& src_rect);
void blit_brightened(IntPoint, Gfx::Bitmap const&, IntRect const& src_rect);
@ -131,8 +131,8 @@ public:
static void for_each_line_segment_on_cubic_bezier_curve(FloatPoint control_point_0, FloatPoint control_point_1, FloatPoint p1, FloatPoint p2, Function<void(FloatPoint, FloatPoint)>&);
static void for_each_line_segment_on_cubic_bezier_curve(FloatPoint control_point_0, FloatPoint control_point_1, FloatPoint p1, FloatPoint p2, Function<void(FloatPoint, FloatPoint)>&&);
static void for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatPoint const radii, float x_axis_rotation, float theta_1, float theta_delta, Function<void(FloatPoint, FloatPoint)>&);
static void for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatPoint const radii, float x_axis_rotation, float theta_1, float theta_delta, Function<void(FloatPoint, FloatPoint)>&&);
static void for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, Function<void(FloatPoint, FloatPoint)>&);
static void for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint p2, FloatPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, Function<void(FloatPoint, FloatPoint)>&&);
void stroke_path(Path const&, Color, int thickness);

View file

@ -14,12 +14,12 @@
namespace Gfx {
void Path::elliptical_arc_to(FloatPoint point, FloatPoint radii, double x_axis_rotation, bool large_arc, bool sweep)
void Path::elliptical_arc_to(FloatPoint point, FloatSize radii, double x_axis_rotation, bool large_arc, bool sweep)
{
auto next_point = point;
double rx = radii.x();
double ry = radii.y();
double rx = radii.width();
double ry = radii.height();
double x_axis_rotation_c = AK::cos(x_axis_rotation);
double x_axis_rotation_s = AK::sin(x_axis_rotation);

View file

@ -107,7 +107,7 @@ private:
class EllipticalArcSegment final : public Segment {
public:
EllipticalArcSegment(FloatPoint point, FloatPoint center, const FloatPoint radii, float x_axis_rotation, float theta_1, float theta_delta, bool large_arc, bool sweep)
EllipticalArcSegment(FloatPoint point, FloatPoint center, FloatSize radii, float x_axis_rotation, float theta_1, float theta_delta, bool large_arc, bool sweep)
: Segment(point)
, m_center(center)
, m_radii(radii)
@ -122,7 +122,7 @@ public:
virtual ~EllipticalArcSegment() override = default;
FloatPoint center() const { return m_center; }
FloatPoint radii() const { return m_radii; }
FloatSize radii() const { return m_radii; }
float x_axis_rotation() const { return m_x_axis_rotation; }
float theta_1() const { return m_theta_1; }
float theta_delta() const { return m_theta_delta; }
@ -133,7 +133,7 @@ private:
virtual Type type() const override { return Segment::Type::EllipticalArcTo; }
FloatPoint m_center;
FloatPoint m_radii;
FloatSize m_radii;
float m_x_axis_rotation;
float m_theta_1;
float m_theta_delta;
@ -184,14 +184,14 @@ public:
invalidate_split_lines();
}
void elliptical_arc_to(FloatPoint point, FloatPoint radii, double x_axis_rotation, bool large_arc, bool sweep);
void elliptical_arc_to(FloatPoint point, FloatSize radii, double x_axis_rotation, bool large_arc, bool sweep);
void arc_to(FloatPoint point, float radius, bool large_arc, bool sweep)
{
elliptical_arc_to(point, { radius, radius }, 0, large_arc, sweep);
}
// Note: This does not do any sanity checks!
void elliptical_arc_to(FloatPoint endpoint, FloatPoint center, FloatPoint radii, double x_axis_rotation, double theta, double theta_delta, bool large_arc, bool sweep)
void elliptical_arc_to(FloatPoint endpoint, FloatPoint center, FloatSize radii, double x_axis_rotation, double theta, double theta_delta, bool large_arc, bool sweep)
{
append_segment<EllipticalArcSegment>(
endpoint,

View file

@ -85,7 +85,7 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const
}
case Gfx::Segment::Type::EllipticalArcTo: {
auto& elliptical_arc_segment = static_cast<Gfx::EllipticalArcSegment const&>(segment);
new_path.elliptical_arc_to(transform_point(elliptical_arc_segment.point()), elliptical_arc_segment.radii().scaled(scaling, scaling), elliptical_arc_segment.x_axis_rotation(), elliptical_arc_segment.large_arc(), elliptical_arc_segment.sweep());
new_path.elliptical_arc_to(transform_point(elliptical_arc_segment.point()), elliptical_arc_segment.radii().scaled_by(scaling, scaling), elliptical_arc_segment.x_axis_rotation(), elliptical_arc_segment.large_arc(), elliptical_arc_segment.sweep());
break;
}
}

View file

@ -60,7 +60,7 @@ Gfx::Path& SVGEllipseElement::get_path()
return m_path.value();
}
Gfx::FloatPoint radii = { rx, ry };
Gfx::FloatSize radii = { rx, ry };
double x_axis_rotation = 0;
bool large_arc = false;
bool sweep = true; // Note: Spec says it should be false, but it's wrong. https://github.com/w3c/svgwg/issues/765

View file

@ -69,8 +69,8 @@ Gfx::Path& SVGRectElement::get_path()
}
auto corner_radii = calculate_used_corner_radius_values();
float rx = corner_radii.x();
float ry = corner_radii.y();
float rx = corner_radii.width();
float ry = corner_radii.height();
// 1. perform an absolute moveto operation to location (x+rx,y);
path.move_to({ x + rx, y });
@ -120,7 +120,7 @@ Gfx::Path& SVGRectElement::get_path()
return m_path.value();
}
Gfx::FloatPoint SVGRectElement::calculate_used_corner_radius_values()
Gfx::FloatSize SVGRectElement::calculate_used_corner_radius_values() const
{
// 1. Let rx and ry be length values.
float rx = 0;
@ -158,7 +158,7 @@ Gfx::FloatPoint SVGRectElement::calculate_used_corner_radius_values()
ry = half_height;
// 8. The effective values of rx and ry are rx and ry, respectively.
return Gfx::FloatPoint { rx, ry };
return { rx, ry };
}
// https://www.w3.org/TR/SVG11/shapes.html#RectElementXAttribute

View file

@ -33,7 +33,7 @@ private:
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
Gfx::FloatPoint calculate_used_corner_radius_values();
Gfx::FloatSize calculate_used_corner_radius_values() const;
Optional<Gfx::Path> m_path;