From cb0e1d603aa4439a4d4804ad2987e4cb1f9bbf90 Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Mon, 2 Aug 2021 04:04:18 -0700 Subject: [PATCH] Allows to set individual (left,top,right,bottom) dotted/dashed borders (#29099) Summary: This issue: fixes https://github.com/facebook/react-native/issues/24224 fixes https://github.com/facebook/react-native/issues/28695 fixes https://github.com/facebook/react-native/issues/23651 fixes https://github.com/facebook/react-native/issues/23475 fixes https://github.com/facebook/react-native/issues/22256 fixes https://github.com/facebook/react-native/issues/22226 fixes https://github.com/facebook/react-native/issues/19234 fixes https://github.com/facebook/react-native/issues/18285 fixes https://github.com/facebook/react-native/issues/17344 fixes https://github.com/facebook/react-native/issues/17343 fixes https://github.com/facebook/react-native/issues/17251 fixes https://github.com/facebook/react-native/issues/12817 fixes https://github.com/facebook/react-native/issues/12403 fixes https://github.com/facebook/react-native/issues/11042 fixes https://github.com/facebook/react-native/issues/9343 fixes https://github.com/facebook/react-native/issues/8236 fixes https://github.com/facebook/react-native/issues/8105 fixes https://github.com/facebook/react-native/issues/7838 fixes https://github.com/facebook/react-native/issues/6721 fixes https://github.com/facebook/react-native/issues/5411 fixes https://github.com/facebook/react-native/issues/3159 fixes https://github.com/facebook/react-native/issues/2335 fixes https://github.com/facebook/react-native/issues/840 fixes https://github.com/facebook/react-native/issues/27133 fixes https://github.com/facebook/react-native/issues/28695 Allows to set individual (left,top,right,bottom) dotted/dashed borders. If a single border is specified and the borderStyle is dotted or dashed, each border will be drawn with moveTo and lineTo taking in consideration of the border style and thickness. ## Changelog [Android] [Fixed] - Quickfix individual border style dotted or dashed rendering as solid Pull Request resolved: https://github.com/facebook/react-native/pull/29099 Test Plan: **
CLICK TO OPEN TESTS RESULTS**

| **AFTER** | **AFTER** | |:-------------------------:|:-------------------------:| | | | | **AFTER** | **AFTER** | |:-------------------------:|:-------------------------:| | | | | **AFTER** | **AFTER** | |:-------------------------:|:-------------------------:| | | | | **AFTER** | **AFTER** | |:-------------------------:|:-------------------------:| | | | | **AFTER** | **AFTER** | |:-------------------------:|:-------------------------:| | | | | **AFTER** | **AFTER** | |:-------------------------:|:-------------------------:| | | |

Reviewed By: mdvacca Differential Revision: D28688914 Pulled By: RSNara fbshipit-source-id: 34781d63265dcf55e30f11c014e6b4a35d67dcbd --- .../view/ReactViewBackgroundDrawable.java | 47 +++++++++++++++---- .../js/examples/Border/BorderExample.js | 9 ++-- 2 files changed, 45 insertions(+), 11 deletions(-) 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 9065f4bc49f..bed2251c84f 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 @@ -89,6 +89,7 @@ public class ReactViewBackgroundDrawable extends Drawable { private @Nullable Path mOuterClipPathForBorderRadius; private @Nullable Path mPathForBorderRadiusOutline; private @Nullable Path mPathForBorder; + private Path mPathForSingleBorder = new Path(); private @Nullable Path mCenterDrawPath; private @Nullable RectF mInnerClipTempRectForBorderRadius; private @Nullable RectF mOuterClipTempRectForBorderRadius; @@ -968,6 +969,14 @@ public class ReactViewBackgroundDrawable extends Drawable { mPaint.setPathEffect(mPathEffectForBorderStyle); } + private void updatePathEffect(int borderWidth) { + PathEffect pathEffectForBorderStyle = null; + if (mBorderStyle != null) { + pathEffectForBorderStyle = BorderStyle.getPathEffect(mBorderStyle, borderWidth); + } + mPaint.setPathEffect(pathEffectForBorderStyle); + } + /** For rounded borders we use default "borderWidth" property. */ public float getFullBorderWidth() { return (mBorderWidth != null && !YogaConstants.isUndefined(mBorderWidth.getRaw(Spacing.ALL))) @@ -1083,6 +1092,7 @@ public class ReactViewBackgroundDrawable extends Drawable { colorTop, colorRight, colorBottom); + if (fastBorderColor != 0) { if (Color.alpha(fastBorderColor) != 0) { // Border color is not transparent. @@ -1090,21 +1100,42 @@ public class ReactViewBackgroundDrawable extends Drawable { int bottom = bounds.bottom; mPaint.setColor(fastBorderColor); + mPaint.setStyle(Paint.Style.STROKE); if (borderLeft > 0) { - int leftInset = left + borderLeft; - canvas.drawRect(left, top, leftInset, bottom - borderBottom, mPaint); + mPathForSingleBorder.reset(); + int width = Math.round(borderWidth.left); + updatePathEffect(width); + mPaint.setStrokeWidth(width); + mPathForSingleBorder.moveTo(left, top - borderWidth.top / 2); + mPathForSingleBorder.lineTo(left, bottom + borderWidth.bottom / 2); + canvas.drawPath(mPathForSingleBorder, mPaint); } if (borderTop > 0) { - int topInset = top + borderTop; - canvas.drawRect(left + borderLeft, top, right, topInset, mPaint); + mPathForSingleBorder.reset(); + int width = Math.round(borderWidth.top); + updatePathEffect(width); + mPaint.setStrokeWidth(width); + mPathForSingleBorder.moveTo(left, top); + mPathForSingleBorder.lineTo(right, top); + canvas.drawPath(mPathForSingleBorder, mPaint); } if (borderRight > 0) { - int rightInset = right - borderRight; - canvas.drawRect(rightInset, top + borderTop, right, bottom, mPaint); + mPathForSingleBorder.reset(); + int width = Math.round(borderWidth.right); + updatePathEffect(width); + mPaint.setStrokeWidth(width); + mPathForSingleBorder.moveTo(right, top - borderWidth.top / 2); + mPathForSingleBorder.lineTo(right, bottom + borderWidth.bottom / 2); + canvas.drawPath(mPathForSingleBorder, mPaint); } if (borderBottom > 0) { - int bottomInset = bottom - borderBottom; - canvas.drawRect(left, bottomInset, right - borderRight, bottom, mPaint); + mPathForSingleBorder.reset(); + int width = Math.round(borderWidth.bottom); + updatePathEffect(width); + mPaint.setStrokeWidth(width); + mPathForSingleBorder.moveTo(left, bottom); + mPathForSingleBorder.lineTo(right, bottom); + canvas.drawPath(mPathForSingleBorder, mPaint); } } } else { diff --git a/packages/rn-tester/js/examples/Border/BorderExample.js b/packages/rn-tester/js/examples/Border/BorderExample.js index dbcb00b7028..80813def9e5 100644 --- a/packages/rn-tester/js/examples/Border/BorderExample.js +++ b/packages/rn-tester/js/examples/Border/BorderExample.js @@ -23,6 +23,7 @@ const styles = StyleSheet.create({ border1: { borderWidth: 10, borderColor: 'brown', + borderStyle: 'dotted', }, borderRadius: { borderWidth: 10, @@ -38,10 +39,10 @@ const styles = StyleSheet.create({ }, border3: { borderColor: 'purple', - borderTopWidth: 10, + borderTopWidth: 7, borderRightWidth: 20, - borderBottomWidth: 30, - borderLeftWidth: 40, + borderBottomWidth: 10, + borderLeftWidth: 5, }, border4: { borderTopWidth: 10, @@ -99,12 +100,14 @@ const styles = StyleSheet.create({ }, border8Left: { borderLeftWidth: 5, + borderStyle: 'dotted', }, border8Bottom: { borderBottomWidth: 5, }, border8Right: { borderRightWidth: 5, + borderStyle: 'dashed', }, border9: { borderWidth: 10,