Skip to content

[css-borders-4] Handle rectangle, self-intersecting, and non-uniform outset corners in the contoured path algorithm - #14142

Open
sb3nder wants to merge 10 commits into
w3c:mainfrom
sb3nder:corner-shape-1
Open

[css-borders-4] Handle rectangle, self-intersecting, and non-uniform outset corners in the contoured path algorithm#14142
sb3nder wants to merge 10 commits into
w3c:mainfrom
sb3nder:corner-shape-1

Conversation

@sb3nder

@sb3nder sb3nder commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
  • Refactored border-aligned corner clip-out path to:

    • Handle non-square corners by scaling the "normal" vectors.
    • Fix when the miter degenerates and self-intersects for concave corners. Fixed by calculating the miter lines as perpendicular to the "normal" vectors (AKA "tangent").
      (note: in square corners this results in the same miter points as the control-point method. When the corner is not square: in concave corners the miter points diverge from the control-point method, in convex corners the miter points are almost the same as the control-point method.)
    • Fix non uniform outset corners and mixed-inset-sign corners, by computing bevel corners as the tangent to 2 circles with center at corner-start and corner-end, and radius the 2 signed insets. All other intermediary corner shapes are adjusted accordingly and are also fixed.
  • Refactored Computing a contoured path to:

    • Respect the outset-adjusted border radius for round corner compat.
      • Fixed by substituting the following algorithm:

        1. Let adjustedRadiusInOutsetCoordinates be the outset-adjusted border radius given borderRect’s size, radius, and (-insetX, -insetY).
        2. Return (adjustedRadiusInOutsetCoordinates’s width - insetX, adjustedRadiusInOutsetCoordinates’s height - insetY).

        with adjustedInset, which calculates the inset from the adjusted radius, and by computing the borderRect outer point from the targetRect and the adjusted inset.

  • Applied opposite corner scale factor to the used value.

  • Made various math fixes.

  • Updated explanation for non-linear interpolation.

  • Fixed some typos.

Fixes #13318
Fixes #14183
Fixes #14184
Fixes #14185

WPT tests:

Questions:

graphs:
clip-out path
testing for clip-out path
half corner
half corner visual

screencasts:
current algorithm, chrome implementation:

screencast-2.mp4

circa proposed changes:

expected-behavior-2.mp4

chrome bugs:
https://issues.chromium.org/issues/532190484
https://issues.chromium.org/issues/532199267
https://issues.chromium.org/issues/532163949

@noamr

noamr commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Thanks for working on this! The screen casts look like they fix the issue but it's hard for me to assess the formula without tests.

Note that the current WPTs for corner-shape implement the spec'ed formula in JS using canvas, see https://github.com/web-platform-tests/wpt/blob/master/css/css-borders/corner-shape/resources/render-corner-shape.js

So supplementing this PR with a WPT PR that does this and some test cases that fix the aforementioned issues would be very helpful.

(Side note: IPR for this issue needs to be filled out)

@sb3nder

sb3nder commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for the pointers. I've added WPTs to the todo list in the PR, and hopefully I'll be able to implement them.

@noamr

noamr commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Thank you for the pointers. I've added WPTs to the todo list in the PR, and hopefully I'll be able to implement them.

Let me know if you need any help. I also might try to get to trying this out.

@svgeesus

Copy link
Copy Markdown
Contributor

s it is a separate repo for WPT, adding tests should be a separate PR right?

@sb3nder

sb3nder commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

it is a separate repo for WPT, adding tests should be a separate PR right?

Yep, the todo list is mostly there to remind me what I still need to do for this PR.

sb3nder added 6 commits July 10, 2026 16:27
Since concave corners are now drawn as the symmetric of convex corners, update the explanation of why we don't interpolate linearly.
- fixed some typo in `normalized inner corner hull`.
- moved `normalized inner corner hull` in `Constraining opposite radii` section.
- fixed coordinate system mismatch in `opposite corner scale factor`, by defining mapping.
@sb3nder

This comment was marked as outdated.

@sb3nder
sb3nder marked this pull request as draft July 20, 2026 13:27
@sb3nder

sb3nder commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

In the following case (positive non-uniform outsets):
image

I think the corner should always be drawn without overflowing the blue area:
screen_20260720_162428

Let me know if you agree (👍) or disagree (👎).

cc @noamr

@sb3nder

sb3nder commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

@noamr no progress yet. I got sidetracked trying to handle non-uniform outsets and was considering giving that another try.
Do you think I should leave that as-is for now and proceed with the WPT tests?

@noamr

noamr commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

@noamr no progress yet. I got sidetracked trying to handle non-uniform outsets and was considering giving that another try. Do you think I should leave that as-is for now and proceed with the WPT tests?

Up to you!

removed adjustedClipOutPath in favor or generalized handling in clip path.
basically bevel corners are computed as the tangent to 2 circles with center at corner-start and corner-end, and radius the 2 signed insets.
@sb3nder
sb3nder marked this pull request as ready for review July 27, 2026 17:55
@sb3nder sb3nder changed the title [css-borders-4] Handle rectangle corners and self-intersecting concave corners in the contoured path algorithm [css-borders-4] Handle rectangle, self-intersecting, and non-uniform outset corners in the contoured path algorithm Jul 27, 2026
@noamr

