From 2d3512a3a2c2dce90fa51e5eff8d839e7d0d8f58 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sun, 29 Apr 2018 18:07:44 +0200 Subject: [PATCH 01/18] Add sources for FileMojiCompat library --- emojicompat/FileMojiCompat/build.gradle | 28 +++ .../filemojicompat/build.gradle | 51 ++++++ .../filemojicompat/proguard-rules.pro | 21 +++ .../src/main/AndroidManifest.xml | 2 + .../src/main/assets/NoEmojiCompat.ttf | Bin 0 -> 45508 bytes .../AssetEmojiCompatConfig.java | 111 ++++++++++++ .../filemojicompat/FileEmojiCompatConfig.java | 154 +++++++++++++++++ emojicompat/FileMojiCompat/gradle.properties | 17 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + emojicompat/FileMojiCompat/gradlew | 160 ++++++++++++++++++ emojicompat/FileMojiCompat/gradlew.bat | 90 ++++++++++ emojicompat/FileMojiCompat/settings.gradle | 1 + 13 files changed, 641 insertions(+) create mode 100644 emojicompat/FileMojiCompat/build.gradle create mode 100644 emojicompat/FileMojiCompat/filemojicompat/build.gradle create mode 100644 emojicompat/FileMojiCompat/filemojicompat/proguard-rules.pro create mode 100644 emojicompat/FileMojiCompat/filemojicompat/src/main/AndroidManifest.xml create mode 100644 emojicompat/FileMojiCompat/filemojicompat/src/main/assets/NoEmojiCompat.ttf create mode 100644 emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/AssetEmojiCompatConfig.java create mode 100644 emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java create mode 100644 emojicompat/FileMojiCompat/gradle.properties create mode 100644 emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.jar create mode 100644 emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.properties create mode 100644 emojicompat/FileMojiCompat/gradlew create mode 100644 emojicompat/FileMojiCompat/gradlew.bat create mode 100644 emojicompat/FileMojiCompat/settings.gradle diff --git a/emojicompat/FileMojiCompat/build.gradle b/emojicompat/FileMojiCompat/build.gradle new file mode 100644 index 000000000..e9ee7ab04 --- /dev/null +++ b/emojicompat/FileMojiCompat/build.gradle @@ -0,0 +1,28 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/emojicompat/FileMojiCompat/filemojicompat/build.gradle b/emojicompat/FileMojiCompat/filemojicompat/build.gradle new file mode 100644 index 000000000..ea0734adc --- /dev/null +++ b/emojicompat/FileMojiCompat/filemojicompat/build.gradle @@ -0,0 +1,51 @@ +apply plugin: 'com.android.library' +buildscript { + repositories { + mavenCentral() + google() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.2' + } +} + +ext { + bintrayRepo = 'FileMojiCompat' + bintrayName = 'filemojicompat' + publishedGroupId = 'de.c1710' + libraryName = 'filemojicompat' + artifact = 'filemojicompat' + libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' + siteUrl = 'https://github.com/c1710/blobmoji' + gitUrl = 'https://github.com/c1710/blobmoji.git' + libraryVersion = '1.0' + developerId = 'c1710' + developerName = 'Constantin A.' + developerEmail = 'c1710.apps@outlook.com' + licenseName = 'The Apache Software License, Version 2.0' + licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + allLicenses = ["Apache-2.0"] +} + +android { + compileSdkVersion 27 + + defaultConfig { + minSdkVersion 14 + targetSdkVersion 27 + versionCode 1 + versionName "1.0" + } + + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + 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/bintrayv.gradle' + diff --git a/emojicompat/FileMojiCompat/filemojicompat/proguard-rules.pro b/emojicompat/FileMojiCompat/filemojicompat/proguard-rules.pro new file mode 100644 index 000000000..f1b424510 --- /dev/null +++ b/emojicompat/FileMojiCompat/filemojicompat/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/AndroidManifest.xml b/emojicompat/FileMojiCompat/filemojicompat/src/main/AndroidManifest.xml new file mode 100644 index 000000000..9333c411b --- /dev/null +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/assets/NoEmojiCompat.ttf b/emojicompat/FileMojiCompat/filemojicompat/src/main/assets/NoEmojiCompat.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8decd7bf8a056b65588fbe7548f936f82ab36271 GIT binary patch literal 45508 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 QnP2l0nU0u&|F_@$59V)JmjD0& literal 0 HcmV?d00001 diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/AssetEmojiCompatConfig.java b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/AssetEmojiCompatConfig.java new file mode 100644 index 000000000..ddf85e2b1 --- /dev/null +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/AssetEmojiCompatConfig.java @@ -0,0 +1,111 @@ +package de.c1710.filemojicompat; +/* + * Original file (https://android.googlesource.com/platform/frameworks/support/+/master/emoji/bundled/src/main/java/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java): + * Copyright (C) 2017 The Android Open Source Project + * Modifications Copyright (C) 2018 Constantin A. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import android.content.Context; +import android.content.res.AssetManager; +import android.support.annotation.NonNull; +import android.support.annotation.RequiresApi; +import android.support.text.emoji.EmojiCompat; +import android.support.text.emoji.MetadataRepo; +import android.util.Log; +import android.support.v4.util.Preconditions; + +/** + * A simple implementation of EmojiCompat.Config using typeface assets. + * Based on: + * 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. + */ +public class AssetEmojiCompatConfig extends EmojiCompat.Config { + // The class name is obviously changed from the original file + + /** + * Create a new configuration for this EmojiCompat + * @param assetName The file name/path of the requested font + * @param context Context instance + */ + public AssetEmojiCompatConfig(@NonNull Context context, + // NEW + @NonNull String assetName) { + // This one is oviously new + super(new AssetMetadataLoader(context, assetName)); + } + + /** + * This is the MetadataLoader. Derived from BundledMetadataLoader but with + * the addition of a custom asset name. + */ + private static class AssetMetadataLoader implements EmojiCompat.MetadataRepoLoader{ + private final Context mContext; + // NEW + private final String assetName; + + private AssetMetadataLoader(@NonNull Context context, + // NEW + String assetName) { + this.mContext = context.getApplicationContext(); + // NEW + this.assetName = assetName; + } + + + // Copied from BundledEmojiCompatConfig + @Override + @RequiresApi(19) + public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) { + // This one doesn't work as it's not android.support + //Preconditions.checkNotNull(loaderCallback, "loaderCallback cannot be null"); + final InitRunnable runnable = new InitRunnable(mContext, loaderCallback, assetName); + final Thread thread = new Thread(runnable); + thread.setDaemon(false); + thread.start(); + } + } + + @RequiresApi(19) + private static class InitRunnable implements Runnable { + // The font name is assigned in the constructor. + private final String FONT_NAME; + // Slightly different variable names + private final EmojiCompat.MetadataRepoLoaderCallback loaderCallback; + private final Context context; + + private InitRunnable(final Context context, + final EmojiCompat.MetadataRepoLoaderCallback loaderCallback, + // NEW parameter + final String FONT_NAME) { + // This has been changed a bit in order to get some consistency + this.context = context; + this.loaderCallback = loaderCallback; + this.FONT_NAME = FONT_NAME; + } + + // This has been copied from BundledEmojiCompatConfig + @Override + public void run() { + try { + final AssetManager assetManager = context.getAssets(); + final MetadataRepo resourceIndex = MetadataRepo.create(assetManager, FONT_NAME); + loaderCallback.onLoaded(resourceIndex); + } catch (Throwable t) { + loaderCallback.onFailed(t); + } + } + } +} diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java new file mode 100644 index 000000000..077fdc27b --- /dev/null +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java @@ -0,0 +1,154 @@ +package de.c1710.filemojicompat; +/* + * Original file (https://android.googlesource.com/platform/frameworks/support/+/master/emoji/bundled/src/main/java/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java): + * Copyright (C) 2017 The Android Open Source Project + * Modifications Copyright (C) 2018 Constantin A. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import android.content.Context; +import android.content.res.AssetManager; +import android.graphics.Typeface; +import android.support.annotation.NonNull; +import android.support.annotation.RequiresApi; +import android.support.text.emoji.EmojiCompat; +import android.support.text.emoji.MetadataRepo; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +/** + * A simple implementation of EmojiCompat.Config using typeface files. + * Based on: + * 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. + */ +public class FileEmojiCompatConfig extends EmojiCompat.Config { + // The class name is obviously changed from the original file + private final static String TAG = "FileEmojiCompatConfig"; + + /** + * This boolean indicates whether the fallback solution is used. + */ + private final boolean 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, new File(path)); + } + + /** + * 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 + @NonNull File fontFile) { + super(new FileMetadataLoader(context, fontFile)); + fallback = !fontFile.exists(); + } + + @Override + public FileEmojiCompatConfig setReplaceAll(boolean replaceAll) { + if(!fallback) { + super.setReplaceAll(replaceAll); + } + else { + super.setReplaceAll(false); + Log.w(TAG, "setReplaceAll: Cannot replace all emojis. Fallback font is active"); + } + return this; + } + + /** + * This is the MetadataLoader. Derived from BundledMetadataLoader but with + * the addition of a custom file name. + */ + private static class FileMetadataLoader implements EmojiCompat.MetadataRepoLoader{ + private final Context mContext; + // NEW + private final File fontFile; + + private FileMetadataLoader(@NonNull Context context, + // NEW + File fontFile) { + this.mContext = context.getApplicationContext(); + // NEW + this.fontFile = fontFile; + } + + + // Copied from BundledEmojiCompatConfig + @Override + @RequiresApi(19) + public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) { + //Preconditions.checkNotNull(loaderCallback, "loaderCallback cannot be null"); + final InitRunnable runnable = new InitRunnable(mContext, loaderCallback, fontFile); + final Thread thread = new Thread(runnable); + thread.setDaemon(false); + thread.start(); + } + } + + @RequiresApi(19) + private static class InitRunnable implements Runnable { + // The font name is assigned in the constructor. + private final File FONT_FILE; + // Slightly different variable names + private final EmojiCompat.MetadataRepoLoaderCallback loaderCallback; + private final Context context; + + private InitRunnable(final Context context, + final EmojiCompat.MetadataRepoLoaderCallback loaderCallback, + // NEW parameter + final File FONT_FILE) { + // This has been changed a bit in order to get some consistency + this.context = context; + this.loaderCallback = loaderCallback; + this.FONT_FILE = FONT_FILE; + } + + @Override + public void run() { + try { + // Changed to load a file + final Typeface typeface = Typeface.createFromFile(FONT_FILE); + final InputStream stream = new FileInputStream(FONT_FILE); + MetadataRepo resourceIndex = MetadataRepo.create(typeface, stream); + loaderCallback.onLoaded(resourceIndex); + } + catch (Throwable t) { + // Instead of crashing, this one will first try to load the fallback font + try { + final AssetManager assetManager = context.getAssets(); + final MetadataRepo resourceIndex = + MetadataRepo.create(assetManager, "NoEmojiCompat.ttf"); + loaderCallback.onLoaded(resourceIndex); + } catch (Throwable t2) { + loaderCallback.onFailed(t); + } + } + } + } +} diff --git a/emojicompat/FileMojiCompat/gradle.properties b/emojicompat/FileMojiCompat/gradle.properties new file mode 100644 index 000000000..869e8cea0 --- /dev/null +++ b/emojicompat/FileMojiCompat/gradle.properties @@ -0,0 +1,17 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1024m + +# When configured, Gradle will run in incubating parallel mode. +# 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 +# org.gradle.parallel=true diff --git a/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.jar b/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ8zCNKueM5c!$)^mKpZNR!eIlFST57ePGQcqCqedAQ3UaUEzpjM--5V4YO zY22VxQm%$2NDnwfK+jkz=i2>NjAM6&P1DdcO<*Xs1-lzdXWn#LGSxwhPH7N%D8-zCgpFWt@`LgNYI+Fh^~nSiQmwH0^>E>*O$47MqfQza@Ce z1wBw;igLc#V2@y-*~Hp?jA1)+MYYyAt|DV_8RQCrRY@sAviO}wv;3gFdO>TE(=9o? z=S(r=0oT`w24=ihA=~iFV5z$ZG74?rmYn#eanx(!Hkxcr$*^KRFJKYYB&l6$WVsJ^ z-Iz#HYmE)Da@&seqG1fXsTER#adA&OrD2-T(z}Cwby|mQf{0v*v3hq~pzF`U`jenT z=XHXeB|fa?Ws$+9ADO0rco{#~+`VM?IXg7N>M0w1fyW1iiKTA@p$y zSiAJ%-Mg{m>&S4r#Tw@?@7ck}#oFo-iZJCWc`hw_J$=rw?omE{^tc59ftd`xq?jzf zo0bFUI=$>O!45{!c4?0KsJmZ#$vuYpZLo_O^oHTmmLMm0J_a{Nn`q5tG1m=0ecv$T z5H7r0DZGl6be@aJ+;26EGw9JENj0oJ5K0=^f-yBW2I0jqVIU};NBp*gF7_KlQnhB6 z##d$H({^HXj@il`*4^kC42&3)(A|tuhs;LygA-EWFSqpe+%#?6HG6}mE215Z4mjO2 zY2^?5$<8&k`O~#~sSc5Fy`5hg5#e{kG>SAbTxCh{y32fHkNryU_c0_6h&$zbWc63T z7|r?X7_H!9XK!HfZ+r?FvBQ$x{HTGS=1VN<>Ss-7M3z|vQG|N}Frv{h-q623@Jz*@ ziXlZIpAuY^RPlu&=nO)pFhML5=ut~&zWDSsn%>mv)!P1|^M!d5AwmSPIckoY|0u9I zTDAzG*U&5SPf+@c_tE_I!~Npfi$?gX(kn=zZd|tUZ_ez(xP+)xS!8=k(<{9@<+EUx zYQgZhjn(0qA#?~Q+EA9oh_Jx5PMfE3#KIh#*cFIFQGi)-40NHbJO&%ZvL|LAqU=Rw zf?Vr4qkUcKtLr^g-6*N-tfk+v8@#Lpl~SgKyH!+m9?T8B>WDWK22;!i5&_N=%f{__ z-LHb`v-LvKqTJZCx~z|Yg;U_f)VZu~q7trb%C6fOKs#eJosw&b$nmwGwP;Bz`=zK4 z>U3;}T_ptP)w=vJaL8EhW;J#SHA;fr13f=r#{o)`dRMOs-T;lp&Toi@u^oB_^pw=P zp#8Geo2?@!h2EYHY?L;ayT}-Df0?TeUCe8Cto{W0_a>!7Gxmi5G-nIIS;X{flm2De z{SjFG%knZoVa;mtHR_`*6)KEf=dvOT3OgT7C7&-4P#4X^B%VI&_57cBbli()(%zZC?Y0b;?5!f22UleQ=9h4_LkcA!Xsqx@q{ko&tvP_V@7epFs}AIpM{g??PA>U(sk$Gum>2Eu zD{Oy{$OF%~?B6>ixQeK9I}!$O0!T3#Ir8MW)j2V*qyJ z8Bg17L`rg^B_#rkny-=<3fr}Y42+x0@q6POk$H^*p3~Dc@5uYTQ$pfaRnIT}Wxb;- zl!@kkZkS=l)&=y|21veY8yz$t-&7ecA)TR|=51BKh(@n|d$EN>18)9kSQ|GqP?aeM ztXd9C&Md$PPF*FVs*GhoHM2L@D$(Qf%%x zwQBUt!jM~GgwluBcwkgwQ!249uPkNz3u@LSYZgmpHgX|P#8!iKk^vSKZ;?)KE$92d z2U>y}VWJ0&zjrIqddM3dz-nU%>bL&KU%SA|LiiUU7Ka|c=jF|vQ1V)Jz`JZe*j<5U6~RVuBEVJoY~ z&GE+F$f>4lN=X4-|9v*5O*Os>>r87u z!_1NSV?_X&HeFR1fOFb8_P)4lybJ6?1BWK`Tv2;4t|x1<#@17UO|hLGnrB%nu)fDk zfstJ4{X4^Y<8Lj<}g2^kksSefQTMuTo?tJLCh zC~>CR#a0hADw!_Vg*5fJwV{~S(j8)~sn>Oyt(ud2$1YfGck77}xN@3U_#T`q)f9!2 zf>Ia;Gwp2_C>WokU%(z2ec8z94pZyhaK+e>3a9sj^-&*V494;p9-xk+u1Jn#N_&xs z59OI2w=PuTErv|aNcK*>3l^W*p3}fjXJjJAXtBA#%B(-0--s;1U#f8gFYW!JL+iVG zV0SSx5w8eVgE?3Sg@eQv)=x<+-JgpVixZQNaZr}3b8sVyVs$@ndkF5FYKka@b+YAh z#nq_gzlIDKEs_i}H4f)(VQ!FSB}j>5znkVD&W0bOA{UZ7h!(FXrBbtdGA|PE1db>s z$!X)WY)u#7P8>^7Pjjj-kXNBuJX3(pJVetTZRNOnR5|RT5D>xmwxhAn)9KF3J05J; z-Mfb~dc?LUGqozC2p!1VjRqUwwDBnJhOua3vCCB-%ykW_ohSe?$R#dz%@Gym-8-RA zjMa_SJSzIl8{9dV+&63e9$4;{=1}w2=l+_j_Dtt@<(SYMbV-18&%F@Zl7F_5! z@xwJ0wiDdO%{}j9PW1(t+8P7Ud79yjY>x>aZYWJL_NI?bI6Y02`;@?qPz_PRqz(7v``20`- z033Dy|4;y6di|>cz|P-z|6c&3f&g^OAt8aN0Zd&0yZ>dq2aFCsE<~Ucf$v{sL=*++ zBxFSa2lfA+Y%U@B&3D=&CBO&u`#*nNc|PCY7XO<}MnG0VR764XrHtrb5zwC*2F!Lp zE<~Vj0;z!S-|3M4DFxuQ=`ShTf28<9p!81(0hFbGNqF%0gg*orez9!qt8e%o@Yfl@ zhvY}{@3&f??}7<`p>FyU;7?VkKbh8_=csozU=|fH&szgZ{=NDCylQ>EH^x5!K3~-V z)_2Y>0uJ`Z0Pb58y`RL+&n@m9tJ)O<%q#&u#DAIt+-rRt0eSe1MTtMl@W)H$b3D)@ z*A-1bUgZI)>HdcI4&W>P4W5{-j=s5p5`cbQ+{(g0+RDnz!TR^mxSLu_y#SDVKrj8i zA^hi6>jMGM;`$9Vfb-Yf!47b)Ow`2OKtNB=z|Kxa$5O}WPo;(Dc^`q(7X8kkeFyO8 z{XOq^07=u|7*P2`m;>PIFf=i80MKUxsN{d2cX0M+REsE*20+WQ79T9&cqT>=I_U% z{=8~^Isg(Nzo~`4iQfIb_#CVCD>#5h>=-Z#5dH}WxYzn%0)GAm6L2WdUdP=0_h>7f z(jh&7%1i(ZOn+}D8$iGK4Vs{pmHl_w4Qm-46H9>4^{3dz^DZDh+dw)6Xd@CpQNK$j z{CU;-cmpK=egplZ3y3%y=sEnCJ^eYVKXzV8H2_r*fJ*%*B;a1_lOpt6)IT1IAK2eB z{rie|uDJUrbgfUE>~C>@RO|m5ex55F{=~Bb4Cucp{ok7Yf9V}QuZ`#Gc|WaqsQlK- zKaV)iMRR__&Ak2Z=IM9R9g5$WM4u{a^C-7uX*!myEym z#_#p^T!P~#Dx$%^K>Y_nj_3J*E_LwJ60-5Xu=LkJAwcP@|0;a&+|+ZX`Jbj9P5;T% z|KOc}4*#4o{U?09`9Hz`Xo-I!P=9XfIrr*MQ}y=$!qgv?_J38^bNb4kM&_OVg^_=Eu-qG5U(fw0KMgH){C8pazq~51rN97hf#20-7=aK0)N|UM H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git a/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.properties b/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..9dc96cf89 --- /dev/null +++ b/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Apr 26 17:31:13 CEST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/emojicompat/FileMojiCompat/gradlew b/emojicompat/FileMojiCompat/gradlew new file mode 100644 index 000000000..9d82f7891 --- /dev/null +++ b/emojicompat/FileMojiCompat/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/emojicompat/FileMojiCompat/gradlew.bat b/emojicompat/FileMojiCompat/gradlew.bat new file mode 100644 index 000000000..8a0b282aa --- /dev/null +++ b/emojicompat/FileMojiCompat/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/emojicompat/FileMojiCompat/settings.gradle b/emojicompat/FileMojiCompat/settings.gradle new file mode 100644 index 000000000..c48a70c8c --- /dev/null +++ b/emojicompat/FileMojiCompat/settings.gradle @@ -0,0 +1 @@ +include ':filemojicompat' From 29f59b037de91b54662f44ef998eb95dc57e1332 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sun, 29 Apr 2018 18:49:33 +0200 Subject: [PATCH 02/18] Add another check to detect unreadable font files --- .../java/de/c1710/filemojicompat/FileEmojiCompatConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java index 077fdc27b..00176fcbc 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java @@ -29,6 +29,7 @@ import android.util.Log; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; +import java.util.concurrent.CopyOnWriteArrayList; /** * A simple implementation of EmojiCompat.Config using typeface files. @@ -66,7 +67,7 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { // NEW @NonNull File fontFile) { super(new FileMetadataLoader(context, fontFile)); - fallback = !fontFile.exists(); + fallback = !fontFile.exists() || !fontFile.canRead(); } @Override From 0d108324e1043f0f39837a3d0cd00ebec9e9f75b Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sun, 29 Apr 2018 18:56:22 +0200 Subject: [PATCH 03/18] Create README.md --- emojicompat/FileMojiCompat/README.md | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 emojicompat/FileMojiCompat/README.md diff --git a/emojicompat/FileMojiCompat/README.md b/emojicompat/FileMojiCompat/README.md new file mode 100644 index 000000000..017352785 --- /dev/null +++ b/emojicompat/FileMojiCompat/README.md @@ -0,0 +1,50 @@ +# FileMojiCompat +## What is this? +This is a library providing an easy solution to use [EmojiCompat](https://developer.android.com/guide/topics/ui/look-and-feel/emoji-compat) +with fonts that are either stored in the `assets`-folder with another name than `NotoColorEmojiCompat.ttf` or you can use +EmojiCompat fonts which are stored anywhere on the device's local storage. +## How do I use it? +There are two different methods included in this library: +1. ### [`AssetEmojiCompatConfig`](https://github.com/C1710/blobmoji/blob/filemojicompat/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/AssetEmojiCompatConfig.java) + You can use this just like you would usually use [`BundledEmojiCompatConfig`](https://developer.android.com/guide/topics/ui/look-and-feel/emoji-compat#bundled-fonts) + except for the detail that you can choose the font's name as the second parameter. + Example: + ```java + EmojiCompat.Config config = new AssetEmojiCompatConfig(getContext(), "Blobmoji.ttf"); + ``` + This will create a new EmojiCompat configuration using the file provided in `assets/Blobmoji.ttf`. +2. ### [`FileEmojiCOmpatConfig`](https://github.com/C1710/blobmoji/blob/filemojicompat/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java) + This is the more complex and interesting option. + Instead of providing a short String containing the font's name, you can provide a [`File`](https://developer.android.com/reference/java/io/File) + (or the String containing the full path of it). + This will try to load the font from this path. + In case it gets into any trouble - let's say because of missing permissions or a non-existent file, it will fallback to using no EmojiCOmpat at all. + (Technically this is wrong as leaving EmojiCompat uninitialized would crash the components using it. There's an explanation below). + Example: + ```java + Context context = getContext(); + File fontFile = new File(context.getExternalFilesDir(null), "emoji/Blobmoji.ttf"), + EmojiCompat.Config config = new FileEmojiCompatConfig(context, fontFile); + ``` + In this example, your app would try to load the font file `Blobmoji.ttf` located at `/storage/emulated/0/Android/data/[your.app.package]/files/Blobmoji.ttf`. + If this file is not available, EmojiCompat won't be visible. + Hint: When accessing a file inside your private directory (i.e. the one used in the example), you _don't_ need storage permissions. + However, if you want to load the font from somewhere else - let's say the `Download` directory, you ***will*** need storage permissions. + But don't worry (too much) - your app won't crash (probably) as this missing file is just being ignored in this case. + +### What happens if I don't provide the font file in `FileEmojiCompatConfig`? +In this case, there won't be a visible difference to not using EmojiCompat. +#### But what does that mean _exactly_? +If you take a look at `EmojiCompat` itself, you'll notice that it isn't build with missing fonts in mind. If anything happens, +`onLoadFailed` is called and EmojiCompat crashes - and so do all components relying on it. +To prevent this case, `FileEmojiCompatConfig` includes a fallback solution - inside the `assets` folder, you'll find a file called [`NoEmojiCompat.ttf`](https://github.com/C1710/blobmoji/blob/filemojicompat/emojicompat/FileMojiCompat/filemojicompat/src/main/assets/NoEmojiCompat.ttf) which +is much smaller than most of the EmojiCompat font files (~40kiB). That's because it only includes 10 characters which are the flags for China, Germany, Spain, France, United Kingdom, Italy, Japan, South Korea, Russia, USA. +These are the flags which where originally included in [Noto Emoji](https://github.com/googlei18n/noto-emoji) and they are only used to _fill_ the font +file with something. +#### WIll my users see these flags when the fallback font is used? +Yes, they will. But only if their device either doesn't support these flags (which is basically impossible) or if they use a device which already uses +these assets as their default emojis. They won't replace any existing emojis. +#### But I did `setReplaceAll(true)`?! +This won't change anything as `FileEmojiCompatConfig` will detect if the font file doesn't exist (or can't be read) and it will simply ignore `setReplaceAll(true)`. +However, this is currently _not_ the case if something else goes wrong, e.g. if the file is not an EmojiCompat font. +But even in this case only these flags are affected. From 420b50869c2266dad367a6e7a7cb4b8050193123 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sun, 29 Apr 2018 19:00:39 +0200 Subject: [PATCH 04/18] Update README.md --- emojicompat/FileMojiCompat/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/emojicompat/FileMojiCompat/README.md b/emojicompat/FileMojiCompat/README.md index 017352785..dcaca7263 100644 --- a/emojicompat/FileMojiCompat/README.md +++ b/emojicompat/FileMojiCompat/README.md @@ -3,6 +3,11 @@ This is a library providing an easy solution to use [EmojiCompat](https://developer.android.com/guide/topics/ui/look-and-feel/emoji-compat) with fonts that are either stored in the `assets`-folder with another name than `NotoColorEmojiCompat.ttf` or you can use EmojiCompat fonts which are stored anywhere on the device's local storage. +## How do I get this library? +That's relatively easy: Just add the following line to your module's `build.gradle` inside `dependencies`: +``` +implementation 'de.c1710:filemojicompat:1.0.1' +``` ## How do I use it? There are two different methods included in this library: 1. ### [`AssetEmojiCompatConfig`](https://github.com/C1710/blobmoji/blob/filemojicompat/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/AssetEmojiCompatConfig.java) From dc4e60cd7a23f63de70d7de476ee23d65093c745 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Tue, 1 May 2018 08:41:18 +0200 Subject: [PATCH 05/18] Update some files for FileMojiCompat --- emojicompat/FileMojiCompat/build.gradle | 56 +++--- .../filemojicompat/build.gradle | 102 +++++----- .../filemojicompat/proguard-rules.pro | 42 ++-- .../src/main/AndroidManifest.xml | 4 +- emojicompat/FileMojiCompat/gradle.properties | 34 ++-- .../gradle/wrapper/gradle-wrapper.properties | 12 +- emojicompat/FileMojiCompat/gradlew.bat | 180 +++++++++--------- emojicompat/FileMojiCompat/settings.gradle | 2 +- 8 files changed, 216 insertions(+), 216 deletions(-) diff --git a/emojicompat/FileMojiCompat/build.gradle b/emojicompat/FileMojiCompat/build.gradle index e9ee7ab04..3fc3f5158 100644 --- a/emojicompat/FileMojiCompat/build.gradle +++ b/emojicompat/FileMojiCompat/build.gradle @@ -1,28 +1,28 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - - repositories { - google() - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:3.1.2' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.2' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/emojicompat/FileMojiCompat/filemojicompat/build.gradle b/emojicompat/FileMojiCompat/filemojicompat/build.gradle index ea0734adc..c1fa6e237 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/build.gradle +++ b/emojicompat/FileMojiCompat/filemojicompat/build.gradle @@ -1,51 +1,51 @@ -apply plugin: 'com.android.library' -buildscript { - repositories { - mavenCentral() - google() - } - dependencies { - classpath 'com.android.tools.build:gradle:3.1.2' - } -} - -ext { - bintrayRepo = 'FileMojiCompat' - bintrayName = 'filemojicompat' - publishedGroupId = 'de.c1710' - libraryName = 'filemojicompat' - artifact = 'filemojicompat' - libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' - siteUrl = 'https://github.com/c1710/blobmoji' - gitUrl = 'https://github.com/c1710/blobmoji.git' - libraryVersion = '1.0' - developerId = 'c1710' - developerName = 'Constantin A.' - developerEmail = 'c1710.apps@outlook.com' - licenseName = 'The Apache Software License, Version 2.0' - licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' - allLicenses = ["Apache-2.0"] -} - -android { - compileSdkVersion 27 - - defaultConfig { - minSdkVersion 14 - targetSdkVersion 27 - versionCode 1 - versionName "1.0" - } - - -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - 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/bintrayv.gradle' - +apply plugin: 'com.android.library' +buildscript { + repositories { + mavenCentral() + google() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.2' + } +} + +ext { + bintrayRepo = 'FileMojiCompat' + bintrayName = 'filemojicompat' + publishedGroupId = 'de.c1710' + libraryName = 'filemojicompat' + artifact = 'filemojicompat' + libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' + siteUrl = 'https://github.com/c1710/blobmoji' + gitUrl = 'https://github.com/c1710/blobmoji.git' + libraryVersion = '1.0.1' + developerId = 'c1710' + developerName = 'Constantin A.' + developerEmail = 'c1710.apps@outlook.com' + licenseName = 'The Apache Software License, Version 2.0' + licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + allLicenses = ["Apache-2.0"] +} + +android { + compileSdkVersion 27 + + defaultConfig { + minSdkVersion 14 + targetSdkVersion 27 + versionCode 2 + versionName "1.0.1" + } + + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + 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/bintrayv.gradle' + diff --git a/emojicompat/FileMojiCompat/filemojicompat/proguard-rules.pro b/emojicompat/FileMojiCompat/filemojicompat/proguard-rules.pro index f1b424510..6e7ffa997 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/proguard-rules.pro +++ b/emojicompat/FileMojiCompat/filemojicompat/proguard-rules.pro @@ -1,21 +1,21 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/AndroidManifest.xml b/emojicompat/FileMojiCompat/filemojicompat/src/main/AndroidManifest.xml index 9333c411b..51b79a617 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/src/main/AndroidManifest.xml +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/AndroidManifest.xml @@ -1,2 +1,2 @@ - + diff --git a/emojicompat/FileMojiCompat/gradle.properties b/emojicompat/FileMojiCompat/gradle.properties index 869e8cea0..9fdc93c10 100644 --- a/emojicompat/FileMojiCompat/gradle.properties +++ b/emojicompat/FileMojiCompat/gradle.properties @@ -1,17 +1,17 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1024m - -# When configured, Gradle will run in incubating parallel mode. -# 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 -# org.gradle.parallel=true +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1024m + +# When configured, Gradle will run in incubating parallel mode. +# 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 +# org.gradle.parallel=true diff --git a/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.properties b/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.properties index 9dc96cf89..870e127a2 100644 --- a/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.properties +++ b/emojicompat/FileMojiCompat/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Apr 26 17:31:13 CEST 2018 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +#Thu Apr 26 17:31:13 CEST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/emojicompat/FileMojiCompat/gradlew.bat b/emojicompat/FileMojiCompat/gradlew.bat index 8a0b282aa..aec99730b 100644 --- a/emojicompat/FileMojiCompat/gradlew.bat +++ b/emojicompat/FileMojiCompat/gradlew.bat @@ -1,90 +1,90 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/emojicompat/FileMojiCompat/settings.gradle b/emojicompat/FileMojiCompat/settings.gradle index c48a70c8c..e91d23c2f 100644 --- a/emojicompat/FileMojiCompat/settings.gradle +++ b/emojicompat/FileMojiCompat/settings.gradle @@ -1 +1 @@ -include ':filemojicompat' +include ':filemojicompat' From a216310a0b57c6aa1a3cef54ef1c021acc4f9e58 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Tue, 1 May 2018 09:45:08 +0200 Subject: [PATCH 06/18] Broken fonts should now be detected correctly. --- .../filemojicompat/build.gradle | 4 ++ .../filemojicompat/FileEmojiCompatConfig.java | 39 +++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/emojicompat/FileMojiCompat/filemojicompat/build.gradle b/emojicompat/FileMojiCompat/filemojicompat/build.gradle index c1fa6e237..28506d027 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/build.gradle +++ b/emojicompat/FileMojiCompat/filemojicompat/build.gradle @@ -38,6 +38,10 @@ android { } + compileOptions { + targetCompatibility 1.8 + sourceCompatibility 1.8 + } } dependencies { diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java index 00176fcbc..95f073e26 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java @@ -1,6 +1,6 @@ package de.c1710.filemojicompat; /* - * Original file (https://android.googlesource.com/platform/frameworks/support/+/master/emoji/bundled/src/main/java/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java): + * Adapted from https://android.googlesource.com/platform/frameworks/support/+/master/emoji/bundled/src/main/java/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java * Copyright (C) 2017 The Android Open Source Project * Modifications Copyright (C) 2018 Constantin A. * @@ -20,6 +20,7 @@ package de.c1710.filemojicompat; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Typeface; +import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; import android.support.text.emoji.EmojiCompat; @@ -29,6 +30,8 @@ import android.util.Log; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -44,7 +47,8 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { /** * This boolean indicates whether the fallback solution is used. */ - private final boolean fallback; + private boolean fallback; + private static final HashMap listeners = new HashMap<>(1); /** * Create a new configuration for this EmojiCompat @@ -67,7 +71,8 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { // NEW @NonNull File fontFile) { super(new FileMetadataLoader(context, fontFile)); - fallback = !fontFile.exists() || !fontFile.canRead(); + // The InitRunable needs to find this config if it fails. + listeners.put(fontFile, this::onFailed); } @Override @@ -77,11 +82,19 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { } else { super.setReplaceAll(false); - Log.w(TAG, "setReplaceAll: Cannot replace all emojis. Fallback font is active"); + if(replaceAll) { + // 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"); + } } return this; } + private void onFailed() { + fallback = true; + setReplaceAll(false); + } + /** * This is the MetadataLoader. Derived from BundledMetadataLoader but with * the addition of a custom file name. @@ -91,9 +104,9 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { // NEW private final File fontFile; - private FileMetadataLoader(@NonNull Context context, - // NEW - File fontFile) { + private FileMetadataLoader(@NonNull Context context, + // NEW + File fontFile) { this.mContext = context.getApplicationContext(); // NEW this.fontFile = fontFile; @@ -142,6 +155,14 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { catch (Throwable t) { // Instead of crashing, this one will first try to load the fallback font try { + /* + This solution is very bad but it's impossible to not use such a solution since + EmojiCompat.Config is very restricted. + */ + if(listeners.containsKey(FONT_FILE)) { + listeners.get(FONT_FILE).onFailed(); + } + android.util.Log.w(TAG, "Error while loading the font file.", t); final AssetManager assetManager = context.getAssets(); final MetadataRepo resourceIndex = MetadataRepo.create(assetManager, "NoEmojiCompat.ttf"); @@ -151,5 +172,9 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { } } } + + interface EmojiFontFailListener { + void onFailed(); + } } } From c05eff4eb11f81f703e5f8aa19ffae92c806fb47 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Tue, 1 May 2018 10:20:41 +0200 Subject: [PATCH 07/18] Add another bad solution to detect non-EmojiCompat-fonts --- .../filemojicompat/build.gradle | 6 +-- .../filemojicompat/FileEmojiCompatConfig.java | 45 ++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/emojicompat/FileMojiCompat/filemojicompat/build.gradle b/emojicompat/FileMojiCompat/filemojicompat/build.gradle index 28506d027..06a51ee8e 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/build.gradle +++ b/emojicompat/FileMojiCompat/filemojicompat/build.gradle @@ -18,7 +18,7 @@ ext { libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' siteUrl = 'https://github.com/c1710/blobmoji' gitUrl = 'https://github.com/c1710/blobmoji.git' - libraryVersion = '1.0.1' + libraryVersion = '1.0.2' developerId = 'c1710' developerName = 'Constantin A.' developerEmail = 'c1710.apps@outlook.com' @@ -33,8 +33,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 27 - versionCode 2 - versionName "1.0.1" + versionCode 4 + versionName "1.0.3" } diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java index 95f073e26..a2001abad 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java @@ -48,7 +48,6 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { * This boolean indicates whether the fallback solution is used. */ private boolean fallback; - private static final HashMap listeners = new HashMap<>(1); /** * Create a new configuration for this EmojiCompat @@ -71,8 +70,38 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { // NEW @NonNull File fontFile) { super(new FileMetadataLoader(context, fontFile)); - // The InitRunable needs to find this config if it fails. - listeners.put(fontFile, this::onFailed); + if(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 @@ -91,8 +120,9 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { } private void onFailed() { + Log.d(TAG, "onFailed: Could not load font"); fallback = true; - setReplaceAll(false); + super.setReplaceAll(false); } /** @@ -155,13 +185,6 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { catch (Throwable t) { // Instead of crashing, this one will first try to load the fallback font try { - /* - This solution is very bad but it's impossible to not use such a solution since - EmojiCompat.Config is very restricted. - */ - if(listeners.containsKey(FONT_FILE)) { - listeners.get(FONT_FILE).onFailed(); - } android.util.Log.w(TAG, "Error while loading the font file.", t); final AssetManager assetManager = context.getAssets(); final MetadataRepo resourceIndex = From da60d4fcdcc94b67be84036215ce41f0a9533c43 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Tue, 1 May 2018 10:22:16 +0200 Subject: [PATCH 08/18] Update version code --- emojicompat/FileMojiCompat/filemojicompat/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emojicompat/FileMojiCompat/filemojicompat/build.gradle b/emojicompat/FileMojiCompat/filemojicompat/build.gradle index 06a51ee8e..d531a93b9 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/build.gradle +++ b/emojicompat/FileMojiCompat/filemojicompat/build.gradle @@ -18,7 +18,7 @@ ext { libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' siteUrl = 'https://github.com/c1710/blobmoji' gitUrl = 'https://github.com/c1710/blobmoji.git' - libraryVersion = '1.0.2' + libraryVersion = '1.0.3' developerId = 'c1710' developerName = 'Constantin A.' developerEmail = 'c1710.apps@outlook.com' From 3667d9b43e63b867249eeee51440e44dd7a3a324 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Tue, 1 May 2018 19:29:54 +0200 Subject: [PATCH 09/18] Hotfix for FileEmojiCompatConfig --- emojicompat/FileMojiCompat/filemojicompat/build.gradle | 6 +++--- .../de/c1710/filemojicompat/FileEmojiCompatConfig.java | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/emojicompat/FileMojiCompat/filemojicompat/build.gradle b/emojicompat/FileMojiCompat/filemojicompat/build.gradle index d531a93b9..4bd4b34be 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/build.gradle +++ b/emojicompat/FileMojiCompat/filemojicompat/build.gradle @@ -18,7 +18,7 @@ ext { libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' siteUrl = 'https://github.com/c1710/blobmoji' gitUrl = 'https://github.com/c1710/blobmoji.git' - libraryVersion = '1.0.3' + libraryVersion = '1.0.5' developerId = 'c1710' developerName = 'Constantin A.' developerEmail = 'c1710.apps@outlook.com' @@ -33,8 +33,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 27 - versionCode 4 - versionName "1.0.3" + versionCode 5 + versionName "1.0.5" } diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java index a2001abad..f531e0cf8 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java @@ -22,6 +22,7 @@ import android.content.res.AssetManager; import android.graphics.Typeface; import android.os.Build; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; import android.support.text.emoji.EmojiCompat; import android.support.text.emoji.MetadataRepo; @@ -68,9 +69,9 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { */ public FileEmojiCompatConfig(@NonNull Context context, // NEW - @NonNull File fontFile) { + @Nullable File fontFile) { super(new FileMetadataLoader(context, fontFile)); - if(fontFile.exists() && fontFile.canRead()) { + if(fontFile != null && fontFile.exists() && fontFile.canRead()) { try { // Is it a font? Typeface typeface = Typeface.createFromFile(fontFile); @@ -136,7 +137,7 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { private FileMetadataLoader(@NonNull Context context, // NEW - File fontFile) { + @Nullable File fontFile) { this.mContext = context.getApplicationContext(); // NEW this.fontFile = fontFile; From 2bd81dce8a4a4a10e8c6c10b78203ba872f5b239 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 15:19:46 +0200 Subject: [PATCH 10/18] Ability added to replace all emojis when using fallback --- .../filemojicompat/build.gradle | 6 +++--- .../filemojicompat/FileEmojiCompatConfig.java | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/emojicompat/FileMojiCompat/filemojicompat/build.gradle b/emojicompat/FileMojiCompat/filemojicompat/build.gradle index 4bd4b34be..31742a2de 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/build.gradle +++ b/emojicompat/FileMojiCompat/filemojicompat/build.gradle @@ -18,7 +18,7 @@ ext { libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' siteUrl = 'https://github.com/c1710/blobmoji' gitUrl = 'https://github.com/c1710/blobmoji.git' - libraryVersion = '1.0.5' + libraryVersion = '1.0.6' developerId = 'c1710' developerName = 'Constantin A.' developerEmail = 'c1710.apps@outlook.com' @@ -33,8 +33,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 27 - versionCode 5 - versionName "1.0.5" + versionCode 6 + versionName "1.0.6" } diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java index f531e0cf8..f23338ff4 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java @@ -34,6 +34,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.ReentrantLock; /** * A simple implementation of EmojiCompat.Config using typeface files. @@ -49,6 +50,10 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { * This boolean indicates whether the fallback solution is used. */ private boolean fallback; + /** + * Indicates whether all emojis should be replaced when the fallback font is used. + */ + private boolean replaceAllOnFallback = false; /** * Create a new configuration for this EmojiCompat @@ -107,7 +112,19 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { @Override public FileEmojiCompatConfig setReplaceAll(boolean replaceAll) { - if(!fallback) { + return setReplaceAll(replaceAll, replaceAllOnFallback); + } + + /** + * Replace all emojis + * @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. + * Useful if the NoEmojiCompat.ttf is overridden by a "real" EmojiCompat font. + * @return This EmojiCompat.Config + */ + public FileEmojiCompatConfig setReplaceAll(boolean replaceAll, boolean replaceAllOnFallback) { + this.replaceAllOnFallback = replaceAllOnFallback; + if(!fallback || replaceAllOnFallback) { super.setReplaceAll(replaceAll); } else { From e7c8f303a444b34a758ec07e43f1fcb4174ea6cc Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 16:04:40 +0200 Subject: [PATCH 11/18] Update README.md --- emojicompat/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emojicompat/README.md b/emojicompat/README.md index 9a619393d..374bb974e 100644 --- a/emojicompat/README.md +++ b/emojicompat/README.md @@ -1,3 +1,4 @@ +# Please note that all these features (except for the Blobmoji EmojiCompat font itself) are now included in their own library which you can find at [FileMojiCompat](FileMojiCompat). This page (and folder) will be updated soon :sweat_smile: ## You can use this font in [EmojiCompat](https://developer.android.com/guide/topics/ui/look-and-feel/emoji-compat.html)! The most important file for this is `NotoEmojiCompat.ttf`. This is the font you'll need. There are three different ways to use this font in EmojiCompat: @@ -53,4 +54,4 @@ The reason for this is same the reason why I made this fork: Users should always have a choice - and by using this solution you can give the users of your app the choice to choose their favorite emoji set*! Plus they don't rely on you updating your app :smiling_imp: -(*as long as it's available as an EmojiCompat font) \ No newline at end of file +(*as long as it's available as an EmojiCompat font) From 52abbd5844e1088a2332c9d3c10091d2448f5e37 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 16:21:15 +0200 Subject: [PATCH 12/18] Update README.md --- emojicompat/FileMojiCompat/README.md | 31 +++++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/emojicompat/FileMojiCompat/README.md b/emojicompat/FileMojiCompat/README.md index dcaca7263..91ee2b16b 100644 --- a/emojicompat/FileMojiCompat/README.md +++ b/emojicompat/FileMojiCompat/README.md @@ -6,7 +6,7 @@ EmojiCompat fonts which are stored anywhere on the device's local storage. ## How do I get this library? That's relatively easy: Just add the following line to your module's `build.gradle` inside `dependencies`: ``` -implementation 'de.c1710:filemojicompat:1.0.1' +implementation 'de.c1710:filemojicompat:1.0.6' ``` ## How do I use it? There are two different methods included in this library: @@ -18,17 +18,17 @@ There are two different methods included in this library: EmojiCompat.Config config = new AssetEmojiCompatConfig(getContext(), "Blobmoji.ttf"); ``` This will create a new EmojiCompat configuration using the file provided in `assets/Blobmoji.ttf`. -2. ### [`FileEmojiCOmpatConfig`](https://github.com/C1710/blobmoji/blob/filemojicompat/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java) +2. ### [`FileEmojiCompatConfig`](https://github.com/C1710/blobmoji/blob/filemojicompat/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java) This is the more complex and interesting option. Instead of providing a short String containing the font's name, you can provide a [`File`](https://developer.android.com/reference/java/io/File) (or the String containing the full path of it). This will try to load the font from this path. - In case it gets into any trouble - let's say because of missing permissions or a non-existent file, it will fallback to using no EmojiCOmpat at all. + In case it gets into any trouble - let's say because of missing permissions or a non-existent file, it will fallback to using no EmojiCompat at all. (Technically this is wrong as leaving EmojiCompat uninitialized would crash the components using it. There's an explanation below). Example: ```java Context context = getContext(); - File fontFile = new File(context.getExternalFilesDir(null), "emoji/Blobmoji.ttf"), + File fontFile = new File(context.getExternalFilesDir(null), "emoji/Blobmoji.ttf"); EmojiCompat.Config config = new FileEmojiCompatConfig(context, fontFile); ``` In this example, your app would try to load the font file `Blobmoji.ttf` located at `/storage/emulated/0/Android/data/[your.app.package]/files/Blobmoji.ttf`. @@ -46,10 +46,25 @@ To prevent this case, `FileEmojiCompatConfig` includes a fallback solution - ins is much smaller than most of the EmojiCompat font files (~40kiB). That's because it only includes 10 characters which are the flags for China, Germany, Spain, France, United Kingdom, Italy, Japan, South Korea, Russia, USA. These are the flags which where originally included in [Noto Emoji](https://github.com/googlei18n/noto-emoji) and they are only used to _fill_ the font file with something. -#### WIll my users see these flags when the fallback font is used? +#### Will my users see these flags when the fallback font is used? Yes, they will. But only if their device either doesn't support these flags (which is basically impossible) or if they use a device which already uses these assets as their default emojis. They won't replace any existing emojis. #### But I did `setReplaceAll(true)`?! -This won't change anything as `FileEmojiCompatConfig` will detect if the font file doesn't exist (or can't be read) and it will simply ignore `setReplaceAll(true)`. -However, this is currently _not_ the case if something else goes wrong, e.g. if the file is not an EmojiCompat font. -But even in this case only these flags are affected. +This won't change anything as `FileEmojiCompatConfig` will detect if the font file is not valid and it will simply ignore `setReplaceAll(true)`. +### I want to let my users only choose another font if they don't like my current one +This is easily possible with the introduction of `FileMojiCompat 1.0.6`. +In this case you override the fallback font by putting your font into the `assets` folder of your app using the name `NoEmojiCompat.ttf`. +Whenever the fallback font is needed (which is the case if the user doesn't specify another one), this font is being used. +In order to prevent blocking the `setReplaceAll` method, you'll have to call it with `setReplaceAll(true, true)`. +The second argument indicates that you want to ignore this `replaceAll`-prevention (if set to `true`. Setting it to `false` won't change anything). +So here's a short example of using this very flexible, yet easy to use method. +But please be aware that changing the emoji font using this snippet isn't very easy as it needs the user to copy (and potentially rename) some files: +```java + Context context = getContext(); + File fontFile = new File(context.getExternalFilesDir(null), "emoji.ttf"); + EmojiCompat.Config config = new FileEmojiCompatConfig(context, fontFile) + .setReplaceAll(true, true); +``` +In this case, the font specified in `assets/NoEmojiCompat.ttf` will be used until `/storage/emulated/0/Android/[yourpackage]/files/emoji.ttf` exists and includes a valid `EmojiCompat` font. +This method combines the easy approach of `AssetEmojiCompatConfig` and the flexibility of `FileEmojiCompatConfig` with some tradeoffs on the usability side. +**_PLEASE use at least this method in your app. It's always better to give the users a choice._** From a58c693eda1499ac33c30202a7c4e93b19e11033 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 16:25:47 +0200 Subject: [PATCH 13/18] Update README.md --- emojicompat/FileMojiCompat/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/emojicompat/FileMojiCompat/README.md b/emojicompat/FileMojiCompat/README.md index 91ee2b16b..59f087ba5 100644 --- a/emojicompat/FileMojiCompat/README.md +++ b/emojicompat/FileMojiCompat/README.md @@ -17,7 +17,8 @@ There are two different methods included in this library: ```java EmojiCompat.Config config = new AssetEmojiCompatConfig(getContext(), "Blobmoji.ttf"); ``` - This will create a new EmojiCompat configuration using the file provided in `assets/Blobmoji.ttf`. + This will create a new EmojiCompat configuration using the file provided in `assets/Blobmoji.ttf`. + Anyhow, I don't recommend using `AssetEmojiCompatConfig` anymore as [this](#i-want-to-let-my-users-only-choose-another-font-if-they-dont-like-my-current-one) approach is more flexible and just as easy to use. There will be a feature to rename the fallback font in the next release. 2. ### [`FileEmojiCompatConfig`](https://github.com/C1710/blobmoji/blob/filemojicompat/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java) This is the more complex and interesting option. Instead of providing a short String containing the font's name, you can provide a [`File`](https://developer.android.com/reference/java/io/File) @@ -51,7 +52,7 @@ Yes, they will. But only if their device either doesn't support these flags (whi these assets as their default emojis. They won't replace any existing emojis. #### But I did `setReplaceAll(true)`?! This won't change anything as `FileEmojiCompatConfig` will detect if the font file is not valid and it will simply ignore `setReplaceAll(true)`. -### I want to let my users only choose another font if they don't like my current one +## I want to let my users only choose another font if they don't like my current one This is easily possible with the introduction of `FileMojiCompat 1.0.6`. In this case you override the fallback font by putting your font into the `assets` folder of your app using the name `NoEmojiCompat.ttf`. Whenever the fallback font is needed (which is the case if the user doesn't specify another one), this font is being used. From c2079263508e2e6805d7a8f42342a95a345222ef Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 16:42:39 +0200 Subject: [PATCH 14/18] Update README.md --- emojicompat/FileMojiCompat/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/emojicompat/FileMojiCompat/README.md b/emojicompat/FileMojiCompat/README.md index 59f087ba5..9aee2887a 100644 --- a/emojicompat/FileMojiCompat/README.md +++ b/emojicompat/FileMojiCompat/README.md @@ -6,7 +6,7 @@ EmojiCompat fonts which are stored anywhere on the device's local storage. ## How do I get this library? That's relatively easy: Just add the following line to your module's `build.gradle` inside `dependencies`: ``` -implementation 'de.c1710:filemojicompat:1.0.6' +implementation 'de.c1710:filemojicompat:1.0.7' ``` ## How do I use it? There are two different methods included in this library: @@ -18,7 +18,7 @@ There are two different methods included in this library: EmojiCompat.Config config = new AssetEmojiCompatConfig(getContext(), "Blobmoji.ttf"); ``` This will create a new EmojiCompat configuration using the file provided in `assets/Blobmoji.ttf`. - Anyhow, I don't recommend using `AssetEmojiCompatConfig` anymore as [this](#i-want-to-let-my-users-only-choose-another-font-if-they-dont-like-my-current-one) approach is more flexible and just as easy to use. There will be a feature to rename the fallback font in the next release. + Anyhow, I don't recommend using `AssetEmojiCompatConfig` anymore as [this](#i-want-to-let-my-users-only-choose-another-font-if-they-dont-like-my-current-one) approach is more flexible and just as easy to use. 2. ### [`FileEmojiCompatConfig`](https://github.com/C1710/blobmoji/blob/filemojicompat/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java) This is the more complex and interesting option. Instead of providing a short String containing the font's name, you can provide a [`File`](https://developer.android.com/reference/java/io/File) @@ -68,4 +68,5 @@ But please be aware that changing the emoji font using this snippet isn't very e ``` In this case, the font specified in `assets/NoEmojiCompat.ttf` will be used until `/storage/emulated/0/Android/[yourpackage]/files/emoji.ttf` exists and includes a valid `EmojiCompat` font. This method combines the easy approach of `AssetEmojiCompatConfig` and the flexibility of `FileEmojiCompatConfig` with some tradeoffs on the usability side. +If you need a different asset path for your fallback file, you can simply add it as another argument when creating this font. This feature has been introduced in `1.0.7`. **_PLEASE use at least this method in your app. It's always better to give the users a choice._** From 8081cce1cbd1915aaddd9a3353900f004efbf820 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 16:43:19 +0200 Subject: [PATCH 15/18] Add the ability to rename the fallback font in FileEmojiCompatConfig --- .../filemojicompat/build.gradle | 6 +- .../filemojicompat/FileEmojiCompatConfig.java | 67 +++++++++++++------ 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/emojicompat/FileMojiCompat/filemojicompat/build.gradle b/emojicompat/FileMojiCompat/filemojicompat/build.gradle index 31742a2de..0dcd5af55 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/build.gradle +++ b/emojicompat/FileMojiCompat/filemojicompat/build.gradle @@ -18,7 +18,7 @@ ext { libraryDescription = 'An EmojiCompat implementation using files from a local file or a file inside your assets directory' siteUrl = 'https://github.com/c1710/blobmoji' gitUrl = 'https://github.com/c1710/blobmoji.git' - libraryVersion = '1.0.6' + libraryVersion = '1.0.7' developerId = 'c1710' developerName = 'Constantin A.' developerEmail = 'c1710.apps@outlook.com' @@ -33,8 +33,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 27 - versionCode 6 - versionName "1.0.6" + versionCode 7 + versionName "1.0.7" } diff --git a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java index f23338ff4..97b72385a 100644 --- a/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java +++ b/emojicompat/FileMojiCompat/filemojicompat/src/main/java/de/c1710/filemojicompat/FileEmojiCompatConfig.java @@ -31,10 +31,6 @@ import android.util.Log; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.ReentrantLock; /** * A simple implementation of EmojiCompat.Config using typeface files. @@ -54,6 +50,10 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { * Indicates whether all emojis should be replaced when the fallback font is used. */ private boolean replaceAllOnFallback = false; + /** + * The default name of the fallback font + */ + private static final String FONT_FALLBACK = "NoEmojiCompat.ttf"; /** * Create a new configuration for this EmojiCompat @@ -64,7 +64,21 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { // NEW @NonNull String path) { // This one is obviously new - this(context, new File(path)); + 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); } /** @@ -75,7 +89,22 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { public FileEmojiCompatConfig(@NonNull Context context, // NEW @Nullable File fontFile) { - super(new FileMetadataLoader(context, 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? @@ -137,12 +166,6 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { return this; } - private void onFailed() { - Log.d(TAG, "onFailed: Could not load font"); - fallback = true; - super.setReplaceAll(false); - } - /** * This is the MetadataLoader. Derived from BundledMetadataLoader but with * the addition of a custom file name. @@ -151,13 +174,16 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { private final Context mContext; // NEW private final File fontFile; + private final String fallbackFont; private FileMetadataLoader(@NonNull Context context, // NEW - @Nullable File fontFile) { + @Nullable File fontFile, + @NonNull String fallbackFont) { this.mContext = context.getApplicationContext(); // NEW this.fontFile = fontFile; + this.fallbackFont = fallbackFont; } @@ -166,7 +192,7 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { @RequiresApi(19) public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) { //Preconditions.checkNotNull(loaderCallback, "loaderCallback cannot be null"); - final InitRunnable runnable = new InitRunnable(mContext, loaderCallback, fontFile); + final InitRunnable runnable = new InitRunnable(mContext, loaderCallback, fontFile, fallbackFont); final Thread thread = new Thread(runnable); thread.setDaemon(false); thread.start(); @@ -175,8 +201,9 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { @RequiresApi(19) private static class InitRunnable implements Runnable { - // The font name is assigned in the constructor. + // The font names are assigned in the constructor. private final File FONT_FILE; + private final String FONT_FALLBACK; // Slightly different variable names private final EmojiCompat.MetadataRepoLoaderCallback loaderCallback; private final Context context; @@ -184,11 +211,13 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { private InitRunnable(final Context context, final EmojiCompat.MetadataRepoLoaderCallback loaderCallback, // NEW parameter - final File FONT_FILE) { + final File FONT_FILE, + final String FONT_FALLBACK) { // This has been changed a bit in order to get some consistency this.context = context; this.loaderCallback = loaderCallback; this.FONT_FILE = FONT_FILE; + this.FONT_FALLBACK = FONT_FALLBACK; } @Override @@ -206,16 +235,12 @@ public class FileEmojiCompatConfig extends EmojiCompat.Config { android.util.Log.w(TAG, "Error while loading the font file.", t); final AssetManager assetManager = context.getAssets(); final MetadataRepo resourceIndex = - MetadataRepo.create(assetManager, "NoEmojiCompat.ttf"); + MetadataRepo.create(assetManager, FONT_FALLBACK); loaderCallback.onLoaded(resourceIndex); } catch (Throwable t2) { loaderCallback.onFailed(t); } } } - - interface EmojiFontFailListener { - void onFailed(); - } } } From d9b17b2ecae3231609382d9fa1579314537ca7a0 Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 16:45:18 +0200 Subject: [PATCH 16/18] Update README.md --- emojicompat/FileMojiCompat/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emojicompat/FileMojiCompat/README.md b/emojicompat/FileMojiCompat/README.md index 9aee2887a..b6295b488 100644 --- a/emojicompat/FileMojiCompat/README.md +++ b/emojicompat/FileMojiCompat/README.md @@ -68,5 +68,5 @@ But please be aware that changing the emoji font using this snippet isn't very e ``` In this case, the font specified in `assets/NoEmojiCompat.ttf` will be used until `/storage/emulated/0/Android/[yourpackage]/files/emoji.ttf` exists and includes a valid `EmojiCompat` font. This method combines the easy approach of `AssetEmojiCompatConfig` and the flexibility of `FileEmojiCompatConfig` with some tradeoffs on the usability side. -If you need a different asset path for your fallback file, you can simply add it as another argument when creating this font. This feature has been introduced in `1.0.7`. +If you need a different asset path for your fallback file, you can simply add it as another argument when creating this font. This feature has been introduced in `1.0.7`. **_PLEASE use at least this method in your app. It's always better to give the users a choice._** From 643bbcde8ba7aaa67cc3d69a71207bcfe96e2f8d Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 16:52:51 +0200 Subject: [PATCH 17/18] Update README.md --- emojicompat/FileMojiCompat/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emojicompat/FileMojiCompat/README.md b/emojicompat/FileMojiCompat/README.md index b6295b488..882c69e71 100644 --- a/emojicompat/FileMojiCompat/README.md +++ b/emojicompat/FileMojiCompat/README.md @@ -68,5 +68,5 @@ But please be aware that changing the emoji font using this snippet isn't very e ``` In this case, the font specified in `assets/NoEmojiCompat.ttf` will be used until `/storage/emulated/0/Android/[yourpackage]/files/emoji.ttf` exists and includes a valid `EmojiCompat` font. This method combines the easy approach of `AssetEmojiCompatConfig` and the flexibility of `FileEmojiCompatConfig` with some tradeoffs on the usability side. -If you need a different asset path for your fallback file, you can simply add it as another argument when creating this font. This feature has been introduced in `1.0.7`. +If you need a different asset path for your fallback file, you can simply add it as another argument for `FileEmojiCompatConfig`. This feature has been introduced in `1.0.7`. **_PLEASE use at least this method in your app. It's always better to give the users a choice._** From d35eba8bce082d325f627ffff84c4e79947907ba Mon Sep 17 00:00:00 2001 From: Constantin A <10349490+C1710@users.noreply.github.com> Date: Sat, 5 May 2018 17:01:06 +0200 Subject: [PATCH 18/18] Removed duplicate files --- emojicompat/AssetEmojiCompatConfig.java | 110 ----------------------- emojicompat/FileEmojiCompatConfig.java | 114 ------------------------ emojicompat/NoEmojiCompat.ttf | Bin 45508 -> 0 bytes 3 files changed, 224 deletions(-) delete mode 100644 emojicompat/AssetEmojiCompatConfig.java delete mode 100644 emojicompat/FileEmojiCompatConfig.java delete mode 100644 emojicompat/NoEmojiCompat.ttf diff --git a/emojicompat/AssetEmojiCompatConfig.java b/emojicompat/AssetEmojiCompatConfig.java deleted file mode 100644 index dd6fc1ced..000000000 --- a/emojicompat/AssetEmojiCompatConfig.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Original file (https://android.googlesource.com/platform/frameworks/support/+/master/emoji/bundled/src/main/java/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java): - * Copyright (C) 2017 The Android Open Source Project - * Modifications Copyright (C) 2018 Constantin A. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import android.content.Context; -import android.content.res.AssetManager; -import android.support.annotation.NonNull; -import android.support.annotation.RequiresApi; -import android.support.text.emoji.EmojiCompat; -import android.support.text.emoji.MetadataRepo; -import android.util.Log; -import android.support.v4.util.Preconditions; - -/** - * A simple implementation of EmojiCompat.Config using typeface assets. - * Based on: - * 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. - */ -public class AssetEmojiCompatConfig extends EmojiCompat.Config { - // The class name is obviously changed from the original file - - /** - * Create a new configuration for this EmojiCompat - * @param assetName The file name/path of the requested font - * @param context Context instance - */ - public AssetEmojiCompatConfig(@NonNull Context context, - // NEW - @NonNull String assetName) { - // This one is oviously new - super(new AssetMetadataLoader(context, assetName)); - } - - /** - * This is the MetadataLoader. Derived from BundledMetadataLoader but with - * the addition of a custom asset name. - */ - private static class AssetMetadataLoader implements EmojiCompat.MetadataRepoLoader{ - private final Context mContext; - // NEW - private final String assetName; - - private AssetMetadataLoader(@NonNull Context context, - // NEW - String assetName) { - this.mContext = context.getApplicationContext(); - // NEW - this.assetName = assetName; - } - - - // Copied from BundledEmojiCompatConfig - @Override - @RequiresApi(19) - public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) { - // This one doesn't work as it's not android.support - //Preconditions.checkNotNull(loaderCallback, "loaderCallback cannot be null"); - final InitRunnable runnable = new InitRunnable(mContext, loaderCallback, assetName); - final Thread thread = new Thread(runnable); - thread.setDaemon(false); - thread.start(); - } - } - - @RequiresApi(19) - private static class InitRunnable implements Runnable { - // The font name is assigned in the constructor. - private final String FONT_NAME; - // Slightly different variable names - private final EmojiCompat.MetadataRepoLoaderCallback loaderCallback; - private final Context context; - - private InitRunnable(final Context context, - final EmojiCompat.MetadataRepoLoaderCallback loaderCallback, - // NEW parameter - final String FONT_NAME) { - // This has been changed a bit in order to get some consistency - this.context = context; - this.loaderCallback = loaderCallback; - this.FONT_NAME = FONT_NAME; - } - - // This has been copied from BundledEmojiCompatConfig - @Override - public void run() { - try { - final AssetManager assetManager = context.getAssets(); - final MetadataRepo resourceIndex = MetadataRepo.create(assetManager, FONT_NAME); - loaderCallback.onLoaded(resourceIndex); - } catch (Throwable t) { - loaderCallback.onFailed(t); - } - } - } -} diff --git a/emojicompat/FileEmojiCompatConfig.java b/emojicompat/FileEmojiCompatConfig.java deleted file mode 100644 index 1ec9975d0..000000000 --- a/emojicompat/FileEmojiCompatConfig.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.keylesspalace.tusky; -/* - * Original file (https://android.googlesource.com/platform/frameworks/support/+/master/emoji/bundled/src/main/java/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java): - * Copyright (C) 2017 The Android Open Source Project - * Modifications Copyright (C) 2018 Constantin A. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import android.content.Context; -import android.graphics.Typeface; -import android.support.annotation.NonNull; -import android.support.annotation.RequiresApi; -import android.support.text.emoji.EmojiCompat; -import android.support.text.emoji.MetadataRepo; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - -/** - * A simple implementation of EmojiCompat.Config using typeface files. - * Based on: - * 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. - */ -public class FileEmojiCompatConfig extends EmojiCompat.Config { - // The class name is obviously changed from the original file - - /** - * 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 - super(new FileMetadataLoader(context, path)); - } - - /** - * This is the MetadataLoader. Derived from BundledMetadataLoader but with - * the addition of a custom file name. - */ - private static class FileMetadataLoader implements EmojiCompat.MetadataRepoLoader{ - private final Context mContext; - // NEW - private final String fileName; - - private FileMetadataLoader(@NonNull Context context, - // NEW - String fileName) { - this.mContext = context.getApplicationContext(); - // NEW - this.fileName = fileName; - } - - - // Copied from BundledEmojiCompatConfig - @Override - @RequiresApi(19) - public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) { - //Preconditions.checkNotNull(loaderCallback, "loaderCallback cannot be null"); - final InitRunnable runnable = new InitRunnable(mContext, loaderCallback, fileName); - final Thread thread = new Thread(runnable); - thread.setDaemon(false); - thread.start(); - } - } - - @RequiresApi(19) - private static class InitRunnable implements Runnable { - // The font name is assigned in the constructor. - private final String FONT_NAME; - // Slightly different variable names - private final EmojiCompat.MetadataRepoLoaderCallback loaderCallback; - private final Context context; - - private InitRunnable(final Context context, - final EmojiCompat.MetadataRepoLoaderCallback loaderCallback, - // NEW parameter - final String FONT_NAME) { - // This has been changed a bit in order to get some consistency - this.context = context; - this.loaderCallback = loaderCallback; - this.FONT_NAME = FONT_NAME; - } - - // This has been copied from BundledEmojiCompatConfig - @Override - public void run() { - try { - final Typeface typeface = Typeface.createFromFile(FONT_NAME); - final File fontFile = new File(FONT_NAME); - final InputStream stream = new FileInputStream(fontFile); - final MetadataRepo resourceIndex = MetadataRepo.create(typeface, stream); - loaderCallback.onLoaded(resourceIndex); - } catch (Throwable t) { - loaderCallback.onFailed(t); - } - } - } -} diff --git a/emojicompat/NoEmojiCompat.ttf b/emojicompat/NoEmojiCompat.ttf deleted file mode 100644 index 8decd7bf8a056b65588fbe7548f936f82ab36271..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45508 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 QnP2l0nU0u&|F_@$59V)JmjD0&