1package com.bumptech.glide.load.resource.bitmap; 2 3import android.content.res.Resources; 4import android.graphics.Bitmap; 5import android.graphics.Canvas; 6import android.graphics.ColorFilter; 7import android.graphics.Paint; 8import android.graphics.PixelFormat; 9import android.graphics.Rect; 10import android.graphics.drawable.Drawable; 11import android.util.DisplayMetrics; 12import android.view.Gravity; 13 14import com.bumptech.glide.load.resource.drawable.GlideDrawable; 15 16/** 17 * A static {@link com.bumptech.glide.load.resource.drawable.GlideDrawable} for displaying a single image. 18 */ 19public class GlideBitmapDrawable extends GlideDrawable { 20 private final Rect destRect = new Rect(); 21 private int width; 22 private int height; 23 private boolean applyGravity; 24 private boolean mutated; 25 private BitmapState state; 26 27 public GlideBitmapDrawable(Resources res, Bitmap bitmap) { 28 this(res, new BitmapState(bitmap)); 29 } 30 31 GlideBitmapDrawable(Resources res, BitmapState state) { 32 if (state == null) { 33 throw new NullPointerException("BitmapState must not be null"); 34 } 35 36 this.state = state; 37 final int targetDensity; 38 if (res != null) { 39 final int density = res.getDisplayMetrics().densityDpi; 40 targetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density; 41 state.targetDensity = targetDensity; 42 } else { 43 targetDensity = state.targetDensity; 44 } 45 width = state.bitmap.getScaledWidth(targetDensity); 46 height = state.bitmap.getScaledHeight(targetDensity); 47 } 48 49 @Override 50 public int getIntrinsicWidth() { 51 return width; 52 } 53 54 @Override 55 public int getIntrinsicHeight() { 56 return height; 57 } 58 59 @Override 60 public boolean isAnimated() { 61 return false; 62 } 63 64 @Override 65 public void setLoopCount(int loopCount) { 66 // Do nothing. 67 } 68 69 @Override 70 public void start() { 71 // Do nothing. 72 } 73 74 @Override 75 public void stop() { 76 // Do nothing. 77 } 78 79 @Override 80 public boolean isRunning() { 81 return false; 82 } 83 84 @Override 85 protected void onBoundsChange(Rect bounds) { 86 super.onBoundsChange(bounds); 87 applyGravity = true; 88 } 89 90 @Override 91 public ConstantState getConstantState() { 92 return state; 93 } 94 95 @Override 96 public void draw(Canvas canvas) { 97 if (applyGravity) { 98 Gravity.apply(BitmapState.GRAVITY, width, height, getBounds(), destRect); 99 applyGravity = false; 100 } 101 canvas.drawBitmap(state.bitmap, null, destRect, state.paint); 102 } 103 104 @Override 105 public void setAlpha(int alpha) { 106 int currentAlpha = state.paint.getAlpha(); 107 if (currentAlpha != alpha) { 108 state.setAlpha(alpha); 109 invalidateSelf(); 110 } 111 } 112 113 @Override 114 public void setColorFilter(ColorFilter colorFilter) { 115 state.setColorFilter(colorFilter); 116 invalidateSelf(); 117 } 118 119 @Override 120 public int getOpacity() { 121 Bitmap bm = state.bitmap; 122 return bm == null || bm.hasAlpha() || state.paint.getAlpha() < 255 123 ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; 124 } 125 126 @Override 127 public Drawable mutate() { 128 if (!mutated && super.mutate() == this) { 129 state = new BitmapState(state); 130 mutated = true; 131 } 132 return this; 133 } 134 135 public Bitmap getBitmap() { 136 return state.bitmap; 137 } 138 139 static class BitmapState extends ConstantState { 140 private static final int DEFAULT_PAINT_FLAGS = Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG; 141 private static final Paint DEFAULT_PAINT = new Paint(DEFAULT_PAINT_FLAGS); 142 private static final int GRAVITY = Gravity.FILL; 143 144 final Bitmap bitmap; 145 146 int targetDensity; 147 Paint paint = DEFAULT_PAINT; 148 149 public BitmapState(Bitmap bitmap) { 150 this.bitmap = bitmap; 151 } 152 153 154 BitmapState(BitmapState other) { 155 this(other.bitmap); 156 targetDensity = other.targetDensity; 157 } 158 159 void setColorFilter(ColorFilter colorFilter) { 160 mutatePaint(); 161 paint.setColorFilter(colorFilter); 162 } 163 164 void setAlpha(int alpha) { 165 mutatePaint(); 166 paint.setAlpha(alpha); 167 } 168 169 // We want to create a new Paint object so we can mutate it safely. 170 @SuppressWarnings("PMD.CompareObjectsWithEquals") 171 void mutatePaint() { 172 if (DEFAULT_PAINT == paint) { 173 paint = new Paint(DEFAULT_PAINT_FLAGS); 174 } 175 } 176 177 @Override 178 public Drawable newDrawable() { 179 return new GlideBitmapDrawable(null, this); 180 } 181 182 @Override 183 public Drawable newDrawable(Resources res) { 184 return new GlideBitmapDrawable(res, this); 185 } 186 187 @Override 188 public int getChangingConfigurations() { 189 return 0; 190 } 191 } 192} 193