noamr commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

This seems like really stellar work. Thanks a lot. We are testing it on the blink implementation/WPT and review it based on this

@sb3nder

sb3nder commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Thanks! I really appreciate it.
Happy to help if anything comes up.

@noamr

noamr commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

I want to merge this.
@emilio @smfr @nt1m can you see if this is OK given your ongoing implementation of the feature?
We tested this in blink/WPT and it seems to give better results along all kinds of edge cases.

@smfr

smfr commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Do you plan to update the WPT JS to show the code? We'd like to review that, and see if it's different from what we've done in WebKit.

@noamr

noamr commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Do you plan to update the WPT JS to show the code? We'd like to review that, and see if it's different from what we've done in WebKit.

web-platform-tests/wpt#61658

cupidsity added a commit to cupidsity/WebKit that referenced this pull request Jul 31, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the
damage showed up on non-round shapes and on elliptical radii: a two-value
border-radius such as 10px 50px had its aspect ratio normalised away when
the offset direction was computed, so the corner offset at roughly 45°
instead of following its own proportions. For that corner at bevel the
offset should run at 78.7°. This replaces them with the single construction
which scales the offset normal per-axis by the two corner radii so an elliptical
corner keeps its shape when offset, and wires up the outset-adjusted border radius.

Adopted algorithm from w3c/csswg-drafts#14142

New tests will be written in another commit

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/platform/graphics/LayoutRoundedRect.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
cupidsity added a commit to cupidsity/WebKit that referenced this pull request Jul 31, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the
damage showed up on non-round shapes and on elliptical radii: a two-value
border-radius such as 10px 50px had its aspect ratio normalised away when
the offset direction was computed, so the corner offset at roughly 45°
instead of following its own proportions. For that corner at bevel the
offset should run at 78.7°. This replaces them with the single construction
which scales the offset normal per-axis by the two corner radii so an elliptical
corner keeps its shape when offset, and wires up the outset-adjusted border radius.

Adopted algorithm from w3c/csswg-drafts#14142

New tests will be written in another commit

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-squircle.html:
@sb3nder

sb3nder commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

I reworked the test algorithm a bit, added some new test cases, and added support for clip-path: margin-box to cover non-uniform outsets.
web-platform-tests/wpt#61696

cupidsity added a commit to cupidsity/WebKit that referenced this pull request Aug 4, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the damage
showed up on non-round shapes and on elliptical radii

This replaces them with the single construction from the revised algorithm,
which scales the offset normal per-axis by the two corner radii so an
elliptical corner keeps its shape when offset. box-shadow spread now uses
that same construction, so a shadow and an outline at the same distance stay
parallel rather than pinching together at the corners.

Adopted algorithm from w3c/csswg-drafts#14142

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
(WebCore::BorderShape::shapeWithBorderWidths const):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical.html: Added.
* Source/WebCore/platform/graphics/BezierUtilities.cpp:
(WebCore::addCatmullRomBeziers):
* Source/WebCore/rendering/BorderShape.h:
(WebCore::BorderShape::shapeForOffsetRect):
* Source/WebCore/rendering/OutlinePainter.cpp:
(WebCore::OutlinePainter::paintOutline const):
(WebCore::OutlinePainter::paintFocusRing const):
cupidsity added a commit to cupidsity/WebKit that referenced this pull request Aug 4, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the damage
showed up on non-round shapes and on elliptical radii

This replaces them with the single construction from the revised algorithm,
which scales the offset normal per-axis by the two corner radii so an
elliptical corner keeps its shape when offset. box-shadow spread now uses
that same construction, so a shadow and an outline at the same distance stay
parallel rather than pinching together at the corners.

Adopted algorithm from w3c/csswg-drafts#14142

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
(WebCore::BorderShape::shapeWithBorderWidths const):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical.html: Added.
* Source/WebCore/platform/graphics/BezierUtilities.cpp:
(WebCore::addCatmullRomBeziers):
* Source/WebCore/rendering/BorderShape.h:
(WebCore::BorderShape::shapeForOffsetRect):
* Source/WebCore/rendering/OutlinePainter.cpp:
(WebCore::OutlinePainter::paintOutline const):
(WebCore::OutlinePainter::paintFocusRing const):
cupidsity added a commit to cupidsity/WebKit that referenced this pull request Aug 4, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the damage
showed up on non-round shapes and on elliptical radii

This replaces them with the single construction from the revised algorithm,
which scales the offset normal per-axis by the two corner radii so an
elliptical corner keeps its shape when offset. box-shadow spread now uses
that same construction, so a shadow and an outline at the same distance stay
parallel rather than pinching together at the corners.

