mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-23 08:00:20 +00:00
LibWeb: Introduce struct to hold border radii and normalize once
The struct BorderRadiusData contains the four radii of the box. In case the specified borders are too large for the dimensions of the box, they get scaled down.
This commit is contained in:
parent
c31046d952
commit
7a566e54e5
Notes:
sideshowbarker
2024-07-18 17:41:13 +09:00
Author: https://github.com/TobyAsE Commit: https://github.com/SerenityOS/serenity/commit/7a566e54e5b Pull-request: https://github.com/SerenityOS/serenity/pull/7115 Reviewed-by: https://github.com/awesomekling
2 changed files with 44 additions and 10 deletions
|
@ -60,13 +60,13 @@ void Box::paint_border(PaintContext& context)
|
||||||
auto bordered_rect = this->bordered_rect();
|
auto bordered_rect = this->bordered_rect();
|
||||||
auto border_rect = enclosing_int_rect(bordered_rect);
|
auto border_rect = enclosing_int_rect(bordered_rect);
|
||||||
|
|
||||||
// FIXME: Support elliptical border radii.
|
auto border_radius_data = normalized_border_radius_data();
|
||||||
|
auto top_left_radius = border_radius_data.top_left;
|
||||||
|
auto top_right_radius = border_radius_data.top_right;
|
||||||
|
auto bottom_right_radius = border_radius_data.bottom_right;
|
||||||
|
auto bottom_left_radius = border_radius_data.bottom_left;
|
||||||
|
|
||||||
// FIXME: some values should be relative to the height() if specified, but which? For now, all relative values are relative to the width.
|
// FIXME: Support elliptical border radii.
|
||||||
auto bottom_left_radius = computed_values().border_bottom_left_radius().resolved_or_zero(*this, width()).to_px(*this);
|
|
||||||
auto bottom_right_radius = computed_values().border_bottom_right_radius().resolved_or_zero(*this, width()).to_px(*this);
|
|
||||||
auto top_left_radius = computed_values().border_top_left_radius().resolved_or_zero(*this, width()).to_px(*this);
|
|
||||||
auto top_right_radius = computed_values().border_top_right_radius().resolved_or_zero(*this, width()).to_px(*this);
|
|
||||||
|
|
||||||
Gfx::FloatRect top_border_rect = {
|
Gfx::FloatRect top_border_rect = {
|
||||||
border_rect.x() + top_left_radius,
|
border_rect.x() + top_left_radius,
|
||||||
|
@ -202,10 +202,11 @@ void Box::paint_background(PaintContext& context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: some values should be relative to the height() if specified, but which? For now, all relative values are relative to the width.
|
// FIXME: some values should be relative to the height() if specified, but which? For now, all relative values are relative to the width.
|
||||||
auto bottom_left_radius = computed_values().border_bottom_left_radius().resolved_or_zero(*this, width()).to_px(*this);
|
auto border_radius_data = normalized_border_radius_data();
|
||||||
auto bottom_right_radius = computed_values().border_bottom_right_radius().resolved_or_zero(*this, width()).to_px(*this);
|
auto top_left_radius = border_radius_data.top_left;
|
||||||
auto top_left_radius = computed_values().border_top_left_radius().resolved_or_zero(*this, width()).to_px(*this);
|
auto top_right_radius = border_radius_data.top_right;
|
||||||
auto top_right_radius = computed_values().border_top_right_radius().resolved_or_zero(*this, width()).to_px(*this);
|
auto bottom_right_radius = border_radius_data.bottom_right;
|
||||||
|
auto bottom_left_radius = border_radius_data.bottom_left;
|
||||||
|
|
||||||
context.painter().fill_rect_with_rounded_corners(background_rect, move(background_color), top_left_radius, top_right_radius, bottom_right_radius, bottom_left_radius);
|
context.painter().fill_rect_with_rounded_corners(background_rect, move(background_color), top_left_radius, top_right_radius, bottom_right_radius, bottom_left_radius);
|
||||||
|
|
||||||
|
@ -247,6 +248,29 @@ void Box::paint_background_image(
|
||||||
context.painter().blit_tiled(background_rect, background_image, background_image.rect());
|
context.painter().blit_tiled(background_rect, background_image, background_image.rect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Box::BorderRadiusData Box::normalized_border_radius_data()
|
||||||
|
{
|
||||||
|
// FIXME: some values should be relative to the height() if specified, but which? For now, all relative values are relative to the width.
|
||||||
|
auto bottom_left_radius = computed_values().border_bottom_left_radius().resolved_or_zero(*this, width()).to_px(*this);
|
||||||
|
auto bottom_right_radius = computed_values().border_bottom_right_radius().resolved_or_zero(*this, width()).to_px(*this);
|
||||||
|
auto top_left_radius = computed_values().border_top_left_radius().resolved_or_zero(*this, width()).to_px(*this);
|
||||||
|
auto top_right_radius = computed_values().border_top_right_radius().resolved_or_zero(*this, width()).to_px(*this);
|
||||||
|
|
||||||
|
// Scale overlapping curves according to https://www.w3.org/TR/css-backgrounds-3/#corner-overlap
|
||||||
|
auto f = 1.0f;
|
||||||
|
f = min(f, bordered_rect().width() / (float)(top_left_radius + top_right_radius));
|
||||||
|
f = min(f, bordered_rect().height() / (float)(top_right_radius + bottom_right_radius));
|
||||||
|
f = min(f, bordered_rect().width() / (float)(bottom_left_radius + bottom_right_radius));
|
||||||
|
f = min(f, bordered_rect().height() / (float)(top_left_radius + bottom_left_radius));
|
||||||
|
|
||||||
|
top_left_radius = (int)(top_left_radius * f);
|
||||||
|
top_right_radius = (int)(top_right_radius * f);
|
||||||
|
bottom_right_radius = (int)(bottom_right_radius * f);
|
||||||
|
bottom_left_radius = (int)(bottom_left_radius * f);
|
||||||
|
|
||||||
|
return { (int)top_left_radius, (int)top_right_radius, (int)bottom_right_radius, (int)bottom_left_radius };
|
||||||
|
}
|
||||||
|
|
||||||
HitTestResult Box::hit_test(const Gfx::IntPoint& position, HitTestType type) const
|
HitTestResult Box::hit_test(const Gfx::IntPoint& position, HitTestType type) const
|
||||||
{
|
{
|
||||||
// FIXME: It would be nice if we could confidently skip over hit testing
|
// FIXME: It would be nice if we could confidently skip over hit testing
|
||||||
|
|
|
@ -121,6 +121,16 @@ public:
|
||||||
|
|
||||||
virtual float width_of_logical_containing_block() const;
|
virtual float width_of_logical_containing_block() const;
|
||||||
|
|
||||||
|
struct BorderRadiusData {
|
||||||
|
// FIXME: Use floats here
|
||||||
|
int top_left { 0 };
|
||||||
|
int top_right { 0 };
|
||||||
|
int bottom_right { 0 };
|
||||||
|
int bottom_left { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
BorderRadiusData normalized_border_radius_data();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Box(DOM::Document& document, DOM::Node* node, NonnullRefPtr<CSS::StyleProperties> style)
|
Box(DOM::Document& document, DOM::Node* node, NonnullRefPtr<CSS::StyleProperties> style)
|
||||||
: NodeWithStyleAndBoxModelMetrics(document, node, move(style))
|
: NodeWithStyleAndBoxModelMetrics(document, node, move(style))
|
||||||
|
|
Loading…
Reference in a new issue