New fallback font which should work on more devices

This commit is contained in:
Constantin A 2018-07-03 13:45:19 +02:00
parent fa57c7eb5e
commit 633f21f777
6 changed files with 113 additions and 113 deletions

View file

@ -18,7 +18,7 @@ ext {
libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory'
siteUrl = 'https://github.com/c1710/blobmoji' siteUrl = 'https://github.com/c1710/blobmoji'
gitUrl = 'https://github.com/c1710/blobmoji.git' gitUrl = 'https://github.com/c1710/blobmoji.git'
libraryVersion = '1.0.11' libraryVersion = '1.0.13'
developerId = 'c1710' developerId = 'c1710'
developerName = 'Constantin A.' developerName = 'Constantin A.'
developerEmail = 'c1710.apps@outlook.com' developerEmail = 'c1710.apps@outlook.com'
@ -33,8 +33,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 27 targetSdkVersion 27
versionCode 12 versionCode 13
versionName "1.0.12" versionName "1.0.13"
} }
@ -49,6 +49,7 @@ dependencies {
implementation 'com.android.support:support-emoji:27.1.1' implementation 'com.android.support:support-emoji:27.1.1'
} }
apply from: 'https://raw.githubusercontent.com/numetriclabz/jcenter/master/installv.gradle' apply from: 'https://raw.githubusercontent.com/numetriclabz/jcenter/master/installv.gradle'
apply from: 'https://raw.githubusercontent.com/numetriclabz/jcenter/master/bintrayv.gradle' apply from: 'https://raw.githubusercontent.com/numetriclabz/jcenter/master/bintrayv.gradle'

View file

@ -1,2 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest package="de.c1710.filemojicompat" />
package="de.c1710.filemojicompat" />

View file

