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