package android.graphics;
import android.annotation.Nullable;
import android.content.res.AssetManager;
import android.graphics.fonts.FontVariationAxis;
import android.text.TextUtils;
import android.util.Log;
import dalvik.annotation.optimization.CriticalNative;
import libcore.util.NativeAllocationRegistry;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class FontFamily {
private static String TAG = "FontFamily";
private static final NativeAllocationRegistry sBuilderRegistry = new NativeAllocationRegistry(
FontFamily.class.getClassLoader(), nGetBuilderReleaseFunc(), 64);
private @Nullable Runnable mNativeBuilderCleaner;
private static final NativeAllocationRegistry sFamilyRegistry = new NativeAllocationRegistry(
FontFamily.class.getClassLoader(), nGetFamilyReleaseFunc(), 64);
public long mNativePtr;
private long mBuilderPtr;
public FontFamily() {
mBuilderPtr = nInitBuilder(null, 0);
mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr);
}
public FontFamily(@Nullable String[] langs, int variant) {
final String langsString;
if (langs == null || langs.length == 0) {
langsString = null;
} else if (langs.length == 1) {
langsString = langs[0];
} else {
langsString = TextUtils.join(",", langs);
}
mBuilderPtr = nInitBuilder(langsString, variant);
mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr);
}
public boolean freeze() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen");
}
mNativePtr = nCreateFamily(mBuilderPtr);
mNativeBuilderCleaner.run();
mBuilderPtr = 0;
if (mNativePtr != 0) {
sFamilyRegistry.registerNativeAllocation(this, mNativePtr);
}
return mNativePtr != 0;
}
public void abortCreation() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen or abandoned");
}
mNativeBuilderCleaner.run();
mBuilderPtr = 0;
}
public boolean addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight,
int italic) {
if (mBuilderPtr == 0) {
throw new IllegalStateException("Unable to call addFont after freezing.");
}
try (FileInputStream file = new FileInputStream(path)) {
FileChannel fileChannel = file.getChannel();
long fontSize = fileChannel.size();
ByteBuffer fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
if (axes != null) {
for (FontVariationAxis axis : axes) {
nAddAxisValue(mBuilderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue());
}
}
return nAddFont(mBuilderPtr, fontBuffer, ttcIndex, weight, italic);
} catch (IOException e) {
Log.e(TAG, "Error mapping font file " + path);
return false;
}
}
public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes,
int weight, int italic) {
if (mBuilderPtr == 0) {
throw new IllegalStateException("Unable to call addFontWeightStyle after freezing.");
}
if (axes != null) {
for (FontVariationAxis axis : axes) {
nAddAxisValue(mBuilderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue());
}
}
return nAddFontWeightStyle(mBuilderPtr, font, ttcIndex, weight, italic);
}
public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie,
boolean isAsset, int ttcIndex, int weight, int isItalic,
FontVariationAxis[] axes) {
if (mBuilderPtr == 0) {
throw new IllegalStateException("Unable to call addFontFromAsset after freezing.");
}
if (axes != null) {
for (FontVariationAxis axis : axes) {
nAddAxisValue(mBuilderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue());
}
}
return nAddFontFromAssetManager(mBuilderPtr, mgr, path, cookie, isAsset, ttcIndex, weight,
isItalic);
}
private static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex) {
return nAddFont(builderPtr, font, ttcIndex, -1, -1);
}
private static native long nInitBuilder(String langs, int variant);
@CriticalNative
private static native long nCreateFamily(long mBuilderPtr);
@CriticalNative
private static native long nGetBuilderReleaseFunc();
@CriticalNative
private static native long nGetFamilyReleaseFunc();
private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex,
int weight, int isItalic);
private static native boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font,
int ttcIndex, int weight, int isItalic);
private static native boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr,
String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic);
@CriticalNative
private static native void nAddAxisValue(long builderPtr, int tag, float value);
}