Title: [201868] trunk
Revision
201868
Author
[email protected]
Date
2016-06-09 09:59:17 -0700 (Thu, 09 Jun 2016)

Log Message

border-radius with different width and height rendered wrong
https://bugs.webkit.org/show_bug.cgi?id=158300
<rdar://problem/26672922>

Reviewed by Zalan Bujtas.
Source/WebCore:

Borders with border-radius close to 100% 100% got oddly clipped. This happened because
of the clipping we do to achieve the diagonal corner joins; RenderBoxModelObject::clipBorderSidePolygon()
created trapezoids for each side, but only extended them to the center of the inner border rect.
This clipped out parts of these borders.

Fix by computing the trapezoids by intersecting the corner diagonal line with a line that passes
through the adjacent corners of the inner rect, whose intersection is always going to be inside the
rounded border. Also fix the quads used to do the antialiased/non-antialiased clipping,
by adding a point rather than moving a corner point to ensure we don't mistakenly clip out any
parts of the border.

Finally, improve the rendering of non-renderable cases by actually doing the diagonal
corner joins rather than just giving up.

Tests: fast/borders/border-non-renderable-radius-inner-clip.html
       fast/borders/border-radius-inner-clip-vertical.html
       fast/borders/border-radius-inner-clip.html

* rendering/RenderBoxModelObject.cpp:
(WebCore::calculateAdjustedInnerBorder): Moved up.
(WebCore::RenderBoxModelObject::paintOneBorderSide):
(WebCore::RenderBoxModelObject::clipBorderSidePolygon):
(WebCore::findInnerVertex): Deleted.
(WebCore::calculateSideRectIncludingInner): Deleted.
(WebCore::RenderBoxModelObject::clipBorderSideForComplexInnerPath): Deleted.
* rendering/RenderBoxModelObject.h:

LayoutTests:

* fast/borders/border-non-renderable-radius-inner-clip-expected.html: Added.
* fast/borders/border-non-renderable-radius-inner-clip.html: Added.
* fast/borders/border-radius-inner-clip-expected-mismatch.html: Added.
* fast/borders/border-radius-inner-clip-vertical-expected-mismatch.html: Added.
* fast/borders/border-radius-inner-clip-vertical.html: Added.
* fast/borders/border-radius-inner-clip.html: Added.
* fast/borders/resources/border-radius-helpers.js: Added.
(createContainer):
(createReferenceContainer):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (201867 => 201868)


--- trunk/LayoutTests/ChangeLog	2016-06-09 16:49:19 UTC (rev 201867)
+++ trunk/LayoutTests/ChangeLog	2016-06-09 16:59:17 UTC (rev 201868)
@@ -1,3 +1,21 @@
+2016-06-09  Simon Fraser  <[email protected]>
+
+        border-radius with different width and height rendered wrong
+        https://bugs.webkit.org/show_bug.cgi?id=158300
+        <rdar://problem/26672922>
+
+        Reviewed by Zalan Bujtas.
+        
+        * fast/borders/border-non-renderable-radius-inner-clip-expected.html: Added.
+        * fast/borders/border-non-renderable-radius-inner-clip.html: Added.
+        * fast/borders/border-radius-inner-clip-expected-mismatch.html: Added.
+        * fast/borders/border-radius-inner-clip-vertical-expected-mismatch.html: Added.
+        * fast/borders/border-radius-inner-clip-vertical.html: Added.
+        * fast/borders/border-radius-inner-clip.html: Added.
+        * fast/borders/resources/border-radius-helpers.js: Added.
+        (createContainer):
+        (createReferenceContainer):
+
 2016-06-09  Per Arne Vollan  <[email protected]>
 
         Unreviewed test gardening.

Added: trunk/LayoutTests/fast/borders/border-non-renderable-radius-inner-clip-expected.html (0 => 201868)


