mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Encapsulate border radius resolution logic (#43983)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43983 We duplicate some pretty hairy code related to conversion between logical and physical edges, along with the grafting between uniform and non uniform radii. This encapsulates border radius resolution/assignment logic. Changelog: [Internal] Reviewed By: alanleedev Differential Revision: D55635743 fbshipit-source-id: 906c35af2bf18f0586d71d05f9cf61d4248ede1e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
efc5ddd3ee
commit
c710386e72
@@ -4081,6 +4081,7 @@ public abstract interface class com/facebook/react/uimanager/FabricViewStateMana
|
||||
public final class com/facebook/react/uimanager/FloatUtil {
|
||||
public static final field INSTANCE Lcom/facebook/react/uimanager/FloatUtil;
|
||||
public static final fun floatsEqual (FF)Z
|
||||
public static final fun floatsEqual (Ljava/lang/Float;Ljava/lang/Float;)Z
|
||||
}
|
||||
|
||||
public abstract class com/facebook/react/uimanager/GuardedFrameCallback : android/view/Choreographer$FrameCallback {
|
||||
@@ -5454,11 +5455,9 @@ public class com/facebook/react/uimanager/drawable/CSSBackgroundDrawable : andro
|
||||
public fun draw (Landroid/graphics/Canvas;)V
|
||||
public fun getAlpha ()I
|
||||
public fun getBorderColor (I)I
|
||||
public fun getBorderRadius (Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;)F
|
||||
public fun getBorderRadiusOrDefaultTo (FLcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;)F
|
||||
public fun getBorderRadius ()Lcom/facebook/react/uimanager/style/BorderRadiusStyle;
|
||||
public fun getBorderWidthOrDefaultTo (FI)F
|
||||
public fun getDirectionAwareBorderInsets ()Landroid/graphics/RectF;
|
||||
public fun getFullBorderRadius ()F
|
||||
public fun getFullBorderWidth ()F
|
||||
public fun getOpacity ()I
|
||||
public fun getOutline (Landroid/graphics/Outline;)V
|
||||
@@ -5469,6 +5468,8 @@ public class com/facebook/react/uimanager/drawable/CSSBackgroundDrawable : andro
|
||||
public fun paddingBoxPath ()Landroid/graphics/Path;
|
||||
public fun setAlpha (I)V
|
||||
public fun setBorderColor (IFF)V
|
||||
public fun setBorderRadius (Lcom/facebook/react/uimanager/style/BorderRadiusProp;Ljava/lang/Float;)V
|
||||
public fun setBorderRadius (Lcom/facebook/react/uimanager/style/BorderRadiusStyle;)V
|
||||
public fun setBorderStyle (Ljava/lang/String;)V
|
||||
public fun setBorderWidth (IF)V
|
||||
public fun setColor (I)V
|
||||
@@ -5478,23 +5479,6 @@ public class com/facebook/react/uimanager/drawable/CSSBackgroundDrawable : andro
|
||||
public fun setResolvedLayoutDirection (I)Z
|
||||
}
|
||||
|
||||
public final class com/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation : java/lang/Enum {
|
||||
public static final field BOTTOM_END Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field BOTTOM_LEFT Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field BOTTOM_RIGHT Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field BOTTOM_START Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field END_END Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field END_START Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field START_END Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field START_START Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field TOP_END Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field TOP_LEFT Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field TOP_RIGHT Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static final field TOP_START Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
public static fun values ()[Lcom/facebook/react/uimanager/drawable/CSSBackgroundDrawable$BorderRadiusLocation;
|
||||
}
|
||||
|
||||
public abstract interface class com/facebook/react/uimanager/events/BatchEventDispatchedListener {
|
||||
public abstract fun onBatchEventDispatched ()V
|
||||
}
|
||||
@@ -5784,6 +5768,97 @@ public abstract interface class com/facebook/react/uimanager/layoutanimation/Lay
|
||||
public abstract fun onAnimationEnd ()V
|
||||
}
|
||||
|
||||
public final class com/facebook/react/uimanager/style/BorderRadiusProp : java/lang/Enum {
|
||||
public static final field BORDER_BOTTOM_END_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_BOTTOM_LEFT_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_BOTTOM_RIGHT_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_BOTTOM_START_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_END_END_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_END_START_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_START_END_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_START_START_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_TOP_END_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_TOP_LEFT_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_TOP_RIGHT_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static final field BORDER_TOP_START_RADIUS Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
public static fun values ()[Lcom/facebook/react/uimanager/style/BorderRadiusProp;
|
||||
}
|
||||
|
||||
public final class com/facebook/react/uimanager/style/BorderRadiusStyle {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;)V
|
||||
public synthetic fun <init> (Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun <init> (Ljava/util/List;)V
|
||||
public final fun component1 ()Ljava/lang/Float;
|
||||
public final fun component10 ()Ljava/lang/Float;
|
||||
public final fun component11 ()Ljava/lang/Float;
|
||||
public final fun component12 ()Ljava/lang/Float;
|
||||
public final fun component13 ()Ljava/lang/Float;
|
||||
public final fun component2 ()Ljava/lang/Float;
|
||||
public final fun component3 ()Ljava/lang/Float;
|
||||
public final fun component4 ()Ljava/lang/Float;
|
||||
public final fun component5 ()Ljava/lang/Float;
|
||||
public final fun component6 ()Ljava/lang/Float;
|
||||
public final fun component7 ()Ljava/lang/Float;
|
||||
public final fun component8 ()Ljava/lang/Float;
|
||||
public final fun component9 ()Ljava/lang/Float;
|
||||
public final fun copy (Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;)Lcom/facebook/react/uimanager/style/BorderRadiusStyle;
|
||||
public static synthetic fun copy$default (Lcom/facebook/react/uimanager/style/BorderRadiusStyle;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;Ljava/lang/Float;ILjava/lang/Object;)Lcom/facebook/react/uimanager/style/BorderRadiusStyle;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun get (Lcom/facebook/react/uimanager/style/BorderRadiusProp;)Ljava/lang/Float;
|
||||
public final fun getBottomEnd ()Ljava/lang/Float;
|
||||
public final fun getBottomLeft ()Ljava/lang/Float;
|
||||
public final fun getBottomRight ()Ljava/lang/Float;
|
||||
public final fun getBottomStart ()Ljava/lang/Float;
|
||||
public final fun getEndEnd ()Ljava/lang/Float;
|
||||
public final fun getEndStart ()Ljava/lang/Float;
|
||||
public final fun getStartEnd ()Ljava/lang/Float;
|
||||
public final fun getStartStart ()Ljava/lang/Float;
|
||||
public final fun getTopEnd ()Ljava/lang/Float;
|
||||
public final fun getTopLeft ()Ljava/lang/Float;
|
||||
public final fun getTopRight ()Ljava/lang/Float;
|
||||
public final fun getTopStart ()Ljava/lang/Float;
|
||||
public final fun getUniform ()Ljava/lang/Float;
|
||||
public final fun hasRoundedBorders ()Z
|
||||
public fun hashCode ()I
|
||||
public final fun resolve (ILandroid/content/Context;)Lcom/facebook/react/uimanager/style/ComputedBorderRadius;
|
||||
public final fun set (Lcom/facebook/react/uimanager/style/BorderRadiusProp;Ljava/lang/Float;)V
|
||||
public final fun setBottomEnd (Ljava/lang/Float;)V
|
||||
public final fun setBottomLeft (Ljava/lang/Float;)V
|
||||
public final fun setBottomRight (Ljava/lang/Float;)V
|
||||
public final fun setBottomStart (Ljava/lang/Float;)V
|
||||
public final fun setEndEnd (Ljava/lang/Float;)V
|
||||
public final fun setEndStart (Ljava/lang/Float;)V
|
||||
public final fun setStartEnd (Ljava/lang/Float;)V
|
||||
public final fun setStartStart (Ljava/lang/Float;)V
|
||||
public final fun setTopEnd (Ljava/lang/Float;)V
|
||||
public final fun setTopLeft (Ljava/lang/Float;)V
|
||||
public final fun setTopRight (Ljava/lang/Float;)V
|
||||
public final fun setTopStart (Ljava/lang/Float;)V
|
||||
public final fun setUniform (Ljava/lang/Float;)V
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/facebook/react/uimanager/style/ComputedBorderRadius {
|
||||
public fun <init> (FFFF)V
|
||||
public final fun component1 ()F
|
||||
public final fun component2 ()F
|
||||
public final fun component3 ()F
|
||||
public final fun component4 ()F
|
||||
public final fun copy (FFFF)Lcom/facebook/react/uimanager/style/ComputedBorderRadius;
|
||||
public static synthetic fun copy$default (Lcom/facebook/react/uimanager/style/ComputedBorderRadius;FFFFILjava/lang/Object;)Lcom/facebook/react/uimanager/style/ComputedBorderRadius;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getBottomLeft ()F
|
||||
public final fun getBottomRight ()F
|
||||
public final fun getTopLeft ()F
|
||||
public final fun getTopRight ()F
|
||||
public final fun hasRoundedBorders ()Z
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public class com/facebook/react/uimanager/util/ReactFindViewUtil {
|
||||
public fun <init> ()V
|
||||
public static fun addViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V
|
||||
@@ -7807,6 +7882,7 @@ public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGro
|
||||
public fun setBorderColor (IFF)V
|
||||
public fun setBorderRadius (F)V
|
||||
public fun setBorderRadius (FI)V
|
||||
public fun setBorderRadius (Lcom/facebook/react/uimanager/style/BorderRadiusProp;Ljava/lang/Float;)V
|
||||
public fun setBorderStyle (Ljava/lang/String;)V
|
||||
public fun setBorderWidth (IF)V
|
||||
public fun setHitSlopRect (Landroid/graphics/Rect;)V
|
||||
|
||||
+11
@@ -18,4 +18,15 @@ public object FloatUtil {
|
||||
java.lang.Float.isNaN(f1) && java.lang.Float.isNaN(f2)
|
||||
} else abs(f2 - f1) < EPSILON
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun floatsEqual(f1: Float?, f2: Float?): Boolean {
|
||||
if (f1 == null) {
|
||||
return f2 == null
|
||||
} else if (f2 == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return floatsEqual(f1, f2)
|
||||
}
|
||||
}
|
||||
|
||||
+29
-151
@@ -28,7 +28,9 @@ import com.facebook.react.common.annotations.VisibleForTesting;
|
||||
import com.facebook.react.modules.i18nmanager.I18nUtil;
|
||||
import com.facebook.react.uimanager.FloatUtil;
|
||||
import com.facebook.react.uimanager.Spacing;
|
||||
import java.util.Arrays;
|
||||
import com.facebook.react.uimanager.style.BorderRadiusProp;
|
||||
import com.facebook.react.uimanager.style.BorderRadiusStyle;
|
||||
import com.facebook.react.uimanager.style.ComputedBorderRadius;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
@@ -99,7 +101,6 @@ public class CSSBackgroundDrawable extends Drawable {
|
||||
private @Nullable PointF mInnerBottomRightCorner;
|
||||
private @Nullable PointF mInnerBottomLeftCorner;
|
||||
private boolean mNeedUpdatePathForBorderRadius = false;
|
||||
private float mBorderRadius = Float.NaN;
|
||||
|
||||
/* Used by all types of background and for drawing borders */
|
||||
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
@@ -112,25 +113,10 @@ public class CSSBackgroundDrawable extends Drawable {
|
||||
// the paths, overlapping them and closing the visible gap.
|
||||
private final float mGapBetweenPaths = 0.8f;
|
||||
|
||||
private @Nullable float[] mBorderCornerRadii;
|
||||
private BorderRadiusStyle mBorderRadius = new BorderRadiusStyle();
|
||||
private final Context mContext;
|
||||
private int mLayoutDirection;
|
||||
|
||||
public enum BorderRadiusLocation {
|
||||
TOP_LEFT,
|
||||
TOP_RIGHT,
|
||||
BOTTOM_RIGHT,
|
||||
BOTTOM_LEFT,
|
||||
TOP_START,
|
||||
TOP_END,
|
||||
BOTTOM_START,
|
||||
BOTTOM_END,
|
||||
END_END,
|
||||
END_START,
|
||||
START_END,
|
||||
START_START
|
||||
}
|
||||
|
||||
public CSSBackgroundDrawable(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
@@ -146,19 +132,7 @@ public class CSSBackgroundDrawable extends Drawable {
|
||||
}
|
||||
|
||||
public boolean hasRoundedBorders() {
|
||||
if (!Float.isNaN(mBorderRadius) && mBorderRadius > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mBorderCornerRadii != null) {
|
||||
for (final float borderRadii : mBorderCornerRadii) {
|
||||
if (!Float.isNaN(borderRadii) && borderRadii > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return mBorderRadius.hasRoundedBorders();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,7 +167,7 @@ public class CSSBackgroundDrawable extends Drawable {
|
||||
/* Android's elevation implementation requires this to be implemented to know where to draw the shadow. */
|
||||
@Override
|
||||
public void getOutline(Outline outline) {
|
||||
if ((!Float.isNaN(mBorderRadius) && mBorderRadius > 0) || mBorderCornerRadii != null) {
|
||||
if (hasRoundedBorders()) {
|
||||
updatePath();
|
||||
|
||||
outline.setConvexPath(mPathForBorderRadiusOutline);
|
||||
@@ -260,48 +234,36 @@ public class CSSBackgroundDrawable extends Drawable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setBorderRadius(BorderRadiusProp, Float)} instead.
|
||||
*/
|
||||
public void setRadius(float radius) {
|
||||
if (!FloatUtil.floatsEqual(mBorderRadius, radius)) {
|
||||
mBorderRadius = radius;
|
||||
mNeedUpdatePathForBorderRadius = true;
|
||||
invalidateSelf();
|
||||
}
|
||||
@Nullable Float boxedRadius = Float.isNaN(radius) ? null : Float.valueOf(radius);
|
||||
setBorderRadius(BorderRadiusProp.BORDER_RADIUS, boxedRadius);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setBorderRadius(BorderRadiusProp, Float)} instead.
|
||||
*/
|
||||
public void setRadius(float radius, int position) {
|
||||
if (mBorderCornerRadii == null) {
|
||||
mBorderCornerRadii = new float[12];
|
||||
Arrays.fill(mBorderCornerRadii, Float.NaN);
|
||||
}
|
||||
@Nullable Float boxedRadius = Float.isNaN(radius) ? null : Float.valueOf(radius);
|
||||
setBorderRadius(BorderRadiusProp.values()[position], boxedRadius);
|
||||
}
|
||||
|
||||
if (!FloatUtil.floatsEqual(mBorderCornerRadii[position], radius)) {
|
||||
mBorderCornerRadii[position] = radius;
|
||||
public void setBorderRadius(BorderRadiusProp property, @Nullable Float radius) {
|
||||
if (!FloatUtil.floatsEqual(mBorderRadius.getUniform(), radius)) {
|
||||
mBorderRadius.set(property, radius);
|
||||
mNeedUpdatePathForBorderRadius = true;
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
public float getFullBorderRadius() {
|
||||
return Float.isNaN(mBorderRadius) ? 0 : mBorderRadius;
|
||||
public void setBorderRadius(BorderRadiusStyle radius) {
|
||||
mBorderRadius = radius;
|
||||
}
|
||||
|
||||
public float getBorderRadius(final BorderRadiusLocation location) {
|
||||
return getBorderRadiusOrDefaultTo(Float.NaN, location);
|
||||
}
|
||||
|
||||
public float getBorderRadiusOrDefaultTo(
|
||||
final float defaultValue, final BorderRadiusLocation location) {
|
||||
if (mBorderCornerRadii == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
final float radius = mBorderCornerRadii[location.ordinal()];
|
||||
|
||||
if (Float.isNaN(radius)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return radius;
|
||||
public BorderRadiusStyle getBorderRadius() {
|
||||
return mBorderRadius;
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
@@ -606,95 +568,11 @@ public class CSSBackgroundDrawable extends Drawable {
|
||||
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);
|
||||
float bottomLeftRadius =
|
||||
getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.BOTTOM_LEFT);
|
||||
float bottomRightRadius =
|
||||
getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.BOTTOM_RIGHT);
|
||||
|
||||
final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
|
||||
float topStartRadius = getBorderRadius(BorderRadiusLocation.TOP_START);
|
||||
float topEndRadius = getBorderRadius(BorderRadiusLocation.TOP_END);
|
||||
float bottomStartRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_START);
|
||||
float bottomEndRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_END);
|
||||
|
||||
float endEndRadius = getBorderRadius(BorderRadiusLocation.END_END);
|
||||
float endStartRadius = getBorderRadius(BorderRadiusLocation.END_START);
|
||||
float startEndRadius = getBorderRadius(BorderRadiusLocation.START_END);
|
||||
float startStartRadius = getBorderRadius(BorderRadiusLocation.START_START);
|
||||
|
||||
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(mContext)) {
|
||||
if (Float.isNaN(topStartRadius)) {
|
||||
topStartRadius = topLeftRadius;
|
||||
}
|
||||
|
||||
if (Float.isNaN(topEndRadius)) {
|
||||
topEndRadius = topRightRadius;
|
||||
}
|
||||
|
||||
if (Float.isNaN(bottomStartRadius)) {
|
||||
bottomStartRadius = bottomLeftRadius;
|
||||
}
|
||||
|
||||
if (Float.isNaN(bottomEndRadius)) {
|
||||
bottomEndRadius = bottomRightRadius;
|
||||
}
|
||||
|
||||
final float logicalTopStartRadius =
|
||||
Float.isNaN(topStartRadius) ? startStartRadius : topStartRadius;
|
||||
final float logicalTopEndRadius = Float.isNaN(topEndRadius) ? startEndRadius : topEndRadius;
|
||||
final float logicalBottomStartRadius =
|
||||
Float.isNaN(bottomStartRadius) ? endStartRadius : bottomStartRadius;
|
||||
final float logicalBottomEndRadius =
|
||||
Float.isNaN(bottomEndRadius) ? endEndRadius : bottomEndRadius;
|
||||
|
||||
final float directionAwareTopLeftRadius = isRTL ? logicalTopEndRadius : logicalTopStartRadius;
|
||||
final float directionAwareTopRightRadius =
|
||||
isRTL ? logicalTopStartRadius : logicalTopEndRadius;
|
||||
final float directionAwareBottomLeftRadius =
|
||||
isRTL ? logicalBottomEndRadius : logicalBottomStartRadius;
|
||||
final float directionAwareBottomRightRadius =
|
||||
isRTL ? logicalBottomStartRadius : logicalBottomEndRadius;
|
||||
|
||||
topLeftRadius = directionAwareTopLeftRadius;
|
||||
topRightRadius = directionAwareTopRightRadius;
|
||||
bottomLeftRadius = directionAwareBottomLeftRadius;
|
||||
bottomRightRadius = directionAwareBottomRightRadius;
|
||||
} else {
|
||||
final float logicalTopStartRadius =
|
||||
Float.isNaN(topStartRadius) ? startStartRadius : topStartRadius;
|
||||
final float logicalTopEndRadius = Float.isNaN(topEndRadius) ? startEndRadius : topEndRadius;
|
||||
final float logicalBottomStartRadius =
|
||||
Float.isNaN(bottomStartRadius) ? endStartRadius : bottomStartRadius;
|
||||
final float logicalBottomEndRadius =
|
||||
Float.isNaN(bottomEndRadius) ? endEndRadius : bottomEndRadius;
|
||||
|
||||
final float directionAwareTopLeftRadius = isRTL ? logicalTopEndRadius : logicalTopStartRadius;
|
||||
final float directionAwareTopRightRadius =
|
||||
isRTL ? logicalTopStartRadius : logicalTopEndRadius;
|
||||
final float directionAwareBottomLeftRadius =
|
||||
isRTL ? logicalBottomEndRadius : logicalBottomStartRadius;
|
||||
final float directionAwareBottomRightRadius =
|
||||
isRTL ? logicalBottomStartRadius : logicalBottomEndRadius;
|
||||
|
||||
if (!Float.isNaN(directionAwareTopLeftRadius)) {
|
||||
topLeftRadius = directionAwareTopLeftRadius;
|
||||
}
|
||||
|
||||
if (!Float.isNaN(directionAwareTopRightRadius)) {
|
||||
topRightRadius = directionAwareTopRightRadius;
|
||||
}
|
||||
|
||||
if (!Float.isNaN(directionAwareBottomLeftRadius)) {
|
||||
bottomLeftRadius = directionAwareBottomLeftRadius;
|
||||
}
|
||||
|
||||
if (!Float.isNaN(directionAwareBottomRightRadius)) {
|
||||
bottomRightRadius = directionAwareBottomRightRadius;
|
||||
}
|
||||
}
|
||||
ComputedBorderRadius radius = mBorderRadius.resolve(mLayoutDirection, mContext);
|
||||
float topLeftRadius = radius.getTopLeft();
|
||||
float topRightRadius = radius.getTopRight();
|
||||
float bottomLeftRadius = radius.getBottomLeft();
|
||||
float bottomRightRadius = radius.getBottomRight();
|
||||
|
||||
final float innerTopLeftRadiusX = Math.max(topLeftRadius - borderWidth.left, 0);
|
||||
final float innerTopLeftRadiusY = Math.max(topLeftRadius - borderWidth.top, 0);
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.uimanager.style
|
||||
|
||||
import android.content.Context
|
||||
import android.util.LayoutDirection
|
||||
import com.facebook.react.modules.i18nmanager.I18nUtil
|
||||
|
||||
/** Represents the collection of possible border radius style properties. */
|
||||
public enum class BorderRadiusProp {
|
||||
BORDER_TOP_LEFT_RADIUS,
|
||||
BORDER_TOP_RIGHT_RADIUS,
|
||||
BORDER_BOTTOM_RIGHT_RADIUS,
|
||||
BORDER_BOTTOM_LEFT_RADIUS,
|
||||
BORDER_TOP_START_RADIUS,
|
||||
BORDER_TOP_END_RADIUS,
|
||||
BORDER_BOTTOM_START_RADIUS,
|
||||
BORDER_BOTTOM_END_RADIUS,
|
||||
BORDER_END_END_RADIUS,
|
||||
BORDER_END_START_RADIUS,
|
||||
BORDER_START_END_RADIUS,
|
||||
BORDER_START_START_RADIUS,
|
||||
BORDER_RADIUS,
|
||||
}
|
||||
|
||||
/** Represents all logical properties and shorthands for border radius. */
|
||||
public data class BorderRadiusStyle(
|
||||
var uniform: Float? = null,
|
||||
var topLeft: Float? = null,
|
||||
var topRight: Float? = null,
|
||||
var bottomLeft: Float? = null,
|
||||
var bottomRight: Float? = null,
|
||||
var topStart: Float? = null,
|
||||
var topEnd: Float? = null,
|
||||
var bottomStart: Float? = null,
|
||||
var bottomEnd: Float? = null,
|
||||
var startStart: Float? = null,
|
||||
var startEnd: Float? = null,
|
||||
var endStart: Float? = null,
|
||||
var endEnd: Float? = null
|
||||
) {
|
||||
public constructor(properties: List<Pair<BorderRadiusProp, Float>>) : this() {
|
||||
properties.forEach { (k, v) -> set(k, v) }
|
||||
}
|
||||
|
||||
public fun set(property: BorderRadiusProp, value: Float?) {
|
||||
when (property) {
|
||||
BorderRadiusProp.BORDER_RADIUS -> uniform = value
|
||||
BorderRadiusProp.BORDER_TOP_LEFT_RADIUS -> topLeft = value
|
||||
BorderRadiusProp.BORDER_TOP_RIGHT_RADIUS -> topRight = value
|
||||
BorderRadiusProp.BORDER_BOTTOM_LEFT_RADIUS -> bottomLeft = value
|
||||
BorderRadiusProp.BORDER_BOTTOM_RIGHT_RADIUS -> bottomRight = value
|
||||
BorderRadiusProp.BORDER_TOP_START_RADIUS -> topStart = value
|
||||
BorderRadiusProp.BORDER_TOP_END_RADIUS -> topEnd = value
|
||||
BorderRadiusProp.BORDER_BOTTOM_START_RADIUS -> bottomStart = value
|
||||
BorderRadiusProp.BORDER_BOTTOM_END_RADIUS -> bottomEnd = value
|
||||
BorderRadiusProp.BORDER_START_START_RADIUS -> startStart = value
|
||||
BorderRadiusProp.BORDER_START_END_RADIUS -> startEnd = value
|
||||
BorderRadiusProp.BORDER_END_START_RADIUS -> endStart = value
|
||||
BorderRadiusProp.BORDER_END_END_RADIUS -> endEnd = value
|
||||
}
|
||||
}
|
||||
|
||||
public fun get(property: BorderRadiusProp): Float? {
|
||||
return when (property) {
|
||||
BorderRadiusProp.BORDER_RADIUS -> uniform
|
||||
BorderRadiusProp.BORDER_TOP_LEFT_RADIUS -> topLeft
|
||||
BorderRadiusProp.BORDER_TOP_RIGHT_RADIUS -> topRight
|
||||
BorderRadiusProp.BORDER_BOTTOM_LEFT_RADIUS -> bottomLeft
|
||||
BorderRadiusProp.BORDER_BOTTOM_RIGHT_RADIUS -> bottomRight
|
||||
BorderRadiusProp.BORDER_TOP_START_RADIUS -> topStart
|
||||
BorderRadiusProp.BORDER_TOP_END_RADIUS -> topEnd
|
||||
BorderRadiusProp.BORDER_BOTTOM_START_RADIUS -> bottomStart
|
||||
BorderRadiusProp.BORDER_BOTTOM_END_RADIUS -> bottomEnd
|
||||
BorderRadiusProp.BORDER_START_START_RADIUS -> startStart
|
||||
BorderRadiusProp.BORDER_START_END_RADIUS -> startEnd
|
||||
BorderRadiusProp.BORDER_END_START_RADIUS -> endStart
|
||||
BorderRadiusProp.BORDER_END_END_RADIUS -> endEnd
|
||||
}
|
||||
}
|
||||
|
||||
public fun hasRoundedBorders(): Boolean {
|
||||
return ((uniform ?: 0f) > 0f) ||
|
||||
((topLeft ?: 0f) > 0f) ||
|
||||
((topRight ?: 0f) > 0f) ||
|
||||
((bottomLeft ?: 0f) > 0f) ||
|
||||
((bottomRight ?: 0f) > 0f) ||
|
||||
((topStart ?: 0f) > 0f) ||
|
||||
((topEnd ?: 0f) > 0f) ||
|
||||
((bottomStart ?: 0f) > 0f) ||
|
||||
((bottomEnd ?: 0f) > 0f) ||
|
||||
((startStart ?: 0f) > 0f) ||
|
||||
((startEnd ?: 0f) > 0f) ||
|
||||
((endStart ?: 0f) > 0f) ||
|
||||
((endEnd ?: 0f) > 0f)
|
||||
}
|
||||
|
||||
public fun resolve(
|
||||
layoutDirection: Int,
|
||||
context: Context,
|
||||
): ComputedBorderRadius {
|
||||
return when (layoutDirection) {
|
||||
LayoutDirection.LTR ->
|
||||
ComputedBorderRadius(
|
||||
topLeft = startStart ?: topStart ?: topLeft ?: uniform ?: 0f,
|
||||
topRight = endStart ?: topEnd ?: topRight ?: uniform ?: 0f,
|
||||
bottomLeft = startEnd ?: bottomStart ?: bottomLeft ?: uniform ?: 0f,
|
||||
bottomRight = endEnd ?: bottomEnd ?: bottomRight ?: uniform ?: 0f)
|
||||
LayoutDirection.RTL ->
|
||||
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(context)) {
|
||||
ComputedBorderRadius(
|
||||
topLeft = endStart ?: topEnd ?: topRight ?: uniform ?: 0f,
|
||||
topRight = startStart ?: topStart ?: topLeft ?: uniform ?: 0f,
|
||||
bottomLeft = endEnd ?: bottomStart ?: bottomRight ?: uniform ?: 0f,
|
||||
bottomRight = startEnd ?: bottomEnd ?: bottomLeft ?: uniform ?: 0f)
|
||||
} else {
|
||||
ComputedBorderRadius(
|
||||
topLeft = endStart ?: topEnd ?: topLeft ?: uniform ?: 0f,
|
||||
topRight = startStart ?: topStart ?: topRight ?: uniform ?: 0f,
|
||||
bottomLeft = endEnd ?: bottomStart ?: bottomLeft ?: uniform ?: 0f,
|
||||
bottomRight = startEnd ?: bottomEnd ?: bottomRight ?: uniform ?: 0f)
|
||||
}
|
||||
else -> throw IllegalArgumentException("Expected resolved layout direction")
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.uimanager.style
|
||||
|
||||
/** Phsysical edge lengths (in DIPs) for a border-radius. */
|
||||
public data class ComputedBorderRadius(
|
||||
val topLeft: Float,
|
||||
val topRight: Float,
|
||||
val bottomLeft: Float,
|
||||
val bottomRight: Float,
|
||||
) {
|
||||
public fun hasRoundedBorders(): Boolean {
|
||||
return topLeft > 0f || topRight > 0f || bottomLeft > 0f || bottomRight > 0f
|
||||
}
|
||||
}
|
||||
+27
-99
@@ -52,7 +52,9 @@ import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.react.uimanager.common.UIManagerType;
|
||||
import com.facebook.react.uimanager.common.ViewUtil;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable;
|
||||
import com.facebook.react.uimanager.style.BorderRadiusProp;
|
||||
import com.facebook.react.uimanager.style.ComputedBorderRadius;
|
||||
|
||||
/**
|
||||
* Backing for a React View. Has support for borders, but since borders aren't common, lazy
|
||||
@@ -315,16 +317,27 @@ public class ReactViewGroup extends ViewGroup
|
||||
getOrCreateReactViewBackground().setBorderColor(position, rgb, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setBorderRadius(BorderRadiusProp, Float)} instead.
|
||||
*/
|
||||
public void setBorderRadius(float borderRadius) {
|
||||
ReactViewBackgroundDrawable backgroundDrawable = getOrCreateReactViewBackground();
|
||||
CSSBackgroundDrawable backgroundDrawable = getOrCreateReactViewBackground();
|
||||
backgroundDrawable.setRadius(borderRadius);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setBorderRadius(BorderRadiusProp, Float)} instead.
|
||||
*/
|
||||
public void setBorderRadius(float borderRadius, int position) {
|
||||
ReactViewBackgroundDrawable backgroundDrawable = getOrCreateReactViewBackground();
|
||||
CSSBackgroundDrawable backgroundDrawable = getOrCreateReactViewBackground();
|
||||
backgroundDrawable.setRadius(borderRadius, position);
|
||||
}
|
||||
|
||||
public void setBorderRadius(BorderRadiusProp property, @Nullable Float borderRadius) {
|
||||
CSSBackgroundDrawable backgroundDrawable = getOrCreateReactViewBackground();
|
||||
backgroundDrawable.setBorderRadius(property, borderRadius);
|
||||
}
|
||||
|
||||
public void setBorderStyle(@Nullable String style) {
|
||||
getOrCreateReactViewBackground().setBorderStyle(style);
|
||||
}
|
||||
@@ -912,95 +925,10 @@ public class ReactViewGroup extends ViewGroup
|
||||
bottom -= borderWidth.bottom;
|
||||
}
|
||||
|
||||
final float borderRadius = mReactBackgroundDrawable.getFullBorderRadius();
|
||||
float topLeftBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
|
||||
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_LEFT);
|
||||
float topRightBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
|
||||
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_RIGHT);
|
||||
float bottomLeftBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
|
||||
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_LEFT);
|
||||
float bottomRightBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
|
||||
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_RIGHT);
|
||||
final ComputedBorderRadius borderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadius().resolve(mLayoutDirection, getContext());
|
||||
|
||||
final boolean isRTL = mLayoutDirection == View.LAYOUT_DIRECTION_RTL;
|
||||
float topStartBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadius(
|
||||
ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_START);
|
||||
float topEndBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadius(
|
||||
ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_END);
|
||||
float bottomStartBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadius(
|
||||
ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_START);
|
||||
float bottomEndBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadius(
|
||||
ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_END);
|
||||
|
||||
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(getContext())) {
|
||||
if (YogaConstants.isUndefined(topStartBorderRadius)) {
|
||||
topStartBorderRadius = topLeftBorderRadius;
|
||||
}
|
||||
|
||||
if (YogaConstants.isUndefined(topEndBorderRadius)) {
|
||||
topEndBorderRadius = topRightBorderRadius;
|
||||
}
|
||||
|
||||
if (YogaConstants.isUndefined(bottomStartBorderRadius)) {
|
||||
bottomStartBorderRadius = bottomLeftBorderRadius;
|
||||
}
|
||||
|
||||
if (YogaConstants.isUndefined(bottomEndBorderRadius)) {
|
||||
bottomEndBorderRadius = bottomRightBorderRadius;
|
||||
}
|
||||
|
||||
final float directionAwareTopLeftRadius =
|
||||
isRTL ? topEndBorderRadius : topStartBorderRadius;
|
||||
final float directionAwareTopRightRadius =
|
||||
isRTL ? topStartBorderRadius : topEndBorderRadius;
|
||||
final float directionAwareBottomLeftRadius =
|
||||
isRTL ? bottomEndBorderRadius : bottomStartBorderRadius;
|
||||
final float directionAwareBottomRightRadius =
|
||||
isRTL ? bottomStartBorderRadius : bottomEndBorderRadius;
|
||||
|
||||
topLeftBorderRadius = directionAwareTopLeftRadius;
|
||||
topRightBorderRadius = directionAwareTopRightRadius;
|
||||
bottomLeftBorderRadius = directionAwareBottomLeftRadius;
|
||||
bottomRightBorderRadius = directionAwareBottomRightRadius;
|
||||
} else {
|
||||
final float directionAwareTopLeftRadius =
|
||||
isRTL ? topEndBorderRadius : topStartBorderRadius;
|
||||
final float directionAwareTopRightRadius =
|
||||
isRTL ? topStartBorderRadius : topEndBorderRadius;
|
||||
final float directionAwareBottomLeftRadius =
|
||||
isRTL ? bottomEndBorderRadius : bottomStartBorderRadius;
|
||||
final float directionAwareBottomRightRadius =
|
||||
isRTL ? bottomStartBorderRadius : bottomEndBorderRadius;
|
||||
|
||||
if (!YogaConstants.isUndefined(directionAwareTopLeftRadius)) {
|
||||
topLeftBorderRadius = directionAwareTopLeftRadius;
|
||||
}
|
||||
|
||||
if (!YogaConstants.isUndefined(directionAwareTopRightRadius)) {
|
||||
topRightBorderRadius = directionAwareTopRightRadius;
|
||||
}
|
||||
|
||||
if (!YogaConstants.isUndefined(directionAwareBottomLeftRadius)) {
|
||||
bottomLeftBorderRadius = directionAwareBottomLeftRadius;
|
||||
}
|
||||
|
||||
if (!YogaConstants.isUndefined(directionAwareBottomRightRadius)) {
|
||||
bottomRightBorderRadius = directionAwareBottomRightRadius;
|
||||
}
|
||||
}
|
||||
|
||||
if (topLeftBorderRadius > 0
|
||||
|| topRightBorderRadius > 0
|
||||
|| bottomRightBorderRadius > 0
|
||||
|| bottomLeftBorderRadius > 0) {
|
||||
if (borderRadius.hasRoundedBorders()) {
|
||||
if (mPath == null) {
|
||||
mPath = new Path();
|
||||
}
|
||||
@@ -1009,14 +937,14 @@ public class ReactViewGroup extends ViewGroup
|
||||
mPath.addRoundRect(
|
||||
new RectF(left, top, right, bottom),
|
||||
new float[] {
|
||||
Math.max(topLeftBorderRadius - borderWidth.left, 0),
|
||||
Math.max(topLeftBorderRadius - borderWidth.top, 0),
|
||||
Math.max(topRightBorderRadius - borderWidth.right, 0),
|
||||
Math.max(topRightBorderRadius - borderWidth.top, 0),
|
||||
Math.max(bottomRightBorderRadius - borderWidth.right, 0),
|
||||
Math.max(bottomRightBorderRadius - borderWidth.bottom, 0),
|
||||
Math.max(bottomLeftBorderRadius - borderWidth.left, 0),
|
||||
Math.max(bottomLeftBorderRadius - borderWidth.bottom, 0),
|
||||
Math.max(borderRadius.getTopLeft() - borderWidth.left, 0),
|
||||
Math.max(borderRadius.getTopLeft() - borderWidth.top, 0),
|
||||
Math.max(borderRadius.getTopRight() - borderWidth.right, 0),
|
||||
Math.max(borderRadius.getTopRight() - borderWidth.top, 0),
|
||||
Math.max(borderRadius.getBottomRight() - borderWidth.right, 0),
|
||||
Math.max(borderRadius.getBottomRight() - borderWidth.bottom, 0),
|
||||
Math.max(borderRadius.getBottomLeft() - borderWidth.left, 0),
|
||||
Math.max(borderRadius.getBottomLeft() - borderWidth.bottom, 0),
|
||||
},
|
||||
Path.Direction.CW);
|
||||
canvas.clipPath(mPath);
|
||||
|
||||
Reference in New Issue
Block a user