13e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddpackage com.bumptech.glide.load.resource.bitmap;
23e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
33e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.content.res.Resources;
43e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.graphics.Bitmap;
53e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.graphics.Canvas;
63e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.graphics.ColorFilter;
73e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.graphics.Paint;
83e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.graphics.PixelFormat;
93e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.graphics.Rect;
103e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.graphics.drawable.Drawable;
113e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.util.DisplayMetrics;
123e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport android.view.Gravity;
133e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
143e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddimport com.bumptech.glide.load.resource.drawable.GlideDrawable;
153e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
163e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd/**
173e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd * A static {@link com.bumptech.glide.load.resource.drawable.GlideDrawable} for displaying a single image.
183e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd */
193e519104d688b295f6b1b46d1cc78695a36654a7Sam Juddpublic class GlideBitmapDrawable extends GlideDrawable {
203e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    private final Rect destRect = new Rect();
213e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    private int width;
223e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    private int height;
233e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    private boolean applyGravity;
24787279ab3e72c83626e65382a1dbd97f45e6cbd3Sam Judd    private boolean mutated;
253e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    private BitmapState state;
263e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
273e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public GlideBitmapDrawable(Resources res, Bitmap bitmap) {
283e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        this(res, new BitmapState(bitmap));
293e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
303e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
313e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    GlideBitmapDrawable(Resources res, BitmapState state) {
3272e189cc27d62677a7e45dc5ddfcf4cc0d6466abSam Judd        if (state == null) {
3372e189cc27d62677a7e45dc5ddfcf4cc0d6466abSam Judd            throw new NullPointerException("BitmapState must not be null");
3472e189cc27d62677a7e45dc5ddfcf4cc0d6466abSam Judd        }
3572e189cc27d62677a7e45dc5ddfcf4cc0d6466abSam Judd
363e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        this.state = state;
373e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        final int targetDensity;
383e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        if (res != null) {
393e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            final int density = res.getDisplayMetrics().densityDpi;
403e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            targetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
413e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            state.targetDensity = targetDensity;
423e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        } else {
433e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            targetDensity = state.targetDensity;
443e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
453e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        width = state.bitmap.getScaledWidth(targetDensity);
463e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        height = state.bitmap.getScaledHeight(targetDensity);
473e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
483e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
493e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
503e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public int getIntrinsicWidth() {
513e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        return width;
523e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
533e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
543e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
553e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public int getIntrinsicHeight() {
563e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        return height;
573e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
583e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
593e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
603e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public boolean isAnimated() {
613e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        return false;
623e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
633e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
643e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
653e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public void setLoopCount(int loopCount) {
663e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        // Do nothing.
673e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
683e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
693e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
703e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public void start() {
713e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        // Do nothing.
723e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
733e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
743e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
753e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public void stop() {
763e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        // Do nothing.
773e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
783e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
793e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
803e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public boolean isRunning() {
813e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        return false;
823e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
833e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
843e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
853e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    protected void onBoundsChange(Rect bounds) {
863e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        super.onBoundsChange(bounds);
873e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        applyGravity = true;
883e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
893e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
903e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
913e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public ConstantState getConstantState() {
923e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        return state;
933e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
943e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
953e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
963e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public void draw(Canvas canvas) {
973e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        if (applyGravity) {
983e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            Gravity.apply(BitmapState.GRAVITY, width, height, getBounds(), destRect);
993e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            applyGravity = false;
1003e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1013e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        canvas.drawBitmap(state.bitmap, null, destRect, state.paint);
1023e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
1033e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1043e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
1053e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public void setAlpha(int alpha) {
1063e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        int currentAlpha = state.paint.getAlpha();
1073e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        if (currentAlpha != alpha) {
1083e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            state.setAlpha(alpha);
1093e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            invalidateSelf();
1103e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1113e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
1123e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1133e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
1143e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public void setColorFilter(ColorFilter colorFilter) {
1153e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        state.setColorFilter(colorFilter);
1163e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        invalidateSelf();
1173e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
1183e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1193e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
1203e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public int getOpacity() {
1213e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        Bitmap bm = state.bitmap;
1225ba19a0e69ad3a651b8f13ba45de48a56b56ce36Sam Judd        return bm == null || bm.hasAlpha() || state.paint.getAlpha() < 255
1233e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd                ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
1243e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
1253e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1263e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    @Override
1273e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public Drawable mutate() {
128787279ab3e72c83626e65382a1dbd97f45e6cbd3Sam Judd        if (!mutated && super.mutate() == this) {
129787279ab3e72c83626e65382a1dbd97f45e6cbd3Sam Judd            state = new BitmapState(state);
130787279ab3e72c83626e65382a1dbd97f45e6cbd3Sam Judd            mutated = true;
131787279ab3e72c83626e65382a1dbd97f45e6cbd3Sam Judd        }
132787279ab3e72c83626e65382a1dbd97f45e6cbd3Sam Judd        return this;
1333e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
1343e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1353e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    public Bitmap getBitmap() {
1363e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        return state.bitmap;
1373e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
1383e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1393e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    static class BitmapState extends ConstantState {
1403e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        private static final int DEFAULT_PAINT_FLAGS = Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG;
1413e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        private static final Paint DEFAULT_PAINT = new Paint(DEFAULT_PAINT_FLAGS);
1423e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        private static final int GRAVITY = Gravity.FILL;
1433e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1443e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        final Bitmap bitmap;
1453e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1463e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        int targetDensity;
1473e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        Paint paint = DEFAULT_PAINT;
1483e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1493e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        public BitmapState(Bitmap bitmap) {
1503e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            this.bitmap = bitmap;
1513e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1523e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1533e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1543e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        BitmapState(BitmapState other) {
1553e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            this(other.bitmap);
1563e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            targetDensity = other.targetDensity;
1573e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1583e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1593e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        void setColorFilter(ColorFilter colorFilter) {
1603e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            mutatePaint();
1613e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            paint.setColorFilter(colorFilter);
1623e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1633e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1643e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        void setAlpha(int alpha) {
1653e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            mutatePaint();
1663e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            paint.setAlpha(alpha);
1673e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1683e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1695ba19a0e69ad3a651b8f13ba45de48a56b56ce36Sam Judd        // We want to create a new Paint object so we can mutate it safely.
1705ba19a0e69ad3a651b8f13ba45de48a56b56ce36Sam Judd        @SuppressWarnings("PMD.CompareObjectsWithEquals")
1713e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        void mutatePaint() {
1725ba19a0e69ad3a651b8f13ba45de48a56b56ce36Sam Judd            if (DEFAULT_PAINT == paint) {
1733e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd                paint = new Paint(DEFAULT_PAINT_FLAGS);
1743e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            }
1753e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1763e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1773e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        @Override
1783e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        public Drawable newDrawable() {
1793e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            return new GlideBitmapDrawable(null, this);
1803e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1813e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1823e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        @Override
1833e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        public Drawable newDrawable(Resources res) {
1843e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            return new GlideBitmapDrawable(res, this);
1853e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1863e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd
1873e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        @Override
1883e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        public int getChangingConfigurations() {
1893e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd            return 0;
1903e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd        }
1913e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd    }
1923e519104d688b295f6b1b46d1cc78695a36654a7Sam Judd}
193