--- trunk/LayoutTests/fast/borders/border-non-renderable-radius-inner-clip-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/borders/border-non-renderable-radius-inner-clip-expected.html	2016-06-09 16:59:17 UTC (rev 201868)
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+
+<html>
+    <head>
+        <style type="text/css">
+            body {
+                margin: 0;
+            }
+
+            div {
+                box-sizing: border-box;
+            }
+            
+            .container {
+                position: relative;
+                width: 800px;
+                height: 100px;
+                margin: 10px 0;
+                padding: 20px;
+            }
+            
+            .container div {
+                position: absolute;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+                background-color: green;
+                border: 1px solid black;
+            }
+        </style>
+        <script src=""
+        <script>
+            const borderWidth = 50;
+            
+            const corners = [
+                'top-left',
+                'top-right',
+                'bottom-left',
+                'bottom-right'
+            ];
+
+            const clipPaths = [
+                'inset(10px 2px 60px 500px)',
+                'inset(10px 500px 60px 2px)',
+                'inset(60px 2px 10px 500px)',
+                'inset(60px 500px 10px 20px)'
+            ];
+
+            var colors = [
+                'transparent',
+                'transparent'
+            ];
+
+            var radii = '1178px 178px';
+            
+            function doSetup()
+            {
+                for (var index in corners)
+                    document.body.appendChild(createContainer(corners[index], colors, clipPaths[index], radii));
+            }
+
+            window.addEventListener('load', doSetup, false);
+        </script>
+    </head>
+    <body>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/borders/border-non-renderable-radius-inner-clip.html (0 => 201868)


--- trunk/LayoutTests/fast/borders/border-non-renderable-radius-inner-clip.html	                        (rev 0)
+++ trunk/LayoutTests/fast/borders/border-non-renderable-radius-inner-clip.html	2016-06-09 16:59:17 UTC (rev 201868)
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+
+<html>
+    <head>
+        <style type="text/css">
+            body {
+                margin: 0;
+            }
+
+            div {
+                box-sizing: border-box;
+            }
+            
+            .container {
+                position: relative;
+                width: 800px;
+                height: 100px;
+                margin: 10px 0;
+                padding: 20px;
+            }
+            
+            .container div {
+                position: absolute;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+                border: 1px solid black;
+            }
+        </style>
+        <script src=""
+        <script>
+            const borderWidth = 50;
+            
+            const corners = [
+                'top-left',
+                'top-right',
+                'bottom-left',
+                'bottom-right'
+            ];
+
+            const clipPaths = [
+                'inset(10px 2px 60px 500px)',
+                'inset(10px 500px 60px 2px)',
+                'inset(60px 2px 10px 500px)',
+                'inset(60px 500px 10px 20px)'
+            ];
+
+            var colors = [
+                'green',
+                'red'
+            ];
+            
+            var radii = '1178px 178px';
+            
+            function doSetup()
+            {
+                for (var index in corners)
+                    document.body.appendChild(createContainer(corners[index], colors, clipPaths[index], radii));
+            }
+
+            window.addEventListener('load', doSetup, false);
+        </script>
+    </head>
+    <body>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/borders/border-radius-inner-clip-expected-mismatch.html (0 => 201868)


--- trunk/LayoutTests/fast/borders/border-radius-inner-clip-expected-mismatch.html	                        (rev 0)
+++ trunk/LayoutTests/fast/borders/border-radius-inner-clip-expected-mismatch.html	2016-06-09 16:59:17 UTC (rev 201868)
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML>
+
+<html>
+    <head>
+        <style type="text/css">
+            body {
+                margin: 0;
+            }
+
+            div {
+                box-sizing: border-box;
+            }
+            
+            .container {
+                position: relative;
+                width: 800px;
+                height: 100px;
+                border: 1px solid black;
+                margin: 10px 0;
+                padding: 20px;
+            }
+            
+            .container div {
+                position: absolute;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+                background-color: silver;
+            }
+        </style>
+        <script src=""
+        <script>
+            const borderWidth = 20;
+            
+            const corners = [
+                'top-left',
+                'top-right',
+                'bottom-left',
+                'bottom-right'
+            ];
+
+            const clipPaths = [
+                'inset(60px 10px 640px 60px)',
+                'inset(60px 60px 640px 10px)',
+                'inset(640px 10px 60px 60px)',
+                'inset(640px 60px 60px 10px)'
+            ];
+
+            var colors = [
+                'green',
+                'blue'
+            ];
+            
+            function doSetup()
+            {
+                for (var index in corners)
+                    document.body.appendChild(createReferenceContainer());
+            }
+
+            window.addEventListener('load', doSetup, false);
+        </script>
+    </head>
+    <body>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/borders/border-radius-inner-clip-vertical-expected-mismatch.html (0 => 201868)


--- trunk/LayoutTests/fast/borders/border-radius-inner-clip-vertical-expected-mismatch.html	                        (rev 0)
+++ trunk/LayoutTests/fast/borders/border-radius-inner-clip-vertical-expected-mismatch.html	2016-06-09 16:59:17 UTC (rev 201868)
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+
+<html>
+    <head>
+        <style type="text/css">
+            body {
+                margin: 0;
+            }
+
+            div {
+                box-sizing: border-box;
+            }
+            
+            .container {
+                display: inline-block;
+                position: relative;
+                width: 100px;
+                height: 800px;
+                border: 1px solid black;
+                margin: 0 10px;
+                padding: 20px;
+            }
+            
+            .container div {
+                position: absolute;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+                background-color: silver;
+            }
+        </style>
+        <script src=""
+        <script>
+            const borderWidth = 20;
+            
+            const corners = [
+                'top-left',
+                'top-right',
+                'bottom-left',
+                'bottom-right'
+            ];
+
+            const clipPaths = [
+                'inset(60px 10px 640px 60px)',
+                'inset(60px 60px 640px 10px)',
+                'inset(640px 10px 60px 60px)',
+                'inset(640px 60px 60px 10px)'
+            ];
+
+            var colors = [
+                'green',
+                'blue'
+            ];
+            
+            function doSetup()
+            {
+                for (var index in corners)
+                    document.body.appendChild(createReferenceContainer());
+            }
+
+            window.addEventListener('load', doSetup, false);
+        </script>
+    </head>
+    <body>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/borders/border-radius-inner-clip-vertical.html (0 => 201868)


--- trunk/LayoutTests/fast/borders/border-radius-inner-clip-vertical.html	                        (rev 0)
+++ trunk/LayoutTests/fast/borders/border-radius-inner-clip-vertical.html	2016-06-09 16:59:17 UTC (rev 201868)
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+
+<html>
+    <head>
+        <style type="text/css">
+            body {
+                margin: 0;
+            }
+
+            div {
+                box-sizing: border-box;
+            }
+            
+            .container {
+                display: inline-block;
+                position: relative;
+                width: 100px;
+                height: 800px;
+                border: 1px solid black;
+                margin: 0 10px;
+                padding: 20px;
+            }
+            
+            .container div {
+                position: absolute;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+            }
+        </style>
+        <script src=""
+        <script>
+            const borderWidth = 20;
+            
+            const corners = [
+                'top-left',
+                'top-right',
+                'bottom-left',
+                'bottom-right'
+            ];
+
+            const clipPaths = [
+                'inset(60px 10px 640px 60px)',
+                'inset(60px 60px 640px 10px)',
+                'inset(640px 10px 60px 60px)',
+                'inset(640px 60px 60px 10px)'
+            ];
+
+            var colors = [
+                'green',
+                'blue'
+            ];
+
+            var radii = '100% 100%';
+            
+            function doSetup()
+            {
+                for (var index in corners)
+                    document.body.appendChild(createContainer(corners[index], colors, clipPaths[index], radii));
+            }
+
+            window.addEventListener('load', doSetup, false);
+        </script>
+    </head>
+    <body>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/borders/border-radius-inner-clip.html (0 => 201868)


--- trunk/LayoutTests/fast/borders/border-radius-inner-clip.html	                        (rev 0)
+++ trunk/LayoutTests/fast/borders/border-radius-inner-clip.html	2016-06-09 16:59:17 UTC (rev 201868)
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+
+<html>
+    <head>
+        <style type="text/css">
+            body {
+                margin: 0;
+            }
+
+            div {
+                box-sizing: border-box;
+            }
+            
+            .container {
+                position: relative;
+                width: 800px;
+                height: 100px;
+                border: 1px solid black;
+                margin: 10px 0;
+                padding: 20px;
+            }
+            
+            .container div {
+                position: absolute;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+            }
+        </style>
+        <script src=""
+        <script>
+            const borderWidth = 20;
+            
+            const corners = [
+                'top-left',
+                'top-right',
+                'bottom-left',
+                'bottom-right'
+            ];
+
+            const clipPaths = [
+                'inset(60px 640px 10px 60px)',
+                'inset(60px 60px 10px 640px)',
+                'inset(10px 640px 60px 60px)',
+                'inset(10px 60px 60px 640px)'
+            ];
+
+            var colors = [
+                'green',
+                'blue'
+            ];
+
+            var radii = '100% 100%';
+            
+            function doSetup()
+            {
+                for (var index in corners)
+                    document.body.appendChild(createContainer(corners[index], colors, clipPaths[index], radii));
+            }
+
+            window.addEventListener('load', doSetup, false);
+        </script>
+    </head>
+    <body>
+    </body>
+</html>

Added: trunk/LayoutTests/fast/borders/resources/border-radius-helpers.js (0 => 201868)


--- trunk/LayoutTests/fast/borders/resources/border-radius-helpers.js	                        (rev 0)
+++ trunk/LayoutTests/fast/borders/resources/border-radius-helpers.js	2016-06-09 16:59:17 UTC (rev 201868)
@@ -0,0 +1,27 @@
+function createContainer(corner, colors, clipPath)
+{
+    var container = document.createElement('div');
+    container.className = 'container';
+    
+    var testDiv = document.createElement('div');
+    testDiv.className = 'test';
+    
+    var sides = corner.split('-');
+    for (var index in sides)
+        testDiv.style['border-' + sides[index]] = borderWidth + 'px solid ' + colors[index];
+
+    testDiv.style['border-' + corner + '-radius'] = '100% 100%';
+    testDiv.style.webkitClipPath = clipPath;
+    
+    container.appendChild(testDiv);
+
+    return container;
+}
+
+function createReferenceContainer()
+{
+    var container = document.createElement('div');
+    container.className = 'container';
+    
+    return container;
+}

Modified: trunk/Source/WebCore/ChangeLog (201867 => 201868)


--- trunk/Source/WebCore/ChangeLog	2016-06-09 16:49:19 UTC (rev 201867)
+++ trunk/Source/WebCore/ChangeLog	2016-06-09 16:59:17 UTC (rev 201868)
@@ -1,3 +1,38 @@
+2016-06-09  Simon Fraser  <[email protected]>
+
+        border-radius with different width and height rendered wrong
+        https://bugs.webkit.org/show_bug.cgi?id=158300
+        <rdar://problem/26672922>
+
+        Reviewed by Zalan Bujtas.
+
+        Borders with border-radius close to 100% 100% got oddly clipped. This happened because
+        of the clipping we do to achieve the diagonal corner joins; RenderBoxModelObject::clipBorderSidePolygon()
+        created trapezoids for each side, but only extended them to the center of the inner border rect.
+        This clipped out parts of these borders.
+
+        Fix by computing the trapezoids by intersecting the corner diagonal line with a line that passes
+        through the adjacent corners of the inner rect, whose intersection is always going to be inside the
+        rounded border. Also fix the quads used to do the antialiased/non-antialiased clipping,
+        by adding a point rather than moving a corner point to ensure we don't mistakenly clip out any
+        parts of the border.
+        
+        Finally, improve the rendering of non-renderable cases by actually doing the diagonal
+        corner joins rather than just giving up.
+
+        Tests: fast/borders/border-non-renderable-radius-inner-clip.html
+               fast/borders/border-radius-inner-clip-vertical.html
+               fast/borders/border-radius-inner-clip.html
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::calculateAdjustedInnerBorder): Moved up.
+        (WebCore::RenderBoxModelObject::paintOneBorderSide):
+        (WebCore::RenderBoxModelObject::clipBorderSidePolygon):
+        (WebCore::findInnerVertex): Deleted.
+        (WebCore::calculateSideRectIncludingInner): Deleted.
+        (WebCore::RenderBoxModelObject::clipBorderSideForComplexInnerPath): Deleted.
+        * rendering/RenderBoxModelObject.h:
+
 2016-06-09  Xabier Rodriguez Calvar  <[email protected]>
 
         Unreviewed, fixing compilation issue with WebRTC

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (201867 => 201868)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2016-06-09 16:49:19 UTC (rev 201867)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2016-06-09 16:59:17 UTC (rev 201868)
@@ -1436,6 +1436,86 @@
     return false;
 }
 
+static RoundedRect calculateAdjustedInnerBorder(const RoundedRect&innerBorder, BoxSide side)
+{
+    // Expand the inner border as necessary to make it a rounded rect (i.e. radii contained within each edge).
+    // This function relies on the fact we only get radii not contained within each edge if one of the radii
+    // for an edge is zero, so we can shift the arc towards the zero radius corner.
+    RoundedRect::Radii newRadii = innerBorder.radii();
+    LayoutRect newRect = innerBorder.rect();
+
+    float overshoot;
+    float maxRadii;
+
+    switch (side) {
+    case BSTop:
+        overshoot = newRadii.topLeft().width() + newRadii.topRight().width() - newRect.width();
+        if (overshoot > 0) {
+            ASSERT(!(newRadii.topLeft().width() && newRadii.topRight().width()));
+            newRect.setWidth(newRect.width() + overshoot);
+            if (!newRadii.topLeft().width())
+                newRect.move(-overshoot, 0);
+        }
+        newRadii.setBottomLeft(IntSize(0, 0));
+        newRadii.setBottomRight(IntSize(0, 0));
+        maxRadii = std::max(newRadii.topLeft().height(), newRadii.topRight().height());
+        if (maxRadii > newRect.height())
+            newRect.setHeight(maxRadii);
+        break;
+
+    case BSBottom:
+        overshoot = newRadii.bottomLeft().width() + newRadii.bottomRight().width() - newRect.width();
+        if (overshoot > 0) {
+            ASSERT(!(newRadii.bottomLeft().width() && newRadii.bottomRight().width()));
+            newRect.setWidth(newRect.width() + overshoot);
+            if (!newRadii.bottomLeft().width())
+                newRect.move(-overshoot, 0);
+        }
+        newRadii.setTopLeft(IntSize(0, 0));
+        newRadii.setTopRight(IntSize(0, 0));
+        maxRadii = std::max(newRadii.bottomLeft().height(), newRadii.bottomRight().height());
+        if (maxRadii > newRect.height()) {
+            newRect.move(0, newRect.height() - maxRadii);
+            newRect.setHeight(maxRadii);
+        }
+        break;
+
+    case BSLeft:
+        overshoot = newRadii.topLeft().height() + newRadii.bottomLeft().height() - newRect.height();
+        if (overshoot > 0) {
+            ASSERT(!(newRadii.topLeft().height() && newRadii.bottomLeft().height()));
+            newRect.setHeight(newRect.height() + overshoot);
+            if (!newRadii.topLeft().height())
+                newRect.move(0, -overshoot);
+        }
+        newRadii.setTopRight(IntSize(0, 0));
+        newRadii.setBottomRight(IntSize(0, 0));
+        maxRadii = std::max(newRadii.topLeft().width(), newRadii.bottomLeft().width());
+        if (maxRadii > newRect.width())
+            newRect.setWidth(maxRadii);
+        break;
+
+    case BSRight:
+        overshoot = newRadii.topRight().height() + newRadii.bottomRight().height() - newRect.height();
+        if (overshoot > 0) {
+            ASSERT(!(newRadii.topRight().height() && newRadii.bottomRight().height()));
+            newRect.setHeight(newRect.height() + overshoot);
+            if (!newRadii.topRight().height())
+                newRect.move(0, -overshoot);
+        }
+        newRadii.setTopLeft(IntSize(0, 0));
+        newRadii.setBottomLeft(IntSize(0, 0));
+        maxRadii = std::max(newRadii.topRight().width(), newRadii.bottomRight().width());
+        if (maxRadii > newRect.width()) {
+            newRect.move(newRect.width() - maxRadii, 0);
+            newRect.setWidth(maxRadii);
+        }
+        break;
+    }
+
+    return RoundedRect(newRect, newRadii);
+}
+
 void RenderBoxModelObject::paintOneBorderSide(GraphicsContext& graphicsContext, const RenderStyle& style, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
     const LayoutRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjacentSide2, const BorderEdge edges[], const Path* path,
     BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor)
@@ -1455,10 +1535,12 @@
 
     if (path) {
         GraphicsContextStateSaver stateSaver(graphicsContext);
-        if (innerBorder.isRenderable())
-            clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, side, adjacentSide1StylesMatch, adjacentSide2StylesMatch);
-        else
-            clipBorderSideForComplexInnerPath(graphicsContext, outerBorder, innerBorder, side, edges);
+
+        clipBorderSidePolygon(graphicsContext, outerBorder, innerBorder, side, adjacentSide1StylesMatch, adjacentSide2StylesMatch);
+
+        if (!innerBorder.isRenderable())
+            graphicsContext.clipOutRoundedRect(FloatRoundedRect(calculateAdjustedInnerBorder(innerBorder, side)));
+
         float thickness = std::max(std::max(edgeToRender.widthForPainting(), adjacentEdge1.widthForPainting()), adjacentEdge2.widthForPainting());
         drawBoxSideFromPath(graphicsContext, outerBorder.rect(), *path, edges, edgeToRender.widthForPainting(), thickness, side, style,
             colorToPaint, edgeToRender.style(), bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge);
@@ -1907,21 +1989,6 @@
     graphicsContext.drawRect(snapRectToDevicePixels(borderRect, document().deviceScaleFactor()));
 }
 
-static void findInnerVertex(const FloatPoint& outerCorner, const FloatPoint& innerCorner, const FloatPoint& centerPoint, FloatPoint& result)
-{
-    // If the line between outer and inner corner is towards the horizontal, intersect with a vertical line through the center,
-    // otherwise with a horizontal line through the center. The points that form this line are arbitrary (we use 0, 100).
-    // Note that if findIntersection fails, it will leave result untouched.
-    float diffInnerOuterX = fabs(innerCorner.x() - outerCorner.x());
-    float diffInnerOuterY = fabs(innerCorner.y() - outerCorner.y());
-    float diffCenterOuterX = fabs(centerPoint.x() - outerCorner.x());
-    float diffCenterOuterY = fabs(centerPoint.y() - outerCorner.y());
-    if (diffInnerOuterY * diffCenterOuterX < diffCenterOuterY * diffInnerOuterX)
-        findIntersection(outerCorner, innerCorner, FloatPoint(centerPoint.x(), 0), FloatPoint(centerPoint.x(), 100), result);
-    else
-        findIntersection(outerCorner, innerCorner, FloatPoint(0, centerPoint.y()), FloatPoint(100, centerPoint.y()), result);
-}
-
 void RenderBoxModelObject::clipBorderSidePolygon(GraphicsContext& graphicsContext, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
                                                  BoxSide side, bool firstEdgeMatches, bool secondEdgeMatches)
 {
@@ -1929,8 +1996,6 @@
     const FloatRect& outerRect = snapRectToDevicePixels(outerBorder.rect(), deviceScaleFactor);
     const FloatRect& innerRect = snapRectToDevicePixels(innerBorder.rect(), deviceScaleFactor);
 
-    FloatPoint centerPoint(innerRect.location().x() + innerRect.width() / 2, innerRect.location().y() + innerRect.height() / 2);
-
     // For each side, create a quad that encompasses all parts of that side that may draw,
     // including areas inside the innerBorder.
     //
@@ -1955,10 +2020,10 @@
         quad.uncheckedAppend(outerRect.maxXMinYCorner());
 
         if (!innerBorder.radii().topLeft().isZero())
-            findInnerVertex(outerRect.minXMinYCorner(), innerRect.minXMinYCorner(), centerPoint, quad[1]);
+            findIntersection(outerRect.minXMinYCorner(), innerRect.minXMinYCorner(), innerRect.minXMaxYCorner(), innerRect.maxXMinYCorner(), quad[1]);
 
         if (!innerBorder.radii().topRight().isZero())
-            findInnerVertex(outerRect.maxXMinYCorner(), innerRect.maxXMinYCorner(), centerPoint, quad[2]);
+            findIntersection(outerRect.maxXMinYCorner(), innerRect.maxXMinYCorner(), innerRect.minXMinYCorner(), innerRect.maxXMaxYCorner(), quad[2]);
         break;
 
     case BSLeft:
@@ -1968,10 +2033,10 @@
         quad.uncheckedAppend(outerRect.minXMaxYCorner());
 
         if (!innerBorder.radii().topLeft().isZero())
-            findInnerVertex(outerRect.minXMinYCorner(), innerRect.minXMinYCorner(), centerPoint, quad[1]);
+            findIntersection(outerRect.minXMinYCorner(), innerRect.minXMinYCorner(), innerRect.minXMaxYCorner(), innerRect.maxXMinYCorner(), quad[1]);
 
         if (!innerBorder.radii().bottomLeft().isZero())
-            findInnerVertex(outerRect.minXMaxYCorner(), innerRect.minXMaxYCorner(), centerPoint, quad[2]);
+            findIntersection(outerRect.minXMaxYCorner(), innerRect.minXMaxYCorner(), innerRect.minXMinYCorner(), innerRect.maxXMaxYCorner(), quad[2]);
         break;
 
     case BSBottom:
@@ -1981,10 +2046,10 @@
         quad.uncheckedAppend(outerRect.maxXMaxYCorner());
 
         if (!innerBorder.radii().bottomLeft().isZero())
-            findInnerVertex(outerRect.minXMaxYCorner(), innerRect.minXMaxYCorner(), centerPoint, quad[1]);
+            findIntersection(outerRect.minXMaxYCorner(), innerRect.minXMaxYCorner(), innerRect.minXMinYCorner(), innerRect.maxXMaxYCorner(), quad[1]);
 
         if (!innerBorder.radii().bottomRight().isZero())
-            findInnerVertex(outerRect.maxXMaxYCorner(), innerRect.maxXMaxYCorner(), centerPoint, quad[2]);
+            findIntersection(outerRect.maxXMaxYCorner(), innerRect.maxXMaxYCorner(), innerRect.maxXMinYCorner(), innerRect.minXMaxYCorner(), quad[2]);
         break;
 
     case BSRight:
@@ -1994,10 +2059,10 @@
         quad.uncheckedAppend(outerRect.maxXMaxYCorner());
 
         if (!innerBorder.radii().topRight().isZero())
-            findInnerVertex(outerRect.maxXMinYCorner(), innerRect.maxXMinYCorner(), centerPoint, quad[1]);
+            findIntersection(outerRect.maxXMinYCorner(), innerRect.maxXMinYCorner(), innerRect.minXMinYCorner(), innerRect.maxXMaxYCorner(), quad[1]);
 
         if (!innerBorder.radii().bottomRight().isZero())
-            findInnerVertex(outerRect.maxXMaxYCorner(), innerRect.maxXMaxYCorner(), centerPoint, quad[2]);
+            findIntersection(outerRect.maxXMaxYCorner(), innerRect.maxXMaxYCorner(), innerRect.maxXMinYCorner(), innerRect.minXMaxYCorner(), quad[2]);
         break;
     }
 
@@ -2015,6 +2080,7 @@
     Vector<FloatPoint> firstQuad = {
         quad[0],
         quad[1],
+        quad[2],
         side == BSTop || side == BSBottom ? FloatPoint(quad[3].x(), quad[2].y()) : FloatPoint(quad[2].x(), quad[3].y()),
         quad[3]
     };
@@ -2025,6 +2091,7 @@
     Vector<FloatPoint> secondQuad = {
         quad[0],
         side == BSTop || side == BSBottom ? FloatPoint(quad[0].x(), quad[1].y()) : FloatPoint(quad[1].x(), quad[0].y()),
+        quad[1],
         quad[2],
         quad[3]
     };
@@ -2035,120 +2102,6 @@
     graphicsContext.setShouldAntialias(wasAntialiased);
 }
 
-static LayoutRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, const BorderEdge edges[], BoxSide side)
-{
-    LayoutRect sideRect = outerBorder.rect();
-    LayoutUnit width;
-
-    switch (side) {
-    case BSTop:
-        width = sideRect.height() - edges[BSBottom].widthForPainting();
-        sideRect.setHeight(width);
-        break;
-    case BSBottom:
-        width = sideRect.height() - edges[BSTop].widthForPainting();
-        sideRect.shiftYEdgeTo(sideRect.maxY() - width);
-        break;
-    case BSLeft:
-        width = sideRect.width() - edges[BSRight].widthForPainting();
-        sideRect.setWidth(width);
-        break;
-    case BSRight:
-        width = sideRect.width() - edges[BSLeft].widthForPainting();
-        sideRect.shiftXEdgeTo(sideRect.maxX() - width);
-        break;
-    }
-
-    return sideRect;
-}
-
-static RoundedRect calculateAdjustedInnerBorder(const RoundedRect&innerBorder, BoxSide side)
-{
-    // Expand the inner border as necessary to make it a rounded rect (i.e. radii contained within each edge).
-    // This function relies on the fact we only get radii not contained within each edge if one of the radii
-    // for an edge is zero, so we can shift the arc towards the zero radius corner.
-    RoundedRect::Radii newRadii = innerBorder.radii();
-    LayoutRect newRect = innerBorder.rect();
-
-    float overshoot;
-    float maxRadii;
-
-    switch (side) {
-    case BSTop:
-        overshoot = newRadii.topLeft().width() + newRadii.topRight().width() - newRect.width();
-        if (overshoot > 0) {
-            ASSERT(!(newRadii.topLeft().width() && newRadii.topRight().width()));
-            newRect.setWidth(newRect.width() + overshoot);
-            if (!newRadii.topLeft().width())
-                newRect.move(-overshoot, 0);
-        }
-        newRadii.setBottomLeft(IntSize(0, 0));
-        newRadii.setBottomRight(IntSize(0, 0));
-        maxRadii = std::max(newRadii.topLeft().height(), newRadii.topRight().height());
-        if (maxRadii > newRect.height())
-            newRect.setHeight(maxRadii);
-        break;
-
-    case BSBottom:
-        overshoot = newRadii.bottomLeft().width() + newRadii.bottomRight().width() - newRect.width();
-        if (overshoot > 0) {
-            ASSERT(!(newRadii.bottomLeft().width() && newRadii.bottomRight().width()));
-            newRect.setWidth(newRect.width() + overshoot);
-            if (!newRadii.bottomLeft().width())
-                newRect.move(-overshoot, 0);
-        }
-        newRadii.setTopLeft(IntSize(0, 0));
-        newRadii.setTopRight(IntSize(0, 0));
-        maxRadii = std::max(newRadii.bottomLeft().height(), newRadii.bottomRight().height());
-        if (maxRadii > newRect.height()) {
-            newRect.move(0, newRect.height() - maxRadii);
-            newRect.setHeight(maxRadii);
-        }
-        break;
-
-    case BSLeft:
-        overshoot = newRadii.topLeft().height() + newRadii.bottomLeft().height() - newRect.height();
-        if (overshoot > 0) {
-            ASSERT(!(newRadii.topLeft().height() && newRadii.bottomLeft().height()));
-            newRect.setHeight(newRect.height() + overshoot);
-            if (!newRadii.topLeft().height())
-                newRect.move(0, -overshoot);
-        }
-        newRadii.setTopRight(IntSize(0, 0));
-        newRadii.setBottomRight(IntSize(0, 0));
-        maxRadii = std::max(newRadii.topLeft().width(), newRadii.bottomLeft().width());
-        if (maxRadii > newRect.width())
-            newRect.setWidth(maxRadii);
-        break;
-
-    case BSRight:
-        overshoot = newRadii.topRight().height() + newRadii.bottomRight().height() - newRect.height();
-        if (overshoot > 0) {
-            ASSERT(!(newRadii.topRight().height() && newRadii.bottomRight().height()));
-            newRect.setHeight(newRect.height() + overshoot);
-            if (!newRadii.topRight().height())
-                newRect.move(0, -overshoot);
-        }
-        newRadii.setTopLeft(IntSize(0, 0));
-        newRadii.setBottomLeft(IntSize(0, 0));
-        maxRadii = std::max(newRadii.topRight().width(), newRadii.bottomRight().width());
-        if (maxRadii > newRect.width()) {
-            newRect.move(newRect.width() - maxRadii, 0);
-            newRect.setWidth(maxRadii);
-        }
-        break;
-    }
-
-    return RoundedRect(newRect, newRadii);
-}
-
-void RenderBoxModelObject::clipBorderSideForComplexInnerPath(GraphicsContext& graphicsContext, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
-    BoxSide side, const class BorderEdge edges[])
-{
-    graphicsContext.clip(calculateSideRectIncludingInner(outerBorder, edges, side));
-    graphicsContext.clipOutRoundedRect(FloatRoundedRect(calculateAdjustedInnerBorder(innerBorder, side)));
-}
-
 bool RenderBoxModelObject::borderObscuresBackgroundEdge(const FloatSize& contextScale) const
 {
     BorderEdge edges[4];

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (201867 => 201868)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2016-06-09 16:49:19 UTC (rev 201867)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2016-06-09 16:59:17 UTC (rev 201868)
@@ -310,7 +310,7 @@
 
     void clipBorderSidePolygon(GraphicsContext&, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
                                BoxSide, bool firstEdgeMatches, bool secondEdgeMatches);
-    void clipBorderSideForComplexInnerPath(GraphicsContext&, const RoundedRect&, const RoundedRect&, BoxSide, const BorderEdge[]);
+
     void paintOneBorderSide(GraphicsContext&, const RenderStyle&, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
         const LayoutRect& sideRect, BoxSide, BoxSide adjacentSide1, BoxSide adjacentSide2, const BorderEdge[],
         const Path*, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor = nullptr);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to