• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.tv.settings.widget;
18 
19 import android.content.Context;
20 import android.graphics.Canvas;
21 import android.graphics.Paint;
22 import android.graphics.drawable.Drawable;
23 import android.text.style.DynamicDrawableSpan;
24 
25 import androidx.annotation.DrawableRes;
26 
27 /**
28  * A customized dynamic drawable span which aligns to the center of the text. This assumes that
29  * the text is smaller than the image, which will be the case most of the time.
30  * This class is mirrored from Setup.
31  *
32  * NOTE: For icon that is considerably larger than the text around it (taller than the distance
33  * between the font's top and bottom), the icon could be cut off if it is in the first or last line
34  * of a TextView. Please consider using smaller icon or adding blank lines before and after the
35  * paragraph.
36  */
37 public class CenterAlignedDynamicDrawableSpan extends DynamicDrawableSpan {
38 
39     private final Context mContext;
40     private final int mResourceId;
41 
CenterAlignedDynamicDrawableSpan(Context context, @DrawableRes int resourceId)42     public CenterAlignedDynamicDrawableSpan(Context context, @DrawableRes int resourceId) {
43         super();
44         this.mContext = context;
45         this.mResourceId = resourceId;
46     }
47 
48     @Override
getSize( Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm)49     public int getSize(
50             Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
51         super.getSize(paint, text, start, end, fm);
52 
53         if (fm != null) {
54             fm.ascent = paint.getFontMetricsInt().ascent;
55             fm.descent = paint.getFontMetricsInt().descent;
56             fm.top = fm.ascent;
57             fm.bottom = fm.descent;
58         }
59 
60         return getDrawable().getBounds().right;
61     }
62 
63     @Override
draw( Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint)64     public void draw(
65             Canvas canvas,
66             CharSequence text,
67             int start,
68             int end,
69             float x,
70             int top,
71             int y,
72             int bottom,
73             Paint paint) {
74         Drawable drawable = getDrawable();
75         canvas.save();
76 
77         Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
78         int fontHeight = fmPaint.descent - fmPaint.ascent;
79 
80         // Align text descent (bottom most part) to bottom of drawable
81         int transY = bottom - drawable.getBounds().bottom;
82         // Translate half of the extra space between the drawable and the font to center.
83         transY += (drawable.getIntrinsicHeight() - fontHeight) / 2;
84 
85         canvas.translate(x, transY);
86         drawable.draw(canvas);
87         canvas.restore();
88     }
89 
90     @Override
getDrawable()91     public Drawable getDrawable() {
92         Drawable drawable = mContext.getDrawable(mResourceId);
93         drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
94         return drawable;
95     }
96 }
97