Skip to content

Commit

Permalink
Correct draw path dimensions while doing even border
Browse files Browse the repository at this point in the history
Reviewed By: achen1

Differential Revision: D7678473

fbshipit-source-id: 8aa5eb29d22379eaabf9951a901e237fb7569632
  • Loading branch information
himabindugadupudi authored and facebook-github-bot committed Apr 19, 2018
1 parent 60b0513 commit c5ca26a
Showing 1 changed file with 139 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ private static enum BorderStyle {
private @Nullable Path mOuterClipPathForBorderRadius;
private @Nullable Path mPathForBorderRadiusOutline;
private @Nullable Path mPathForBorder;
private @Nullable Path mCenterDrawPath;
private @Nullable RectF mInnerClipTempRectForBorderRadius;
private @Nullable RectF mOuterClipTempRectForBorderRadius;
private @Nullable RectF mTempRectForBorderRadiusOutline;
private @Nullable RectF mTempRectForCenterDrawPath;
private @Nullable PointF mInnerTopLeftCorner;
private @Nullable PointF mInnerTopRightCorner;
private @Nullable PointF mInnerBottomRightCorner;
Expand Down Expand Up @@ -343,110 +345,130 @@ private void drawRoundedBackgroundWithBorders(Canvas canvas) {
|| borderWidth.bottom > 0
|| borderWidth.left > 0
|| borderWidth.right > 0) {
mPaint.setStyle(Paint.Style.FILL);

// Draw border
canvas.clipPath(mOuterClipPathForBorderRadius, Region.Op.INTERSECT);
canvas.clipPath(mInnerClipPathForBorderRadius, Region.Op.DIFFERENCE);
//If it's a full and even border draw inner rect path with stroke
final float fullBorderWidth = getFullBorderWidth();
if (borderWidth.top == fullBorderWidth &&
borderWidth.bottom == fullBorderWidth &&
borderWidth.left == fullBorderWidth &&
borderWidth.right == fullBorderWidth) {
if (fullBorderWidth > 0) {
int borderColor = getBorderColor(Spacing.ALL);
mPaint.setColor(ColorUtil.multiplyColorAlpha(borderColor, mAlpha));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(fullBorderWidth);
canvas.drawPath(mCenterDrawPath, mPaint);
}
}
//In the case of uneven border widths/colors draw quadrilateral in each direction
else {
mPaint.setStyle(Paint.Style.FILL);

int colorLeft = getBorderColor(Spacing.LEFT);
int colorTop = getBorderColor(Spacing.TOP);
int colorRight = getBorderColor(Spacing.RIGHT);
int colorBottom = getBorderColor(Spacing.BOTTOM);
// Draw border
canvas.clipPath(mOuterClipPathForBorderRadius, Region.Op.INTERSECT);
canvas.clipPath(mInnerClipPathForBorderRadius, Region.Op.DIFFERENCE);

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);
int colorLeft = getBorderColor(Spacing.LEFT);
int colorTop = getBorderColor(Spacing.TOP);
int colorRight = getBorderColor(Spacing.RIGHT);
int colorBottom = getBorderColor(Spacing.BOTTOM);

if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(mContext)) {
if (!isBorderColorDefined(Spacing.START)) {
colorStart = colorLeft;
}
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 (!isBorderColorDefined(Spacing.END)) {
colorEnd = colorRight;
}
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(mContext)) {
if (!isBorderColorDefined(Spacing.START)) {
colorStart = colorLeft;
}

final int directionAwareColorLeft = isRTL ? colorEnd : colorStart;
final int directionAwareColorRight = isRTL ? colorStart : colorEnd;
if (!isBorderColorDefined(Spacing.END)) {
colorEnd = colorRight;
}

colorLeft = directionAwareColorLeft;
colorRight = directionAwareColorRight;
} else {
final int directionAwareColorLeft = isRTL ? colorEnd : colorStart;
final int directionAwareColorRight = isRTL ? colorStart : colorEnd;
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;
} 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;
}
}
}
}

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);
}
final float left = mOuterClipTempRectForBorderRadius.left;
final float right = mOuterClipTempRectForBorderRadius.right;
final float top = mOuterClipTempRectForBorderRadius.top;
final float bottom = mOuterClipTempRectForBorderRadius.bottom;

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.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;

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);
}
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;

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);
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);
}
}
}

Expand All @@ -472,6 +494,10 @@ private void updatePath() {
mPathForBorderRadiusOutline = new Path();
}

if (mCenterDrawPath == null) {
mCenterDrawPath = new Path();
}

if (mInnerClipTempRectForBorderRadius == null) {
mInnerClipTempRectForBorderRadius = new RectF();
}
Expand All @@ -484,13 +510,24 @@ private void updatePath() {
mTempRectForBorderRadiusOutline = new RectF();
}

if (mTempRectForCenterDrawPath == null) {
mTempRectForCenterDrawPath = new RectF();
}

mInnerClipPathForBorderRadius.reset();
mOuterClipPathForBorderRadius.reset();
mPathForBorderRadiusOutline.reset();
mCenterDrawPath.reset();

mInnerClipTempRectForBorderRadius.set(getBounds());
mOuterClipTempRectForBorderRadius.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();

Expand Down Expand Up @@ -623,6 +660,20 @@ private void updatePath() {
},
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:
*
Expand Down

0 comments on commit c5ca26a

Please sign in to comment.