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