259 lines
8.0 KiB
Java
259 lines
8.0 KiB
Java
package androidx.core.graphics.drawable;
|
|
|
|
import android.content.res.Resources;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.BitmapShader;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.ColorFilter;
|
|
import android.graphics.Matrix;
|
|
import android.graphics.Paint;
|
|
import android.graphics.Rect;
|
|
import android.graphics.RectF;
|
|
import android.graphics.Shader;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.util.DisplayMetrics;
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
public abstract class RoundedBitmapDrawable extends Drawable {
|
|
private static final int DEFAULT_PAINT_FLAGS = 3;
|
|
private boolean mApplyGravity = true;
|
|
public final Bitmap mBitmap;
|
|
private int mBitmapHeight;
|
|
private final BitmapShader mBitmapShader;
|
|
private int mBitmapWidth;
|
|
private float mCornerRadius;
|
|
public final Rect mDstRect = new Rect();
|
|
private final RectF mDstRectF = new RectF();
|
|
private int mGravity = 119;
|
|
private boolean mIsCircular;
|
|
private final Paint mPaint = new Paint(3);
|
|
private final Matrix mShaderMatrix = new Matrix();
|
|
private int mTargetDensity = 160;
|
|
|
|
public RoundedBitmapDrawable(Resources resources, Bitmap bitmap) {
|
|
if (resources != null) {
|
|
this.mTargetDensity = resources.getDisplayMetrics().densityDpi;
|
|
}
|
|
this.mBitmap = bitmap;
|
|
if (bitmap != null) {
|
|
computeBitmapSize();
|
|
Shader.TileMode tileMode = Shader.TileMode.CLAMP;
|
|
this.mBitmapShader = new BitmapShader(bitmap, tileMode, tileMode);
|
|
return;
|
|
}
|
|
this.mBitmapHeight = -1;
|
|
this.mBitmapWidth = -1;
|
|
this.mBitmapShader = null;
|
|
}
|
|
|
|
private void computeBitmapSize() {
|
|
this.mBitmapWidth = this.mBitmap.getScaledWidth(this.mTargetDensity);
|
|
this.mBitmapHeight = this.mBitmap.getScaledHeight(this.mTargetDensity);
|
|
}
|
|
|
|
private static boolean isGreaterThanZero(float f) {
|
|
return f > 0.05f;
|
|
}
|
|
|
|
private void updateCircularCornerRadius() {
|
|
this.mCornerRadius = (float) (Math.min(this.mBitmapHeight, this.mBitmapWidth) / 2);
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public void draw(@NonNull Canvas canvas) {
|
|
Bitmap bitmap = this.mBitmap;
|
|
if (bitmap != null) {
|
|
updateDstRect();
|
|
if (this.mPaint.getShader() == null) {
|
|
canvas.drawBitmap(bitmap, (Rect) null, this.mDstRect, this.mPaint);
|
|
return;
|
|
}
|
|
RectF rectF = this.mDstRectF;
|
|
float f = this.mCornerRadius;
|
|
canvas.drawRoundRect(rectF, f, f, this.mPaint);
|
|
}
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public int getAlpha() {
|
|
return this.mPaint.getAlpha();
|
|
}
|
|
|
|
@Nullable
|
|
public final Bitmap getBitmap() {
|
|
return this.mBitmap;
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public ColorFilter getColorFilter() {
|
|
return this.mPaint.getColorFilter();
|
|
}
|
|
|
|
public float getCornerRadius() {
|
|
return this.mCornerRadius;
|
|
}
|
|
|
|
public int getGravity() {
|
|
return this.mGravity;
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public int getIntrinsicHeight() {
|
|
return this.mBitmapHeight;
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public int getIntrinsicWidth() {
|
|
return this.mBitmapWidth;
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public int getOpacity() {
|
|
Bitmap bitmap;
|
|
return (this.mGravity != 119 || this.mIsCircular || (bitmap = this.mBitmap) == null || bitmap.hasAlpha() || this.mPaint.getAlpha() < 255 || isGreaterThanZero(this.mCornerRadius)) ? -3 : -1;
|
|
}
|
|
|
|
@NonNull
|
|
public final Paint getPaint() {
|
|
return this.mPaint;
|
|
}
|
|
|
|
public void gravityCompatApply(int i, int i2, int i3, Rect rect, Rect rect2) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
public boolean hasAntiAlias() {
|
|
return this.mPaint.isAntiAlias();
|
|
}
|
|
|
|
public boolean hasMipMap() {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
public boolean isCircular() {
|
|
return this.mIsCircular;
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public void onBoundsChange(Rect rect) {
|
|
super.onBoundsChange(rect);
|
|
if (this.mIsCircular) {
|
|
updateCircularCornerRadius();
|
|
}
|
|
this.mApplyGravity = true;
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public void setAlpha(int i) {
|
|
if (i != this.mPaint.getAlpha()) {
|
|
this.mPaint.setAlpha(i);
|
|
invalidateSelf();
|
|
}
|
|
}
|
|
|
|
public void setAntiAlias(boolean z2) {
|
|
this.mPaint.setAntiAlias(z2);
|
|
invalidateSelf();
|
|
}
|
|
|
|
public void setCircular(boolean z2) {
|
|
this.mIsCircular = z2;
|
|
this.mApplyGravity = true;
|
|
if (z2) {
|
|
updateCircularCornerRadius();
|
|
this.mPaint.setShader(this.mBitmapShader);
|
|
invalidateSelf();
|
|
return;
|
|
}
|
|
setCornerRadius(0.0f);
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public void setColorFilter(ColorFilter colorFilter) {
|
|
this.mPaint.setColorFilter(colorFilter);
|
|
invalidateSelf();
|
|
}
|
|
|
|
public void setCornerRadius(float f) {
|
|
if (this.mCornerRadius != f) {
|
|
this.mIsCircular = false;
|
|
if (isGreaterThanZero(f)) {
|
|
this.mPaint.setShader(this.mBitmapShader);
|
|
} else {
|
|
this.mPaint.setShader(null);
|
|
}
|
|
this.mCornerRadius = f;
|
|
invalidateSelf();
|
|
}
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public void setDither(boolean z2) {
|
|
this.mPaint.setDither(z2);
|
|
invalidateSelf();
|
|
}
|
|
|
|
@Override // android.graphics.drawable.Drawable
|
|
public void setFilterBitmap(boolean z2) {
|
|
this.mPaint.setFilterBitmap(z2);
|
|
invalidateSelf();
|
|
}
|
|
|
|
public void setGravity(int i) {
|
|
if (this.mGravity != i) {
|
|
this.mGravity = i;
|
|
this.mApplyGravity = true;
|
|
invalidateSelf();
|
|
}
|
|
}
|
|
|
|
public void setMipMap(boolean z2) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
public void setTargetDensity(int i) {
|
|
if (this.mTargetDensity != i) {
|
|
if (i == 0) {
|
|
i = 160;
|
|
}
|
|
this.mTargetDensity = i;
|
|
if (this.mBitmap != null) {
|
|
computeBitmapSize();
|
|
}
|
|
invalidateSelf();
|
|
}
|
|
}
|
|
|
|
public void setTargetDensity(@NonNull Canvas canvas) {
|
|
setTargetDensity(canvas.getDensity());
|
|
}
|
|
|
|
public void setTargetDensity(@NonNull DisplayMetrics displayMetrics) {
|
|
setTargetDensity(displayMetrics.densityDpi);
|
|
}
|
|
|
|
public void updateDstRect() {
|
|
if (this.mApplyGravity) {
|
|
if (this.mIsCircular) {
|
|
int min = Math.min(this.mBitmapWidth, this.mBitmapHeight);
|
|
gravityCompatApply(this.mGravity, min, min, getBounds(), this.mDstRect);
|
|
int min2 = Math.min(this.mDstRect.width(), this.mDstRect.height());
|
|
this.mDstRect.inset(Math.max(0, (this.mDstRect.width() - min2) / 2), Math.max(0, (this.mDstRect.height() - min2) / 2));
|
|
this.mCornerRadius = ((float) min2) * 0.5f;
|
|
} else {
|
|
gravityCompatApply(this.mGravity, this.mBitmapWidth, this.mBitmapHeight, getBounds(), this.mDstRect);
|
|
}
|
|
this.mDstRectF.set(this.mDstRect);
|
|
if (this.mBitmapShader != null) {
|
|
Matrix matrix = this.mShaderMatrix;
|
|
RectF rectF = this.mDstRectF;
|
|
matrix.setTranslate(rectF.left, rectF.top);
|
|
this.mShaderMatrix.preScale(this.mDstRectF.width() / ((float) this.mBitmap.getWidth()), this.mDstRectF.height() / ((float) this.mBitmap.getHeight()));
|
|
this.mBitmapShader.setLocalMatrix(this.mShaderMatrix);
|
|
this.mPaint.setShader(this.mBitmapShader);
|
|
}
|
|
this.mApplyGravity = false;
|
|
}
|
|
}
|
|
}
|