2 * Copyright (C) 2012 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.gallery3d.ui;
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Bitmap.Config;
22 import android.graphics.BitmapFactory;
23 import android.graphics.Canvas;
24 import android.graphics.PorterDuff;
25 import android.graphics.Typeface;
26 import android.text.TextPaint;
27 import android.text.TextUtils;
29 import com.android.gallery3d.R;
30 import com.android.gallery3d.data.DataSourceType;
31 import com.android.photos.data.GalleryBitmapPool;
32 import com.android.gallery3d.util.ThreadPool;
33 import com.android.gallery3d.util.ThreadPool.JobContext;
35 public class AlbumLabelMaker {
36 private static final int BORDER_SIZE = 0;
38 private final AlbumSetSlotRenderer.LabelSpec mSpec;
39 private final TextPaint mTitlePaint;
40 private final TextPaint mCountPaint;
41 private final Context mContext;
43 private int mLabelWidth;
44 private int mBitmapWidth;
45 private int mBitmapHeight;
47 private final LazyLoadedBitmap mLocalSetIcon;
48 private final LazyLoadedBitmap mPicasaIcon;
49 private final LazyLoadedBitmap mCameraIcon;
51 public AlbumLabelMaker(Context context, AlbumSetSlotRenderer.LabelSpec spec) {
54 mTitlePaint = getTextPaint(spec.titleFontSize, spec.titleColor, false);
55 mCountPaint = getTextPaint(spec.countFontSize, spec.countColor, false);
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);
62 public static int getBorderSize() {
66 private Bitmap getOverlayAlbumIcon(int sourceType) {
68 case DataSourceType.TYPE_CAMERA:
69 return mCameraIcon.get();
70 case DataSourceType.TYPE_LOCAL:
71 return mLocalSetIcon.get();
72 case DataSourceType.TYPE_PICASA:
73 return mPicasaIcon.get();
78 private static TextPaint getTextPaint(int textSize, int color, boolean isBold) {
79 TextPaint paint = new TextPaint();
80 paint.setTextSize(textSize);
81 paint.setAntiAlias(true);
82 paint.setColor(color);
83 //paint.setShadowLayer(2f, 0f, 0f, Color.LTGRAY);
85 paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
90 private class LazyLoadedBitmap {
91 private Bitmap mBitmap;
94 public LazyLoadedBitmap(int resId) {
98 public synchronized Bitmap get() {
99 if (mBitmap == null) {
100 BitmapFactory.Options options = new BitmapFactory.Options();
101 options.inPreferredConfig = Bitmap.Config.ARGB_8888;
102 mBitmap = BitmapFactory.decodeResource(
103 mContext.getResources(), mResId, options);
109 public synchronized void setLabelWidth(int width) {
110 if (mLabelWidth == width) return;
112 int borders = 2 * BORDER_SIZE;
113 mBitmapWidth = width + borders;
114 mBitmapHeight = mSpec.labelBackgroundHeight + borders;
117 public ThreadPool.Job<Bitmap> requestLabel(
118 String title, String count, int sourceType) {
119 return new AlbumLabelJob(title, count, sourceType);
122 static void drawText(Canvas canvas,
123 int x, int y, String text, int lengthLimit, TextPaint p) {
124 // The TextPaint cannot be used concurrently
126 text = TextUtils.ellipsize(
127 text, p, lengthLimit, TextUtils.TruncateAt.END).toString();
128 canvas.drawText(text, x, y - p.getFontMetricsInt().ascent, p);
132 private class AlbumLabelJob implements ThreadPool.Job<Bitmap> {
133 private final String mTitle;
134 private final String mCount;
135 private final int mSourceType;
137 public AlbumLabelJob(String title, String count, int sourceType) {
140 mSourceType = sourceType;
144 public Bitmap run(JobContext jc) {
145 AlbumSetSlotRenderer.LabelSpec s = mSpec;
147 String title = mTitle;
148 String count = mCount;
149 Bitmap icon = getOverlayAlbumIcon(mSourceType);
154 synchronized (this) {
155 labelWidth = mLabelWidth;
156 bitmap = GalleryBitmapPool.getInstance().get(mBitmapWidth, mBitmapHeight);
159 if (bitmap == null) {
160 int borders = 2 * BORDER_SIZE;
161 bitmap = Bitmap.createBitmap(labelWidth + borders,
162 s.labelBackgroundHeight + borders, Config.ARGB_8888);
165 Canvas canvas = new Canvas(bitmap);
166 canvas.clipRect(BORDER_SIZE, BORDER_SIZE,
167 bitmap.getWidth() - BORDER_SIZE,
168 bitmap.getHeight() - BORDER_SIZE);
169 canvas.drawColor(mSpec.backgroundColor, PorterDuff.Mode.SRC);
171 canvas.translate(BORDER_SIZE, BORDER_SIZE);
174 if (jc.isCancelled()) return null;
175 int x = s.leftMargin + s.iconSize;
176 // TODO: is the offset relevant in new reskin?
177 // int y = s.titleOffset;
178 int y = (s.labelBackgroundHeight - s.titleFontSize) / 2;
179 drawText(canvas, x, y, title, labelWidth - s.leftMargin - x -
180 s.titleRightMargin, mTitlePaint);
183 if (jc.isCancelled()) return null;
184 x = labelWidth - s.titleRightMargin;
185 y = (s.labelBackgroundHeight - s.countFontSize) / 2;
186 drawText(canvas, x, y, count,
187 labelWidth - x , mCountPaint);
191 if (jc.isCancelled()) return null;
192 float scale = (float) s.iconSize / icon.getWidth();
193 canvas.translate(s.leftMargin, (s.labelBackgroundHeight -
194 Math.round(scale * icon.getHeight()))/2f);
195 canvas.scale(scale, scale);
196 canvas.drawBitmap(icon, 0, 0, null);
203 public void recycleLabel(Bitmap label) {
204 GalleryBitmapPool.getInstance().put(label);