135 lines
5.9 KiB
Java
135 lines
5.9 KiB
Java
package androidx.core.graphics;
|
|
|
|
import android.content.Context;
|
|
import android.content.res.Resources;
|
|
import android.graphics.Typeface;
|
|
import android.net.Uri;
|
|
import android.os.CancellationSignal;
|
|
import android.util.Log;
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.annotation.RequiresApi;
|
|
import androidx.annotation.RestrictTo;
|
|
import androidx.collection.SimpleArrayMap;
|
|
import androidx.core.content.res.FontResourcesParserCompat;
|
|
import androidx.core.provider.FontsContractCompat;
|
|
import java.lang.reflect.Array;
|
|
import java.lang.reflect.Constructor;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.nio.ByteBuffer;
|
|
import java.util.List;
|
|
@RequiresApi(24)
|
|
@RestrictTo({RestrictTo.Scope.LIBRARY_GROUP_PREFIX})
|
|
public class TypefaceCompatApi24Impl extends TypefaceCompatBaseImpl {
|
|
private static final String ADD_FONT_WEIGHT_STYLE_METHOD = "addFontWeightStyle";
|
|
private static final String CREATE_FROM_FAMILIES_WITH_DEFAULT_METHOD = "createFromFamiliesWithDefault";
|
|
private static final String FONT_FAMILY_CLASS = "android.graphics.FontFamily";
|
|
private static final String TAG = "TypefaceCompatApi24Impl";
|
|
private static final Method sAddFontWeightStyle;
|
|
private static final Method sCreateFromFamiliesWithDefault;
|
|
private static final Class<?> sFontFamily;
|
|
private static final Constructor<?> sFontFamilyCtor;
|
|
|
|
static {
|
|
Method method;
|
|
Method method2;
|
|
Class<?> cls;
|
|
Constructor<?> constructor = null;
|
|
try {
|
|
cls = Class.forName("android.graphics.FontFamily");
|
|
Constructor<?> constructor2 = cls.getConstructor(new Class[0]);
|
|
Class<?> cls2 = Integer.TYPE;
|
|
method = cls.getMethod("addFontWeightStyle", ByteBuffer.class, cls2, List.class, cls2, Boolean.TYPE);
|
|
method2 = Typeface.class.getMethod("createFromFamiliesWithDefault", Array.newInstance(cls, 1).getClass());
|
|
constructor = constructor2;
|
|
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
|
Log.e("TypefaceCompatApi24Impl", e.getClass().getName(), e);
|
|
cls = null;
|
|
method2 = null;
|
|
method = null;
|
|
}
|
|
sFontFamilyCtor = constructor;
|
|
sFontFamily = cls;
|
|
sAddFontWeightStyle = method;
|
|
sCreateFromFamiliesWithDefault = method2;
|
|
}
|
|
|
|
private static boolean addFontWeightStyle(Object obj, ByteBuffer byteBuffer, int i, int i2, boolean z2) {
|
|
try {
|
|
return ((Boolean) sAddFontWeightStyle.invoke(obj, byteBuffer, Integer.valueOf(i), null, Integer.valueOf(i2), Boolean.valueOf(z2))).booleanValue();
|
|
} catch (IllegalAccessException | InvocationTargetException unused) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static Typeface createFromFamiliesWithDefault(Object obj) {
|
|
try {
|
|
Object newInstance = Array.newInstance(sFontFamily, 1);
|
|
Array.set(newInstance, 0, obj);
|
|
return (Typeface) sCreateFromFamiliesWithDefault.invoke(null, newInstance);
|
|
} catch (IllegalAccessException | InvocationTargetException unused) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static boolean isUsable() {
|
|
Method method = sAddFontWeightStyle;
|
|
if (method == null) {
|
|
Log.w("TypefaceCompatApi24Impl", "Unable to collect necessary private methods.Fallback to legacy implementation.");
|
|
}
|
|
return method != null;
|
|
}
|
|
|
|
private static Object newFamily() {
|
|
try {
|
|
return sFontFamilyCtor.newInstance(new Object[0]);
|
|
} catch (IllegalAccessException | InstantiationException | InvocationTargetException unused) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override // androidx.core.graphics.TypefaceCompatBaseImpl
|
|
@Nullable
|
|
public Typeface createFromFontFamilyFilesResourceEntry(Context context, FontResourcesParserCompat.FontFamilyFilesResourceEntry fontFamilyFilesResourceEntry, Resources resources, int i) {
|
|
Object newFamily = newFamily();
|
|
if (newFamily == null) {
|
|
return null;
|
|
}
|
|
FontResourcesParserCompat.FontFileResourceEntry[] entries = fontFamilyFilesResourceEntry.getEntries();
|
|
for (FontResourcesParserCompat.FontFileResourceEntry fontFileResourceEntry : entries) {
|
|
ByteBuffer copyToDirectBuffer = TypefaceCompatUtil.copyToDirectBuffer(context, resources, fontFileResourceEntry.getResourceId());
|
|
if (copyToDirectBuffer == null || !addFontWeightStyle(newFamily, copyToDirectBuffer, fontFileResourceEntry.getTtcIndex(), fontFileResourceEntry.getWeight(), fontFileResourceEntry.isItalic())) {
|
|
return null;
|
|
}
|
|
}
|
|
return createFromFamiliesWithDefault(newFamily);
|
|
}
|
|
|
|
@Override // androidx.core.graphics.TypefaceCompatBaseImpl
|
|
@Nullable
|
|
public Typeface createFromFontInfo(Context context, @Nullable CancellationSignal cancellationSignal, @NonNull FontsContractCompat.FontInfo[] fontInfoArr, int i) {
|
|
Object newFamily = newFamily();
|
|
if (newFamily == null) {
|
|
return null;
|
|
}
|
|
SimpleArrayMap simpleArrayMap = new SimpleArrayMap();
|
|
for (FontsContractCompat.FontInfo fontInfo : fontInfoArr) {
|
|
Uri uri = fontInfo.getUri();
|
|
ByteBuffer byteBuffer = (ByteBuffer) simpleArrayMap.get(uri);
|
|
if (byteBuffer == null) {
|
|
byteBuffer = TypefaceCompatUtil.mmap(context, cancellationSignal, uri);
|
|
simpleArrayMap.put(uri, byteBuffer);
|
|
}
|
|
if (byteBuffer == null || !addFontWeightStyle(newFamily, byteBuffer, fontInfo.getTtcIndex(), fontInfo.getWeight(), fontInfo.isItalic())) {
|
|
return null;
|
|
}
|
|
}
|
|
Typeface createFromFamiliesWithDefault = createFromFamiliesWithDefault(newFamily);
|
|
if (createFromFamiliesWithDefault == null) {
|
|
return null;
|
|
}
|
|
return Typeface.create(createFromFamiliesWithDefault, i);
|
|
}
|
|
}
|