Encapsulate float-ish border color APIs (#45338)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45338

`CSSBackgroundDrawable` is a silly goose and reuses layout types to store color. This has extended into a really strange public API, where we use floating point colors, where the color is itself in int with packed integer color components.

This hides that away, and marks some classes with `UnstableReactNativeAPI` that I plan to hide shortly.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D59488811

fbshipit-source-id: 7dc57edc9888f8a92088d2410ee71c2768ae8ec1
This commit is contained in:
Nick Gerleman
2024-07-09 14:59:40 -07:00
committed by Facebook GitHub Bot
parent 0e621295fb
commit 58c726a6ba
14 changed files with 40 additions and 106 deletions
@@ -5545,38 +5545,6 @@ public abstract interface class com/facebook/react/uimanager/debug/NotThreadSafe
public abstract fun onViewHierarchyUpdateFinished ()V
}
public class com/facebook/react/uimanager/drawable/CSSBackgroundDrawable : android/graphics/drawable/Drawable {
public fun <init> (Landroid/content/Context;)V
public fun draw (Landroid/graphics/Canvas;)V
public fun getAlpha ()I
public fun getBorderBoxPath ()Landroid/graphics/Path;
public fun getBorderBoxRect ()Landroid/graphics/RectF;
public fun getBorderColor (I)I
public fun getBorderRadius ()Lcom/facebook/react/uimanager/style/BorderRadiusStyle;
public fun getBorderWidthOrDefaultTo (FI)F
public fun getComputedBorderRadius ()Lcom/facebook/react/uimanager/style/ComputedBorderRadius;
public fun getDirectionAwareBorderInsets ()Landroid/graphics/RectF;
public fun getFullBorderWidth ()F
public fun getLayoutDirection ()I
public fun getOpacity ()I
public fun getOutline (Landroid/graphics/Outline;)V
public fun getPaddingBoxPath ()Landroid/graphics/Path;
public fun getPaddingBoxRect ()Landroid/graphics/RectF;
public fun hasRoundedBorders ()Z
protected fun onBoundsChange (Landroid/graphics/Rect;)V
public fun setAlpha (I)V
public fun setBorderColor (IFF)V
public fun setBorderRadius (Lcom/facebook/react/uimanager/style/BorderRadiusProp;Lcom/facebook/react/uimanager/LengthPercentage;)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
public fun setColorFilter (Landroid/graphics/ColorFilter;)V
public fun setLayoutDirectionOverride (I)V
public fun setRadius (F)V
public fun setRadius (FI)V
}
public abstract interface class com/facebook/react/uimanager/events/BatchEventDispatchedListener {
public abstract fun onBatchEventDispatched ()V
}
@@ -6746,7 +6714,7 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android
public fun scrollTo (II)V
public fun scrollToPreservingMomentum (II)V
public fun setBackgroundColor (I)V
public fun setBorderColor (IFF)V
public fun setBorderColor (ILjava/lang/Integer;)V
public fun setBorderRadius (F)V
public fun setBorderRadius (FI)V
public fun setBorderStyle (Ljava/lang/String;)V
@@ -6875,7 +6843,7 @@ public class com/facebook/react/views/scroll/ReactScrollView : android/widget/Sc
public fun scrollTo (II)V
public fun scrollToPreservingMomentum (II)V
public fun setBackgroundColor (I)V
public fun setBorderColor (IFF)V
public fun setBorderColor (ILjava/lang/Integer;)V
public fun setBorderRadius (F)V
public fun setBorderRadius (FI)V
public fun setBorderStyle (Ljava/lang/String;)V
@@ -7397,7 +7365,7 @@ public class com/facebook/react/views/text/ReactTextView : androidx/appcompat/wi
public fun reactTagForTouch (FF)I
public fun setAdjustFontSizeToFit (Z)V
public fun setBackgroundColor (I)V
public fun setBorderColor (IFF)V
public fun setBorderColor (ILjava/lang/Integer;)V
public fun setBorderRadius (F)V
public fun setBorderRadius (FI)V
public fun setBorderStyle (Ljava/lang/String;)V
@@ -7735,7 +7703,7 @@ public class com/facebook/react/views/textinput/ReactEditText : androidx/appcomp
public fun setAllowFontScaling (Z)V
public fun setAutoFocus (Z)V
public fun setBackgroundColor (I)V
public fun setBorderColor (IFF)V
public fun setBorderColor (ILjava/lang/Integer;)V
public fun setBorderRadius (F)V
public fun setBorderRadius (FI)V
public fun setBorderStyle (Ljava/lang/String;)V
@@ -7943,21 +7911,6 @@ public class com/facebook/react/views/view/ReactViewBackgroundDrawable : com/fac
public fun <init> (Landroid/content/Context;)V
}
public class com/facebook/react/views/view/ReactViewBackgroundManager {
public fun <init> (Landroid/view/View;)V
public fun cleanup ()V
public fun getBackgroundColor ()I
public fun getBorderColor (I)I
public fun maybeClipToPaddingBox (Landroid/graphics/Canvas;)V
public fun setBackgroundColor (I)V
public fun setBorderColor (IFF)V
public fun setBorderRadius (F)V
public fun setBorderRadius (FI)V
public fun setBorderStyle (Ljava/lang/String;)V
public fun setBorderWidth (IF)V
public fun setOverflow (Ljava/lang/String;)V
}
public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGroup, com/facebook/react/touch/ReactHitSlopView, com/facebook/react/touch/ReactInterceptingViewGroup, com/facebook/react/uimanager/ReactClippingViewGroup, com/facebook/react/uimanager/ReactOverflowViewWithInset, com/facebook/react/uimanager/ReactPointerEventsView, com/facebook/react/uimanager/ReactZIndexedViewGroup {
public fun <init> (Landroid/content/Context;)V
public fun addView (Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
@@ -7993,7 +7946,7 @@ public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGro
public fun setBackfaceVisibilityDependantOpacity ()V
public fun setBackground (Landroid/graphics/drawable/Drawable;)V
public fun setBackgroundColor (I)V
public fun setBorderColor (IFF)V
public fun setBorderColor (ILjava/lang/Integer;)V
public fun setBorderRadius (F)V
public fun setBorderRadius (FI)V
public fun setBorderRadius (Lcom/facebook/react/uimanager/style/BorderRadiusProp;Lcom/facebook/react/uimanager/LengthPercentage;)V
@@ -15,6 +15,7 @@ import android.graphics.RenderNode
import android.graphics.drawable.Drawable
import androidx.annotation.RequiresApi
import com.facebook.common.logging.FLog
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.uimanager.FilterHelper
import com.facebook.react.uimanager.LengthPercentage
import com.facebook.react.uimanager.LengthPercentageType
@@ -32,6 +33,7 @@ private const val BLUR_RADIUS_SIGMA_SCALE = 0.5f
/** Draws an outer-box shadow https://www.w3.org/TR/css-backgrounds-3/#shadow-shape */
@RequiresApi(31)
@OptIn(UnstableReactNativeAPI::class)
internal class BoxShadowDrawable(
context: Context,
private val background: CSSBackgroundDrawable,
@@ -27,6 +27,7 @@ import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import androidx.core.util.Preconditions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.modules.i18nmanager.I18nUtil;
import com.facebook.react.uimanager.FloatUtil;
@@ -51,6 +52,7 @@ import java.util.Objects;
* have a rectangular borders we allocate {@code mBorderWidthResult} and similar. When only
* background color is set we won't allocate any extra/unnecessary objects.
*/
@UnstableReactNativeAPI
@Nullsafe(Nullsafe.Mode.LOCAL)
public class CSSBackgroundDrawable extends Drawable {
@@ -219,9 +221,12 @@ public class CSSBackgroundDrawable extends Drawable {
}
}
public void setBorderColor(int position, float rgb, float alpha) {
this.setBorderRGB(position, rgb);
this.setBorderAlpha(position, alpha);
public void setBorderColor(int position, @Nullable Integer color) {
float rgbComponent = color == null ? Float.NaN : (float) ((int) color & 0x00FFFFFF);
float alphaComponent = color == null ? Float.NaN : (float) ((int) color >>> 24);
this.setBorderRGB(position, rgbComponent);
this.setBorderAlpha(position, alphaComponent);
mNeedUpdatePathForBorderRadius = true;
}
@@ -1283,8 +1283,8 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
mReactBackgroundManager.setBorderWidth(position, width);
}
public void setBorderColor(int position, float color, float alpha) {
mReactBackgroundManager.setBorderColor(position, color, alpha);
public void setBorderColor(int position, @Nullable Integer color) {
mReactBackgroundManager.setBorderColor(position, color);
}
public void setBorderRadius(float borderRadius) {
@@ -27,7 +27,6 @@ import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.yoga.YogaConstants;
import java.util.ArrayList;
import java.util.List;
@@ -298,11 +297,8 @@ public class ReactHorizontalScrollViewManager extends ViewGroupManager<ReactHori
"borderBottomColor"
},
customType = "Color")
public void setBorderColor(ReactHorizontalScrollView view, int index, Integer color) {
float rgbComponent =
color == null ? YogaConstants.UNDEFINED : (float) ((int) color & 0x00FFFFFF);
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int) color >>> 24);
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
public void setBorderColor(ReactHorizontalScrollView view, int index, @Nullable Integer color) {
view.setBorderColor(SPACING_TYPES[index], color);
}
@ReactProp(name = "overflow")
@@ -1216,8 +1216,8 @@ public class ReactScrollView extends ScrollView
mReactBackgroundManager.setBorderWidth(position, width);
}
public void setBorderColor(int position, float color, float alpha) {
mReactBackgroundManager.setBorderColor(position, color, alpha);
public void setBorderColor(int position, @Nullable Integer color) {
mReactBackgroundManager.setBorderColor(position, color);
}
public void setBorderRadius(float borderRadius) {
@@ -28,7 +28,6 @@ import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.yoga.YogaConstants;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -279,10 +278,8 @@ public class ReactScrollViewManager extends ViewGroupManager<ReactScrollView>
"borderBottomColor"
},
customType = "Color")
public void setBorderColor(ReactScrollView view, int index, Integer color) {
float rgbComponent = color == null ? YogaConstants.UNDEFINED : (float) (color & 0x00FFFFFF);
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) (color >>> 24);
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
public void setBorderColor(ReactScrollView view, int index, @Nullable Integer color) {
view.setBorderColor(SPACING_TYPES[index], color);
}
@ReactProp(name = "overflow")
@@ -23,7 +23,6 @@ import com.facebook.react.uimanager.ViewDefaults;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.yoga.YogaConstants;
/**
* Abstract class for anchor {@code <Text>}-ish spannable views, such as {@link TextView} or {@link
@@ -180,11 +179,8 @@ public abstract class ReactTextAnchorViewManager<T extends View, C extends React
"borderBottomColor"
},
customType = "Color")
public void setBorderColor(ReactTextView view, int index, Integer color) {
float rgbComponent =
color == null ? YogaConstants.UNDEFINED : (float) ((int) color & 0x00FFFFFF);
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int) color >>> 24);
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
public void setBorderColor(ReactTextView view, int index, @Nullable Integer color) {
view.setBorderColor(SPACING_TYPES[index], color);
}
@ReactProp(name = ViewProps.INCLUDE_FONT_PADDING, defaultBoolean = true)
@@ -686,8 +686,8 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
mReactBackgroundManager.setBorderWidth(position, width);
}
public void setBorderColor(int position, float color, float alpha) {
mReactBackgroundManager.setBorderColor(position, color, alpha);
public void setBorderColor(int position, @Nullable Integer color) {
mReactBackgroundManager.setBorderColor(position, color);
}
public void setBorderRadius(float borderRadius) {
@@ -1077,8 +1077,8 @@ public class ReactEditText extends AppCompatEditText {
mReactBackgroundManager.setBorderWidth(position, width);
}
public void setBorderColor(int position, float color, float alpha) {
mReactBackgroundManager.setBorderColor(position, color, alpha);
public void setBorderColor(int position, @Nullable Integer color) {
mReactBackgroundManager.setBorderColor(position, color);
}
public int getBorderColor(int position) {
@@ -70,7 +70,6 @@ import com.facebook.react.views.text.TextAttributeProps;
import com.facebook.react.views.text.TextLayoutManager;
import com.facebook.react.views.text.TextTransform;
import com.facebook.react.views.text.internal.span.TextInlineImageSpan;
import com.facebook.yoga.YogaConstants;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedList;
@@ -702,16 +701,7 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
if (underlineColor == null) {
drawableToMutate.clearColorFilter();
} else {
// fixes underlineColor transparent not working on API 21
// re-sets the TextInput underlineColor https://bit.ly/3M4alr6
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
int bottomBorderColor = view.getBorderColor(Spacing.BOTTOM);
setBorderColor(view, Spacing.START, underlineColor);
drawableToMutate.setColorFilter(underlineColor, PorterDuff.Mode.SRC_IN);
setBorderColor(view, Spacing.START, bottomBorderColor);
} else {
drawableToMutate.setColorFilter(underlineColor, PorterDuff.Mode.SRC_IN);
}
drawableToMutate.setColorFilter(underlineColor, PorterDuff.Mode.SRC_IN);
}
}
@@ -1024,11 +1014,8 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
"borderBottomColor"
},
customType = "Color")
public void setBorderColor(ReactEditText view, int index, Integer color) {
float rgbComponent =
color == null ? YogaConstants.UNDEFINED : (float) ((int) color & 0x00FFFFFF);
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int) color >>> 24);
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
public void setBorderColor(ReactEditText view, int index, @Nullable Integer color) {
view.setBorderColor(SPACING_TYPES[index], color);
}
@ReactProp(name = "overflow")
@@ -17,9 +17,11 @@ import android.graphics.drawable.LayerDrawable;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable;
/** Class that manages the background for views and borders. */
@UnstableReactNativeAPI
public class ReactViewBackgroundManager {
private static enum Overflow {
VISIBLE,
@@ -76,8 +78,8 @@ public class ReactViewBackgroundManager {
getOrCreateReactViewBackground().setBorderWidth(position, width);
}
public void setBorderColor(int position, float color, float alpha) {
getOrCreateReactViewBackground().setBorderColor(position, color, alpha);
public void setBorderColor(int position, @Nullable Integer color) {
getOrCreateReactViewBackground().setBorderColor(position, color);
}
public int getBorderColor(int position) {
@@ -305,8 +305,8 @@ public class ReactViewGroup extends ViewGroup
getOrCreateReactViewBackground().setBorderWidth(position, width);
}
public void setBorderColor(int position, float rgb, float alpha) {
getOrCreateReactViewBackground().setBorderColor(position, rgb, alpha);
public void setBorderColor(int position, @Nullable Integer color) {
getOrCreateReactViewBackground().setBorderColor(position, color);
}
/**
@@ -33,7 +33,6 @@ import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.style.BorderRadiusProp;
import com.facebook.yoga.YogaConstants;
import java.util.Map;
/** View manager for AndroidViews (plain React Views). */
@@ -246,11 +245,8 @@ public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
ViewProps.BORDER_BLOCK_START_COLOR
},
customType = "Color")
public void setBorderColor(ReactViewGroup view, int index, Integer color) {
float rgbComponent =
color == null ? YogaConstants.UNDEFINED : (float) ((int) color & 0x00FFFFFF);
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int) color >>> 24);
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
public void setBorderColor(ReactViewGroup view, int index, @Nullable Integer color) {
view.setBorderColor(SPACING_TYPES[index], color);
}
@ReactProp(name = ViewProps.COLLAPSABLE)