mirror of
https://github.com/status-im/react-native.git
synced 2025-01-15 20:15:11 +00:00
Correct draw path dimensions while doing even border
Reviewed By: achen1 Differential Revision: D7678473 fbshipit-source-id: 8aa5eb29d22379eaabf9951a901e237fb7569632
This commit is contained in:
parent
60b05133ba
commit
c5ca26a0e5
@ -90,9 +90,11 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||||||
private @Nullable Path mOuterClipPathForBorderRadius;
|
private @Nullable Path mOuterClipPathForBorderRadius;
|
||||||
private @Nullable Path mPathForBorderRadiusOutline;
|
private @Nullable Path mPathForBorderRadiusOutline;
|
||||||
private @Nullable Path mPathForBorder;
|
private @Nullable Path mPathForBorder;
|
||||||
|
private @Nullable Path mCenterDrawPath;
|
||||||
private @Nullable RectF mInnerClipTempRectForBorderRadius;
|
private @Nullable RectF mInnerClipTempRectForBorderRadius;
|
||||||
private @Nullable RectF mOuterClipTempRectForBorderRadius;
|
private @Nullable RectF mOuterClipTempRectForBorderRadius;
|
||||||
private @Nullable RectF mTempRectForBorderRadiusOutline;
|
private @Nullable RectF mTempRectForBorderRadiusOutline;
|
||||||
|
private @Nullable RectF mTempRectForCenterDrawPath;
|
||||||
private @Nullable PointF mInnerTopLeftCorner;
|
private @Nullable PointF mInnerTopLeftCorner;
|
||||||
private @Nullable PointF mInnerTopRightCorner;
|
private @Nullable PointF mInnerTopRightCorner;
|
||||||
private @Nullable PointF mInnerBottomRightCorner;
|
private @Nullable PointF mInnerBottomRightCorner;
|
||||||
@ -343,110 +345,130 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||||||
|| borderWidth.bottom > 0
|
|| borderWidth.bottom > 0
|
||||||
|| borderWidth.left > 0
|
|| borderWidth.left > 0
|
||||||
|| borderWidth.right > 0) {
|
|| borderWidth.right > 0) {
|
||||||
mPaint.setStyle(Paint.Style.FILL);
|
|
||||||
|
|
||||||
// Draw border
|
//If it's a full and even border draw inner rect path with stroke
|
||||||
canvas.clipPath(mOuterClipPathForBorderRadius, Region.Op.INTERSECT);
|
final float fullBorderWidth = getFullBorderWidth();
|
||||||
canvas.clipPath(mInnerClipPathForBorderRadius, Region.Op.DIFFERENCE);
|
if (borderWidth.top == fullBorderWidth &&
|
||||||
|
borderWidth.bottom == fullBorderWidth &&
|
||||||
int colorLeft = getBorderColor(Spacing.LEFT);
|
borderWidth.left == fullBorderWidth &&
|
||||||
int colorTop = getBorderColor(Spacing.TOP);
|
borderWidth.right == fullBorderWidth) {
|
||||||
int colorRight = getBorderColor(Spacing.RIGHT);
|
if (fullBorderWidth > 0) {
|
||||||
int colorBottom = getBorderColor(Spacing.BOTTOM);
|
int borderColor = getBorderColor(Spacing.ALL);
|
||||||
|
mPaint.setColor(ColorUtil.multiplyColorAlpha(borderColor, mAlpha));
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
mPaint.setStyle(Paint.Style.STROKE);
|
||||||
final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
|
mPaint.setStrokeWidth(fullBorderWidth);
|
||||||
int colorStart = getBorderColor(Spacing.START);
|
canvas.drawPath(mCenterDrawPath, mPaint);
|
||||||
int colorEnd = getBorderColor(Spacing.END);
|
|
||||||
|
|
||||||
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(mContext)) {
|
|
||||||
if (!isBorderColorDefined(Spacing.START)) {
|
|
||||||
colorStart = colorLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isBorderColorDefined(Spacing.END)) {
|
|
||||||
colorEnd = colorRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int directionAwareColorLeft = isRTL ? colorEnd : colorStart;
|
|
||||||
final int directionAwareColorRight = isRTL ? colorStart : colorEnd;
|
|
||||||
|
|
||||||
colorLeft = directionAwareColorLeft;
|
|
||||||
colorRight = directionAwareColorRight;
|
|
||||||
} else {
|
|
||||||
final int directionAwareColorLeft = isRTL ? colorEnd : colorStart;
|
|
||||||
final int directionAwareColorRight = isRTL ? colorStart : colorEnd;
|
|
||||||
|
|
||||||
final boolean isColorStartDefined = isBorderColorDefined(Spacing.START);
|
|
||||||
final boolean isColorEndDefined = isBorderColorDefined(Spacing.END);
|
|
||||||
final boolean isDirectionAwareColorLeftDefined = isRTL ? isColorEndDefined : isColorStartDefined;
|
|
||||||
final boolean isDirectionAwareColorRightDefined = isRTL ? isColorStartDefined : isColorEndDefined;
|
|
||||||
|
|
||||||
if (isDirectionAwareColorLeftDefined) {
|
|
||||||
colorLeft = directionAwareColorLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDirectionAwareColorRightDefined) {
|
|
||||||
colorRight = directionAwareColorRight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//In the case of uneven border widths/colors draw quadrilateral in each direction
|
||||||
|
else {
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
|
||||||
final float left = mOuterClipTempRectForBorderRadius.left;
|
// Draw border
|
||||||
final float right = mOuterClipTempRectForBorderRadius.right;
|
canvas.clipPath(mOuterClipPathForBorderRadius, Region.Op.INTERSECT);
|
||||||
final float top = mOuterClipTempRectForBorderRadius.top;
|
canvas.clipPath(mInnerClipPathForBorderRadius, Region.Op.DIFFERENCE);
|
||||||
final float bottom = mOuterClipTempRectForBorderRadius.bottom;
|
|
||||||
|
|
||||||
if (borderWidth.left > 0) {
|
int colorLeft = getBorderColor(Spacing.LEFT);
|
||||||
final float x1 = left;
|
int colorTop = getBorderColor(Spacing.TOP);
|
||||||
final float y1 = top;
|
int colorRight = getBorderColor(Spacing.RIGHT);
|
||||||
final float x2 = mInnerTopLeftCorner.x;
|
int colorBottom = getBorderColor(Spacing.BOTTOM);
|
||||||
final float y2 = mInnerTopLeftCorner.y;
|
|
||||||
final float x3 = mInnerBottomLeftCorner.x;
|
|
||||||
final float y3 = mInnerBottomLeftCorner.y;
|
|
||||||
final float x4 = left;
|
|
||||||
final float y4 = bottom;
|
|
||||||
|
|
||||||
drawQuadrilateral(canvas, colorLeft, x1, y1, x2, y2, x3, y3, x4, y4);
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
}
|
final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
|
||||||
|
int colorStart = getBorderColor(Spacing.START);
|
||||||
|
int colorEnd = getBorderColor(Spacing.END);
|
||||||
|
|
||||||
if (borderWidth.top > 0) {
|
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(mContext)) {
|
||||||
final float x1 = left;
|
if (!isBorderColorDefined(Spacing.START)) {
|
||||||
final float y1 = top;
|
colorStart = colorLeft;
|
||||||
final float x2 = mInnerTopLeftCorner.x;
|
}
|
||||||
final float y2 = mInnerTopLeftCorner.y;
|
|
||||||
final float x3 = mInnerTopRightCorner.x;
|
|
||||||
final float y3 = mInnerTopRightCorner.y;
|
|
||||||
final float x4 = right;
|
|
||||||
final float y4 = top;
|
|
||||||
|
|
||||||
drawQuadrilateral(canvas, colorTop, x1, y1, x2, y2, x3, y3, x4, y4);
|
if (!isBorderColorDefined(Spacing.END)) {
|
||||||
}
|
colorEnd = colorRight;
|
||||||
|
}
|
||||||
|
|
||||||
if (borderWidth.right > 0) {
|
final int directionAwareColorLeft = isRTL ? colorEnd : colorStart;
|
||||||
final float x1 = right;
|
final int directionAwareColorRight = isRTL ? colorStart : colorEnd;
|
||||||
final float y1 = top;
|
|
||||||
final float x2 = mInnerTopRightCorner.x;
|
|
||||||
final float y2 = mInnerTopRightCorner.y;
|
|
||||||
final float x3 = mInnerBottomRightCorner.x;
|
|
||||||
final float y3 = mInnerBottomRightCorner.y;
|
|
||||||
final float x4 = right;
|
|
||||||
final float y4 = bottom;
|
|
||||||
|
|
||||||
drawQuadrilateral(canvas, colorRight, x1, y1, x2, y2, x3, y3, x4, y4);
|
colorLeft = directionAwareColorLeft;
|
||||||
}
|
colorRight = directionAwareColorRight;
|
||||||
|
} else {
|
||||||
|
final int directionAwareColorLeft = isRTL ? colorEnd : colorStart;
|
||||||
|
final int directionAwareColorRight = isRTL ? colorStart : colorEnd;
|
||||||
|
|
||||||
if (borderWidth.bottom > 0) {
|
final boolean isColorStartDefined = isBorderColorDefined(Spacing.START);
|
||||||
final float x1 = left;
|
final boolean isColorEndDefined = isBorderColorDefined(Spacing.END);
|
||||||
final float y1 = bottom;
|
final boolean isDirectionAwareColorLeftDefined =
|
||||||
final float x2 = mInnerBottomLeftCorner.x;
|
isRTL ? isColorEndDefined : isColorStartDefined;
|
||||||
final float y2 = mInnerBottomLeftCorner.y;
|
final boolean isDirectionAwareColorRightDefined =
|
||||||
final float x3 = mInnerBottomRightCorner.x;
|
isRTL ? isColorStartDefined : isColorEndDefined;
|
||||||
final float y3 = mInnerBottomRightCorner.y;
|
|
||||||
final float x4 = right;
|
|
||||||
final float y4 = bottom;
|
|
||||||
|
|
||||||
drawQuadrilateral(canvas, colorBottom, x1, y1, x2, y2, x3, y3, x4, y4);
|
if (isDirectionAwareColorLeftDefined) {
|
||||||
|
colorLeft = directionAwareColorLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDirectionAwareColorRightDefined) {
|
||||||
|
colorRight = directionAwareColorRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final float left = mOuterClipTempRectForBorderRadius.left;
|
||||||
|
final float right = mOuterClipTempRectForBorderRadius.right;
|
||||||
|
final float top = mOuterClipTempRectForBorderRadius.top;
|
||||||
|
final float bottom = mOuterClipTempRectForBorderRadius.bottom;
|
||||||
|
|
||||||
|
if (borderWidth.left > 0) {
|
||||||
|
final float x1 = left;
|
||||||
|
final float y1 = top;
|
||||||
|
final float x2 = mInnerTopLeftCorner.x;
|
||||||
|
final float y2 = mInnerTopLeftCorner.y;
|
||||||
|
final float x3 = mInnerBottomLeftCorner.x;
|
||||||
|
final float y3 = mInnerBottomLeftCorner.y;
|
||||||
|
final float x4 = left;
|
||||||
|
final float y4 = bottom;
|
||||||
|
|
||||||
|
drawQuadrilateral(canvas, colorLeft, x1, y1, x2, y2, x3, y3, x4, y4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (borderWidth.top > 0) {
|
||||||
|
final float x1 = left;
|
||||||
|
final float y1 = top;
|
||||||
|
final float x2 = mInnerTopLeftCorner.x;
|
||||||
|
final float y2 = mInnerTopLeftCorner.y;
|
||||||
|
final float x3 = mInnerTopRightCorner.x;
|
||||||
|
final float y3 = mInnerTopRightCorner.y;
|
||||||
|
final float x4 = right;
|
||||||
|
final float y4 = top;
|
||||||
|
|
||||||
|
drawQuadrilateral(canvas, colorTop, x1, y1, x2, y2, x3, y3, x4, y4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (borderWidth.right > 0) {
|
||||||
|
final float x1 = right;
|
||||||
|
final float y1 = top;
|
||||||
|
final float x2 = mInnerTopRightCorner.x;
|
||||||
|
final float y2 = mInnerTopRightCorner.y;
|
||||||
|
final float x3 = mInnerBottomRightCorner.x;
|
||||||
|
final float y3 = mInnerBottomRightCorner.y;
|
||||||
|
final float x4 = right;
|
||||||
|
final float y4 = bottom;
|
||||||
|
|
||||||
|
drawQuadrilateral(canvas, colorRight, x1, y1, x2, y2, x3, y3, x4, y4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (borderWidth.bottom > 0) {
|
||||||
|
final float x1 = left;
|
||||||
|
final float y1 = bottom;
|
||||||
|
final float x2 = mInnerBottomLeftCorner.x;
|
||||||
|
final float y2 = mInnerBottomLeftCorner.y;
|
||||||
|
final float x3 = mInnerBottomRightCorner.x;
|
||||||
|
final float y3 = mInnerBottomRightCorner.y;
|
||||||
|
final float x4 = right;
|
||||||
|
final float y4 = bottom;
|
||||||
|
|
||||||
|
drawQuadrilateral(canvas, colorBottom, x1, y1, x2, y2, x3, y3, x4, y4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,6 +494,10 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||||||
mPathForBorderRadiusOutline = new Path();
|
mPathForBorderRadiusOutline = new Path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mCenterDrawPath == null) {
|
||||||
|
mCenterDrawPath = new Path();
|
||||||
|
}
|
||||||
|
|
||||||
if (mInnerClipTempRectForBorderRadius == null) {
|
if (mInnerClipTempRectForBorderRadius == null) {
|
||||||
mInnerClipTempRectForBorderRadius = new RectF();
|
mInnerClipTempRectForBorderRadius = new RectF();
|
||||||
}
|
}
|
||||||
@ -484,13 +510,24 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||||||
mTempRectForBorderRadiusOutline = new RectF();
|
mTempRectForBorderRadiusOutline = new RectF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mTempRectForCenterDrawPath == null) {
|
||||||
|
mTempRectForCenterDrawPath = new RectF();
|
||||||
|
}
|
||||||
|
|
||||||
mInnerClipPathForBorderRadius.reset();
|
mInnerClipPathForBorderRadius.reset();
|
||||||
mOuterClipPathForBorderRadius.reset();
|
mOuterClipPathForBorderRadius.reset();
|
||||||
mPathForBorderRadiusOutline.reset();
|
mPathForBorderRadiusOutline.reset();
|
||||||
|
mCenterDrawPath.reset();
|
||||||
|
|
||||||
mInnerClipTempRectForBorderRadius.set(getBounds());
|
mInnerClipTempRectForBorderRadius.set(getBounds());
|
||||||
mOuterClipTempRectForBorderRadius.set(getBounds());
|
mOuterClipTempRectForBorderRadius.set(getBounds());
|
||||||
mTempRectForBorderRadiusOutline.set(getBounds());
|
mTempRectForBorderRadiusOutline.set(getBounds());
|
||||||
|
mTempRectForCenterDrawPath.set(getBounds());
|
||||||
|
|
||||||
|
float fullBorderWidth = getFullBorderWidth();
|
||||||
|
if (fullBorderWidth > 0) {
|
||||||
|
mTempRectForCenterDrawPath.inset(fullBorderWidth * 0.5f, fullBorderWidth * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
final RectF borderWidth = getDirectionAwareBorderInsets();
|
final RectF borderWidth = getDirectionAwareBorderInsets();
|
||||||
|
|
||||||
@ -623,6 +660,20 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||||||
},
|
},
|
||||||
Path.Direction.CW);
|
Path.Direction.CW);
|
||||||
|
|
||||||
|
mCenterDrawPath.addRoundRect(
|
||||||
|
mTempRectForCenterDrawPath,
|
||||||
|
new float[] {
|
||||||
|
innerTopLeftRadiusX + extraRadiusForOutline,
|
||||||
|
innerTopLeftRadiusY + extraRadiusForOutline,
|
||||||
|
innerTopRightRadiusX + extraRadiusForOutline,
|
||||||
|
innerTopRightRadiusY + extraRadiusForOutline,
|
||||||
|
innerBottomRightRadiusX + extraRadiusForOutline,
|
||||||
|
innerBottomRightRadiusY + extraRadiusForOutline,
|
||||||
|
innerBottomLeftRadiusX + extraRadiusForOutline,
|
||||||
|
innerBottomLeftRadiusY + extraRadiusForOutline
|
||||||
|
},
|
||||||
|
Path.Direction.CW);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rounded Multi-Colored Border Algorithm:
|
* Rounded Multi-Colored Border Algorithm:
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user