Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebKit fails to render extreme border-radius #6632

Conversation

vitorroriz
Copy link
Contributor

@vitorroriz vitorroriz commented Nov 18, 2022

8a3db1a

WebKit fails to render extreme border-radius
https://bugs.webkit.org/show_bug.cgi?id=244638
rdar://99668793

Reviewed by Antti Koivisto.

* LayoutTests/imported/w3c/web-platform-tests/css/css-backgrounds/inner-border-non-renderable-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-backgrounds/inner-border-non-renderable-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-backgrounds/inner-border-non-renderable.html: Added.
Testing that child-background doesn't bleed through its parent border for a inner-border-radius that is larger than the content rect.

* Source/WebCore/rendering/BorderPainter.cpp:
(WebCore::BorderPainter::paintOneBorderSide):
Improving readability.

* Source/WebCore/rendering/RenderBox.cpp:
(WebCore::RenderBox::clipContentForBorderRadius):
(WebCore::RenderBox::pushContentsClip):
The bug can be fixed by adjusting the inner-border radius, if not renderable, here. However, with we adjust it just here the bug can still be triggered in
other situations, for example, when applying a clip-path in an element with non-renderable border. Therefore, we are adjusting the non-renderable inner-border
directly in RenderStyle::getRoundedInnerBorderFor. Here, we are adding a helper function that still calls getRoundedInnerBorderFor for improving readability.

* Source/WebCore/rendering/RenderBox.h:
* Source/WebCore/rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::getRoundedInnerBorderFor):
Adjusting the inner-border-radii for non-renderable inner-border.

Canonical link: https://commits.webkit.org/256943@main

1a21d79

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  πŸ§ͺ win
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-debug βœ… πŸ›  gtk βœ… πŸ›  wincairo
βœ… πŸ§ͺ webkitperl   πŸ§ͺ ios-wk2 βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ gtk-wk2
βœ… πŸ§ͺ api-ios   πŸ§ͺ api-mac βœ… πŸ§ͺ api-gtk
βœ… πŸ›  tv   πŸ§ͺ mac-wk1
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2
βœ… πŸ›  πŸ§ͺ merge βœ… πŸ›  watch   πŸ§ͺ mac-AS-debug-wk2
βœ… πŸ›  watch-sim βœ… πŸ§ͺ mac-wk2-stress