Adopted algorithm from w3c/csswg-drafts#14142

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
(WebCore::BorderShape::shapeWithBorderWidths const):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical.html: Added.
* Source/WebCore/platform/graphics/BezierUtilities.cpp:
(WebCore::addCatmullRomBeziers):
* Source/WebCore/rendering/BorderShape.h:
(WebCore::BorderShape::shapeForOffsetRect):
* Source/WebCore/rendering/OutlinePainter.cpp:
(WebCore::OutlinePainter::paintOutline const):
(WebCore::OutlinePainter::paintFocusRing const):
cupidsity added a commit to cupidsity/WebKit that referenced this pull request Aug 4, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the damage
showed up on non-round shapes and on elliptical radii

This replaces them with the single construction from the revised algorithm,
which scales the offset normal per-axis by the two corner radii so an
elliptical corner keeps its shape when offset. box-shadow spread now uses
that same construction, so a shadow and an outline at the same distance stay
parallel rather than pinching together at the corners.

Adopted algorithm from w3c/csswg-drafts#14142

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
(WebCore::BorderShape::shapeWithBorderWidths const):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical.html: Added.
* Source/WebCore/platform/graphics/BezierUtilities.cpp:
(WebCore::addCatmullRomBeziers):
* Source/WebCore/rendering/BorderShape.h:
(WebCore::BorderShape::shapeForOffsetRect):
* Source/WebCore/rendering/OutlinePainter.cpp:
(WebCore::OutlinePainter::paintOutline const):
(WebCore::OutlinePainter::paintFocusRing const):
cupidsity added a commit to cupidsity/WebKit that referenced this pull request Aug 4, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the damage
showed up on non-round shapes and on elliptical radii

This replaces them with the single construction from the revised algorithm,
which scales the offset normal per-axis by the two corner radii so an
elliptical corner keeps its shape when offset. box-shadow spread now uses
that same construction, so a shadow and an outline at the same distance stay
parallel rather than pinching together at the corners.

Adopted algorithm from w3c/csswg-drafts#14142

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
(WebCore::BorderShape::shapeWithBorderWidths const):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical.html: Added.
* Source/WebCore/rendering/BorderShape.h:
(WebCore::BorderShape::shapeForOffsetRect):
* Source/WebCore/rendering/OutlinePainter.cpp:
(WebCore::OutlinePainter::paintOutline const):
(WebCore::OutlinePainter::paintFocusRing const):
cupidsity added a commit to cupidsity/WebKit that referenced this pull request Aug 4, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the damage
showed up on non-round shapes and on elliptical radii

This replaces them with the single construction from the revised algorithm,
which scales the offset normal per-axis by the two corner radii so an
elliptical corner keeps its shape when offset. box-shadow spread now uses
that same construction, so a shadow and an outline at the same distance stay
parallel rather than pinching together at the corners.

Adopted algorithm from w3c/csswg-drafts#14142

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
(WebCore::BorderShape::shapeWithBorderWidths const):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical.html: Added.
* Source/WebCore/rendering/BorderShape.h:
(WebCore::BorderShape::shapeForOffsetRect):
* Source/WebCore/rendering/OutlinePainter.cpp:
(WebCore::OutlinePainter::paintOutline const):
(WebCore::OutlinePainter::paintFocusRing const):
cupidsity added a commit to cupidsity/WebKit that referenced this pull request Aug 5, 2026
https://bugs.webkit.org/show_bug.cgi?id=320753
rdar://183753095

Reviewed by NOBODY (OOPS!).

Offsetting a shaped corner outward picked between several constructions
based on the corner's shape, and they disagreed with one another. They
coincided only for a plain round corner with a single radius, so the damage
showed up on non-round shapes and on elliptical radii

This replaces them with the single construction from the revised algorithm,
which scales the offset normal per-axis by the two corner radii so an
elliptical corner keeps its shape when offset. box-shadow spread now uses
that same construction, so a shadow and an outline at the same distance stay
parallel rather than pinching together at the corners.

Adopted algorithm from w3c/csswg-drafts#14142

* Source/WebCore/platform/graphics/CornerShapeUtilities.cpp:
(WebCore::borderContourPath):
* Source/WebCore/platform/graphics/GeometryUtilities.cpp:
(WebCore::findSegmentLineIntersection):
* Source/WebCore/platform/graphics/GeometryUtilities.h:
* Source/WebCore/rendering/BorderShape.cpp:
(WebCore::BorderShape::shapeForOffsetRect):
(WebCore::buildOutsetCornerInputs):
(WebCore::addAreaExpansionOffsetContour):
(WebCore::BorderShape::pathForOuterCornerShape const):
(WebCore::BorderShape::pathForInnerCornerShape const):
(WebCore::adjustedRadiusDimension):
(WebCore::outsetAdjustedBorderRadius):
(WebCore::expandRadiiForOutset):
(WebCore::BorderShape::shapeWithBorderWidths const):
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel-overflow.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-convex.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-bevel.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-superellipse-squircle.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-box-shadow-spread-elliptical.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-bevel.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-borders/corner-shape/corner-shape-outline-offset-elliptical.html: Added.
* Source/WebCore/rendering/BorderShape.h:
(WebCore::BorderShape::shapeForOffsetRect):
* Source/WebCore/rendering/OutlinePainter.cpp:
(WebCore::OutlinePainter::paintOutline const):
(WebCore::OutlinePainter::paintFocusRing const):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants