mirror of
https://github.com/status-im/react-native.git
synced 2025-01-28 18:25:06 +00:00
Avoid using path for normal border cases
Reviewed By: achen1 Differential Revision: D5111223 fbshipit-source-id: d85da53a9409efc2edb1ca6ecb040a30a35266b8
This commit is contained in:
parent
bada25d158
commit
02856938ea
@ -48,6 +48,11 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
||||
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
|
||||
private static final int DEFAULT_BORDER_RGB = 0x00FFFFFF & DEFAULT_BORDER_COLOR;
|
||||
private static final int DEFAULT_BORDER_ALPHA = (0xFF000000 & DEFAULT_BORDER_COLOR) >>> 24;
|
||||
// ~0 == 0xFFFFFFFF, all bits set to 1.
|
||||
private static final int ALL_BITS_SET = ~0;
|
||||
// 0 == 0x00000000, all bits set to 0.
|
||||
private static final int ALL_BITS_UNSET = 0;
|
||||
|
||||
|
||||
private static enum BorderStyle {
|
||||
SOLID,
|
||||
@ -239,7 +244,7 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
||||
private void drawRoundedBackgroundWithBorders(Canvas canvas) {
|
||||
updatePath();
|
||||
int useColor = ColorUtil.multiplyColorAlpha(mColor, mAlpha);
|
||||
if ((useColor >>> 24) != 0) { // color is not transparent
|
||||
if (Color.alpha(useColor) != 0) { // color is not transparent
|
||||
mPaint.setColor(useColor);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawPath(mPathForBorderRadius, mPaint);
|
||||
@ -349,9 +354,38 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
||||
return ReactViewBackgroundDrawable.colorFromAlphaAndRGBComponents(alpha, rgb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quickly determine if all the set border colors are equal. Bitwise AND all the set colors
|
||||
* together, then OR them all together. If the AND and the OR are the same, then the colors
|
||||
* are compatible, so return this color.
|
||||
*
|
||||
* Used to avoid expensive path creation and expensive calls to canvas.drawPath
|
||||
*
|
||||
* @return A compatible border color, or zero if the border colors are not compatible.
|
||||
*/
|
||||
private static int fastBorderCompatibleColorOrZero(
|
||||
int borderLeft,
|
||||
int borderTop,
|
||||
int borderRight,
|
||||
int borderBottom,
|
||||
int colorLeft,
|
||||
int colorTop,
|
||||
int colorRight,
|
||||
int colorBottom) {
|
||||
int andSmear = (borderLeft > 0 ? colorLeft : ALL_BITS_SET) &
|
||||
(borderTop > 0 ? colorTop : ALL_BITS_SET) &
|
||||
(borderRight > 0 ? colorRight : ALL_BITS_SET) &
|
||||
(borderBottom > 0 ? colorBottom : ALL_BITS_SET);
|
||||
int orSmear = (borderLeft > 0 ? colorLeft : ALL_BITS_UNSET) |
|
||||
(borderTop > 0 ? colorTop : ALL_BITS_UNSET) |
|
||||
(borderRight > 0 ? colorRight : ALL_BITS_UNSET) |
|
||||
(borderBottom > 0 ? colorBottom : ALL_BITS_UNSET);
|
||||
return andSmear == orSmear ? andSmear : 0;
|
||||
}
|
||||
|
||||
private void drawRectangularBackgroundWithBorders(Canvas canvas) {
|
||||
int useColor = ColorUtil.multiplyColorAlpha(mColor, mAlpha);
|
||||
if ((useColor >>> 24) != 0) { // color is not transparent
|
||||
if (Color.alpha(useColor) != 0) { // color is not transparent
|
||||
mPaint.setColor(useColor);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawRect(getBounds(), mPaint);
|
||||
@ -370,69 +404,106 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
||||
int colorRight = getBorderColor(Spacing.RIGHT);
|
||||
int colorBottom = getBorderColor(Spacing.BOTTOM);
|
||||
|
||||
int top = bounds.top;
|
||||
int left = bounds.left;
|
||||
int width = bounds.width();
|
||||
int height = bounds.height();
|
||||
int top = bounds.top;
|
||||
|
||||
// If the path drawn previously is of the same color,
|
||||
// there would be a slight white space between borders
|
||||
// with anti-alias set to true.
|
||||
// Therefore we need to disable anti-alias, and
|
||||
// after drawing is done, we will re-enable it.
|
||||
// Check for fast path to border drawing.
|
||||
int fastBorderColor = fastBorderCompatibleColorOrZero(
|
||||
borderLeft,
|
||||
borderTop,
|
||||
borderRight,
|
||||
borderBottom,
|
||||
colorLeft,
|
||||
colorTop,
|
||||
colorRight,
|
||||
colorBottom);
|
||||
if (fastBorderColor != 0) {
|
||||
if (Color.alpha(fastBorderColor) != 0) {
|
||||
// Border color is not transparent.
|
||||
int right = bounds.right;
|
||||
int bottom = bounds.bottom;
|
||||
|
||||
mPaint.setAntiAlias(false);
|
||||
mPaint.setColor(fastBorderColor);
|
||||
if (borderLeft > 0) {
|
||||
int leftInset = left + borderLeft;
|
||||
canvas.drawRect(left, top, leftInset, bottom - borderBottom, mPaint);
|
||||
}
|
||||
if (borderTop > 0) {
|
||||
int topInset = top + borderTop;
|
||||
canvas.drawRect(left + borderLeft, top, right, topInset, mPaint);
|
||||
}
|
||||
if (borderRight > 0) {
|
||||
int rightInset = right - borderRight;
|
||||
canvas.drawRect(rightInset, top + borderTop, right, bottom, mPaint);
|
||||
}
|
||||
if (borderBottom > 0) {
|
||||
int bottomInset = bottom - borderBottom;
|
||||
canvas.drawRect(left, bottomInset, right - borderRight, bottom, mPaint);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mPathForBorder == null) {
|
||||
mPathForBorder = new Path();
|
||||
}
|
||||
|
||||
if (mPathForBorder == null) {
|
||||
mPathForBorder = new Path();
|
||||
// If the path drawn previously is of the same color,
|
||||
// there would be a slight white space between borders
|
||||
// with anti-alias set to true.
|
||||
// Therefore we need to disable anti-alias, and
|
||||
// after drawing is done, we will re-enable it.
|
||||
|
||||
mPaint.setAntiAlias(false);
|
||||
|
||||
int width = bounds.width();
|
||||
int height = bounds.height();
|
||||
|
||||
if (borderLeft > 0 && colorLeft != Color.TRANSPARENT) {
|
||||
mPaint.setColor(colorLeft);
|
||||
mPathForBorder.reset();
|
||||
mPathForBorder.moveTo(left, top);
|
||||
mPathForBorder.lineTo(left + borderLeft, top + borderTop);
|
||||
mPathForBorder.lineTo(left + borderLeft, top + height - borderBottom);
|
||||
mPathForBorder.lineTo(left, top + height);
|
||||
mPathForBorder.lineTo(left, top);
|
||||
canvas.drawPath(mPathForBorder, mPaint);
|
||||
}
|
||||
|
||||
if (borderTop > 0 && colorTop != Color.TRANSPARENT) {
|
||||
mPaint.setColor(colorTop);
|
||||
mPathForBorder.reset();
|
||||
mPathForBorder.moveTo(left, top);
|
||||
mPathForBorder.lineTo(left + borderLeft, top + borderTop);
|
||||
mPathForBorder.lineTo(left + width - borderRight, top + borderTop);
|
||||
mPathForBorder.lineTo(left + width, top);
|
||||
mPathForBorder.lineTo(left, top);
|
||||
canvas.drawPath(mPathForBorder, mPaint);
|
||||
}
|
||||
|
||||
if (borderRight > 0 && colorRight != Color.TRANSPARENT) {
|
||||
mPaint.setColor(colorRight);
|
||||
mPathForBorder.reset();
|
||||
mPathForBorder.moveTo(left + width, top);
|
||||
mPathForBorder.lineTo(left + width, top + height);
|
||||
mPathForBorder.lineTo(left + width - borderRight, top + height - borderBottom);
|
||||
mPathForBorder.lineTo(left + width - borderRight, top + borderTop);
|
||||
mPathForBorder.lineTo(left + width, top);
|
||||
canvas.drawPath(mPathForBorder, mPaint);
|
||||
}
|
||||
|
||||
if (borderBottom > 0 && colorBottom != Color.TRANSPARENT) {
|
||||
mPaint.setColor(colorBottom);
|
||||
mPathForBorder.reset();
|
||||
mPathForBorder.moveTo(left, top + height);
|
||||
mPathForBorder.lineTo(left + width, top + height);
|
||||
mPathForBorder.lineTo(left + width - borderRight, top + height - borderBottom);
|
||||
mPathForBorder.lineTo(left + borderLeft, top + height - borderBottom);
|
||||
mPathForBorder.lineTo(left, top + height);
|
||||
canvas.drawPath(mPathForBorder, mPaint);
|
||||
}
|
||||
|
||||
// re-enable anti alias
|
||||
mPaint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
if (borderLeft > 0 && colorLeft != Color.TRANSPARENT) {
|
||||
mPaint.setColor(colorLeft);
|
||||
mPathForBorder.reset();
|
||||
mPathForBorder.moveTo(left, top);
|
||||
mPathForBorder.lineTo(left + borderLeft, top + borderTop);
|
||||
mPathForBorder.lineTo(left + borderLeft, top + height - borderBottom);
|
||||
mPathForBorder.lineTo(left, top + height);
|
||||
mPathForBorder.lineTo(left, top);
|
||||
canvas.drawPath(mPathForBorder, mPaint);
|
||||
}
|
||||
|
||||
if (borderTop > 0 && colorTop != Color.TRANSPARENT) {
|
||||
mPaint.setColor(colorTop);
|
||||
mPathForBorder.reset();
|
||||
mPathForBorder.moveTo(left, top);
|
||||
mPathForBorder.lineTo(left + borderLeft, top + borderTop);
|
||||
mPathForBorder.lineTo(left + width - borderRight, top + borderTop);
|
||||
mPathForBorder.lineTo(left + width, top);
|
||||
mPathForBorder.lineTo(left, top);
|
||||
canvas.drawPath(mPathForBorder, mPaint);
|
||||
}
|
||||
|
||||
if (borderRight > 0 && colorRight != Color.TRANSPARENT) {
|
||||
mPaint.setColor(colorRight);
|
||||
mPathForBorder.reset();
|
||||
mPathForBorder.moveTo(left + width, top);
|
||||
mPathForBorder.lineTo(left + width, top + height);
|
||||
mPathForBorder.lineTo(left + width - borderRight, top + height - borderBottom);
|
||||
mPathForBorder.lineTo(left + width - borderRight, top + borderTop);
|
||||
mPathForBorder.lineTo(left + width, top);
|
||||
canvas.drawPath(mPathForBorder, mPaint);
|
||||
}
|
||||
|
||||
if (borderBottom > 0 && colorBottom != Color.TRANSPARENT) {
|
||||
mPaint.setColor(colorBottom);
|
||||
mPathForBorder.reset();
|
||||
mPathForBorder.moveTo(left, top + height);
|
||||
mPathForBorder.lineTo(left + width, top + height);
|
||||
mPathForBorder.lineTo(left + width - borderRight, top + height - borderBottom);
|
||||
mPathForBorder.lineTo(left + borderLeft, top + height - borderBottom);
|
||||
mPathForBorder.lineTo(left, top + height);
|
||||
canvas.drawPath(mPathForBorder, mPaint);
|
||||
}
|
||||
|
||||
// re-enable anti alias
|
||||
mPaint.setAntiAlias(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user