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