2 * Copyright (C) 2013 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.photos.shims;
19 import android.graphics.Bitmap;
20 import android.graphics.Canvas;
21 import android.graphics.ColorFilter;
22 import android.graphics.Matrix;
23 import android.graphics.Paint;
24 import android.graphics.PixelFormat;
25 import android.graphics.Rect;
26 import android.graphics.drawable.Drawable;
28 import com.android.gallery3d.data.MediaItem;
29 import com.android.gallery3d.ui.BitmapLoader;
30 import com.android.gallery3d.util.Future;
31 import com.android.gallery3d.util.FutureListener;
32 import com.android.gallery3d.util.ThreadPool;
33 import com.android.photos.data.GalleryBitmapPool;
36 public class BitmapJobDrawable extends Drawable implements Runnable {
38 private ThumbnailLoader mLoader;
39 private MediaItem mItem;
40 private Bitmap mBitmap;
41 private Paint mPaint = new Paint();
42 private Matrix mDrawMatrix = new Matrix();
43 private int mRotation = 0;
45 public BitmapJobDrawable() {
48 public void setMediaItem(MediaItem item) {
49 if (mItem == item) return;
51 if (mLoader != null) {
55 if (mBitmap != null) {
56 GalleryBitmapPool.getInstance().put(mBitmap);
60 // TODO: Figure out why ThumbnailLoader doesn't like to be re-used
61 mLoader = new ThumbnailLoader(this);
63 mRotation = mItem.getRotation();
70 Bitmap bitmap = mLoader.getBitmap();
78 protected void onBoundsChange(Rect bounds) {
79 super.onBoundsChange(bounds);
84 public void draw(Canvas canvas) {
85 Rect bounds = getBounds();
86 if (mBitmap != null) {
88 canvas.clipRect(bounds);
89 canvas.concat(mDrawMatrix);
90 canvas.rotate(mRotation, bounds.centerX(), bounds.centerY());
91 canvas.drawBitmap(mBitmap, 0, 0, mPaint);
94 mPaint.setColor(0xFFCCCCCC);
95 canvas.drawRect(bounds, mPaint);
99 private void updateDrawMatrix() {
100 Rect bounds = getBounds();
101 if (mBitmap == null || bounds.isEmpty()) {
107 float dx = 0, dy = 0;
109 int dwidth = mBitmap.getWidth();
110 int dheight = mBitmap.getHeight();
111 int vwidth = bounds.width();
112 int vheight = bounds.height();
114 // Calculates a matrix similar to ScaleType.CENTER_CROP
115 if (dwidth * vheight > vwidth * dheight) {
116 scale = (float) vheight / (float) dheight;
117 dx = (vwidth - dwidth * scale) * 0.5f;
119 scale = (float) vwidth / (float) dwidth;
120 dy = (vheight - dheight * scale) * 0.5f;
123 mDrawMatrix.setScale(scale, scale);
124 mDrawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
129 public int getIntrinsicWidth() {
130 return MediaItem.getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL);
134 public int getIntrinsicHeight() {
135 return MediaItem.getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL);
139 public int getOpacity() {
141 return (bm == null || bm.hasAlpha() || mPaint.getAlpha() < 255) ?
142 PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
146 public void setAlpha(int alpha) {
147 int oldAlpha = mPaint.getAlpha();
148 if (alpha != oldAlpha) {
149 mPaint.setAlpha(alpha);
155 public void setColorFilter(ColorFilter cf) {
156 mPaint.setColorFilter(cf);
160 private static class ThumbnailLoader extends BitmapLoader {
161 private static final ThreadPool sThreadPool = new ThreadPool(0, 2);
162 private BitmapJobDrawable mParent;
164 public ThumbnailLoader(BitmapJobDrawable parent) {
169 protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l) {
170 return sThreadPool.submit(
171 mParent.mItem.requestImage(MediaItem.TYPE_MICROTHUMBNAIL), this);
175 protected void onLoadComplete(Bitmap bitmap) {
176 mParent.scheduleSelf(mParent, 0);