Fix border clipping

Reviewed By: achen1

Differential Revision: D5992045

fbshipit-source-id: fccd864dbc24592c3cd4df7300aca5096537e1d8
This commit is contained in:
Ramanpreet Nara 2017-10-18 19:29:28 -07:00 committed by Facebook Github Bot
parent b60fa63de8
commit de313f6fdd
2 changed files with 69 additions and 13 deletions

View File

@ -98,6 +98,13 @@ public class ReactViewBackgroundDrawable extends Drawable {
private @Nullable float[] mBorderCornerRadii; private @Nullable float[] mBorderCornerRadii;
public enum BorderRadiusLocation {
TOP_LEFT,
TOP_RIGHT,
BOTTOM_RIGHT,
BOTTOM_LEFT
}
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
updatePathEffect(); updatePathEffect();
@ -228,8 +235,23 @@ public class ReactViewBackgroundDrawable extends Drawable {
} }
} }
public float getRadius() { public float getFullBorderRadius() {
return mBorderRadius; return YogaConstants.isUndefined(mBorderRadius) ? 0 : mBorderRadius;
}
public float getBorderRadiusOrDefaultTo(
final float defaultValue, final BorderRadiusLocation location) {
if (mBorderCornerRadii == null) {
return defaultValue;
}
final float radius = mBorderCornerRadii[location.ordinal()];
if (YogaConstants.isUndefined(radius)) {
return defaultValue;
}
return radius;
} }
public void setColor(int color) { public void setColor(int color) {
@ -283,11 +305,15 @@ public class ReactViewBackgroundDrawable extends Drawable {
mTempRectForBorderRadius.inset(fullBorderWidth * 0.5f, fullBorderWidth * 0.5f); mTempRectForBorderRadius.inset(fullBorderWidth * 0.5f, fullBorderWidth * 0.5f);
} }
float defaultBorderRadius = !YogaConstants.isUndefined(mBorderRadius) ? mBorderRadius : 0; final float borderRadius = getFullBorderRadius();
float topLeftRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[0]) ? mBorderCornerRadii[0] : defaultBorderRadius; final float topLeftRadius =
float topRightRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[1]) ? mBorderCornerRadii[1] : defaultBorderRadius; getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.TOP_LEFT);
float bottomRightRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[2]) ? mBorderCornerRadii[2] : defaultBorderRadius; final float topRightRadius =
float bottomLeftRadius = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[3]) ? mBorderCornerRadii[3] : defaultBorderRadius; getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.TOP_RIGHT);
final float bottomLeftRadius =
getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.BOTTOM_LEFT);
final float bottomRightRadius =
getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.BOTTOM_RIGHT);
mPathForBorderRadius.addRoundRect( mPathForBorderRadius.addRoundRect(
mTempRectForBorderRadius, mTempRectForBorderRadius,

View File

@ -34,7 +34,6 @@ import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
import com.facebook.react.uimanager.ReactPointerEventsView; import com.facebook.react.uimanager.ReactPointerEventsView;
import com.facebook.react.uimanager.ReactZIndexedViewGroup; import com.facebook.react.uimanager.ReactZIndexedViewGroup;
import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper; import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper;
import com.facebook.yoga.YogaConstants;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
@ -625,23 +624,54 @@ public class ReactViewGroup extends ViewGroup implements
float top = 0f; float top = 0f;
float right = getWidth(); float right = getWidth();
float bottom = getHeight(); float bottom = getHeight();
if (mReactBackgroundDrawable.getFullBorderWidth() != 0f) { final float borderWidth = mReactBackgroundDrawable.getFullBorderWidth();
float borderWidth = mReactBackgroundDrawable.getFullBorderWidth();
if (borderWidth != 0f) {
left += borderWidth; left += borderWidth;
top += borderWidth; top += borderWidth;
right -= borderWidth; right -= borderWidth;
bottom -= borderWidth; bottom -= borderWidth;
} }
float radius = mReactBackgroundDrawable.getRadius();
if (!YogaConstants.isUndefined(radius) && radius > 0.5f) { final float borderRadius = mReactBackgroundDrawable.getFullBorderRadius();
final float topLeftBorderRadius =
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_LEFT);
final float topRightBorderRadius =
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_RIGHT);
final float bottomLeftBorderRadius =
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_LEFT);
final float bottomRightBorderRadius =
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_RIGHT);
if (topLeftBorderRadius > 0
|| topRightBorderRadius > 0
|| bottomRightBorderRadius > 0
|| bottomLeftBorderRadius > 0) {
if (mPath == null) { if (mPath == null) {
mPath = new Path(); mPath = new Path();
} }
mPath.rewind(); mPath.rewind();
mPath.addRoundRect( mPath.addRoundRect(
new RectF(left, top, right, bottom), radius, radius, Path.Direction.CW); new RectF(left, top, right, bottom),
new float[] {
Math.max(topLeftBorderRadius - borderWidth, 0),
Math.max(topLeftBorderRadius - borderWidth, 0),
Math.max(topRightBorderRadius - borderWidth, 0),
Math.max(topRightBorderRadius - borderWidth, 0),
Math.max(bottomRightBorderRadius - borderWidth, 0),
Math.max(bottomRightBorderRadius - borderWidth, 0),
Math.max(bottomLeftBorderRadius - borderWidth, 0),
Math.max(bottomLeftBorderRadius - borderWidth, 0),
},
Path.Direction.CW);
canvas.clipPath(mPath); canvas.clipPath(mPath);
} else {
canvas.clipRect(new RectF(left, top, right, bottom));
} }
} }
break; break;