@vitorroriz vitorroriz self-assigned this Nov 18, 2022
@vitorroriz vitorroriz added the Layout and Rendering For bugs with layout and rendering of Web pages. label Nov 18, 2022
Source/WebCore/rendering/BorderPainter.h Outdated Show resolved Hide resolved
Comment on lines 2025 to 2033
auto innerBorder = style().getRoundedInnerBorderFor(LayoutRect(accumulatedOffset, size()));
if (innerBorder.isRenderable())
paintInfo.context().clipRoundedRect(innerBorder.pixelSnappedRoundedRectForPainting(deviceScaleFactor));
else {
paintInfo.context().clipRoundedRect(calculateAdjustedInnerBorder(innerBorder, BoxSide::Top).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
paintInfo.context().clipRoundedRect(calculateAdjustedInnerBorder(innerBorder, BoxSide::Bottom).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
paintInfo.context().clipRoundedRect(calculateAdjustedInnerBorder(innerBorder, BoxSide::Left).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
paintInfo.context().clipRoundedRect(calculateAdjustedInnerBorder(innerBorder, BoxSide::Right).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you have a helper for this that takes GraphicsContext a parameter, clipContentForBorderRadius or something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems wrong to compute a clip for each side (ending up with the intersection of 4 clips) rather than just having logic that fixes up the rounded rect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just do:

diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index 704c4286a85d4d304024cf7043d8f82637b39c34..6e6b63fc0229d372080fe08ae647ea8dfa778f89 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -2021,8 +2021,13 @@ bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu
     float deviceScaleFactor = document().deviceScaleFactor();
     FloatRect clipRect = snapRectToDevicePixels((isControlClip ? controlClipRect(accumulatedOffset) : overflowClipRect(accumulatedOffset, nullptr, IgnoreOverlayScrollbarSize, paintInfo.phase)), deviceScaleFactor);
     paintInfo.context().save();
-    if (style().hasBorderRadius())
-        paintInfo.context().clipRoundedRect(style().getRoundedInnerBorderFor(LayoutRect(accumulatedOffset, size())).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
+    if (style().hasBorderRadius()) {
+        auto innerRoundedRect = style().getRoundedInnerBorderFor(LayoutRect(accumulatedOffset, size())).pixelSnappedRoundedRectForPainting(deviceScaleFactor);
+        if (!innerRoundedRect.isRenderable())
+            innerRoundedRect.adjustRadii();
+        paintInfo.context().clipRoundedRect(innerRoundedRect);
+    }
+    
     paintInfo.context().clip(clipRect);
 
     if (paintInfo.phase == PaintPhase::EventRegion)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@vitorroriz vitorroriz force-pushed the eng/WebKit-fails-to-render-extreme-border-radius branch from 764d008 to 34dba54 Compare November 18, 2022 16:45
<!DOCTYPE html>
<html>
<head>
<link rel="match" href="inner-border-ref.html">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The match link here seems wrong, should be inner-border-non-renderable-ref.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

border: 30px solid green;
border-top-color: gold;
border-top-right-radius: 150px 267px;
/* border-bottom-left-radius: 150px 267px; */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this commented out code useful? This whole file should probably match the -expected.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

<html>
<head>
<link rel="match" href="inner-border-ref.html">
<meta name=fuzzy content="0-144;0-484">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you include maxDifference=/totalPixels= for clarity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need fuzziness anymore.

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Nov 19, 2022
@vitorroriz vitorroriz removed the merging-blocked Applied to prevent a change from being merged label Nov 21, 2022
@vitorroriz vitorroriz force-pushed the eng/WebKit-fails-to-render-extreme-border-radius branch from 34dba54 to 0c3a00c Compare November 21, 2022 19:15
@vitorroriz vitorroriz force-pushed the eng/WebKit-fails-to-render-extreme-border-radius branch from 0c3a00c to 1a21d79 Compare November 22, 2022 11:02
@vitorroriz vitorroriz changed the title WebKit fails to clip non-renderable inner-border with border-radius WebKit fails to render extreme border-radius Nov 22, 2022
@nt1m nt1m added the merge-queue Applied to send a pull request to merge-queue label Nov 22, 2022
https://bugs.webkit.org/show_bug.cgi?id=244638
rdar://99668793

Reviewed by Antti Koivisto.

* LayoutTests/imported/w3c/web-platform-tests/css/css-backgrounds/inner-border-non-renderable-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-backgrounds/inner-border-non-renderable-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-backgrounds/inner-border-non-renderable.html: Added.
Testing that child-background doesn't bleed through its parent border for a inner-border-radius that is larger than the content rect.

* Source/WebCore/rendering/BorderPainter.cpp:
(WebCore::BorderPainter::paintOneBorderSide):
Improving readability.

* Source/WebCore/rendering/RenderBox.cpp:
(WebCore::RenderBox::clipContentForBorderRadius):
(WebCore::RenderBox::pushContentsClip):
The bug can be fixed by adjusting the inner-border radius, if not renderable, here. However, with we adjust it just here the bug can still be triggered in
other situations, for example, when applying a clip-path in an element with non-renderable border. Therefore, we are adjusting the non-renderable inner-border
directly in RenderStyle::getRoundedInnerBorderFor. Here, we are adding a helper function that still calls getRoundedInnerBorderFor for improving readability.

* Source/WebCore/rendering/RenderBox.h:
* Source/WebCore/rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::getRoundedInnerBorderFor):
Adjusting the inner-border-radii for non-renderable inner-border.

Canonical link: https://commits.webkit.org/256943@main
@webkit-early-warning-system webkit-early-warning-system force-pushed the eng/WebKit-fails-to-render-extreme-border-radius branch from 1a21d79 to 8a3db1a Compare November 22, 2022 17:53
@webkit-commit-queue
Copy link
Collaborator

Committed 256943@main (8a3db1a): https://commits.webkit.org/256943@main

Reviewed commits have been landed. Closing PR #6632 and removing active labels.

@webkit-early-warning-system webkit-early-warning-system merged commit 8a3db1a into WebKit:main Nov 22, 2022
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Nov 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Layout and Rendering For bugs with layout and rendering of Web pages.
Projects
None yet
7 participants