AlbumLabelMaker.java revision 1a4bd273afe5dd11592f7625c2f19853b6f174e9
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.Typeface;
12import android.text.TextPaint;
13import android.text.TextUtils;
14
15import com.android.gallery3d.R;
16import com.android.gallery3d.common.Utils;
17import com.android.gallery3d.data.MediaSet;
18import com.android.gallery3d.util.ThreadPool;
19import com.android.gallery3d.util.ThreadPool.JobContext;
20
21public class AlbumLabelMaker {
22    private static final int FONT_COLOR_TITLE = Color.WHITE;
23    private static final int FONT_COLOR_COUNT = 0x80FFFFFF;  // 50% white
24
25    private final AlbumSetView.LabelSpec mSpec;
26    private final TextPaint mTitlePaint;
27    private final TextPaint mCountPaint;
28    private final Context mContext;
29
30    private final LazyLoadedBitmap mLocalSetIcon;
31    private final LazyLoadedBitmap mPicasaIcon;
32    private final LazyLoadedBitmap mCameraIcon;
33    private final LazyLoadedBitmap mMtpIcon;
34
35    public AlbumLabelMaker(Context context, AlbumSetView.LabelSpec spec) {
36        mContext = context;
37        mSpec = spec;
38        mTitlePaint = getTextPaint(spec.titleFontSize, FONT_COLOR_TITLE, false);
39        mCountPaint = getTextPaint(spec.countFontSize, FONT_COLOR_COUNT, true);
40
41        mLocalSetIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_folder);
42        mPicasaIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_picasa);
43        mCameraIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_camera);
44        mMtpIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_ptp);
45    }
46
47    private Bitmap getOverlayAlbumIcon(int sourceType) {
48        switch (sourceType) {
49            case SelectionDrawer.DATASOURCE_TYPE_CAMERA:
50                return mCameraIcon.get();
51            case SelectionDrawer.DATASOURCE_TYPE_LOCAL:
52                return mLocalSetIcon.get();
53            case SelectionDrawer.DATASOURCE_TYPE_MTP:
54                return mMtpIcon.get();
55            case SelectionDrawer.DATASOURCE_TYPE_PICASA:
56                return mPicasaIcon.get();
57        }
58        return null;
59    }
60
61    private static TextPaint getTextPaint(int textSize, int color, boolean isBold) {
62        TextPaint paint = new TextPaint();
63        paint.setTextSize(textSize);
64        paint.setAntiAlias(true);
65        paint.setColor(color);
66        paint.setShadowLayer(2f, 0f, 0f, Color.BLACK);
67        if (isBold) {
68            paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
69        }
70        return paint;
71    }
72
73    private class LazyLoadedBitmap {
74        private Bitmap mBitmap;
75        private int mResId;
76
77        public LazyLoadedBitmap(int resId) {
78            mResId = resId;
79        }
80
81        public synchronized Bitmap get() {
82            if (mBitmap == null) {
83                BitmapFactory.Options options = new BitmapFactory.Options();
84                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
85                mBitmap = BitmapFactory.decodeResource(
86                        mContext.getResources(), mResId, options);
87            }
88            return mBitmap;
89        }
90    }
91
92    public ThreadPool.Job<Bitmap> requestLabel(
93            String title, String count, int sourceType, int slotWidth) {
94        return new AlbumLabelJob(null, title, count, sourceType, slotWidth);
95    }
96
97    public ThreadPool.Job<Bitmap> requestLabel(
98            MediaSet album, int sourceType, int slotWidth) {
99        return new AlbumLabelJob(album, null, null, sourceType, slotWidth);
100    }
101
102    private static void drawText(Canvas canvas,
103            int x, int y, String text, int lengthLimit, TextPaint p) {
104        // The TextPaint cannot be used concurrently
105        synchronized (p) {
106            text = TextUtils.ellipsize(
107                    text, p, lengthLimit, TextUtils.TruncateAt.END).toString();
108            canvas.drawText(text, x, y - p.getFontMetricsInt().ascent, p);
109        }
110    }
111
112    private class AlbumLabelJob implements ThreadPool.Job<Bitmap> {
113        private final MediaSet mAlbum;
114        private final String mTitle;
115        private final String mCount;
116        private final int mSourceType;
117        private final int mSlotWidth;
118
119        public AlbumLabelJob(MediaSet album,
120                String title, String count, int sourceType, int slotWidth) {
121            mAlbum = album;
122            mTitle = title;
123            mCount = count;
124            mSourceType = sourceType;
125            mSlotWidth = slotWidth;
126        }
127
128        @Override
129        public Bitmap run(JobContext jc) {
130            MediaSet album = mAlbum;
131            AlbumSetView.LabelSpec s = mSpec;
132
133            String title = Utils.ensureNotNull(
134                    (album == null) ? mTitle : album.getName());
135            String count = album == null
136                    ? Utils.ensureNotNull(mCount)
137                    : String.valueOf(album.getTotalMediaItemCount());
138            Bitmap icon = getOverlayAlbumIcon(mSourceType);
139            Bitmap bitmap = Bitmap.createBitmap(mSlotWidth,
140                    s.labelBackgroundHeight, Config.ARGB_8888);
141            Canvas canvas = new Canvas(bitmap);
142
143            // draw title
144            if (jc.isCancelled()) return null;
145            int x = s.leftMargin;
146            int y = s.titleOffset;
147            drawText(canvas, x, y, title, mSlotWidth - s.leftMargin, mTitlePaint);
148
149            // draw the count
150            if (jc.isCancelled()) return null;
151            if (icon != null) x = s.iconSize;
152            y += s.titleFontSize + s.countOffset;
153            drawText(canvas, x, y, count,
154                    mSlotWidth - s.leftMargin - s.iconSize, mCountPaint);
155
156            // draw the icon
157            if (icon != null) {
158                if (jc.isCancelled()) return null;
159                float scale = (float) s.iconSize / icon.getWidth();
160                canvas.translate(0, bitmap.getHeight()
161                        - Math.round(scale * icon.getHeight()));
162                canvas.scale(scale, scale);
163                canvas.drawBitmap(icon, 0, 0, null);
164            }
165
166            return bitmap;
167        }
168    }
169}
170