1 /*
2  * Copyright (C) 2015 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.calculator2;
18 
19 import android.content.Context;
20 import android.graphics.Paint;
21 import android.graphics.Rect;
22 import android.util.AttributeSet;
23 import android.widget.TextView;
24 
25 /**
26  * Extended {@link TextView} that supports ascent/baseline alignment.
27  */
28 public class AlignedTextView extends TextView {
29 
30     private static final String LATIN_CAPITAL_LETTER = "H";
31 
32     // temporary rect for use during layout
33     private final Rect mTempRect = new Rect();
34 
35     private int mTopPaddingOffset;
36     private int mBottomPaddingOffset;
37 
AlignedTextView(Context context)38     public AlignedTextView(Context context) {
39         this(context, null /* attrs */);
40     }
41 
AlignedTextView(Context context, AttributeSet attrs)42     public AlignedTextView(Context context, AttributeSet attrs) {
43         this(context, attrs, android.R.attr.textViewStyle);
44     }
45 
AlignedTextView(Context context, AttributeSet attrs, int defStyleAttr)46     public AlignedTextView(Context context, AttributeSet attrs, int defStyleAttr) {
47         super(context, attrs, defStyleAttr);
48 
49         // Disable any included font padding by default.
50         setIncludeFontPadding(false);
51     }
52 
53     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)54     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
55         final Paint paint = getPaint();
56 
57         // Always align text to the default capital letter height.
58         paint.getTextBounds(LATIN_CAPITAL_LETTER, 0, 1, mTempRect);
59 
60         mTopPaddingOffset = Math.min(getPaddingTop(),
61                 (int) Math.ceil(mTempRect.top - paint.ascent()));
62         mBottomPaddingOffset = Math.min(getPaddingBottom(), (int) Math.ceil(paint.descent()));
63 
64         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
65     }
66 
67     @Override
getCompoundPaddingTop()68     public int getCompoundPaddingTop() {
69         return super.getCompoundPaddingTop() - mTopPaddingOffset;
70     }
71 
72     @Override
getCompoundPaddingBottom()73     public int getCompoundPaddingBottom() {
74         return super.getCompoundPaddingBottom() - mBottomPaddingOffset;
75     }
76 }
77