Home | History | Annotate | Download | only in browse
      1 /*
      2  * Copyright (C) 2012 Google Inc.
      3  * Licensed to The Android Open Source Project.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.mail.browse;
     19 
     20 import android.content.Context;
     21 import android.graphics.Canvas;
     22 import android.graphics.Paint;
     23 import android.graphics.Paint.FontMetricsInt;
     24 import android.graphics.Rect;
     25 import android.graphics.drawable.Drawable;
     26 import android.text.style.DynamicDrawableSpan;
     27 import android.text.style.ImageSpan;
     28 import android.text.style.ReplacementSpan;
     29 
     30 import java.lang.ref.WeakReference;
     31 
     32 /**
     33  * Acts like an {@link ImageSpan}, with some important distinctions:
     34  * <ol>
     35  * <li>modifies font metrics in a manner consistent with {@link FolderSpan}
     36  * (will not increase line height beyond {@link FolderSpan} height)</li>
     37  * <li>draws its image vertically centered within its line</li>
     38  * <li>allows horizontal and vertical padding</li>
     39  * </ol>
     40  * Much of this code was copied from {@link DynamicDrawableSpan} and ImageSpan
     41  * because
     42  * {@link DynamicDrawableSpan#draw(Canvas, CharSequence, int, int, float, int, int, int, Paint)}
     43  * is difficult to override efficiently owing to the private getCachedDrawable()
     44  * method (filed as bug 5354674).
     45  */
     46 public class PriorityIndicatorSpan extends ReplacementSpan {
     47 
     48     private final Context mContext;
     49     private final int mResId;
     50     private final int mPaddingV;
     51     private final int mPaddingH;
     52     private final int mPaddingAbove;
     53 
     54     private WeakReference<Drawable> mDrawableRef;
     55 
     56     public PriorityIndicatorSpan(Context context, int resId, int paddingV, int paddingH,
     57             int paddingAbove) {
     58         mContext = context;
     59         mResId = resId;
     60         mPaddingV = paddingV;
     61         mPaddingH = paddingH;
     62         mPaddingAbove = paddingAbove;
     63     }
     64 
     65     private Drawable getDrawable() {
     66         Drawable d = mContext.getResources().getDrawable(mResId);
     67         d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
     68         return d;
     69     }
     70 
     71     private Drawable getCachedDrawable() {
     72         WeakReference<Drawable> wr = mDrawableRef;
     73         Drawable d = null;
     74 
     75         if (wr != null)
     76             d = wr.get();
     77 
     78         if (d == null) {
     79             d = getDrawable();
     80             mDrawableRef = new WeakReference<Drawable>(d);
     81         }
     82 
     83         return d;
     84     }
     85 
     86     @Override
     87     public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
     88         Drawable d = getCachedDrawable();
     89         Rect rect = d.getBounds();
     90 
     91         if (fm != null) {
     92             paint.getFontMetricsInt(fm);
     93             fm.ascent -= mPaddingV;
     94             fm.top = fm.ascent;
     95             fm.bottom += mPaddingV;
     96             fm.descent += mPaddingV;
     97         }
     98 
     99         return rect.right + 2 * mPaddingH;
    100     }
    101 
    102     @Override
    103     public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
    104             int y, int bottom, Paint paint) {
    105         Drawable b = getCachedDrawable();
    106         canvas.save();
    107 
    108         final int transY = (top + bottom + mPaddingAbove - b.getBounds().bottom) / 2;
    109 
    110         canvas.translate(x + mPaddingH, transY);
    111         b.draw(canvas);
    112         canvas.restore();
    113     }
    114 
    115 }
    116