android.graphics.RectF#inset ( )源码实例Demo

下面列出了android.graphics.RectF#inset ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: BaseDialog   文件: MaterialProgressDrawable.java
/**
 * Draw the progress spinner
 */
public void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;

    mPaint.setColor(mCurrentColor);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
                mCirclePaint);
    }
}
 
/** Draw the progress spinner */
void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;

    mPaint.setColor(mCurrentColor);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(
                bounds.exactCenterX(),
                bounds.exactCenterY(),
                bounds.width() / 2,
                mCirclePaint);
    }
}
 
源代码3 项目: o2oa   文件: MaterialProgressDrawable.java
/**
 * Draw the progress spinner
 */
public void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;
    mPaint.setColor(mColors[mColorIndex]);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
                mCirclePaint);
    }
}
 
/**
 * Draw the progress spinner
 */
public void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;

    mPaint.setColor(mColors[mColorIndex]);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
                mCirclePaint);
    }
}
 
源代码5 项目: android_9.0.0_r45   文件: Animation.java
/**
 * @param left
 * @param top
 * @param right
 * @param bottom
 * @param invalidate
 * @param transformation
 *
 * @hide
 */
public void getInvalidateRegion(int left, int top, int right, int bottom,
        RectF invalidate, Transformation transformation) {

    final RectF tempRegion = mRegion;
    final RectF previousRegion = mPreviousRegion;

    invalidate.set(left, top, right, bottom);
    transformation.getMatrix().mapRect(invalidate);
    // Enlarge the invalidate region to account for rounding errors
    invalidate.inset(-1.0f, -1.0f);
    tempRegion.set(invalidate);
    invalidate.union(previousRegion);

    previousRegion.set(tempRegion);

    final Transformation tempTransformation = mTransformation;
    final Transformation previousTransformation = mPreviousTransformation;

    tempTransformation.set(transformation);
    transformation.set(previousTransformation);
    previousTransformation.set(tempTransformation);
}
 
/**
 * Draw the progress spinner
 */
public void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;

    mPaint.setColor(mCurrentColor);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
                mCirclePaint);
    }
}
 
/**
 * Draw the progress spinner
 */
public void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;
    mPaint.setColor(mColors[mColorIndex]);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
                mCirclePaint);
    }
}
 
源代码8 项目: android-chromium   文件: BookmarkUtils.java
/**
 * Use touch-icon or higher-resolution favicon and round the corners.
 * @param context    Context used to get resources.
 * @param touchIcon  Touch icon bitmap.
 * @param canvas     Canvas that holds the touch icon.
 */
private static void drawTouchIconToCanvas(
        Context context, Bitmap touchIcon, Canvas canvas) {
    Rect iconBounds = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());
    Rect src = new Rect(0, 0, touchIcon.getWidth(), touchIcon.getHeight());
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setFilterBitmap(true);
    canvas.drawBitmap(touchIcon, src, iconBounds, paint);
    // Convert dp to px.
    int borderRadii = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
            TOUCHICON_BORDER_RADII, context.getResources().getDisplayMetrics());
    Path path = new Path();
    path.setFillType(Path.FillType.INVERSE_WINDING);
    RectF rect = new RectF(iconBounds);
    rect.inset(INSET_DIMENSION_FOR_TOUCHICON, INSET_DIMENSION_FOR_TOUCHICON);
    path.addRoundRect(rect, borderRadii, borderRadii, Path.Direction.CW);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    canvas.drawPath(path, paint);
}
 
/**
 * Draw the progress spinner
 */
public void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;

    mPaint.setColor(mColors[mColorIndex]);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
                mCirclePaint);
    }
}
 
源代码10 项目: Mysplash   文件: MaterialProgressDrawable.java
/**
 * Draw the progress spinner
 */
public void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;

    mPaint.setColor(mCurrentColor);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
                mCirclePaint);
    }
}
 
源代码11 项目: MaterialQQLite   文件: MaterialDrawable.java
/**
 * Draw the progress spinner
 */
public void draw(Canvas c, Rect bounds) {
    final RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeInset, mStrokeInset);

    final float startAngle = (mStartTrim + mRotation) * 360;
    final float endAngle = (mEndTrim + mRotation) * 360;
    float sweepAngle = endAngle - startAngle;

    mPaint.setColor(mColors[mColorIndex]);
    c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);

    drawTriangle(c, startAngle, sweepAngle, bounds);

    if (mAlpha < 255) {
        mCirclePaint.setColor(mBackgroundColor);
        mCirclePaint.setAlpha(255 - mAlpha);
        c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,
                mCirclePaint);
    }
}
 
