AlbumLabelMaker.java revision cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1
1// Copyright 2012 Google Inc. All Rights Reserved. 2 3package com.android.gallery3d.ui; 4 5import android.content.Context; 6import android.graphics.Bitmap; 7import android.graphics.Bitmap.Config; 8import android.graphics.BitmapFactory; 9import android.graphics.Canvas; 10import android.graphics.Color; 11import android.graphics.PorterDuff; 12import android.graphics.Typeface; 13import android.text.TextPaint; 14import android.text.TextUtils; 15 16import com.android.gallery3d.R; 17import com.android.gallery3d.common.Utils; 18import com.android.gallery3d.data.DataSourceType; 19import com.android.gallery3d.data.MediaSet; 20import com.android.gallery3d.util.ThreadPool; 21import com.android.gallery3d.util.ThreadPool.JobContext; 22 23public class AlbumLabelMaker { 24 private static final int FONT_COLOR_TITLE = Color.WHITE; 25 private static final int FONT_COLOR_COUNT = 0x80FFFFFF; // 50% white 26 27 // We keep a border around the album label to prevent aliasing 28 private static final int BORDER_SIZE = 1; 29 private static final int BACKGROUND_COLOR = 0x60000000; // 36% Dark 30 31 private final AlbumSetView.LabelSpec mSpec; 32 private final TextPaint mTitlePaint; 33 private final TextPaint mCountPaint; 34 private final Context mContext; 35 36 private int mLabelWidth; 37 private BitmapPool mBitmapPool; 38 39 private final LazyLoadedBitmap mLocalSetIcon; 40 private final LazyLoadedBitmap mPicasaIcon; 41 private final LazyLoadedBitmap mCameraIcon; 42 private final LazyLoadedBitmap mMtpIcon; 43 44 public AlbumLabelMaker(Context context, AlbumSetView.LabelSpec spec) { 45 mContext = context; 46 mSpec = spec; 47 mTitlePaint = getTextPaint(spec.titleFontSize, FONT_COLOR_TITLE, false); 48 mCountPaint = getTextPaint(spec.countFontSize, FONT_COLOR_COUNT, true); 49 50 mLocalSetIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_folder); 51 mPicasaIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_picasa); 52 mCameraIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_camera); 53 mMtpIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_ptp); 54 } 55 56 public static int getBorderSize() { 57 return BORDER_SIZE; 58 } 59 60 private Bitmap getOverlayAlbumIcon(int sourceType) { 61 switch (sourceType) { 62 case DataSourceType.TYPE_CAMERA: 63 return mCameraIcon.get(); 64 case DataSourceType.TYPE_LOCAL: 65 return mLocalSetIcon.get(); 66 case DataSourceType.TYPE_MTP: 67 return mMtpIcon.get(); 68 case DataSourceType.TYPE_PICASA: 69 return mPicasaIcon.get(); 70 } 71 return null; 72 } 73 74 private static TextPaint getTextPaint(int textSize, int color, boolean isBold) { 75 TextPaint paint = new TextPaint(); 76 paint.setTextSize(textSize); 77 paint.setAntiAlias(true); 78 paint.setColor(color); 79 paint.setShadowLayer(2f, 0f, 0f, Color.BLACK); 80 if (isBold) { 81 paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD)); 82 } 83 return paint; 84 } 85 86 private class LazyLoadedBitmap { 87 private Bitmap mBitmap; 88 private int mResId; 89 90 public LazyLoadedBitmap(int resId) { 91 mResId = resId; 92 } 93 94 public synchronized Bitmap get() { 95 if (mBitmap == null) { 96 BitmapFactory.Options options = new BitmapFactory.Options(); 97 options.inPreferredConfig = Bitmap.Config.ARGB_8888; 98 mBitmap = BitmapFactory.decodeResource( 99 mContext.getResources(), mResId, options); 100 } 101 return mBitmap; 102 } 103 } 104 105 public synchronized void setLabelWidth(int width) { 106 if (mLabelWidth == width) return; 107 mLabelWidth = width; 108 int borders = 2 * BORDER_SIZE; 109 mBitmapPool = new BitmapPool( 110 width + borders, mSpec.labelBackgroundHeight + borders); 111 } 112 113 public ThreadPool.Job<Bitmap> requestLabel( 114 String title, String count, int sourceType) { 115 return new AlbumLabelJob(null, title, count, sourceType); 116 } 117 118 public ThreadPool.Job<Bitmap> requestLabel( 119 MediaSet album, int sourceType) { 120 return new AlbumLabelJob(album, null, null, sourceType); 121 } 122 123 private static void drawText(Canvas canvas, 124 int x, int y, String text, int lengthLimit, TextPaint p) { 125 // The TextPaint cannot be used concurrently 126 synchronized (p) { 127 text = TextUtils.ellipsize( 128 text, p, lengthLimit, TextUtils.TruncateAt.END).toString(); 129 canvas.drawText(text, x, y - p.getFontMetricsInt().ascent, p); 130 } 131 } 132 133 private class AlbumLabelJob implements ThreadPool.Job<Bitmap> { 134 private final MediaSet mAlbum; 135 private final String mTitle; 136 private final String mCount; 137 private final int mSourceType; 138 139 public AlbumLabelJob(MediaSet album, 140 String title, String count, int sourceType) { 141 mAlbum = album; 142 mTitle = title; 143 mCount = count; 144 mSourceType = sourceType; 145 } 146 147 @Override 148 public Bitmap run(JobContext jc) { 149 MediaSet album = mAlbum; 150 AlbumSetView.LabelSpec s = mSpec; 151 152 String title = Utils.ensureNotNull( 153 (album == null) ? mTitle : album.getName()); 154 String count = album == null 155 ? Utils.ensureNotNull(mCount) 156 : String.valueOf(album.getTotalMediaItemCount()); 157 Bitmap icon = getOverlayAlbumIcon(mSourceType); 158 159 Bitmap bitmap; 160 int labelWidth; 161 162 synchronized (this) { 163 labelWidth = mLabelWidth; 164 bitmap = mBitmapPool.getBitmap(); 165 } 166 167 if (bitmap == null) { 168 int borders = 2 * BORDER_SIZE; 169 bitmap = Bitmap.createBitmap(labelWidth + borders, 170 s.labelBackgroundHeight + borders, Config.ARGB_8888); 171 } 172 173 Canvas canvas = new Canvas(bitmap); 174 canvas.clipRect(BORDER_SIZE, BORDER_SIZE, 175 bitmap.getWidth() - BORDER_SIZE, 176 bitmap.getHeight() - BORDER_SIZE); 177 canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC); 178 179 canvas.translate(BORDER_SIZE, BORDER_SIZE); 180 181 // draw title 182 if (jc.isCancelled()) return null; 183 int x = s.leftMargin; 184 int y = s.titleOffset; 185 drawText(canvas, x, y, title, labelWidth - s.leftMargin, mTitlePaint); 186 187 // draw the count 188 if (jc.isCancelled()) return null; 189 if (icon != null) x = s.iconSize; 190 y += s.titleFontSize + s.countOffset; 191 drawText(canvas, x, y, count, 192 labelWidth - s.leftMargin - s.iconSize, mCountPaint); 193 194 // draw the icon 195 if (icon != null) { 196 if (jc.isCancelled()) return null; 197 float scale = (float) s.iconSize / icon.getWidth(); 198 canvas.translate(0, bitmap.getHeight() 199 - Math.round(scale * icon.getHeight())); 200 canvas.scale(scale, scale); 201 canvas.drawBitmap(icon, 0, 0, null); 202 } 203 204 return bitmap; 205 } 206 } 207 208 public void reycleLabel(Bitmap label) { 209 mBitmapPool.recycle(label); 210 } 211 212 public void clearRecycledLabels() { 213 mBitmapPool.clear(); 214 } 215} 216