mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:27:43 +00:00
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:
parent
e9078e216d
commit
7c607462a4
10 changed files with 26 additions and 26 deletions
|
@ -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) {
|
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);
|
draw_line_for_path(fp1, fp2, color, thickness, style);
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
void stroke_path(Path const&, Color, float thickness);
|
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_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_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(float dx, float dy) { m_transform.translate(dx, dy); }
|
||||||
void translate(FloatPoint delta) { m_transform.translate(delta); }
|
void translate(FloatPoint delta) { m_transform.translate(delta); }
|
||||||
|
|
|
@ -2254,9 +2254,9 @@ void Painter::draw_cubic_bezier_curve(IntPoint control_point_0, IntPoint control
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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;
|
return;
|
||||||
|
|
||||||
auto start = p1;
|
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 relative_start = start - center;
|
||||||
|
|
||||||
auto a = radii.x();
|
auto a = radii.width();
|
||||||
auto b = radii.y();
|
auto b = radii.height();
|
||||||
|
|
||||||
// The segments are at most 1 long
|
// The segments are at most 1 long
|
||||||
auto largest_radius = max(a, b);
|
auto largest_radius = max(a, b);
|
||||||
|
@ -2306,12 +2306,12 @@ void Painter::for_each_line_segment_on_elliptical_arc(FloatPoint p1, FloatPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// 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);
|
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.
|
VERIFY(scale() == 1); // FIXME: Add scaling support.
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
void draw_triangle_wave(IntPoint, IntPoint, Color color, int amplitude, int thickness = 1);
|
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_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_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(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_dimmed(IntPoint, Gfx::Bitmap const&, IntRect const& src_rect);
|
||||||
void blit_brightened(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_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, 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, 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)>&&);
|
||||||
|
|
||||||
void stroke_path(Path const&, Color, int thickness);
|
void stroke_path(Path const&, Color, int thickness);
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
|
|
||||||
namespace Gfx {
|
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;
|
auto next_point = point;
|
||||||
|
|
||||||
double rx = radii.x();
|
double rx = radii.width();
|
||||||
double ry = radii.y();
|
double ry = radii.height();
|
||||||
|
|
||||||
double x_axis_rotation_c = AK::cos(x_axis_rotation);
|
double x_axis_rotation_c = AK::cos(x_axis_rotation);
|
||||||
double x_axis_rotation_s = AK::sin(x_axis_rotation);
|
double x_axis_rotation_s = AK::sin(x_axis_rotation);
|
||||||
|
|
|
@ -107,7 +107,7 @@ private:
|
||||||
|
|
||||||
class EllipticalArcSegment final : public Segment {
|
class EllipticalArcSegment final : public Segment {
|
||||||
public:
|
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)
|
: Segment(point)
|
||||||
, m_center(center)
|
, m_center(center)
|
||||||
, m_radii(radii)
|
, m_radii(radii)
|
||||||
|
@ -122,7 +122,7 @@ public:
|
||||||
virtual ~EllipticalArcSegment() override = default;
|
virtual ~EllipticalArcSegment() override = default;
|
||||||
|
|
||||||
FloatPoint center() const { return m_center; }
|
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 x_axis_rotation() const { return m_x_axis_rotation; }
|
||||||
float theta_1() const { return m_theta_1; }
|
float theta_1() const { return m_theta_1; }
|
||||||
float theta_delta() const { return m_theta_delta; }
|
float theta_delta() const { return m_theta_delta; }
|
||||||
|
@ -133,7 +133,7 @@ private:
|
||||||
virtual Type type() const override { return Segment::Type::EllipticalArcTo; }
|
virtual Type type() const override { return Segment::Type::EllipticalArcTo; }
|
||||||
|
|
||||||
FloatPoint m_center;
|
FloatPoint m_center;
|
||||||
FloatPoint m_radii;
|
FloatSize m_radii;
|
||||||
float m_x_axis_rotation;
|
float m_x_axis_rotation;
|
||||||
float m_theta_1;
|
float m_theta_1;
|
||||||
float m_theta_delta;
|
float m_theta_delta;
|
||||||
|
@ -184,14 +184,14 @@ public:
|
||||||
invalidate_split_lines();
|
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)
|
void arc_to(FloatPoint point, float radius, bool large_arc, bool sweep)
|
||||||
{
|
{
|
||||||
elliptical_arc_to(point, { radius, radius }, 0, large_arc, sweep);
|
elliptical_arc_to(point, { radius, radius }, 0, large_arc, sweep);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: This does not do any sanity checks!
|
// 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>(
|
append_segment<EllipticalArcSegment>(
|
||||||
endpoint,
|
endpoint,
|
||||||
|
|
|
@ -85,7 +85,7 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const
|
||||||
}
|
}
|
||||||
case Gfx::Segment::Type::EllipticalArcTo: {
|
case Gfx::Segment::Type::EllipticalArcTo: {
|
||||||
auto& elliptical_arc_segment = static_cast<Gfx::EllipticalArcSegment const&>(segment);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ Gfx::Path& SVGEllipseElement::get_path()
|
||||||
return m_path.value();
|
return m_path.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::FloatPoint radii = { rx, ry };
|
Gfx::FloatSize radii = { rx, ry };
|
||||||
double x_axis_rotation = 0;
|
double x_axis_rotation = 0;
|
||||||
bool large_arc = false;
|
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
|
bool sweep = true; // Note: Spec says it should be false, but it's wrong. https://github.com/w3c/svgwg/issues/765
|
||||||
|
|
|
@ -69,8 +69,8 @@ Gfx::Path& SVGRectElement::get_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
auto corner_radii = calculate_used_corner_radius_values();
|
auto corner_radii = calculate_used_corner_radius_values();
|
||||||
float rx = corner_radii.x();
|
float rx = corner_radii.width();
|
||||||
float ry = corner_radii.y();
|
float ry = corner_radii.height();
|
||||||
|
|
||||||
// 1. perform an absolute moveto operation to location (x+rx,y);
|
// 1. perform an absolute moveto operation to location (x+rx,y);
|
||||||
path.move_to({ x + rx, y });
|
path.move_to({ x + rx, y });
|
||||||
|
@ -120,7 +120,7 @@ Gfx::Path& SVGRectElement::get_path()
|
||||||
return m_path.value();
|
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.
|
// 1. Let rx and ry be length values.
|
||||||
float rx = 0;
|
float rx = 0;
|
||||||
|
@ -158,7 +158,7 @@ Gfx::FloatPoint SVGRectElement::calculate_used_corner_radius_values()
|
||||||
ry = half_height;
|
ry = half_height;
|
||||||
|
|
||||||
// 8. The effective values of ‘rx’ and ‘ry’ are rx and ry, respectively.
|
// 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
|
// https://www.w3.org/TR/SVG11/shapes.html#RectElementXAttribute
|
||||||
|
|
|
@ -33,7 +33,7 @@ private:
|
||||||
|
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
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;
|
Optional<Gfx::Path> m_path;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue