Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright (C) 2013 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.inputmethod.latin.utils;
     18 
     19 import android.graphics.Paint;
     20 import android.graphics.Rect;
     21 import android.graphics.Typeface;
     22 import android.util.SparseArray;
     23 
     24 public final class TypefaceUtils {
     25     private TypefaceUtils() {
     26         // This utility class is not publicly instantiable.
     27     }
     28 
     29     // This sparse array caches key label text height in pixel indexed by key label text size.
     30     private static final SparseArray<Float> sTextHeightCache = CollectionUtils.newSparseArray();
     31     // Working variable for the following method.
     32     private static final Rect sTextHeightBounds = new Rect();
     33 
     34     public static float getCharHeight(final char[] referenceChar, final Paint paint) {
     35         final int key = getCharGeometryCacheKey(referenceChar[0], paint);
     36         synchronized (sTextHeightCache) {
     37             final Float cachedValue = sTextHeightCache.get(key);
     38             if (cachedValue != null) {
     39                 return cachedValue;
     40             }
     41 
     42             paint.getTextBounds(referenceChar, 0, 1, sTextHeightBounds);
     43             final float height = sTextHeightBounds.height();
     44             sTextHeightCache.put(key, height);
     45             return height;
     46         }
     47     }
     48 
     49     // This sparse array caches key label text width in pixel indexed by key label text size.
     50     private static final SparseArray<Float> sTextWidthCache = CollectionUtils.newSparseArray();
     51     // Working variable for the following method.
     52     private static final Rect sTextWidthBounds = new Rect();
     53 
     54     public static float getCharWidth(final char[] referenceChar, final Paint paint) {
     55         final int key = getCharGeometryCacheKey(referenceChar[0], paint);
     56         synchronized (sTextWidthCache) {
     57             final Float cachedValue = sTextWidthCache.get(key);
     58             if (cachedValue != null) {
     59                 return cachedValue;
     60             }
     61 
     62             paint.getTextBounds(referenceChar, 0, 1, sTextWidthBounds);
     63             final float width = sTextWidthBounds.width();
     64             sTextWidthCache.put(key, width);
     65             return width;
     66         }
     67     }
     68 
     69     public static float getStringWidth(final String string, final Paint paint) {
     70         paint.getTextBounds(string, 0, string.length(), sTextWidthBounds);
     71         return sTextWidthBounds.width();
     72     }
     73 
     74     private static int getCharGeometryCacheKey(final char referenceChar, final Paint paint) {
     75         final int labelSize = (int)paint.getTextSize();
     76         final Typeface face = paint.getTypeface();
     77         final int codePointOffset = referenceChar << 15;
     78         if (face == Typeface.DEFAULT) {
     79             return codePointOffset + labelSize;
     80         } else if (face == Typeface.DEFAULT_BOLD) {
     81             return codePointOffset + labelSize + 0x1000;
     82         } else if (face == Typeface.MONOSPACE) {
     83             return codePointOffset + labelSize + 0x2000;
     84         } else {
     85             return codePointOffset + labelSize;
     86         }
     87     }
     88 
     89     public static float getLabelWidth(final String label, final Paint paint) {
     90         final Rect textBounds = new Rect();
     91         paint.getTextBounds(label, 0, label.length(), textBounds);
     92         return textBounds.width();
     93     }
     94 }
     95