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