FontFamily.java revision 2660aca4912b4bd890c5c76688f67f1898dc7b97
11a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien/* 21a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Copyright (C) 2014 The Android Open Source Project 31a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * 41a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Licensed under the Apache License, Version 2.0 (the "License"); 51a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * you may not use this file except in compliance with the License. 61a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * You may obtain a copy of the License at 71a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * 81a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * http://www.apache.org/licenses/LICENSE-2.0 91a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * 101a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Unless required by applicable law or agreed to in writing, software 111a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * distributed under the License is distributed on an "AS IS" BASIS, 121a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * See the License for the specific language governing permissions and 141a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * limitations under the License. 151a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien */ 161a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 171a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienpackage android.graphics; 181a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 19d573794d83a049fe59e289944f0cd77406dd776aRaph Levienimport android.content.res.AssetManager; 2004d72abde1efc963ebb2f145f859552e83b92d13Clara Bayarriimport android.text.FontConfig; 21296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levienimport android.util.Log; 228b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonakaimport dalvik.annotation.optimization.CriticalNative; 23d573794d83a049fe59e289944f0cd77406dd776aRaph Levien 24296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levienimport java.io.FileInputStream; 25296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levienimport java.io.IOException; 26fb95699364e555148b437cfa1e5c69384f843845Ben Wagnerimport java.nio.ByteBuffer; 27296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levienimport java.nio.channels.FileChannel; 28a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner 291a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien/** 301a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * A family of typefaces with different styles. 311a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * 321a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * @hide 331a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien */ 341a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienpublic class FontFamily { 35296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien 36296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien private static String TAG = "FontFamily"; 37296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien 389a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien /** 399a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien * @hide 409a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien */ 411a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien public long mNativePtr; 429a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien 438b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka // Points native font family builder. Must be zero after freezing this family. 448b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka private long mBuilderPtr; 458b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka 461a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien public FontFamily() { 478b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka mBuilderPtr = nInitBuilder(null, 0); 48f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien } 49f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien 50ac873c9f25d2a687c9195226b9d680f51c91fa30Seigo Nonaka public FontFamily(String lang, int variant) { 51ac873c9f25d2a687c9195226b9d680f51c91fa30Seigo Nonaka mBuilderPtr = nInitBuilder(lang, variant); 528b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka } 538b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka 548b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka public void freeze() { 558b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka if (mBuilderPtr == 0) { 568b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka throw new IllegalStateException("This FontFamily is already frozen"); 578b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka } 588b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka mNativePtr = nCreateFamily(mBuilderPtr); 598b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka mBuilderPtr = 0; 608b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka } 618b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka 628b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka public void abortCreation() { 638b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka if (mBuilderPtr == 0) { 648b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka throw new IllegalStateException("This FontFamily is already frozen or abandoned"); 659a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien } 668b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka nAbort(mBuilderPtr); 678b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka mBuilderPtr = 0; 681a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien } 6915cf4757dc0099301662f8a26da561434cc07cfaRaph Levien 7015cf4757dc0099301662f8a26da561434cc07cfaRaph Levien @Override 7115cf4757dc0099301662f8a26da561434cc07cfaRaph Levien protected void finalize() throws Throwable { 7215cf4757dc0099301662f8a26da561434cc07cfaRaph Levien try { 738b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka if (mNativePtr != 0) { 748b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka nUnrefFamily(mNativePtr); 758b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka } 768b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka if (mBuilderPtr != 0) { 778b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka nAbort(mBuilderPtr); 788b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka } 7915cf4757dc0099301662f8a26da561434cc07cfaRaph Levien } finally { 8015cf4757dc0099301662f8a26da561434cc07cfaRaph Levien super.finalize(); 8115cf4757dc0099301662f8a26da561434cc07cfaRaph Levien } 8215cf4757dc0099301662f8a26da561434cc07cfaRaph Levien } 831a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 8420e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka public boolean addFont(String path, int ttcIndex, FontConfig.Axis[] axes, int weight, 8520e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka int italic) { 868b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka if (mBuilderPtr == 0) { 878b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka throw new IllegalStateException("Unable to call addFont after freezing."); 888b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka } 89296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien try (FileInputStream file = new FileInputStream(path)) { 90296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien FileChannel fileChannel = file.getChannel(); 91296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien long fontSize = fileChannel.size(); 92296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien ByteBuffer fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize); 9320e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka if (axes != null) { 9420e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka for (FontConfig.Axis axis : axes) { 9520e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka nAddAxisValue(mBuilderPtr, axis.getTag(), axis.getStyleValue()); 9620e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka } 9720e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka } 9820e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka return nAddFont(mBuilderPtr, fontBuffer, ttcIndex, weight, italic); 99296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien } catch (IOException e) { 100296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien Log.e(TAG, "Error mapping font file " + path); 101296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien return false; 102296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien } 103d573794d83a049fe59e289944f0cd77406dd776aRaph Levien } 104d573794d83a049fe59e289944f0cd77406dd776aRaph Levien 10520e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontConfig.Axis[] axes, 10620e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka int weight, int italic) { 1078b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka if (mBuilderPtr == 0) { 1088b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka throw new IllegalStateException("Unable to call addFontWeightStyle after freezing."); 1098b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka } 11020e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka if (axes != null) { 11120e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka for (FontConfig.Axis axis : axes) { 11220e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka nAddAxisValue(mBuilderPtr, axis.getTag(), axis.getStyleValue()); 11320e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka } 114ac873c9f25d2a687c9195226b9d680f51c91fa30Seigo Nonaka } 11520e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka return nAddFontWeightStyle(mBuilderPtr, font, ttcIndex, weight, italic); 116117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien } 117117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien 118b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri /** 119b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * @param mgr The AssetManager to use for this context. 120b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * @param path The path to the font file to load. 121b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * @param cookie If available, the resource cookie given by Resources. 122b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * @param isAsset {@code true} if this is from the assets/ folder, {@code false} if from 123b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * resources 124b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * @param weight The weight of the font. If 0 is given, the weight and italic will be resolved 125b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * using the OS/2 table in the font. 126b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * @param isItalic Whether this font is italic. If the weight is set to 0, this will be resolved 127b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * using the OS/2 table in the font. 128b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri * @return 129b44abf290190ceee037f24c47493a34de45fa3f4Clara Bayarri */ 13018e9f9f3778318918c44d944489cb50daaf45d1cClara Bayarri public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie, 13120e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka boolean isAsset, int ttcIndex, int weight, int isItalic, 13220e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka FontConfig.Axis[] axes) { 1338b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka if (mBuilderPtr == 0) { 1348b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka throw new IllegalStateException("Unable to call addFontFromAsset after freezing."); 1358b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka } 13620e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka if (axes != null) { 13720e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka for (FontConfig.Axis axis : axes) { 13820e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka nAddAxisValue(mBuilderPtr, axis.getTag(), axis.getStyleValue()); 13920e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka } 14020e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka } 14120e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka return nAddFontFromAssetManager(mBuilderPtr, mgr, path, cookie, isAsset, ttcIndex, weight, 14220e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka isItalic); 1431a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien } 1441a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 1452660aca4912b4bd890c5c76688f67f1898dc7b97Seigo Nonaka // TODO: Remove once internal user stop using private API. 1462660aca4912b4bd890c5c76688f67f1898dc7b97Seigo Nonaka private static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex) { 1472660aca4912b4bd890c5c76688f67f1898dc7b97Seigo Nonaka return nAddFont(builderPtr, font, ttcIndex, -1, -1); 1482660aca4912b4bd890c5c76688f67f1898dc7b97Seigo Nonaka } 1492660aca4912b4bd890c5c76688f67f1898dc7b97Seigo Nonaka 1508b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka private static native long nInitBuilder(String lang, int variant); 1518b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka 1528b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka @CriticalNative 1538b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka private static native long nCreateFamily(long mBuilderPtr); 1548b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka 1558b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka @CriticalNative 1568b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka private static native void nAbort(long mBuilderPtr); 1578b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka 1588b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka @CriticalNative 159d573794d83a049fe59e289944f0cd77406dd776aRaph Levien private static native void nUnrefFamily(long nativePtr); 16020e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka // By passing -1 to weigth argument, the weight value is resolved by OS/2 table in the font. 16120e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka // By passing -1 to italic argument, the italic value is resolved by OS/2 table in the font. 16220e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex, 16320e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka int weight, int isItalic); 1648b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka private static native boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font, 16520e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka int ttcIndex, int weight, int isItalic); 1668b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka private static native boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, 16720e5d91739fb88a02afb4888bf9f938308bc9b7bSeigo Nonaka String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic); 168ac873c9f25d2a687c9195226b9d680f51c91fa30Seigo Nonaka 169ac873c9f25d2a687c9195226b9d680f51c91fa30Seigo Nonaka // The added axis values are only valid for the next nAddFont* method call. 170ac873c9f25d2a687c9195226b9d680f51c91fa30Seigo Nonaka @CriticalNative 171ac873c9f25d2a687c9195226b9d680f51c91fa30Seigo Nonaka private static native void nAddAxisValue(long builderPtr, int tag, float value); 1721a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 173