下面列出了android.graphics.RectF#inset ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 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);
}
}
/**
* 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);
}
}
/**
* @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);
}
}
/**
* 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);
}
}
/**
* 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);
}
}
@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);
}
/**
* 转为圆形图片
*
* @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;
}
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);
}
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);
}
}
/** 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);
}
}
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();
}
/** 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);
}
}
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();
}