mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:18:11 +00:00
LibWeb: Add flag to normalize border radii to width only
This is needed to avoid issues (such as overlapping curves) for outline border radii, which do not currently support elliptical corners.
This commit is contained in:
parent
28c78b45ca
commit
0e7aa1e98c
5 changed files with 44 additions and 27 deletions
|
@ -11,30 +11,41 @@
|
|||
|
||||
namespace Web::Painting {
|
||||
|
||||
BorderRadiiData normalized_border_radii_data(Layout::Node const& node, Gfx::FloatRect const& rect, CSS::BorderRadiusData top_left_radius, CSS::BorderRadiusData top_right_radius, CSS::BorderRadiusData bottom_right_radius, CSS::BorderRadiusData bottom_left_radius)
|
||||
BorderRadiiData normalized_border_radii_data(Layout::Node const& node, Gfx::FloatRect const& rect, CSS::BorderRadiusData top_left_radius, CSS::BorderRadiusData top_right_radius, CSS::BorderRadiusData bottom_right_radius, CSS::BorderRadiusData bottom_left_radius, RelativeToWidthOnly relative_to_width_only)
|
||||
{
|
||||
BorderRadiusData bottom_left_radius_px {};
|
||||
BorderRadiusData bottom_right_radius_px {};
|
||||
BorderRadiusData top_left_radius_px {};
|
||||
BorderRadiusData top_right_radius_px {};
|
||||
|
||||
auto width_length = CSS::Length::make_px(rect.width());
|
||||
auto height_length = CSS::Length::make_px(rect.height());
|
||||
bottom_left_radius_px.horizontal_radius = bottom_left_radius.horizontal_radius.resolved(node, width_length).to_px(node);
|
||||
bottom_right_radius_px.horizontal_radius = bottom_right_radius.horizontal_radius.resolved(node, width_length).to_px(node);
|
||||
top_left_radius_px.horizontal_radius = top_left_radius.horizontal_radius.resolved(node, width_length).to_px(node);
|
||||
top_right_radius_px.horizontal_radius = top_right_radius.horizontal_radius.resolved(node, width_length).to_px(node);
|
||||
|
||||
BorderRadiusData bottom_left_radius_px {
|
||||
bottom_left_radius.horizontal_radius.resolved(node, width_length).to_px(node),
|
||||
bottom_left_radius.vertical_radius.resolved(node, height_length).to_px(node)
|
||||
};
|
||||
|
||||
BorderRadiusData bottom_right_radius_px {
|
||||
bottom_right_radius.horizontal_radius.resolved(node, width_length).to_px(node),
|
||||
bottom_right_radius.vertical_radius.resolved(node, height_length).to_px(node)
|
||||
};
|
||||
|
||||
BorderRadiusData top_left_radius_px {
|
||||
top_left_radius.horizontal_radius.resolved(node, width_length).to_px(node),
|
||||
top_left_radius.vertical_radius.resolved(node, height_length).to_px(node)
|
||||
};
|
||||
|
||||
BorderRadiusData top_right_radius_px {
|
||||
top_right_radius.horizontal_radius.resolved(node, width_length).to_px(node),
|
||||
top_right_radius.vertical_radius.resolved(node, height_length).to_px(node)
|
||||
};
|
||||
// FIXME: Remove `relative_to_width_only = Yes' flag, this only exists to
|
||||
// avoid overlapping curves for (outline) borders, which do not yet
|
||||
// support elliptical corners.
|
||||
switch (relative_to_width_only) {
|
||||
case RelativeToWidthOnly::No: {
|
||||
// Normal correct rendering:
|
||||
auto height_length = CSS::Length::make_px(rect.height());
|
||||
bottom_left_radius_px.vertical_radius = bottom_left_radius.vertical_radius.resolved(node, height_length).to_px(node);
|
||||
bottom_right_radius_px.vertical_radius = bottom_right_radius.vertical_radius.resolved(node, height_length).to_px(node);
|
||||
top_left_radius_px.vertical_radius = top_left_radius.vertical_radius.resolved(node, height_length).to_px(node);
|
||||
top_right_radius_px.vertical_radius = top_right_radius.vertical_radius.resolved(node, height_length).to_px(node);
|
||||
break;
|
||||
}
|
||||
case RelativeToWidthOnly::Yes:
|
||||
bottom_left_radius_px.vertical_radius = bottom_left_radius_px.horizontal_radius;
|
||||
bottom_right_radius_px.vertical_radius = bottom_right_radius_px.horizontal_radius;
|
||||
top_left_radius_px.vertical_radius = top_left_radius_px.horizontal_radius;
|
||||
top_right_radius_px.vertical_radius = top_right_radius_px.horizontal_radius;
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
// Scale overlapping curves according to https://www.w3.org/TR/css-backgrounds-3/#corner-overlap
|
||||
auto f = 1.0f;
|
||||
|
|
|
@ -23,7 +23,12 @@ struct BorderRadiiData {
|
|||
BorderRadiusData bottom_left;
|
||||
};
|
||||
|
||||
BorderRadiiData normalized_border_radii_data(Layout::Node const&, Gfx::FloatRect const&, CSS::BorderRadiusData top_left_radius, CSS::BorderRadiusData top_right_radius, CSS::BorderRadiusData bottom_right_radius, CSS::BorderRadiusData bottom_left_radius);
|
||||
enum class RelativeToWidthOnly {
|
||||
Yes,
|
||||
No
|
||||
};
|
||||
|
||||
BorderRadiiData normalized_border_radii_data(Layout::Node const&, Gfx::FloatRect const&, CSS::BorderRadiusData top_left_radius, CSS::BorderRadiusData top_right_radius, CSS::BorderRadiusData bottom_right_radius, CSS::BorderRadiusData bottom_left_radius, RelativeToWidthOnly relative_to_width_only = RelativeToWidthOnly::No);
|
||||
|
||||
enum class BorderEdge {
|
||||
Top,
|
||||
|
|
|
@ -106,7 +106,7 @@ void InlinePaintable::paint(PaintContext& context, Painting::PaintPhase phase) c
|
|||
}
|
||||
|
||||
auto bordered_rect = absolute_fragment_rect.inflated(borders_data.top.width, borders_data.right.width, borders_data.bottom.width, borders_data.left.width);
|
||||
auto border_radii_data = Painting::normalized_border_radii_data(layout_node(), bordered_rect, top_left_border_radius, top_right_border_radius, bottom_right_border_radius, bottom_left_border_radius);
|
||||
auto border_radii_data = Painting::normalized_border_radii_data(layout_node(), bordered_rect, top_left_border_radius, top_right_border_radius, bottom_right_border_radius, bottom_left_border_radius, Painting::RelativeToWidthOnly::Yes);
|
||||
|
||||
Painting::paint_all_borders(context, bordered_rect, border_radii_data, borders_data);
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ void PaintableBox::paint_border(PaintContext& context) const
|
|||
.bottom = computed_values().border_bottom(),
|
||||
.left = computed_values().border_left(),
|
||||
};
|
||||
paint_all_borders(context, absolute_border_box_rect(), normalized_border_radii_data(), borders_data);
|
||||
paint_all_borders(context, absolute_border_box_rect(), normalized_border_radii_data(Painting::RelativeToWidthOnly::Yes), borders_data);
|
||||
}
|
||||
|
||||
void PaintableBox::paint_background(PaintContext& context) const
|
||||
|
@ -233,13 +233,14 @@ void PaintableBox::paint_box_shadow(PaintContext& context) const
|
|||
Painting::paint_box_shadow(context, enclosing_int_rect(absolute_border_box_rect()), resolved_box_shadow_data);
|
||||
}
|
||||
|
||||
BorderRadiiData PaintableBox::normalized_border_radii_data() const
|
||||
BorderRadiiData PaintableBox::normalized_border_radii_data(Painting::RelativeToWidthOnly relative_to_width_only) const
|
||||
{
|
||||
return Painting::normalized_border_radii_data(layout_box(), absolute_border_box_rect(),
|
||||
computed_values().border_top_left_radius(),
|
||||
computed_values().border_top_right_radius(),
|
||||
computed_values().border_bottom_right_radius(),
|
||||
computed_values().border_bottom_left_radius());
|
||||
computed_values().border_bottom_left_radius(),
|
||||
relative_to_width_only);
|
||||
}
|
||||
|
||||
void PaintableBox::before_children_paint(PaintContext& context, PaintPhase) const
|
||||
|
|
|
@ -130,7 +130,7 @@ protected:
|
|||
virtual Gfx::FloatRect compute_absolute_rect() const;
|
||||
|
||||
private:
|
||||
Painting::BorderRadiiData normalized_border_radii_data() const;
|
||||
Painting::BorderRadiiData normalized_border_radii_data(Painting::RelativeToWidthOnly relative_to_width_only = Painting::RelativeToWidthOnly::No) const;
|
||||
|
||||
OwnPtr<Painting::StackingContext> m_stacking_context;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue