REGRESSION (r215613): Incorrect corners clipping with border-radius
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Sep 2017 02:20:28 +0000 (02:20 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Sep 2017 02:20:28 +0000 (02:20 +0000)
commit0e0bcd6c978e611e998e3308d94cf61733d791f2
tree2a70c95048d5c319d2dc1a863f879e24385c9009
parenta7156fb7410cd8748e198ce16e192a205afcc4da
REGRESSION (r215613): Incorrect corners clipping with border-radius
https://bugs.webkit.org/show_bug.cgi?id=176498
<rdar://problem/34112607>

Reviewed by Tim Horton.

Source/WebCore:

http://trac.webkit.org/r215613 introduced an optimization to bail out of repainting borders if the invalidated
rect to paint is fully contained within the inner rounded rect of the border. However, due to issues with
coordinate and intersection math in RoundedRect::contains() and ellipseContainsPoint(), this causes
RenderBoxModelObject::paintBorder to return early even in circumstances where the border requires a repaint.
This patch fixes the contains() helper in RoundedRect and adds a new API test suite for RoundedRect that covers
these changes.

Test: WebCore.RoundedRectContainsRect

* platform/graphics/GeometryUtilities.cpp:
(WebCore::ellipseContainsPoint):

This function attempts to return early if the Manhattan distance of the transformed point is less than the
radius of the circle that results from applying the same transformation to the ellipse. However, this bails and
returns true if `x + y <= R`, but this means that if x and y are negative, we'll always end up returning true.
We fix this by adding the absolute values instead, so the check becomes: |x| + |y| <= R.

* platform/graphics/RoundedRect.cpp:
(WebCore::RoundedRect::contains const):

Before this patch, otherRect's upper left location was being used to hit-test against the ellipses formed from
each of the 4 corners of the rounded rect. Instead, this should use (x, y), (maxX, y), (x, maxY), (maxX, maxY)
for the top left, top right, bottom left, and bottom right corners, respectively.

Additionally, the checks for the bottom left and bottom right to determine whether the rect corner should be
checked for intersection against the ellipse's corner are incorrect. In the bottom left corner, the check for
`otherRect.maxX() >= center.x()` should instead be `otherRect.x() <= center.x()`, and the check for
`otherRect.x() <= center.x()` should instead be `otherRect.maxX() >= center.x()`.

* platform/graphics/RoundedRect.h:

Tools:

Add WebCore API tests for RoundedRect::contains().

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/RoundedRectTests.cpp: Added.
(TestWebKitAPI::layoutRect):
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222245 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GeometryUtilities.cpp
Source/WebCore/platform/graphics/RoundedRect.cpp
Source/WebCore/platform/graphics/RoundedRect.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebCore/RoundedRectTests.cpp [new file with mode: 0644]