Home | History | Annotate | Download | only in bitmap
      1 package com.bumptech.glide.load.resource.bitmap;
      2 
      3 import android.content.res.Resources;
      4 import android.graphics.Bitmap;
      5 import android.graphics.Canvas;
      6 import android.graphics.ColorFilter;
      7 import android.graphics.Paint;
      8 import android.graphics.PixelFormat;
      9 import android.graphics.Rect;
     10 import android.graphics.drawable.Drawable;
     11 import android.util.DisplayMetrics;
     12 import android.view.Gravity;
     13 
     14 import 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  */
     19 public 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