diff options
author | MacDue <macdue@dueutil.tech> | 2022-06-12 15:21:32 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-06-13 09:43:45 +0100 |
commit | 0e7aa1e98c88a40cddd6f8ffddb29d7cf937f69f (patch) | |
tree | 8ef8c5e178add2578dbe45b5caa0876bca80f252 | |
parent | 28c78b45ca86291b10318a0546ad6526a9c572e7 (diff) | |
download | serenity-0e7aa1e98c88a40cddd6f8ffddb29d7cf937f69f.zip |
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.
5 files changed, 45 insertions, 28 deletions
diff --git a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp index 8bc63ea9f6..bb57d505f9 100644 --- a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp +++ b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp @@ -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) { - auto width_length = CSS::Length::make_px(rect.width()); - auto height_length = CSS::Length::make_px(rect.height()); - - 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 bottom_left_radius_px {}; + BorderRadiusData bottom_right_radius_px {}; + BorderRadiusData top_left_radius_px {}; + BorderRadiusData top_right_radius_px {}; - 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) - }; + auto width_length = CSS::Length::make_px(rect.width()); + 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); + + // 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; diff --git a/Userland/Libraries/LibWeb/Painting/BorderPainting.h b/Userland/Libraries/LibWeb/Painting/BorderPainting.h index a553396447..ee45e50730 100644 --- a/Userland/Libraries/LibWeb/Painting/BorderPainting.h +++ b/Userland/Libraries/LibWeb/Painting/BorderPainting.h @@ -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, diff --git a/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp b/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp index d7c2848c09..9b2355b5f4 100644 --- a/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp @@ -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); diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index e651ca62ad..8025aa0f74 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -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 diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.h b/Userland/Libraries/LibWeb/Painting/PaintableBox.h index 6094b5e33e..1763a17d14 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.h @@ -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; |