19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetManager; 201a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienimport android.util.Log; 2136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatimport android.util.LongSparseArray; 225849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinirimport android.util.LruCache; 239a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport android.util.SparseArray; 249a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 259a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport org.xmlpull.v1.XmlPullParserException; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guyimport java.io.File; 289a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.io.FileInputStream; 299a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.io.FileNotFoundException; 309a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.io.IOException; 31fb95699364e555148b437cfa1e5c69384f843845Ben Wagnerimport java.nio.ByteBuffer; 32fb95699364e555148b437cfa1e5c69384f843845Ben Wagnerimport java.nio.channels.FileChannel; 339a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.util.ArrayList; 349a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.util.HashMap; 359a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.util.List; 369a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levienimport java.util.Map; 37a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The Typeface class specifies the typeface and intrinsic style of a font. 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is used in the paint, along with optionally Paint settings like 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * textSize, textSkewX, textScaleX to specify 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * how text appears when drawn (and measured). 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Typeface { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien private static String TAG = "Typeface"; 479a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The default NORMAL typeface object */ 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Typeface DEFAULT; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default BOLD typeface object. Note: this may be not actually be 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * bold, depending on what fonts are installed. Call getStyle() to know 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for sure. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Typeface DEFAULT_BOLD; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The NORMAL style of the default sans serif typeface. */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Typeface SANS_SERIF; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The NORMAL style of the default serif typeface. */ 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Typeface SERIF; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The NORMAL style of the default monospace typeface. */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Typeface MONOSPACE; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6346926698996d3857a650ed535024a88dbeaff1e1Romain Guy static Typeface[] sDefaults; 6436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private static final LongSparseArray<SparseArray<Typeface>> sTypefaceCache = 6536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat new LongSparseArray<SparseArray<Typeface>>(3); 6646926698996d3857a650ed535024a88dbeaff1e1Romain Guy 675849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir /** 685849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * Cache for Typeface objects dynamically loaded from assets. Currently max size is 16. 695849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir */ 705849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir private static final LruCache<String, Typeface> sDynamicTypefaceCache = new LruCache<>(16); 715849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir 729a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien static Typeface sDefaultTypeface; 739a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien static Map<String, Typeface> sSystemFontMap; 74363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien static FontFamily[] sFallbackFonts; 759a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 76117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien static final String FONTS_CONFIG = "fonts.xml"; 77baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta 78a033630e805c407080221e20b236b6054f324670Raph Levien /** 79a033630e805c407080221e20b236b6054f324670Raph Levien * @hide 80a033630e805c407080221e20b236b6054f324670Raph Levien */ 8136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat public long native_instance; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Style 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int NORMAL = 0; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int BOLD = 1; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ITALIC = 2; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int BOLD_ITALIC = 3; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8946926698996d3857a650ed535024a88dbeaff1e1Romain Guy private int mStyle = 0; 9046926698996d3857a650ed535024a88dbeaff1e1Romain Guy 919a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien private static void setDefault(Typeface t) { 929a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien sDefaultTypeface = t; 939a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien nativeSetDefault(t.native_instance); 949a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 959a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Returns the typeface's intrinsic style attributes */ 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStyle() { 9846926698996d3857a650ed535024a88dbeaff1e1Romain Guy return mStyle; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Returns true if getStyle() has the BOLD bit set. */ 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean isBold() { 10346926698996d3857a650ed535024a88dbeaff1e1Romain Guy return (mStyle & BOLD) != 0; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Returns true if getStyle() has the ITALIC bit set. */ 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean isItalic() { 10846926698996d3857a650ed535024a88dbeaff1e1Romain Guy return (mStyle & ITALIC) != 0; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a typeface object given a family name, and option style information. 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If null is passed for the name, then the "default" font will be chosen. 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The resulting typeface object can be queried (getStyle()) to discover what 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * its "real" style characteristics are. 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param familyName May be null. The name of the font family. 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param style The style (normal, bold, italic) of the typeface. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The best matching typeface. 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static Typeface create(String familyName, int style) { 1239a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien if (sSystemFontMap != null) { 1249a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien return create(sSystemFontMap.get(familyName), style); 1259a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 1263660789f06c5fbcb81e6c7c79612048bff8f0f66Raph Levien return null; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a typeface object that best matches the specified existing 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * typeface and the specified Style. Use this call if you want to pick a new 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * style from the same family of an existing typeface object. If family is 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null, this selects from the default font's family. 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param family May be null. The name of the existing type face. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param style The style (normal, bold, italic) of the typeface. 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The best matching typeface. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static Typeface create(Typeface family, int style) { 141ff86bcd08827d1050a8cfd99b521c21848b3f364Raph Levien if (style < 0 || style > 3) { 142ff86bcd08827d1050a8cfd99b521c21848b3f364Raph Levien style = 0; 143ff86bcd08827d1050a8cfd99b521c21848b3f364Raph Levien } 14436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat long ni = 0; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (family != null) { 14646926698996d3857a650ed535024a88dbeaff1e1Romain Guy // Return early if we're asked for the same face/style 14746926698996d3857a650ed535024a88dbeaff1e1Romain Guy if (family.mStyle == style) { 14846926698996d3857a650ed535024a88dbeaff1e1Romain Guy return family; 14946926698996d3857a650ed535024a88dbeaff1e1Romain Guy } 15046926698996d3857a650ed535024a88dbeaff1e1Romain Guy 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ni = family.native_instance; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15346926698996d3857a650ed535024a88dbeaff1e1Romain Guy 15446926698996d3857a650ed535024a88dbeaff1e1Romain Guy Typeface typeface; 15546926698996d3857a650ed535024a88dbeaff1e1Romain Guy SparseArray<Typeface> styles = sTypefaceCache.get(ni); 15646926698996d3857a650ed535024a88dbeaff1e1Romain Guy 15746926698996d3857a650ed535024a88dbeaff1e1Romain Guy if (styles != null) { 15846926698996d3857a650ed535024a88dbeaff1e1Romain Guy typeface = styles.get(style); 15946926698996d3857a650ed535024a88dbeaff1e1Romain Guy if (typeface != null) { 16046926698996d3857a650ed535024a88dbeaff1e1Romain Guy return typeface; 16146926698996d3857a650ed535024a88dbeaff1e1Romain Guy } 16246926698996d3857a650ed535024a88dbeaff1e1Romain Guy } 16346926698996d3857a650ed535024a88dbeaff1e1Romain Guy 16446926698996d3857a650ed535024a88dbeaff1e1Romain Guy typeface = new Typeface(nativeCreateFromTypeface(ni, style)); 16546926698996d3857a650ed535024a88dbeaff1e1Romain Guy if (styles == null) { 16646926698996d3857a650ed535024a88dbeaff1e1Romain Guy styles = new SparseArray<Typeface>(4); 16746926698996d3857a650ed535024a88dbeaff1e1Romain Guy sTypefaceCache.put(ni, styles); 16846926698996d3857a650ed535024a88dbeaff1e1Romain Guy } 16946926698996d3857a650ed535024a88dbeaff1e1Romain Guy styles.put(style, typeface); 17046926698996d3857a650ed535024a88dbeaff1e1Romain Guy 17146926698996d3857a650ed535024a88dbeaff1e1Romain Guy return typeface; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns one of the default typeface objects, based on the specified style 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the default typeface that corresponds to the style 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static Typeface defaultFromStyle(int style) { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sDefaults[style]; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new typeface from the specified font data. 1855849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * 1865849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * @param mgr The application's asset manager 1875849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * @param path The file name of the font data in the assets directory 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The new typeface. 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static Typeface createFromAsset(AssetManager mgr, String path) { 191d573794d83a049fe59e289944f0cd77406dd776aRaph Levien if (sFallbackFonts != null) { 1925849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir synchronized (sDynamicTypefaceCache) { 1935849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir final String key = createAssetUid(mgr, path); 1945849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir Typeface typeface = sDynamicTypefaceCache.get(key); 1955849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir if (typeface != null) return typeface; 1965849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir 1975849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir FontFamily fontFamily = new FontFamily(); 1985849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir if (fontFamily.addFontFromAsset(mgr, path)) { 1995849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir FontFamily[] families = { fontFamily }; 2005849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir typeface = createFromFamiliesWithDefault(families); 2015849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir sDynamicTypefaceCache.put(key, typeface); 2025849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir return typeface; 2035849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir } 204d573794d83a049fe59e289944f0cd77406dd776aRaph Levien } 205d573794d83a049fe59e289944f0cd77406dd776aRaph Levien } 206bf8d5620f7f3be72ec217f4bcc14a417d4e1dee6Behdad Esfahbod throw new RuntimeException("Font asset not found " + path); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 208a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy 209a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy /** 2105849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * Creates a unique id for a given AssetManager and asset path. 2115849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * 2125849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * @param mgr AssetManager instance 2135849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * @param path The path for the asset. 2145849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir * @return Unique id for a given AssetManager and asset path. 2155849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir */ 2165849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir private static String createAssetUid(final AssetManager mgr, String path) { 2175849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir final SparseArray<String> pkgs = mgr.getAssignedPackageIdentifiers(); 2185849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir final StringBuilder builder = new StringBuilder(); 2195849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir final int size = pkgs.size(); 2205849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir for (int i = 0; i < size; i++) { 2215849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir builder.append(pkgs.valueAt(i)); 2225849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir builder.append("-"); 2235849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir } 2245849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir builder.append(path); 2255849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir return builder.toString(); 2265849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir } 2275849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir 2285849500a193ac1327242e01d7f6912d0a384ffc9Siyamed Sinir /** 229a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy * Create a new typeface from the specified font file. 230a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy * 2319a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * @param path The path to the font data. 232a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy * @return The new typeface. 233a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy */ 234a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy public static Typeface createFromFile(File path) { 235d573794d83a049fe59e289944f0cd77406dd776aRaph Levien return createFromFile(path.getAbsolutePath()); 236a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy } 237a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy 238a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy /** 239a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy * Create a new typeface from the specified font file. 240a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy * 2419a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * @param path The full path to the font data. 242a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy * @return The new typeface. 243a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy */ 244a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy public static Typeface createFromFile(String path) { 245d573794d83a049fe59e289944f0cd77406dd776aRaph Levien if (sFallbackFonts != null) { 246d573794d83a049fe59e289944f0cd77406dd776aRaph Levien FontFamily fontFamily = new FontFamily(); 2473fa667e22401bf3ba96957fe31167bf05d164c55Seigo Nonaka if (fontFamily.addFont(path, 0 /* ttcIndex */)) { 248d573794d83a049fe59e289944f0cd77406dd776aRaph Levien FontFamily[] families = { fontFamily }; 249d573794d83a049fe59e289944f0cd77406dd776aRaph Levien return createFromFamiliesWithDefault(families); 250d573794d83a049fe59e289944f0cd77406dd776aRaph Levien } 251d573794d83a049fe59e289944f0cd77406dd776aRaph Levien } 252bf8d5620f7f3be72ec217f4bcc14a417d4e1dee6Behdad Esfahbod throw new RuntimeException("Font not found " + path); 253a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy } 254a87a132ebf1c2dd733cf52feff6e44525257c961Romain Guy 2551a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien /** 2561a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Create a new typeface from an array of font families. 2571a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * 2581a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * @param families array of font families 2591a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * @hide 2601a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien */ 2611a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien public static Typeface createFromFamilies(FontFamily[] families) { 2621a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien long[] ptrArray = new long[families.length]; 2631a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien for (int i = 0; i < families.length; i++) { 2641a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien ptrArray[i] = families[i].mNativePtr; 2651a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien } 2661a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien return new Typeface(nativeCreateFromArray(ptrArray)); 2671a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien } 2681a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 269363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien /** 270363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien * Create a new typeface from an array of font families, including 271363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien * also the font families in the fallback list. 272363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien * 273363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien * @param families array of font families 274363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien * @hide 275363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien */ 276363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien public static Typeface createFromFamiliesWithDefault(FontFamily[] families) { 277363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien long[] ptrArray = new long[families.length + sFallbackFonts.length]; 278363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien for (int i = 0; i < families.length; i++) { 279363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien ptrArray[i] = families[i].mNativePtr; 280363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien } 281363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien for (int i = 0; i < sFallbackFonts.length; i++) { 282363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien ptrArray[i + families.length] = sFallbackFonts[i].mNativePtr; 283363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien } 284363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien return new Typeface(nativeCreateFromArray(ptrArray)); 285363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien } 286363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't allow clients to call this directly 28836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private Typeface(long ni) { 28946926698996d3857a650ed535024a88dbeaff1e1Romain Guy if (ni == 0) { 29031a69fdbe1edd8d686043e8ca7d278289f65808eMike Reed throw new RuntimeException("native typeface cannot be made"); 29131a69fdbe1edd8d686043e8ca7d278289f65808eMike Reed } 29246926698996d3857a650ed535024a88dbeaff1e1Romain Guy 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_instance = ni; 29446926698996d3857a650ed535024a88dbeaff1e1Romain Guy mStyle = nativeGetStyle(ni); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 297fb95699364e555148b437cfa1e5c69384f843845Ben Wagner private static FontFamily makeFamilyFromParsed(FontListParser.Family family, 298fb95699364e555148b437cfa1e5c69384f843845Ben Wagner Map<String, ByteBuffer> bufferForPath) { 299f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien FontFamily fontFamily = new FontFamily(family.lang, family.variant); 300117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien for (FontListParser.Font font : family.fonts) { 301fb95699364e555148b437cfa1e5c69384f843845Ben Wagner ByteBuffer fontBuffer = bufferForPath.get(font.fontName); 302fb95699364e555148b437cfa1e5c69384f843845Ben Wagner if (fontBuffer == null) { 303fb95699364e555148b437cfa1e5c69384f843845Ben Wagner try (FileInputStream file = new FileInputStream(font.fontName)) { 304fb95699364e555148b437cfa1e5c69384f843845Ben Wagner FileChannel fileChannel = file.getChannel(); 305fb95699364e555148b437cfa1e5c69384f843845Ben Wagner long fontSize = fileChannel.size(); 306fb95699364e555148b437cfa1e5c69384f843845Ben Wagner fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize); 307fb95699364e555148b437cfa1e5c69384f843845Ben Wagner bufferForPath.put(font.fontName, fontBuffer); 308fb95699364e555148b437cfa1e5c69384f843845Ben Wagner } catch (IOException e) { 309fb95699364e555148b437cfa1e5c69384f843845Ben Wagner Log.e(TAG, "Error mapping font file " + font.fontName); 310fb95699364e555148b437cfa1e5c69384f843845Ben Wagner continue; 311fb95699364e555148b437cfa1e5c69384f843845Ben Wagner } 312fb95699364e555148b437cfa1e5c69384f843845Ben Wagner } 313fb95699364e555148b437cfa1e5c69384f843845Ben Wagner if (!fontFamily.addFontWeightStyle(fontBuffer, font.ttcIndex, font.axes, 314fb95699364e555148b437cfa1e5c69384f843845Ben Wagner font.weight, font.isItalic)) { 315fb95699364e555148b437cfa1e5c69384f843845Ben Wagner Log.e(TAG, "Error creating font " + font.fontName + "#" + font.ttcIndex); 316fb95699364e555148b437cfa1e5c69384f843845Ben Wagner } 3179a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 3189a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien return fontFamily; 3199a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 3209a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 321baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta /* 322baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta * (non-Javadoc) 323baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta * 324baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta * This should only be called once, from the static class initializer block. 325baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta */ 326baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta private static void init() { 3279a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien // Load font config and initialize Minikin state 328baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta File systemFontConfigLocation = getSystemFontConfigLocation(); 329117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien File configFilename = new File(systemFontConfigLocation, FONTS_CONFIG); 3309a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien try { 331117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien FileInputStream fontsIn = new FileInputStream(configFilename); 332117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien FontListParser.Config fontConfig = FontListParser.parse(fontsIn); 3339a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 334fb95699364e555148b437cfa1e5c69384f843845Ben Wagner Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>(); 335fb95699364e555148b437cfa1e5c69384f843845Ben Wagner 336363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien List<FontFamily> familyList = new ArrayList<FontFamily>(); 337363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien // Note that the default typeface is always present in the fallback list; 338363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien // this is an enhancement from pre-Minikin behavior. 339117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien for (int i = 0; i < fontConfig.families.size(); i++) { 340a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner FontListParser.Family f = fontConfig.families.get(i); 341117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien if (i == 0 || f.name == null) { 342fb95699364e555148b437cfa1e5c69384f843845Ben Wagner familyList.add(makeFamilyFromParsed(f, bufferForPath)); 343117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 344363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien } 345363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]); 346363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien setDefault(Typeface.createFromFamilies(sFallbackFonts)); 347363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien 3489a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien Map<String, Typeface> systemFonts = new HashMap<String, Typeface>(); 349117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien for (int i = 0; i < fontConfig.families.size(); i++) { 350363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien Typeface typeface; 351a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner FontListParser.Family f = fontConfig.families.get(i); 352117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien if (f.name != null) { 353117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien if (i == 0) { 354117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien // The first entry is the default typeface; no sense in 355117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien // duplicating the corresponding FontFamily. 356117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien typeface = sDefaultTypeface; 357117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } else { 358fb95699364e555148b437cfa1e5c69384f843845Ben Wagner FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath); 359117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien FontFamily[] families = { fontFamily }; 360117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien typeface = Typeface.createFromFamiliesWithDefault(families); 361117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 362117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien systemFonts.put(f.name, typeface); 363363e21b4518d7059638df2821b8a0947f74eaf2cRaph Levien } 364117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 365117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien for (FontListParser.Alias alias : fontConfig.aliases) { 366117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien Typeface base = systemFonts.get(alias.toName); 367117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien Typeface newFace = base; 368117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien int weight = alias.weight; 369117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien if (weight != 400) { 370117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien newFace = new Typeface(nativeCreateWeightAlias(base.native_instance, weight)); 3719a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 372117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien systemFonts.put(alias.name, newFace); 3739a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 3749a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien sSystemFontMap = systemFonts; 3759a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 3769a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } catch (RuntimeException e) { 377117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien Log.w(TAG, "Didn't create default family (most likely, non-Minikin build)", e); 3789a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien // TODO: normal in non-Minikin case, remove or make error when Minikin-only 3799a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } catch (FileNotFoundException e) { 380a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner Log.e(TAG, "Error opening " + configFilename, e); 3819a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } catch (IOException e) { 382a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner Log.e(TAG, "Error reading " + configFilename, e); 3839a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } catch (XmlPullParserException e) { 384a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner Log.e(TAG, "XML parse exception for " + configFilename, e); 3859a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 386baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta } 3879a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 388baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta static { 389baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta init(); 3909a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien // Set up defaults and typefaces exposed in public API 39146926698996d3857a650ed535024a88dbeaff1e1Romain Guy DEFAULT = create((String) null, 0); 39246926698996d3857a650ed535024a88dbeaff1e1Romain Guy DEFAULT_BOLD = create((String) null, Typeface.BOLD); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SANS_SERIF = create("sans-serif", 0); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SERIF = create("serif", 0); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MONOSPACE = create("monospace", 0); 3969a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sDefaults = new Typeface[] { 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DEFAULT, 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DEFAULT_BOLD, 40046926698996d3857a650ed535024a88dbeaff1e1Romain Guy create((String) null, Typeface.ITALIC), 40146926698996d3857a650ed535024a88dbeaff1e1Romain Guy create((String) null, Typeface.BOLD_ITALIC), 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 403baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta 404baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta } 405baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta 406baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta private static File getSystemFontConfigLocation() { 407baef8c1ffe5c900fb0da9512654bf249b5fc9269Deepanshu Gupta return new File("/system/etc/"); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien @Override 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 41246926698996d3857a650ed535024a88dbeaff1e1Romain Guy try { 41346926698996d3857a650ed535024a88dbeaff1e1Romain Guy nativeUnref(native_instance); 414ffa84e008c712ceffa09d6b89a49882c88b3cca5Hans Boehm native_instance = 0; // Other finalizers can still call us. 41546926698996d3857a650ed535024a88dbeaff1e1Romain Guy } finally { 41646926698996d3857a650ed535024a88dbeaff1e1Romain Guy super.finalize(); 41746926698996d3857a650ed535024a88dbeaff1e1Romain Guy } 41846926698996d3857a650ed535024a88dbeaff1e1Romain Guy } 41946926698996d3857a650ed535024a88dbeaff1e1Romain Guy 42046926698996d3857a650ed535024a88dbeaff1e1Romain Guy @Override 42146926698996d3857a650ed535024a88dbeaff1e1Romain Guy public boolean equals(Object o) { 42246926698996d3857a650ed535024a88dbeaff1e1Romain Guy if (this == o) return true; 42346926698996d3857a650ed535024a88dbeaff1e1Romain Guy if (o == null || getClass() != o.getClass()) return false; 42446926698996d3857a650ed535024a88dbeaff1e1Romain Guy 42546926698996d3857a650ed535024a88dbeaff1e1Romain Guy Typeface typeface = (Typeface) o; 42646926698996d3857a650ed535024a88dbeaff1e1Romain Guy 42746926698996d3857a650ed535024a88dbeaff1e1Romain Guy return mStyle == typeface.mStyle && native_instance == typeface.native_instance; 42846926698996d3857a650ed535024a88dbeaff1e1Romain Guy } 42946926698996d3857a650ed535024a88dbeaff1e1Romain Guy 43046926698996d3857a650ed535024a88dbeaff1e1Romain Guy @Override 43146926698996d3857a650ed535024a88dbeaff1e1Romain Guy public int hashCode() { 43236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat /* 43336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat * Modified method for hashCode with long native_instance derived from 43436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat * http://developer.android.com/reference/java/lang/Object.html 43536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat */ 43636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat int result = 17; 43736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat result = 31 * result + (int) (native_instance ^ (native_instance >>> 32)); 43846926698996d3857a650ed535024a88dbeaff1e1Romain Guy result = 31 * result + mStyle; 43946926698996d3857a650ed535024a88dbeaff1e1Romain Guy return result; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private static native long nativeCreateFromTypeface(long native_instance, int style); 443117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien private static native long nativeCreateWeightAlias(long native_instance, int weight); 44436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private static native void nativeUnref(long native_instance); 44536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat private static native int nativeGetStyle(long native_instance); 4461a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien private static native long nativeCreateFromArray(long[] familyArray); 4479a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien private static native void nativeSetDefault(long native_instance); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 449