/**
  * We use this method for getting color for rounded borders only similarly as for {@link
  * #getFullBorderWidth}.
  */
 private int getFullBorderColor() {
   float rgb =
       (mBorderRGB != null && !CSSConstants.isUndefined(mBorderRGB.getRaw(Spacing.ALL)))
           ? mBorderRGB.getRaw(Spacing.ALL)
           : DEFAULT_BORDER_RGB;
   float alpha =
       (mBorderAlpha != null && !CSSConstants.isUndefined(mBorderAlpha.getRaw(Spacing.ALL)))
           ? mBorderAlpha.getRaw(Spacing.ALL)
           : DEFAULT_BORDER_ALPHA;
   return ReactViewBackgroundDrawable.colorFromAlphaAndRGBComponents(alpha, rgb);
 }
 @ReactProp(name = ViewProps.BORDER_WIDTH, defaultFloat = CSSConstants.UNDEFINED)
 public void setBorderWidth(ReactViewGroup view, float width) {
   if (!CSSConstants.isUndefined(width)) {
     width = PixelUtil.toPixelFromDIP(width);
   }
   view.setBorderWidth(Spacing.ALL, width);
 }
  @Override
  public void draw(Canvas canvas) {
    updatePathEffect();
    boolean roundedBorders =
        mBorderCornerRadii != null
            || (!CSSConstants.isUndefined(mBorderRadius) && mBorderRadius > 0);

    if ((mBorderStyle == null || mBorderStyle == BorderStyle.SOLID) && !roundedBorders) {
      drawRectangularBackgroundWithBorders(canvas);
    } else {
      drawRoundedBackgroundWithBorders(canvas);
    }
  }
  /* Android's elevation implementation requires this to be implemented to know where to draw the shadow. */
  @Override
  public void getOutline(Outline outline) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
      super.getOutline(outline);
      return;
    }
    if ((!CSSConstants.isUndefined(mBorderRadius) && mBorderRadius > 0)
        || mBorderCornerRadii != null) {
      updatePath();

      outline.setConvexPath(mPathForBorderRadiusOutline);
    } else {
      outline.setRect(getBounds());
    }
  }
 @ReactPropGroup(
     names = {
       ViewProps.BORDER_WIDTH,
       ViewProps.BORDER_LEFT_WIDTH,
       ViewProps.BORDER_RIGHT_WIDTH,
       ViewProps.BORDER_TOP_WIDTH,
       ViewProps.BORDER_BOTTOM_WIDTH,
     },
     defaultFloat = CSSConstants.UNDEFINED)
 public void setBorderWidth(ReactViewGroup view, int index, float width) {
   if (!CSSConstants.isUndefined(width)) {
     width = PixelUtil.toPixelFromDIP(width);
   }
   view.setBorderWidth(SPACING_TYPES[index], width);
 }
 /** For rounded borders we use default "borderWidth" property. */
 private float getFullBorderWidth() {
   return (mBorderWidth != null && !CSSConstants.isUndefined(mBorderWidth.getRaw(Spacing.ALL)))
       ? mBorderWidth.getRaw(Spacing.ALL)
       : 0f;
 }
  private void updatePath() {
    if (!mNeedUpdatePathForBorderRadius) {
      return;
    }
    mNeedUpdatePathForBorderRadius = false;
    if (mPathForBorderRadius == null) {
      mPathForBorderRadius = new Path();
      mTempRectForBorderRadius = new RectF();
      mPathForBorderRadiusOutline = new Path();
      mTempRectForBorderRadiusOutline = new RectF();
    }

    mPathForBorderRadius.reset();
    mPathForBorderRadiusOutline.reset();

    mTempRectForBorderRadius.set(getBounds());
    mTempRectForBorderRadiusOutline.set(getBounds());
    float fullBorderWidth = getFullBorderWidth();
    if (fullBorderWidth > 0) {
      mTempRectForBorderRadius.inset(fullBorderWidth * 0.5f, fullBorderWidth * 0.5f);
    }

    float defaultBorderRadius = !CSSConstants.isUndefined(mBorderRadius) ? mBorderRadius : 0;
    float topLeftRadius =
        mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[0])
            ? mBorderCornerRadii[0]
            : defaultBorderRadius;
    float topRightRadius =
        mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[1])
            ? mBorderCornerRadii[1]
            : defaultBorderRadius;
    float bottomRightRadius =
        mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[2])
            ? mBorderCornerRadii[2]
            : defaultBorderRadius;
    float bottomLeftRadius =
        mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[3])
            ? mBorderCornerRadii[3]
            : defaultBorderRadius;

    mPathForBorderRadius.addRoundRect(
        mTempRectForBorderRadius,
        new float[] {
          topLeftRadius,
          topLeftRadius,
          topRightRadius,
          topRightRadius,
          bottomRightRadius,
          bottomRightRadius,
          bottomLeftRadius,
          bottomLeftRadius
        },
        Path.Direction.CW);

    float extraRadiusForOutline = 0;

    if (mBorderWidth != null) {
      extraRadiusForOutline = mBorderWidth.get(Spacing.ALL) / 2f;
    }

    mPathForBorderRadiusOutline.addRoundRect(
        mTempRectForBorderRadiusOutline,
        new float[] {
          topLeftRadius + extraRadiusForOutline,
          topLeftRadius + extraRadiusForOutline,
          topRightRadius + extraRadiusForOutline,
          topRightRadius + extraRadiusForOutline,
          bottomRightRadius + extraRadiusForOutline,
          bottomRightRadius + extraRadiusForOutline,
          bottomLeftRadius + extraRadiusForOutline,
          bottomLeftRadius + extraRadiusForOutline
        },
        Path.Direction.CW);
  }