源代码12 项目: Plumble   文件: CircleDrawable.java
@Override
public void draw(Canvas canvas) {
    RectF imageRect = new RectF(getBounds());
    RectF strokeRect = new RectF(getBounds());
    // Default stroke drawing is both inset and outset.
    strokeRect.inset(mStrokePaint.getStrokeWidth()/2,
                     mStrokePaint.getStrokeWidth()/2);

    canvas.drawOval(imageRect, mPaint);
    canvas.drawOval(strokeRect, mStrokePaint);
}
 
源代码13 项目: FastAndroid   文件: BitmapUtils.java
/**
 * 转为圆形图片
 *
 * @param src         源图片
 * @param recycle     是否回收
 * @param borderSize  边框尺寸
 * @param borderColor 边框颜色
 * @return 圆形图片
 */
public static Bitmap toRound(@NonNull Bitmap src,
                             @IntRange(from = 0) int borderSize,
                             @ColorInt int borderColor,
                             boolean recycle) {
    int width = src.getWidth();
    int height = src.getHeight();
    int size = Math.min(width, height);
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    Bitmap ret = Bitmap.createBitmap(width, height, src.getConfig());
    float center = size / 2f;
    RectF rectF = new RectF(0, 0, width, height);
    rectF.inset((width - size) / 2f, (height - size) / 2f);
    Matrix matrix = new Matrix();
    matrix.setTranslate(rectF.left, rectF.top);
    matrix.preScale((float) size / width, (float) size / height);
    BitmapShader shader = new BitmapShader(src, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    shader.setLocalMatrix(matrix);
    paint.setShader(shader);
    Canvas canvas = new Canvas(ret);
    canvas.drawRoundRect(rectF, center, center, paint);
    if (borderSize > 0) {
        paint.setShader(null);
        paint.setColor(borderColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(borderSize);
        float radius = center - borderSize / 2f;
        canvas.drawCircle(width / 2f, height / 2f, radius, paint);
    }
    if (recycle && !src.isRecycled()) src.recycle();
    return ret;
}
 
源代码14 项目: GLEXP-Team-onebillion   文件: OC_MoreNumbers_S1.java
public void createMasks() throws Exception
{
    lockScreen();
    String[] masks = eventAttributes.get("masks").split(",");
    for(String maskNum : masks)
    {
        OBControl newMask = new OBControl();
        newMask.setProperty("correct",false);
        if(maskNum == masks[0])
        {
            ((OBLabel)objectDict.get(String.format("num_%s",maskNum))).setColour(Color.RED);
            objectDict.get(String.format("box_%s",maskNum)).setBackgroundColor(hilitecolour);
            newMask.setProperty("correct",true);
            newMask.setProperty("value" ,Integer.valueOf(maskNum));

        }
        OBControl alingBox = objectDict.get(String.format("box_%s", maskNum));
        RectF frame = new RectF(alingBox.getWorldFrame());
        frame.inset(alingBox.borderWidth/2.0f, alingBox.borderWidth/2.0f);
        newMask.setFrame(frame);
        newMask.setFillColor(maskcolour);
        targetMasks.add(newMask);
        newMask.setZPosition(50);
        attachControl(newMask);
    }
    unlockScreen();
    playSfxAudio("cover_on",true);
}
 
源代码15 项目: GLEXP-Team-onebillion   文件: OC_Numberlines_S2.java
public  void checkDrop() throws Exception
{
    playAudio(null);
    OBControl cont = target;
    target =  null;
    OBGroup peg = (OBGroup)objectDict.get(cont.settings.get("target"));
    RectF hotRect = new RectF(peg.frame());
    hotRect.inset(-1.5f* peg.width(), -0.5f * peg.height());
    if(eventTargets.contains(cont.propertyValue("value")) && RectF.intersects(cont.frame(),hotRect))
    {
        float left = peg.position().x - (cont.width()/2);
        if(cont.top() < peg.bottom())
        {
            OBAnimationGroup.runAnims(Arrays.asList(OBAnim.propertyAnim("left",left,cont),
                    OBAnim.propertyAnim("top",peg.bottom()+peg.height(),cont))
                    ,0.15,true,OBAnim.ANIM_EASE_IN_EASE_OUT,this);
            peg.setZPosition(11);
            cont.setZPosition(3);
            OBAnimationGroup.runAnims(Arrays.asList(OBAnim.propertyAnim("top",objectDict.get("rope").bottom(),cont))
                    ,0.15,true,OBAnim.ANIM_EASE_IN_EASE_OUT,this);
        }
        else
        {
            peg.setZPosition(11);
            cont.setZPosition(3);
            OBAnimationGroup.runAnims(Arrays.asList(OBAnim.propertyAnim("left",left,cont),
                    OBAnim.propertyAnim("top",objectDict.get("rope").bottom(),cont))
                    ,0.2,true,OBAnim.ANIM_EASE_IN_EASE_OUT,this);
        }
        closePeg(peg);
        gotItRight();
        eventTargets.remove(cont.settings.get("value"));
        dragTargets.remove(cont);
        if(eventTargets.size() == 0)
        {
            waitForSecs(0.2f);
            displayTick();
            waitForSecs(0.2f);
            performSel("demoFin",currentEvent());
            nextScene();
        }
        else
        {
            setStatus(STATUS_WAITING_FOR_DRAG);
        }
    }
    else
    {
        OBControl rope = objectDict.get("rope");
        RectF rect = new RectF(cont.frame());
        rect.inset( 0, -4*rope.height());
        boolean remind = RectF.intersects(cont.frame(),rect);
        gotItWrongWithSfx();
        OBAnimationGroup.runAnims(Arrays.asList(OBAnim.moveAnim((PointF)cont.propertyValue("startpos"),cont))
                ,0.2,true,OBAnim.ANIM_EASE_IN_EASE_OUT,this);
        waitSFX();
        if(remind)
            playAudioQueuedScene("INCORRECT",0.3f,false);
        setStatus(STATUS_WAITING_FOR_DRAG);
    }
}
 
源代码16 项目: Android-Image-Cropper   文件: CropOverlayView.java
/** Draw the corner of crop overlay. */
private void drawCorners(Canvas canvas) {
  if (mBorderCornerPaint != null) {

    float lineWidth = mBorderPaint != null ? mBorderPaint.getStrokeWidth() : 0;
    float cornerWidth = mBorderCornerPaint.getStrokeWidth();

    // for rectangle crop shape we allow the corners to be offset from the borders
    float w =
        cornerWidth / 2
            + (mCropShape == CropImageView.CropShape.RECTANGLE ? mBorderCornerOffset : 0);

    RectF rect = mCropWindowHandler.getRect();
    rect.inset(w, w);

    float cornerOffset = (cornerWidth - lineWidth) / 2;
    float cornerExtension = cornerWidth / 2 + cornerOffset;

    // Top left
    canvas.drawLine(
        rect.left - cornerOffset,
        rect.top - cornerExtension,
        rect.left - cornerOffset,
        rect.top + mBorderCornerLength,
        mBorderCornerPaint);
    canvas.drawLine(
        rect.left - cornerExtension,
        rect.top - cornerOffset,
        rect.left + mBorderCornerLength,
        rect.top - cornerOffset,
        mBorderCornerPaint);

    // Top right
    canvas.drawLine(
        rect.right + cornerOffset,
        rect.top - cornerExtension,
        rect.right + cornerOffset,
        rect.top + mBorderCornerLength,
        mBorderCornerPaint);
    canvas.drawLine(
        rect.right + cornerExtension,
        rect.top - cornerOffset,
        rect.right - mBorderCornerLength,
        rect.top - cornerOffset,
        mBorderCornerPaint);

    // Bottom left
    canvas.drawLine(
        rect.left - cornerOffset,
        rect.bottom + cornerExtension,
        rect.left - cornerOffset,
        rect.bottom - mBorderCornerLength,
        mBorderCornerPaint);
    canvas.drawLine(
        rect.left - cornerExtension,
        rect.bottom + cornerOffset,
        rect.left + mBorderCornerLength,
        rect.bottom + cornerOffset,
        mBorderCornerPaint);

    // Bottom left
    canvas.drawLine(
        rect.right + cornerOffset,
        rect.bottom + cornerExtension,
        rect.right + cornerOffset,
        rect.bottom - mBorderCornerLength,
        mBorderCornerPaint);
    canvas.drawLine(
        rect.right + cornerExtension,
        rect.bottom + cornerOffset,
        rect.right - mBorderCornerLength,
        rect.bottom + cornerOffset,
        mBorderCornerPaint);
  }
}
 
源代码17 项目: HaiNaBaiChuan   文件: HighlightView.java
void growBy(float dx, float dy) {
    if (maintainAspectRatio) {
        if (dx != 0) {
            dy = dx / initialAspectRatio;
        } else if (dy != 0) {
            dx = dy * initialAspectRatio;
        }
    }

    // Don't let the cropping rectangle grow too fast.
    // Grow at most half of the difference between the image rectangle and
    // the cropping rectangle.
    RectF r = new RectF(cropRect);
    if (dx > 0F && r.width() + 2 * dx > imageRect.width()) {
        dx = (imageRect.width() - r.width()) / 2F;
        if (maintainAspectRatio) {
            dy = dx / initialAspectRatio;
        }
    }
    if (dy > 0F && r.height() + 2 * dy > imageRect.height()) {
        dy = (imageRect.height() - r.height()) / 2F;
        if (maintainAspectRatio) {
            dx = dy * initialAspectRatio;
        }
    }

    r.inset(-dx, -dy);

    // Don't let the cropping rectangle shrink too fast
    final float widthCap = 25F;
    if (r.width() < widthCap) {
        r.inset(-(widthCap - r.width()) / 2F, 0F);
    }
    float heightCap = maintainAspectRatio
            ? (widthCap / initialAspectRatio)
            : widthCap;
    if (r.height() < heightCap) {
        r.inset(0F, -(heightCap - r.height()) / 2F);
    }

    // Put the cropping rectangle inside the image rectangle
    if (r.left < imageRect.left) {
        r.offset(imageRect.left - r.left, 0F);
    } else if (r.right > imageRect.right) {
        r.offset(-(r.right - imageRect.right), 0F);
    }
    if (r.top < imageRect.top) {
        r.offset(0F, imageRect.top - r.top);
    } else if (r.bottom > imageRect.bottom) {
        r.offset(0F, -(r.bottom - imageRect.bottom));
    }

    cropRect.set(r);
    drawRect = computeLayout();
    viewContext.invalidate();
}
 
源代码18 项目: giffun   文件: CropOverlayView.java
/** Draw the corner of crop overlay. */
private void drawCorners(Canvas canvas) {
  if (mBorderCornerPaint != null) {

    float lineWidth = mBorderPaint != null ? mBorderPaint.getStrokeWidth() : 0;
    float cornerWidth = mBorderCornerPaint.getStrokeWidth();

    // for rectangle crop shape we allow the corners to be offset from the borders
    float w =
        cornerWidth / 2
            + (mCropShape == CropImageView.CropShape.RECTANGLE ? mBorderCornerOffset : 0);

    RectF rect = mCropWindowHandler.getRect();
    rect.inset(w, w);

    float cornerOffset = (cornerWidth - lineWidth) / 2;
    float cornerExtension = cornerWidth / 2 + cornerOffset;

    // Top left
    canvas.drawLine(
        rect.left - cornerOffset,
        rect.top - cornerExtension,
        rect.left - cornerOffset,
        rect.top + mBorderCornerLength,
        mBorderCornerPaint);
    canvas.drawLine(
        rect.left - cornerExtension,
        rect.top - cornerOffset,
        rect.left + mBorderCornerLength,
        rect.top - cornerOffset,
        mBorderCornerPaint);

    // Top right
    canvas.drawLine(
        rect.right + cornerOffset,
        rect.top - cornerExtension,
        rect.right + cornerOffset,
        rect.top + mBorderCornerLength,
        mBorderCornerPaint);
    canvas.drawLine(
        rect.right + cornerExtension,
        rect.top - cornerOffset,
        rect.right - mBorderCornerLength,
        rect.top - cornerOffset,
        mBorderCornerPaint);

    // Bottom left
    canvas.drawLine(
        rect.left - cornerOffset,
        rect.bottom + cornerExtension,
        rect.left - cornerOffset,
        rect.bottom - mBorderCornerLength,
        mBorderCornerPaint);
    canvas.drawLine(
        rect.left - cornerExtension,
        rect.bottom + cornerOffset,
        rect.left + mBorderCornerLength,
        rect.bottom + cornerOffset,
        mBorderCornerPaint);

    // Bottom left
    canvas.drawLine(
        rect.right + cornerOffset,
        rect.bottom + cornerExtension,
        rect.right + cornerOffset,
        rect.bottom - mBorderCornerLength,
        mBorderCornerPaint);
    canvas.drawLine(
        rect.right + cornerExtension,
        rect.bottom + cornerOffset,
        rect.right - mBorderCornerLength,
        rect.bottom + cornerOffset,
        mBorderCornerPaint);
  }
}
 
源代码19 项目: XERUNG   文件: HighlightView.java
void growBy(float dx, float dy) {
    if (maintainAspectRatio) {
        if (dx != 0) {
            dy = dx / initialAspectRatio;
        } else if (dy != 0) {
            dx = dy * initialAspectRatio;
        }
    }

    // Don't let the cropping rectangle grow too fast.
    // Grow at most half of the difference between the image rectangle and
    // the cropping rectangle.
    RectF r = new RectF(cropRect);
    if (dx > 0F && r.width() + 2 * dx > imageRect.width()) {
        dx = (imageRect.width() - r.width()) / 2F;
        if (maintainAspectRatio) {
            dy = dx / initialAspectRatio;
        }
    }
    if (dy > 0F && r.height() + 2 * dy > imageRect.height()) {
        dy = (imageRect.height() - r.height()) / 2F;
        if (maintainAspectRatio) {
            dx = dy * initialAspectRatio;
        }
    }

    r.inset(-dx, -dy);

    // Don't let the cropping rectangle shrink too fast
    final float widthCap = 25F;
    if (r.width() < widthCap) {
        r.inset(-(widthCap - r.width()) / 2F, 0F);
    }
    float heightCap = maintainAspectRatio
            ? (widthCap / initialAspectRatio)
            : widthCap;
    if (r.height() < heightCap) {
        r.inset(0F, -(heightCap - r.height()) / 2F);
    }

    // Put the cropping rectangle inside the image rectangle
    if (r.left < imageRect.left) {
        r.offset(imageRect.left - r.left, 0F);
    } else if (r.right > imageRect.right) {
        r.offset(-(r.right - imageRect.right), 0F);
    }
    if (r.top < imageRect.top) {
        r.offset(0F, imageRect.top - r.top);
    } else if (r.bottom > imageRect.bottom) {
        r.offset(0F, -(r.bottom - imageRect.bottom));
    }

    cropRect.set(r);
    drawRect = computeLayout();
    viewContext.invalidate();
}
 
/**
 * Draws a corner shadow on the canvas in the current bounds with the matrix transform applied.
 */
public void drawCornerShadow(
    @NonNull Canvas canvas,
    @Nullable Matrix matrix,
    @NonNull RectF bounds,
    int elevation,
    float startAngle,
    float sweepAngle) {

  boolean drawShadowInsideBounds = sweepAngle < 0;

  Path arcBounds = scratch;

  if (drawShadowInsideBounds) {
    cornerColors[0] = 0;
    cornerColors[1] = shadowEndColor;
    cornerColors[2] = shadowMiddleColor;
    cornerColors[3] = shadowStartColor;
  } else {
    // Calculate the arc bounds to prevent drawing shadow in the same part of the arc.
    arcBounds.rewind();
    arcBounds.moveTo(bounds.centerX(), bounds.centerY());
    arcBounds.arcTo(bounds, startAngle, sweepAngle);
    arcBounds.close();

    bounds.inset(-elevation, -elevation);
    cornerColors[0] = 0;
    cornerColors[1] = shadowStartColor;
    cornerColors[2] = shadowMiddleColor;
    cornerColors[3] = shadowEndColor;
  }

  float startRatio = 1f - (elevation / (bounds.width() / 2f));
  float midRatio = startRatio + ((1f - startRatio) / 2f);
  cornerPositions[1] = startRatio;
  cornerPositions[2] = midRatio;

  cornerShadowPaint.setShader(
      new RadialGradient(
          bounds.centerX(),
          bounds.centerY(),
          bounds.width() / 2,
          cornerColors,
          cornerPositions,
          Shader.TileMode.CLAMP));

  // TODO(b/117606382): handle oval bounds by scaling the canvas.
  canvas.save();
  canvas.concat(matrix);

  if (!drawShadowInsideBounds) {
    canvas.clipPath(arcBounds, Op.DIFFERENCE);
    // This line is required for the next drawArc to work correctly, I think.
    canvas.drawPath(arcBounds, transparentPaint);
  }

  canvas.drawArc(bounds, startAngle, sweepAngle, true, cornerShadowPaint);
  canvas.restore();
}