• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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.mail.photomanager;
18 
19 import android.content.Context;
20 import android.content.res.Resources;
21 import android.content.res.TypedArray;
22 import android.graphics.Bitmap;
23 import android.graphics.BitmapFactory;
24 import android.graphics.Canvas;
25 import android.graphics.Paint.Align;
26 import android.graphics.Rect;
27 import android.graphics.Typeface;
28 import android.text.TextPaint;
29 import android.text.TextUtils;
30 
31 import com.android.mail.R;
32 import com.android.mail.ui.ImageCanvas.Dimensions;
33 import com.android.mail.utils.BitmapUtil;
34 import com.android.mail.utils.LogTag;
35 import com.android.mail.utils.LogUtils;
36 
37 /**
38  * LetterTileProvider is an implementation of the DefaultImageProvider. When no
39  * matching contact photo is found, and there is a supplied displayName or email
40  * address whose first letter corresponds to an English alphabet letter (or
41  * number), this method creates a bitmap with the letter in the center of a
42  * tile. If there is no English alphabet character (or digit), it creates a
43  * bitmap with the default contact avatar.
44  */
45 @Deprecated
46 public class LetterTileProvider {
47     private static final String TAG = LogTag.getLogTag();
48     private final Bitmap mDefaultBitmap;
49     private final Bitmap[] mBitmapBackgroundCache;
50     private final Bitmap[] mDefaultBitmapCache;
51     private final Typeface mSansSerifLight;
52     private final Rect mBounds;
53     private final int mTileLetterFontSize;
54     private final int mTileLetterFontSizeSmall;
55     private final int mTileFontColor;
56     private final TextPaint mPaint = new TextPaint();
57     private final TypedArray mColors;
58     private final int mColorCount;
59     private final int mDefaultColor;
60     private final Canvas mCanvas = new Canvas();
61     private final Dimensions mDims = new Dimensions();
62     private final char[] mFirstChar = new char[1];
63 
64     private static final int POSSIBLE_BITMAP_SIZES = 3;
65 
LetterTileProvider(Context context)66     public LetterTileProvider(Context context) {
67         final Resources res = context.getResources();
68         mTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size);
69         mTileLetterFontSizeSmall = res
70                 .getDimensionPixelSize(R.dimen.tile_letter_font_size_small);
71         mTileFontColor = res.getColor(R.color.letter_tile_font_color);
72         mSansSerifLight = Typeface.create("sans-serif-light", Typeface.NORMAL);
73         mBounds = new Rect();
74         mPaint.setTypeface(mSansSerifLight);
75         mPaint.setColor(mTileFontColor);
76         mPaint.setTextAlign(Align.CENTER);
77         mPaint.setAntiAlias(true);
78         mBitmapBackgroundCache = new Bitmap[POSSIBLE_BITMAP_SIZES];
79 
80         mDefaultBitmap = BitmapFactory.decodeResource(res, R.drawable.ic_generic_man);
81         mDefaultBitmapCache = new Bitmap[POSSIBLE_BITMAP_SIZES];
82 
83         mColors = res.obtainTypedArray(R.array.letter_tile_colors);
84         mColorCount = mColors.length();
85         mDefaultColor = res.getColor(R.color.letter_tile_default_color);
86     }
87 
getLetterTile(final Dimensions dimensions, final String displayName, final String address)88     public Bitmap getLetterTile(final Dimensions dimensions, final String displayName,
89             final String address) {
90         final String display = !TextUtils.isEmpty(displayName) ? displayName : address;
91         final char firstChar = display.charAt(0);
92 
93         // get an empty bitmap
94         final Bitmap bitmap = getBitmap(dimensions, false /* getDefault */);
95         if (bitmap == null) {
96             LogUtils.w(TAG, "LetterTileProvider width(%d) or height(%d) is 0 for name %s and "
97                     + "address %s.", dimensions.width, dimensions.height, displayName, address);
98             return null;
99         }
100 
101         final Canvas c = mCanvas;
102         c.setBitmap(bitmap);
103         c.drawColor(pickColor(address));
104 
105         // If its a valid English alphabet letter,
106         // draw the letter on top of the color
107         if (isEnglishLetterOrDigit(firstChar)) {
108             mFirstChar[0] = Character.toUpperCase(firstChar);
109             mPaint.setTextSize(getFontSize(dimensions.scale));
110             mPaint.getTextBounds(mFirstChar, 0, 1, mBounds);
111             c.drawText(mFirstChar, 0, 1, 0 + dimensions.width / 2,
112                     0 + dimensions.height / 2 + (mBounds.bottom - mBounds.top) / 2, mPaint);
113         } else { // draw the generic icon on top
114             c.drawBitmap(getBitmap(dimensions, true /* getDefault */), 0, 0, null);
115         }
116 
117         return bitmap;
118     }
119 
isEnglishLetterOrDigit(char c)120     private static boolean isEnglishLetterOrDigit(char c) {
121         return ('A' <= c && c <= 'Z')
122                 || ('a' <= c && c <= 'z')
123                 || ('0' <= c && c <= '9');
124     }
125 
getBitmap(final Dimensions d, boolean getDefault)126     private Bitmap getBitmap(final Dimensions d, boolean getDefault) {
127         if (d.width <= 0 || d.height <= 0) {
128             LogUtils.w(TAG,
129                     "LetterTileProvider width(%d) or height(%d) is 0.", d.width, d.height);
130             return null;
131         }
132         final int pos;
133         float scale = d.scale;
134         if (scale == Dimensions.SCALE_ONE) {
135             pos = 0;
136         } else if (scale == Dimensions.SCALE_HALF) {
137             pos = 1;
138         } else {
139             pos = 2;
140         }
141 
142         final Bitmap[] cache = (getDefault) ? mDefaultBitmapCache : mBitmapBackgroundCache;
143 
144         Bitmap bitmap = cache[pos];
145         // ensure bitmap is suitable for the desired w/h
146         // (two-pane uses two different sets of dimensions depending on pane width)
147         if (bitmap == null || bitmap.getWidth() != d.width || bitmap.getHeight() != d.height) {
148             // create and place the bitmap
149             if (getDefault) {
150                 bitmap = BitmapUtil.centerCrop(mDefaultBitmap, d.width, d.height);
151             } else {
152                 bitmap = Bitmap.createBitmap(d.width, d.height, Bitmap.Config.ARGB_8888);
153             }
154             cache[pos] = bitmap;
155         }
156         return bitmap;
157     }
158 
getFontSize(float scale)159     private int getFontSize(float scale)  {
160         if (scale == Dimensions.SCALE_ONE) {
161             return mTileLetterFontSize;
162         } else {
163             return mTileLetterFontSizeSmall;
164         }
165     }
166 
pickColor(String emailAddress)167     private int pickColor(String emailAddress) {
168         // String.hashCode() implementation is not supposed to change across java versions, so
169         // this should guarantee the same email address always maps to the same color.
170         int color = Math.abs(emailAddress.hashCode()) % mColorCount;
171         return mColors.getColor(color, mDefaultColor);
172     }
173 }
174