Implement direction-aware border clipping
Reviewed By: achen1 Differential Revision: D6015812 fbshipit-source-id: 406ddb12884a1c490cee784c6ef42322bd497b24
This commit is contained in:
parent
875f273dba
commit
00c9c1ad74
|
@ -114,7 +114,11 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||
TOP_LEFT,
|
||||
TOP_RIGHT,
|
||||
BOTTOM_RIGHT,
|
||||
BOTTOM_LEFT
|
||||
BOTTOM_LEFT,
|
||||
TOP_START,
|
||||
TOP_END,
|
||||
BOTTOM_START,
|
||||
BOTTOM_END
|
||||
}
|
||||
|
||||
public ReactViewBackgroundDrawable(Context context) {
|
||||
|
@ -262,6 +266,10 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||
return YogaConstants.isUndefined(mBorderRadius) ? 0 : mBorderRadius;
|
||||
}
|
||||
|
||||
public float getBorderRadius(final BorderRadiusLocation location) {
|
||||
return getBorderRadiusOrDefaultTo(YogaConstants.UNDEFINED, location);
|
||||
}
|
||||
|
||||
public float getBorderRadiusOrDefaultTo(
|
||||
final float defaultValue, final BorderRadiusLocation location) {
|
||||
if (mBorderCornerRadii == null) {
|
||||
|
@ -470,13 +478,13 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||
float bottomRightRadius =
|
||||
getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.BOTTOM_RIGHT);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && mBorderCornerRadii != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
|
||||
float topStartRadius = mBorderCornerRadii[4];
|
||||
float topEndRadius = mBorderCornerRadii[5];
|
||||
float bottomStartRadius = mBorderCornerRadii[6];
|
||||
float bottomEndRadius = mBorderCornerRadii[7];
|
||||
|
||||
float topStartRadius = getBorderRadius(BorderRadiusLocation.TOP_START);
|
||||
float topEndRadius = getBorderRadius(BorderRadiusLocation.TOP_END);
|
||||
float bottomStartRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_START);
|
||||
float bottomEndRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_END);
|
||||
|
||||
if (I18nUtil.getInstance().doesRTLFlipLeftAndRightStyles(mContext)) {
|
||||
if (YogaConstants.isUndefined(topStartRadius)) {
|
||||
topStartRadius = topLeftRadius;
|
||||
|
|
|
@ -34,8 +34,8 @@ import com.facebook.react.uimanager.ReactClippingViewGroup;
|
|||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
||||
import com.facebook.react.uimanager.ReactPointerEventsView;
|
||||
import com.facebook.react.uimanager.ReactZIndexedViewGroup;
|
||||
import com.facebook.react.uimanager.Spacing;
|
||||
import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
|
@ -644,40 +644,105 @@ public class ReactViewGroup extends ViewGroup implements
|
|||
float right = getWidth();
|
||||
float bottom = getHeight();
|
||||
|
||||
final float borderWidth = mReactBackgroundDrawable.getFullBorderWidth();
|
||||
final float borderTopWidth =
|
||||
mReactBackgroundDrawable.getBorderWidthOrDefaultTo(borderWidth, Spacing.TOP);
|
||||
final float borderBottomWidth =
|
||||
mReactBackgroundDrawable.getBorderWidthOrDefaultTo(borderWidth, Spacing.BOTTOM);
|
||||
final float borderLeftWidth =
|
||||
mReactBackgroundDrawable.getBorderWidthOrDefaultTo(borderWidth, Spacing.LEFT);
|
||||
final float borderRightWidth =
|
||||
mReactBackgroundDrawable.getBorderWidthOrDefaultTo(borderWidth, Spacing.RIGHT);
|
||||
final RectF borderWidth = mReactBackgroundDrawable.getDirectionAwareBorderInsets();
|
||||
|
||||
if (borderTopWidth > 0
|
||||
|| borderLeftWidth > 0
|
||||
|| borderBottomWidth > 0
|
||||
|| borderRightWidth > 0) {
|
||||
left += borderLeftWidth;
|
||||
top += borderTopWidth;
|
||||
right -= borderRightWidth;
|
||||
bottom -= borderBottomWidth;
|
||||
if (borderWidth.top > 0
|
||||
|| borderWidth.left > 0
|
||||
|| borderWidth.bottom > 0
|
||||
|| borderWidth.right > 0) {
|
||||
left += borderWidth.left;
|
||||
top += borderWidth.top;
|
||||
right -= borderWidth.right;
|
||||
bottom -= borderWidth.bottom;
|
||||
}
|
||||
|
||||
final float borderRadius = mReactBackgroundDrawable.getFullBorderRadius();
|
||||
final float topLeftBorderRadius =
|
||||
float topLeftBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
|
||||
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_LEFT);
|
||||
final float topRightBorderRadius =
|
||||
float topRightBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
|
||||
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_RIGHT);
|
||||
final float bottomLeftBorderRadius =
|
||||
float bottomLeftBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
|
||||
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_LEFT);
|
||||
final float bottomRightBorderRadius =
|
||||
float bottomRightBorderRadius =
|
||||
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
|
||||
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_RIGHT);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
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().doesRTLFlipLeftAndRightStyles(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
|
||||
|
@ -690,14 +755,14 @@ public class ReactViewGroup extends ViewGroup implements
|
|||
mPath.addRoundRect(
|
||||
new RectF(left, top, right, bottom),
|
||||
new float[] {
|
||||
Math.max(topLeftBorderRadius - borderLeftWidth, 0),
|
||||
Math.max(topLeftBorderRadius - borderTopWidth, 0),
|
||||
Math.max(topRightBorderRadius - borderRightWidth, 0),
|
||||
Math.max(topRightBorderRadius - borderTopWidth, 0),
|
||||
Math.max(bottomRightBorderRadius - borderRightWidth, 0),
|
||||
Math.max(bottomRightBorderRadius - borderBottomWidth, 0),
|
||||
Math.max(bottomLeftBorderRadius - borderLeftWidth, 0),
|
||||
Math.max(bottomLeftBorderRadius - borderBottomWidth, 0),
|
||||
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),
|
||||
},
|
||||
Path.Direction.CW);
|
||||
canvas.clipPath(mPath);
|
||||
|
|
Loading…
Reference in New Issue