@ -29,6 +29,7 @@ import android.support.text.emoji.MetadataRepo;
* Based on: * Based on:
* https://android.googlesource.com/platform/frameworks/support/+/master/emoji/bundled/src/main/java/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java * https://android.googlesource.com/platform/frameworks/support/+/master/emoji/bundled/src/main/java/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java
* Changes are marked with comments. Formatting and other simple changes are not always marked. * Changes are marked with comments. Formatting and other simple changes are not always marked.
*
* @deprecated Please use {@link FileEmojiCompatConfig#createFromAsset(Context, String)} instead * @deprecated Please use {@link FileEmojiCompatConfig#createFromAsset(Context, String)} instead
* for greater flexibility. * for greater flexibility.
*/ */
@ -38,8 +39,9 @@ public class AssetEmojiCompatConfig extends EmojiCompat.Config {
/** /**
* Create a new configuration for this EmojiCompat * Create a new configuration for this EmojiCompat
*
* @param assetName The file name/path of the requested font * @param assetName The file name/path of the requested font
* @param context Context instance * @param context Context instance
*/ */
public AssetEmojiCompatConfig(@NonNull Context context, public AssetEmojiCompatConfig(@NonNull Context context,
// NEW // NEW
@ -52,12 +54,12 @@ public class AssetEmojiCompatConfig extends EmojiCompat.Config {
* This is the MetadataLoader. Derived from BundledMetadataLoader but with * This is the MetadataLoader. Derived from BundledMetadataLoader but with
* the addition of a custom asset name. * the addition of a custom asset name.
*/ */
private static class AssetMetadataLoader implements EmojiCompat.MetadataRepoLoader{ private static class AssetMetadataLoader implements EmojiCompat.MetadataRepoLoader {
private final Context mContext; private final Context mContext;
// NEW // NEW
private final String assetName; private final String assetName;
private AssetMetadataLoader(@NonNull Context context, private AssetMetadataLoader(@NonNull Context context,
// NEW // NEW
String assetName) { String assetName) {
this.mContext = context.getApplicationContext(); this.mContext = context.getApplicationContext();
@ -96,7 +98,7 @@ public class AssetEmojiCompatConfig extends EmojiCompat.Config {
this.loaderCallback = loaderCallback; this.loaderCallback = loaderCallback;
this.FONT_NAME = FONT_NAME; this.FONT_NAME = FONT_NAME;
} }
// This has been copied from BundledEmojiCompatConfig // This has been copied from BundledEmojiCompatConfig
@Override @Override
public void run() { public void run() {

View file

@ -41,7 +41,10 @@ import java.io.InputStream;
public class FileEmojiCompatConfig extends EmojiCompat.Config { public class FileEmojiCompatConfig extends EmojiCompat.Config {
// The class name is obviously changed from the original file // The class name is obviously changed from the original file
private final static String TAG = "FileEmojiCompatConfig"; private final static String TAG = "FileEmojiCompatConfig";
/**
* The default name of the fallback font
*/
private static final String FONT_FALLBACK = "NoEmojiCompat.ttf";
/** /**
* This boolean indicates whether the fallback solution is used. * This boolean indicates whether the fallback solution is used.
*/ */
@ -50,17 +53,101 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config {
* Indicates whether all emojis should be replaced when the fallback font is used. * Indicates whether all emojis should be replaced when the fallback font is used.
*/ */
private boolean replaceAllOnFallback = false; private boolean replaceAllOnFallback = false;
/** /**
* The default name of the fallback font * Create a new configuration for this EmojiCompat
*
* @param path The file name/path of the requested font
* @param context Context instance
*/ */
private static final String FONT_FALLBACK = "NoEmojiCompat.ttf"; public FileEmojiCompatConfig(@NonNull Context context,
// NEW
@NonNull String path) {
// This one is obviously new
this(context, path, FONT_FALLBACK);
}
/**
* Create a new configuration for this EmojiCompat
*
* @param path The file name/path of the requested font
* @param context Context instance
* @param fallbackFont The asset path of the fallback font
*/
public FileEmojiCompatConfig(@NonNull Context context,
// NEW
@NonNull String path,
@Nullable String fallbackFont) {
// This one is obviously new
this(context, new File(path), fallbackFont);
}
/**
* Create a new configuration for this EmojiCompat based on a file
*
* @param context Context instance
* @param fontFile The file containing the EmojiCompat font
*/
public FileEmojiCompatConfig(@NonNull Context context,
// NEW
@Nullable File fontFile) {
this(context, fontFile, FONT_FALLBACK);
}
/**
* Create a new configuration for this EmojiCompat based on a file
*
* @param context Context instance
* @param fontFile The file containing the EmojiCompat font
* @param fallbackFont The asset path of the fallback font
*/
public FileEmojiCompatConfig(@NonNull Context context,
// NEW
@Nullable File fontFile,
@Nullable String fallbackFont) {
super(new FileMetadataLoader(context,
fontFile,
fallbackFont != null ? fallbackFont : FONT_FALLBACK));
if (fontFile != null && fontFile.exists() && fontFile.canRead()) {
try {
// Is it a font?
Typeface typeface = Typeface.createFromFile(fontFile);
// Is it an EmojiCompat font?
/*
Please note that this will possibly cause a race condition. But all in all it's
better to have a chance of detecting such a non-valid font than either having to
wait for a long time or not being able to detect it at all.
However, since this Thread is started immediately, it should be faster than
the initialization process of EmojiCompat itself...
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
new Thread(() -> {
try {
MetadataRepo.create(typeface, new FileInputStream(fontFile));
} catch (Throwable t) {
fallback = true;
setReplaceAll(false);
Log.w(TAG, "FileEmojiCompatConfig: No valid EmojiCompat font provided. Fallback enabled", t);
}
}).start();
}
} catch (RuntimeException ex) {
fallback = true;
Log.e(TAG, "FileEmojiCompatConfig: Font file corrupt. Fallback enabled", ex);
}
} else {
// The heck, this is not even an actual _file_!
fallback = true;
}
}
/** /**
* Creates a new FileEmojiCompatConfig based on an asset. * Creates a new FileEmojiCompatConfig based on an asset.
* <p/> * <p>
* This means that you can have the flexibility of {@link AssetEmojiCompatConfig} * This means that you can have the flexibility of {@link AssetEmojiCompatConfig}
* while giving your users the choice to optionally override the font. * while giving your users the choice to optionally override the font.
* <p/> * <p>
* The default location for a substituting font is * The default location for a substituting font is
* {@code /sdcard/Android/data/your.apps.package/files/EmojiCompat.ttf}. * {@code /sdcard/Android/data/your.apps.package/files/EmojiCompat.ttf}.
* *
@ -83,13 +170,13 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config {
/** /**
* Creates a new FileEmojiCompatConfig based on an asset. * Creates a new FileEmojiCompatConfig based on an asset.
* <p/> * <p>
* This means that you can have the flexibility of {@link AssetEmojiCompatConfig} * This means that you can have the flexibility of {@link AssetEmojiCompatConfig}
* while giving your users the choice to optionally override the font. * while giving your users the choice to optionally override the font.
* <p/> * <p>
* The default location for a substituting font is * The default location for a substituting font is
* {@code /sdcard/Android/data/your.apps.package/files/EmojiCompat.ttf}. * {@code /sdcard/Android/data/your.apps.package/files/EmojiCompat.ttf}.
* <p/> * <p>
* The default name for the Assets font is {@code NoEmojiCompat.ttf}. * The default name for the Assets font is {@code NoEmojiCompat.ttf}.
* If you wish to use a different name for this font, please use * If you wish to use a different name for this font, please use
* {@link #createFromAsset(Context, String)}. * {@link #createFromAsset(Context, String)}.
@ -101,90 +188,6 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config {
return createFromAsset(context, FONT_FALLBACK); return createFromAsset(context, FONT_FALLBACK);
} }
/**
* Create a new configuration for this EmojiCompat
* @param path The file name/path of the requested font
* @param context Context instance
*/
public FileEmojiCompatConfig(@NonNull Context context,
// NEW
@NonNull String path) {
// This one is obviously new
this(context, path, FONT_FALLBACK);
}
/**
* Create a new configuration for this EmojiCompat
* @param path The file name/path of the requested font
* @param context Context instance
* @param fallbackFont The asset path of the fallback font
*/
public FileEmojiCompatConfig(@NonNull Context context,
// NEW
@NonNull String path,
@Nullable String fallbackFont) {
// This one is obviously new
this(context, new File(path), fallbackFont);
}
/**
* Create a new configuration for this EmojiCompat based on a file
* @param context Context instance
* @param fontFile The file containing the EmojiCompat font
*/
public FileEmojiCompatConfig(@NonNull Context context,
// NEW
@Nullable File fontFile) {
this(context, fontFile, FONT_FALLBACK);
}
/**
* Create a new configuration for this EmojiCompat based on a file
* @param context Context instance
* @param fontFile The file containing the EmojiCompat font
* @param fallbackFont The asset path of the fallback font
*/
public FileEmojiCompatConfig(@NonNull Context context,
// NEW
@Nullable File fontFile,
@Nullable String fallbackFont) {
super(new FileMetadataLoader(context,
fontFile,
fallbackFont != null ? fallbackFont : FONT_FALLBACK));
if(fontFile != null && fontFile.exists() && fontFile.canRead()) {
try {
// Is it a font?
Typeface typeface = Typeface.createFromFile(fontFile);
// Is it an EmojiCompat font?
/*
Please note that this will possibly cause a race condition. But all in all it's
better to have a chance of detecting such a non-valid font than either having to
wait for a long time or not being able to detect it at all.
However, since this Thread is started immediately, it should be faster than
the initialization process of EmojiCompat itself...
*/
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
new Thread(() -> {
try {
MetadataRepo.create(typeface, new FileInputStream(fontFile));
} catch (Throwable t) {
fallback = true;
setReplaceAll(false);
Log.w(TAG, "FileEmojiCompatConfig: No valid EmojiCompat font provided. Fallback enabled", t);
}
}).start();
}
} catch (RuntimeException ex) {
fallback = true;
Log.e(TAG, "FileEmojiCompatConfig: Font file corrupt. Fallback enabled", ex);
}
} else {
// The heck, this is not even an actual _file_!
fallback = true;
}
}
@Override @Override
public FileEmojiCompatConfig setReplaceAll(boolean replaceAll) { public FileEmojiCompatConfig setReplaceAll(boolean replaceAll) {
return setReplaceAll(replaceAll, replaceAllOnFallback); return setReplaceAll(replaceAll, replaceAllOnFallback);
@ -192,19 +195,19 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config {
/** /**
* Replace all emojis * Replace all emojis
* @param replaceAll Whether all emojis should be replaced *
* @param replaceAll Whether all emojis should be replaced
* @param replaceAllOnFallback true if this is supposed to be the case even when using the fallback font. * @param replaceAllOnFallback true if this is supposed to be the case even when using the fallback font.
* Useful if the NoEmojiCompat.ttf is overridden by a "real" EmojiCompat font. * Useful if the NoEmojiCompat.ttf is overridden by a "real" EmojiCompat font.
* @return This EmojiCompat.Config * @return This EmojiCompat.Config
*/ */
public FileEmojiCompatConfig setReplaceAll(boolean replaceAll, boolean replaceAllOnFallback) { public FileEmojiCompatConfig setReplaceAll(boolean replaceAll, boolean replaceAllOnFallback) {
this.replaceAllOnFallback = replaceAllOnFallback; this.replaceAllOnFallback = replaceAllOnFallback;
if(!fallback || replaceAllOnFallback) { if (!fallback || replaceAllOnFallback) {
super.setReplaceAll(replaceAll); super.setReplaceAll(replaceAll);
} } else {
else {
super.setReplaceAll(false); super.setReplaceAll(false);
if(replaceAll) { if (replaceAll) {
// If replaceAll would have been set to false anyway, there's no need for apologizing. // If replaceAll would have been set to false anyway, there's no need for apologizing.
Log.w(TAG, "setReplaceAll: Cannot replace all emojis. Fallback font is active"); Log.w(TAG, "setReplaceAll: Cannot replace all emojis. Fallback font is active");
} }
@ -216,7 +219,7 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config {
* This is the MetadataLoader. Derived from BundledMetadataLoader but with * This is the MetadataLoader. Derived from BundledMetadataLoader but with
* the addition of a custom file name. * the addition of a custom file name.
*/ */
private static class FileMetadataLoader implements EmojiCompat.MetadataRepoLoader{ private static class FileMetadataLoader implements EmojiCompat.MetadataRepoLoader {
private final Context mContext; private final Context mContext;
// NEW // NEW
private final File fontFile; private final File fontFile;
@ -274,8 +277,7 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config {
final InputStream stream = new FileInputStream(FONT_FILE); final InputStream stream = new FileInputStream(FONT_FILE);
MetadataRepo resourceIndex = MetadataRepo.create(typeface, stream); MetadataRepo resourceIndex = MetadataRepo.create(typeface, stream);
loaderCallback.onLoaded(resourceIndex); loaderCallback.onLoaded(resourceIndex);
} } catch (Throwable t) {
catch (Throwable t) {
// Instead of crashing, this one will first try to load the fallback font // Instead of crashing, this one will first try to load the fallback font
try { try {
android.util.Log.w(TAG, "Error while loading the font file.", t); android.util.Log.w(TAG, "Error while loading the font file.", t);

View file

@ -1,16 +1,12 @@
# Project-wide Gradle settings. # Project-wide Gradle settings.
# IDE (e.g. Android Studio) users: # IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override* # Gradle settings configured through the IDE *will override*
# any settings specified in this file. # any settings specified in this file.
# For more details on how to configure your build environment visit # For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html # http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1024m org.gradle.jvmargs=-Xmx1024m
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects