FontFamily.java revision 8b48e624457e438fcc2b6b9363329036ef2f7743
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 Wagnerimport java.util.List;
29a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner
301a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien/**
311a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * A family of typefaces with different styles.
321a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien *
331a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * @hide
341a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien */
351a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienpublic class FontFamily {
36296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien
37296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien    private static String TAG = "FontFamily";
38296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien
399a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien    /**
409a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien     * @hide
419a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien     */
421a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    public long mNativePtr;
439a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien
448b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    // Points native font family builder. Must be zero after freezing this family.
458b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    private long mBuilderPtr;
468b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka
471a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    public FontFamily() {
488b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        mBuilderPtr = nInitBuilder(null, 0);
49f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien    }
50f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien
51f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien    public FontFamily(String lang, String variant) {
52f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien        int varEnum = 0;
53f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien        if ("compact".equals(variant)) {
54f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien            varEnum = 1;
55f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien        } else if ("elegant".equals(variant)) {
56f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien            varEnum = 2;
57f9e3d311275c37fe5f2562993687a1627780a6d0Raph Levien        }
588b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        mBuilderPtr = nInitBuilder(lang, varEnum);
598b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    }
608b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka
618b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    public void freeze() {
628b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        if (mBuilderPtr == 0) {
638b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            throw new IllegalStateException("This FontFamily is already frozen");
648b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        }
658b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        mNativePtr = nCreateFamily(mBuilderPtr);
668b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        mBuilderPtr = 0;
678b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    }
688b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka
698b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    public void abortCreation() {
708b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        if (mBuilderPtr == 0) {
718b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            throw new IllegalStateException("This FontFamily is already frozen or abandoned");
729a5b61ccc83303ceeec2059f58c1977af9faa9e3Raph Levien        }
738b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        nAbort(mBuilderPtr);
748b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        mBuilderPtr = 0;
751a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    }
7615cf4757dc0099301662f8a26da561434cc07cfaRaph Levien
7715cf4757dc0099301662f8a26da561434cc07cfaRaph Levien    @Override
7815cf4757dc0099301662f8a26da561434cc07cfaRaph Levien    protected void finalize() throws Throwable {
7915cf4757dc0099301662f8a26da561434cc07cfaRaph Levien        try {
808b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            if (mNativePtr != 0) {
818b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka                nUnrefFamily(mNativePtr);
828b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            }
838b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            if (mBuilderPtr != 0) {
848b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka                nAbort(mBuilderPtr);
858b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            }
8615cf4757dc0099301662f8a26da561434cc07cfaRaph Levien        } finally {
8715cf4757dc0099301662f8a26da561434cc07cfaRaph Levien            super.finalize();
8815cf4757dc0099301662f8a26da561434cc07cfaRaph Levien        }
8915cf4757dc0099301662f8a26da561434cc07cfaRaph Levien    }
901a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
913fa667e22401bf3ba96957fe31167bf05d164c55Seigo Nonaka    public boolean addFont(String path, int ttcIndex) {
928b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        if (mBuilderPtr == 0) {
938b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            throw new IllegalStateException("Unable to call addFont after freezing.");
948b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        }
95296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        try (FileInputStream file = new FileInputStream(path)) {
96296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien            FileChannel fileChannel = file.getChannel();
97296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien            long fontSize = fileChannel.size();
98296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien            ByteBuffer fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
998b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            return nAddFont(mBuilderPtr, fontBuffer, ttcIndex);
100296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        } catch (IOException e) {
101296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien            Log.e(TAG, "Error mapping font file " + path);
102296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien            return false;
103296bf8c55aaba0025f3e5b904fda3b6e15686753Raph Levien        }
104d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    }
105d573794d83a049fe59e289944f0cd77406dd776aRaph Levien
10604d72abde1efc963ebb2f145f859552e83b92d13Clara Bayarri    public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List<FontConfig.Axis> axes,
107a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            int weight, boolean style) {
1088b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        if (mBuilderPtr == 0) {
1098b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            throw new IllegalStateException("Unable to call addFontWeightStyle after freezing.");
1108b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        }
1118b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        return nAddFontWeightStyle(mBuilderPtr, font, ttcIndex, axes, weight, style);
112117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien    }
113117cbebe810613d4a6de034f02652cdbbfef4cdeRaph Levien
11418e9f9f3778318918c44d944489cb50daaf45d1cClara Bayarri    public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie,
11518e9f9f3778318918c44d944489cb50daaf45d1cClara Bayarri            boolean isAsset) {
1168b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        if (mBuilderPtr == 0) {
1178b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka            throw new IllegalStateException("Unable to call addFontFromAsset after freezing.");
1188b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        }
1198b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka        return nAddFontFromAssetManager(mBuilderPtr, mgr, path, cookie, isAsset);
1201a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    }
1211a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
1228b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    private static native long nInitBuilder(String lang, int variant);
1238b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka
1248b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    @CriticalNative
1258b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    private static native long nCreateFamily(long mBuilderPtr);
1268b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka
1278b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    @CriticalNative
1288b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    private static native void nAbort(long mBuilderPtr);
1298b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka
1308b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    @CriticalNative
131d573794d83a049fe59e289944f0cd77406dd776aRaph Levien    private static native void nUnrefFamily(long nativePtr);
1328b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex);
1338b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    private static native boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font,
13404d72abde1efc963ebb2f145f859552e83b92d13Clara Bayarri            int ttcIndex, List<FontConfig.Axis> listOfAxis,
135a87b07d7fafd59ae26073a80cd742b17ea427ecdBen Wagner            int weight, boolean isItalic);
1368b48e624457e438fcc2b6b9363329036ef2f7743Seigo Nonaka    private static native boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr,
13718e9f9f3778318918c44d944489cb50daaf45d1cClara Bayarri            String path, int cookie, boolean isAsset);
1381a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}
139