From 28dce3665d8a63e902c165c060400486fe6234f4 Mon Sep 17 00:00:00 2001 From: Hein Rutjes Date: Sun, 19 Apr 2020 23:42:16 -0700 Subject: [PATCH] Fix rounded border drawing when border-radius is smaller than border-width (#28358) Summary: This PR fixes the drawing of the border rounded edges when the border-radius is small than the border-width. The current implementation capped the possible border-radius making it impossible to set smaller border-radii when using thicker borders. After inspection it was found that the rounded-rect calculation is incorrect. ## Changelog `[Android] [Fixed] - Fix rounded border-drawing when border-radius is smaller than border-width` Pull Request resolved: https://github.com/facebook/react-native/pull/28358 Test Plan: **Faulty situation:** As you can see, when the border-radius becomes very low, the border is stuck at a minimum value. Only after setting the border-radius fully to 0 is it again rendered correctly. ![ezgif com-video-to-gif (2)](https://user-images.githubusercontent.com/6184593/77183540-c3435b00-6ace-11ea-950d-29a0ea1757bd.gif) **After the fix:** ![ezgif com-video-to-gif (3)](https://user-images.githubusercontent.com/6184593/77183619-e837ce00-6ace-11ea-93a5-910127d352b7.gif) Differential Revision: D21124739 Pulled By: shergin fbshipit-source-id: cefd1776b77b5b9fb335e95fd7fdd7f345579dc4 --- RNTester/js/examples/View/ViewExample.js | 49 +++++++++++++++++-- .../view/ReactViewBackgroundDrawable.java | 34 ++++++++----- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/RNTester/js/examples/View/ViewExample.js b/RNTester/js/examples/View/ViewExample.js index 06b27412120e4e..7f89797ed51570 100644 --- a/RNTester/js/examples/View/ViewExample.js +++ b/RNTester/js/examples/View/ViewExample.js @@ -148,12 +148,53 @@ exports.examples = [ }, }, { - title: 'Circle with Border Radius', + title: 'Rounded Borders', render(): React.Node { return ( - + + + + + + ); }, }, diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java index 9fe66d2fad46df..b9863d87203bd8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java @@ -526,11 +526,6 @@ private void updatePath() { mTempRectForBorderRadiusOutline.set(getBounds()); mTempRectForCenterDrawPath.set(getBounds()); - float fullBorderWidth = getFullBorderWidth(); - if (fullBorderWidth > 0) { - mTempRectForCenterDrawPath.inset(fullBorderWidth * 0.5f, fullBorderWidth * 0.5f); - } - final RectF borderWidth = getDirectionAwareBorderInsets(); mInnerClipTempRectForBorderRadius.top += borderWidth.top; @@ -538,6 +533,11 @@ private void updatePath() { mInnerClipTempRectForBorderRadius.left += borderWidth.left; mInnerClipTempRectForBorderRadius.right -= borderWidth.right; + mTempRectForCenterDrawPath.top += borderWidth.top * 0.5f; + mTempRectForCenterDrawPath.bottom -= borderWidth.bottom * 0.5f; + mTempRectForCenterDrawPath.left += borderWidth.left * 0.5f; + mTempRectForCenterDrawPath.right -= borderWidth.right * 0.5f; + final float borderRadius = getFullBorderRadius(); float topLeftRadius = getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.TOP_LEFT); float topRightRadius = getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.TOP_RIGHT); @@ -663,14 +663,22 @@ private void updatePath() { mCenterDrawPath.addRoundRect( mTempRectForCenterDrawPath, new float[] { - innerTopLeftRadiusX + (topLeftRadius > 0 ? extraRadiusForOutline : 0), - innerTopLeftRadiusY + (topLeftRadius > 0 ? extraRadiusForOutline : 0), - innerTopRightRadiusX + (topRightRadius > 0 ? extraRadiusForOutline : 0), - innerTopRightRadiusY + (topRightRadius > 0 ? extraRadiusForOutline : 0), - innerBottomRightRadiusX + (bottomRightRadius > 0 ? extraRadiusForOutline : 0), - innerBottomRightRadiusY + (bottomRightRadius > 0 ? extraRadiusForOutline : 0), - innerBottomLeftRadiusX + (bottomLeftRadius > 0 ? extraRadiusForOutline : 0), - innerBottomLeftRadiusY + (bottomLeftRadius > 0 ? extraRadiusForOutline : 0) + Math.max(topLeftRadius - borderWidth.left * 0.5f, + (borderWidth.left > 0.0f) ? (topLeftRadius / borderWidth.left) : 0.0f), + Math.max(topLeftRadius - borderWidth.top * 0.5f, + (borderWidth.top > 0.0f) ? (topLeftRadius / borderWidth.top) : 0.0f), + Math.max(topRightRadius - borderWidth.right * 0.5f, + (borderWidth.right > 0.0f) ? (topRightRadius / borderWidth.right) : 0.0f), + Math.max(topRightRadius - borderWidth.top * 0.5f, + (borderWidth.top > 0.0f) ? (topRightRadius / borderWidth.top) : 0.0f), + Math.max(bottomRightRadius - borderWidth.right * 0.5f, + (borderWidth.right > 0.0f) ? (bottomRightRadius / borderWidth.right) : 0.0f), + Math.max(bottomRightRadius - borderWidth.bottom * 0.5f, + (borderWidth.bottom > 0.0f) ? (bottomRightRadius / borderWidth.bottom) : 0.0f), + Math.max(bottomLeftRadius - borderWidth.left * 0.5f, + (borderWidth.left > 0.0f) ? (bottomLeftRadius / borderWidth.left) : 0.0f), + Math.max(bottomLeftRadius - borderWidth.bottom * 0.5f, + (borderWidth.bottom > 0.0f) ? (bottomLeftRadius / borderWidth.bottom) : 0.0f) }, Path.Direction.CW);