1 package com.android.ex.chips.recipientchip;
2 
3 import android.graphics.Canvas;
4 import android.graphics.Paint;
5 import android.graphics.Rect;
6 import android.graphics.drawable.Drawable;
7 import android.text.style.ReplacementSpan;
8 
9 /**
10  * ReplacementSpan that properly draws the drawable that is centered around the text
11  * without changing the default text size or layout.
12  */
13 public class ReplacementDrawableSpan extends ReplacementSpan {
14     protected static final Paint sWorkPaint = new Paint();
15 
16     protected Drawable mDrawable;
17     private float mExtraMargin;
18 
ReplacementDrawableSpan(Drawable drawable)19     public ReplacementDrawableSpan(Drawable drawable) {
20         super();
21         mDrawable = drawable;
22     }
23 
setExtraMargin(float margin)24     public void setExtraMargin(float margin) {
25         mExtraMargin = margin;
26     }
27 
setupFontMetrics(Paint.FontMetricsInt fm, Paint paint)28     private void setupFontMetrics(Paint.FontMetricsInt fm, Paint paint) {
29         sWorkPaint.set(paint);
30         if (fm != null) {
31             sWorkPaint.getFontMetricsInt(fm);
32 
33             final Rect bounds = getBounds();
34             final int textHeight = fm.descent - fm.ascent;
35             final int halfMargin = (int) mExtraMargin / 2;
36             fm.ascent = Math.min(fm.top, fm.top + (textHeight - bounds.bottom) / 2) - halfMargin;
37             fm.descent = Math.max(fm.bottom, fm.bottom + (bounds.bottom - textHeight) / 2)
38                     + halfMargin;
39             fm.top = fm.ascent;
40             fm.bottom = fm.descent;
41         }
42     }
43 
44     @Override
getSize(Paint paint, CharSequence text, int i, int i2, Paint.FontMetricsInt fm)45     public int getSize(Paint paint, CharSequence text, int i, int i2, Paint.FontMetricsInt fm) {
46         setupFontMetrics(fm, paint);
47         return getBounds().right;
48     }
49 
50     @Override
draw(Canvas canvas, CharSequence charSequence, int start, int end, float x, int top, int y, int bottom, Paint paint)51     public void draw(Canvas canvas, CharSequence charSequence, int start, int end, float x, int top,
52                      int y, int bottom, Paint paint) {
53         canvas.save();
54         int transY = (bottom - mDrawable.getBounds().bottom + top) / 2;
55         canvas.translate(x, transY);
56         mDrawable.draw(canvas);
57         canvas.restore();
58     }
59 
getBounds()60     protected Rect getBounds() {
61         return mDrawable.getBounds();
62     }
63 }
64