1 /* 2 * Copyright (C) 2014 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 android.graphics; 18 19 import android.annotation.Nullable; 20 import android.annotation.UnsupportedAppUsage; 21 import android.content.res.AssetManager; 22 import android.graphics.fonts.FontVariationAxis; 23 import android.text.TextUtils; 24 import android.util.Log; 25 26 import dalvik.annotation.optimization.CriticalNative; 27 28 import libcore.util.NativeAllocationRegistry; 29 30 import java.io.FileInputStream; 31 import java.io.IOException; 32 import java.nio.ByteBuffer; 33 import java.nio.channels.FileChannel; 34 35 /** 36 * A family of typefaces with different styles. 37 * 38 * @hide 39 * 40 * @deprecated Use {@link android.graphics.fonts.FontFamily} instead. 41 */ 42 @Deprecated 43 public class FontFamily { 44 45 private static String TAG = "FontFamily"; 46 47 private static final NativeAllocationRegistry sBuilderRegistry = 48 NativeAllocationRegistry.createMalloced( 49 FontFamily.class.getClassLoader(), nGetBuilderReleaseFunc()); 50 51 private @Nullable Runnable mNativeBuilderCleaner; 52 53 private static final NativeAllocationRegistry sFamilyRegistry = 54 NativeAllocationRegistry.createMalloced( 55 FontFamily.class.getClassLoader(), nGetFamilyReleaseFunc()); 56 57 /** 58 * @hide 59 * 60 * This cannot be deleted because it's in use by AndroidX. 61 */ 62 @UnsupportedAppUsage(trackingBug = 123768928) 63 public long mNativePtr; 64 65 // Points native font family builder. Must be zero after freezing this family. 66 private long mBuilderPtr; 67 68 /** 69 * This cannot be deleted because it's in use by AndroidX. 70 */ 71 @UnsupportedAppUsage(trackingBug = 123768928) FontFamily()72 public FontFamily() { 73 mBuilderPtr = nInitBuilder(null, 0); 74 mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr); 75 } 76 77 /** 78 * This cannot be deleted because it's in use by AndroidX. 79 */ 80 @UnsupportedAppUsage(trackingBug = 123768928) FontFamily(@ullable String[] langs, int variant)81 public FontFamily(@Nullable String[] langs, int variant) { 82 final String langsString; 83 if (langs == null || langs.length == 0) { 84 langsString = null; 85 } else if (langs.length == 1) { 86 langsString = langs[0]; 87 } else { 88 langsString = TextUtils.join(",", langs); 89 } 90 mBuilderPtr = nInitBuilder(langsString, variant); 91 mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr); 92 } 93 94 /** 95 * Finalize the FontFamily creation. 96 * 97 * @return boolean returns false if some error happens in native code, e.g. broken font file is 98 * passed, etc. 99 * 100 * This cannot be deleted because it's in use by AndroidX. 101 */ 102 @UnsupportedAppUsage(trackingBug = 123768928) freeze()103 public boolean freeze() { 104 if (mBuilderPtr == 0) { 105 throw new IllegalStateException("This FontFamily is already frozen"); 106 } 107 mNativePtr = nCreateFamily(mBuilderPtr); 108 mNativeBuilderCleaner.run(); 109 mBuilderPtr = 0; 110 if (mNativePtr != 0) { 111 sFamilyRegistry.registerNativeAllocation(this, mNativePtr); 112 } 113 return mNativePtr != 0; 114 } 115 116 /** 117 * This cannot be deleted because it's in use by AndroidX. 118 */ 119 @UnsupportedAppUsage(trackingBug = 123768928) abortCreation()120 public void abortCreation() { 121 if (mBuilderPtr == 0) { 122 throw new IllegalStateException("This FontFamily is already frozen or abandoned"); 123 } 124 mNativeBuilderCleaner.run(); 125 mBuilderPtr = 0; 126 } 127 128 /** 129 * This cannot be deleted because it's in use by AndroidX. 130 */ 131 @UnsupportedAppUsage(trackingBug = 123768928) addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight, int italic)132 public boolean addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight, 133 int italic) { 134 if (mBuilderPtr == 0) { 135 throw new IllegalStateException("Unable to call addFont after freezing."); 136 } 137 try (FileInputStream file = new FileInputStream(path)) { 138 FileChannel fileChannel = file.getChannel(); 139 long fontSize = fileChannel.size(); 140 ByteBuffer fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize); 141 if (axes != null) { 142 for (FontVariationAxis axis : axes) { 143 nAddAxisValue(mBuilderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue()); 144 } 145 } 146 return nAddFont(mBuilderPtr, fontBuffer, ttcIndex, weight, italic); 147 } catch (IOException e) { 148 Log.e(TAG, "Error mapping font file " + path); 149 return false; 150 } 151 } 152 153 /** 154 * This cannot be deleted because it's in use by AndroidX. 155 */ 156 @UnsupportedAppUsage(trackingBug = 123768928) addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes, int weight, int italic)157 public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes, 158 int weight, int italic) { 159 if (mBuilderPtr == 0) { 160 throw new IllegalStateException("Unable to call addFontWeightStyle after freezing."); 161 } 162 if (axes != null) { 163 for (FontVariationAxis axis : axes) { 164 nAddAxisValue(mBuilderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue()); 165 } 166 } 167 return nAddFontWeightStyle(mBuilderPtr, font, ttcIndex, weight, italic); 168 } 169 170 /** 171 * @param mgr The AssetManager to use for this context. 172 * @param path The path to the font file to load. 173 * @param cookie If available, the resource cookie given by Resources. 174 * @param isAsset {@code true} if this is from the assets/ folder, {@code false} if from 175 * resources 176 * @param weight The weight of the font. If 0 is given, the weight and italic will be resolved 177 * using the OS/2 table in the font. 178 * @param isItalic Whether this font is italic. If the weight is set to 0, this will be resolved 179 * using the OS/2 table in the font. 180 * @return 181 * 182 * This cannot be deleted because it's in use by AndroidX. 183 */ 184 @UnsupportedAppUsage(trackingBug = 123768928) addFontFromAssetManager(AssetManager mgr, String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic, FontVariationAxis[] axes)185 public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie, 186 boolean isAsset, int ttcIndex, int weight, int isItalic, 187 FontVariationAxis[] axes) { 188 if (mBuilderPtr == 0) { 189 throw new IllegalStateException("Unable to call addFontFromAsset after freezing."); 190 } 191 if (axes != null) { 192 for (FontVariationAxis axis : axes) { 193 nAddAxisValue(mBuilderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue()); 194 } 195 } 196 return nAddFontFromAssetManager(mBuilderPtr, mgr, path, cookie, isAsset, ttcIndex, weight, 197 isItalic); 198 } 199 200 // TODO: Remove once internal user stop using private API. nAddFont(long builderPtr, ByteBuffer font, int ttcIndex)201 private static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex) { 202 return nAddFont(builderPtr, font, ttcIndex, -1, -1); 203 } 204 nInitBuilder(String langs, int variant)205 private static native long nInitBuilder(String langs, int variant); 206 207 @CriticalNative nCreateFamily(long mBuilderPtr)208 private static native long nCreateFamily(long mBuilderPtr); 209 210 @CriticalNative nGetBuilderReleaseFunc()211 private static native long nGetBuilderReleaseFunc(); 212 213 @CriticalNative nGetFamilyReleaseFunc()214 private static native long nGetFamilyReleaseFunc(); 215 // By passing -1 to weigth argument, the weight value is resolved by OS/2 table in the font. 216 // By passing -1 to italic argument, the italic value is resolved by OS/2 table in the font. nAddFont(long builderPtr, ByteBuffer font, int ttcIndex, int weight, int isItalic)217 private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex, 218 int weight, int isItalic); nAddFontWeightStyle(long builderPtr, ByteBuffer font, int ttcIndex, int weight, int isItalic)219 private static native boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font, 220 int ttcIndex, int weight, int isItalic); nAddFontFromAssetManager(long builderPtr, AssetManager mgr, String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic)221 private static native boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, 222 String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic); 223 224 // The added axis values are only valid for the next nAddFont* method call. 225 @CriticalNative nAddAxisValue(long builderPtr, int tag, float value)226 private static native void nAddAxisValue(long builderPtr, int tag, float value); 227 } 228