Home | History | Annotate | Download | only in photomanager
      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 
     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 
     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 
    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 
    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 
    159     private int getFontSize(float scale)  {
    160         if (scale == Dimensions.SCALE_ONE) {
    161             return mTileLetterFontSize;
    162         } else {
    163             return mTileLetterFontSizeSmall;
    164         }
    165     }
    166 
    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