From 19fa3dc772b38b522124b7b58f1987d14c2a7762 Mon Sep 17 00:00:00 2001 From: sspanak Date: Mon, 16 Dec 2024 16:42:59 +0200 Subject: [PATCH] fixed incorrect displaying of word + punctuation in Hindi --- .../github/sspanak/tt9/ime/modes/Mode123.java | 2 +- .../github/sspanak/tt9/ime/modes/ModeABC.java | 2 +- .../sspanak/tt9/ime/modes/ModeCheonjiin.java | 2 +- .../tt9/ime/modes/helpers/AutoSpace.java | 2 +- .../modes/predictions/WordPredictions.java | 2 +- .../sspanak/tt9/languages/EmojiLanguage.java | 2 +- .../tt9/languages/NaturalLanguage.java | 2 +- .../sspanak/tt9/ui/main/keys/SoftKey.java | 2 +- .../sspanak/tt9/ui/main/keys/SoftKeyF5.java | 2 +- .../sspanak/tt9/ui/main/keys/SoftKeyFn.java | 2 +- .../tt9/ui/main/keys/SoftKeyPunctuation.java | 2 +- .../sspanak/tt9/ui/tray/SuggestionsBar.java | 10 +- .../github/sspanak/tt9/util/Characters.java | 159 ------------------ .../java/io/github/sspanak/tt9/util/Text.java | 1 + .../io/github/sspanak/tt9/util/TextTools.java | 2 + .../sspanak/tt9/util/chars/Characters.java | 43 +++++ .../github/sspanak/tt9/util/chars/Emoji.java | 64 +++++++ .../sspanak/tt9/util/chars/Punctuation.java | 75 +++++++++ 18 files changed, 203 insertions(+), 173 deletions(-) delete mode 100644 app/src/main/java/io/github/sspanak/tt9/util/Characters.java create mode 100644 app/src/main/java/io/github/sspanak/tt9/util/chars/Characters.java create mode 100644 app/src/main/java/io/github/sspanak/tt9/util/chars/Emoji.java create mode 100644 app/src/main/java/io/github/sspanak/tt9/util/chars/Punctuation.java diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/Mode123.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/Mode123.java index d799f27a..0feaa4f9 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/Mode123.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/Mode123.java @@ -8,8 +8,8 @@ import io.github.sspanak.tt9.hacks.InputType; import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.NaturalLanguage; import io.github.sspanak.tt9.preferences.settings.SettingsStore; -import io.github.sspanak.tt9.util.Characters; import io.github.sspanak.tt9.util.TextTools; +import io.github.sspanak.tt9.util.chars.Characters; class Mode123 extends ModePassthrough { @Override public int getId() { return MODE_123; } diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeABC.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeABC.java index 8b5e635d..d1605ede 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeABC.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeABC.java @@ -10,7 +10,7 @@ import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.LanguageKind; import io.github.sspanak.tt9.languages.NaturalLanguage; import io.github.sspanak.tt9.preferences.settings.SettingsStore; -import io.github.sspanak.tt9.util.Characters; +import io.github.sspanak.tt9.util.chars.Characters; class ModeABC extends InputMode { private final ArrayList> KEY_CHARACTERS = new ArrayList<>(); diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeCheonjiin.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeCheonjiin.java index fa6a53f4..b63fd15f 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeCheonjiin.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/ModeCheonjiin.java @@ -17,8 +17,8 @@ import io.github.sspanak.tt9.languages.LanguageCollection; import io.github.sspanak.tt9.languages.LanguageKind; import io.github.sspanak.tt9.languages.NaturalLanguage; import io.github.sspanak.tt9.preferences.settings.SettingsStore; -import io.github.sspanak.tt9.util.Characters; import io.github.sspanak.tt9.util.TextTools; +import io.github.sspanak.tt9.util.chars.Characters; class ModeCheonjiin extends InputMode { // used when we want do display a different set of characters for a given key, for example diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java index 23d4ffd6..a4e56da0 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/helpers/AutoSpace.java @@ -7,8 +7,8 @@ import io.github.sspanak.tt9.ime.helpers.TextField; import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.LanguageKind; import io.github.sspanak.tt9.preferences.settings.SettingsStore; -import io.github.sspanak.tt9.util.Characters; import io.github.sspanak.tt9.util.Text; +import io.github.sspanak.tt9.util.chars.Characters; public class AutoSpace { private static final Set PRECEDING_SPACE_PUNCTUATION = Set.of('(', '«', '„'); diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/modes/predictions/WordPredictions.java b/app/src/main/java/io/github/sspanak/tt9/ime/modes/predictions/WordPredictions.java index d95308b1..b872fec9 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/modes/predictions/WordPredictions.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/modes/predictions/WordPredictions.java @@ -7,8 +7,8 @@ import io.github.sspanak.tt9.ime.helpers.TextField; import io.github.sspanak.tt9.languages.EmojiLanguage; import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.preferences.settings.SettingsStore; -import io.github.sspanak.tt9.util.Characters; import io.github.sspanak.tt9.util.TextTools; +import io.github.sspanak.tt9.util.chars.Characters; public class WordPredictions extends Predictions { private final TextField textField; diff --git a/app/src/main/java/io/github/sspanak/tt9/languages/EmojiLanguage.java b/app/src/main/java/io/github/sspanak/tt9/languages/EmojiLanguage.java index 3aac1e5d..6cc9bd67 100644 --- a/app/src/main/java/io/github/sspanak/tt9/languages/EmojiLanguage.java +++ b/app/src/main/java/io/github/sspanak/tt9/languages/EmojiLanguage.java @@ -5,8 +5,8 @@ import androidx.annotation.NonNull; import java.util.ArrayList; import java.util.Locale; -import io.github.sspanak.tt9.util.Characters; import io.github.sspanak.tt9.util.TextTools; +import io.github.sspanak.tt9.util.chars.Characters; public class EmojiLanguage extends Language { final public static String EMOJI_SEQUENCE = "11"; diff --git a/app/src/main/java/io/github/sspanak/tt9/languages/NaturalLanguage.java b/app/src/main/java/io/github/sspanak/tt9/languages/NaturalLanguage.java index f22878cc..e438fc35 100644 --- a/app/src/main/java/io/github/sspanak/tt9/languages/NaturalLanguage.java +++ b/app/src/main/java/io/github/sspanak/tt9/languages/NaturalLanguage.java @@ -9,9 +9,9 @@ import java.util.Locale; import java.util.Map; import io.github.sspanak.tt9.languages.exceptions.InvalidLanguageCharactersException; -import io.github.sspanak.tt9.util.Characters; import io.github.sspanak.tt9.util.Text; import io.github.sspanak.tt9.util.TextTools; +import io.github.sspanak.tt9.util.chars.Characters; public class NaturalLanguage extends Language implements Comparable { diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKey.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKey.java index 087d8876..9379a3da 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKey.java +++ b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKey.java @@ -20,9 +20,9 @@ import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.ime.TraditionalT9; import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.ui.Vibration; -import io.github.sspanak.tt9.util.Characters; import io.github.sspanak.tt9.util.Logger; import io.github.sspanak.tt9.util.Text; +import io.github.sspanak.tt9.util.chars.Characters; public class SoftKey extends androidx.appcompat.widget.AppCompatButton implements View.OnTouchListener, View.OnLongClickListener { private final String LOG_TAG = getClass().getSimpleName(); diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyF5.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyF5.java index d4a698cd..3440b980 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyF5.java +++ b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyF5.java @@ -4,7 +4,7 @@ import android.content.Context; import android.util.AttributeSet; import io.github.sspanak.tt9.R; -import io.github.sspanak.tt9.util.Characters; +import io.github.sspanak.tt9.util.chars.Characters; public class SoftKeyF5 extends SoftKeyFn { public SoftKeyF5(Context context) { diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyFn.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyFn.java index 41306c14..917935cd 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyFn.java +++ b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyFn.java @@ -10,7 +10,7 @@ import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.widget.TextViewCompat; import io.github.sspanak.tt9.R; -import io.github.sspanak.tt9.util.Characters; +import io.github.sspanak.tt9.util.chars.Characters; public class SoftKeyFn extends SoftKeyNumber { public SoftKeyFn(Context context) { super(context);} diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyPunctuation.java b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyPunctuation.java index 965178bf..fddd49a2 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyPunctuation.java +++ b/app/src/main/java/io/github/sspanak/tt9/ui/main/keys/SoftKeyPunctuation.java @@ -5,7 +5,7 @@ import android.util.AttributeSet; import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.languages.LanguageKind; -import io.github.sspanak.tt9.util.Characters; +import io.github.sspanak.tt9.util.chars.Characters; public class SoftKeyPunctuation extends SoftKey { public SoftKeyPunctuation(Context context) { diff --git a/app/src/main/java/io/github/sspanak/tt9/ui/tray/SuggestionsBar.java b/app/src/main/java/io/github/sspanak/tt9/ui/tray/SuggestionsBar.java index 9b891949..73120a04 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ui/tray/SuggestionsBar.java +++ b/app/src/main/java/io/github/sspanak/tt9/ui/tray/SuggestionsBar.java @@ -21,12 +21,12 @@ import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.ui.Vibration; import io.github.sspanak.tt9.ui.main.ResizableMainView; -import io.github.sspanak.tt9.util.Characters; +import io.github.sspanak.tt9.util.chars.Characters; public class SuggestionsBar { private final String STEM_SUFFIX = "… +"; private final String STEM_VARIATION_PREFIX = "…"; - private final String STEM_PUNCTUATION_VARIATION_PREFIX = " "; + private final String STEM_PUNCTUATION_VARIATION_PREFIX = "​"; @NonNull private String stem = ""; private double lastClickTime = 0; @@ -199,7 +199,11 @@ public class SuggestionsBar { // shorten the stem variations if (!stem.isEmpty() && suggestion.length() == stem.length() + 1 && suggestion.toLowerCase().startsWith(stem.toLowerCase())) { String trimmedSuggestion = suggestion.substring(stem.length()); - trimmedSuggestion = Character.isAlphabetic(trimmedSuggestion.charAt(0)) ? STEM_VARIATION_PREFIX + trimmedSuggestion : STEM_PUNCTUATION_VARIATION_PREFIX + trimmedSuggestion; + char firstChar = trimmedSuggestion.charAt(0); + + String prefix = Character.isAlphabetic(firstChar) && !Characters.isCombiningPunctuation(firstChar) ? STEM_VARIATION_PREFIX : STEM_PUNCTUATION_VARIATION_PREFIX; + trimmedSuggestion = prefix + trimmedSuggestion; + suggestions.add(trimmedSuggestion); return; } diff --git a/app/src/main/java/io/github/sspanak/tt9/util/Characters.java b/app/src/main/java/io/github/sspanak/tt9/util/Characters.java deleted file mode 100644 index 17a5cf7d..00000000 --- a/app/src/main/java/io/github/sspanak/tt9/util/Characters.java +++ /dev/null @@ -1,159 +0,0 @@ -package io.github.sspanak.tt9.util; - -import android.graphics.Paint; -import android.os.Build; - -import java.util.ArrayList; -import java.util.Arrays; - -import io.github.sspanak.tt9.languages.Language; -import io.github.sspanak.tt9.languages.LanguageKind; - -public class Characters { - public static final String GR_QUESTION_MARK = ";"; - public static final String NEW_LINE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && new Paint().hasGlyph("⏎") ? "⏎" : "\\n"; - public static final String ZWJ = "\u200D"; - public static final String ZWJ_GRAPHIC = "ZWJ"; - public static final String ZWNJ = "\u200C"; - public static final String ZWNJ_GRAPHIC = "ZWNJ"; - - final public static ArrayList ArabicNumbers = new ArrayList<>(Arrays.asList( - "٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩" - )); - - final public static ArrayList CombiningPunctuation = new ArrayList<>(Arrays.asList( - ',', '-', '\'', ':', ';', '!', '?', '.' - )); - - final public static ArrayList CombiningPunctuationHebrew = new ArrayList<>(Arrays.asList( - ',' , '-', '\'', ':', ';', '!', '?', '.', '"', - '·', GR_QUESTION_MARK.charAt(0), // Greek - '،', '؛', ':', '!', '؟' // Arabic - )); - - final public static ArrayList PunctuationArabic = new ArrayList<>(Arrays.asList( - "،", ".", "-", "(", ")", "&", "~", "`", "'", "\"", "؛", ":", "!", "؟" - )); - - final public static ArrayList PunctuationEnglish = new ArrayList<>(Arrays.asList( - ",", ".", "-", "(", ")", "&", "~", "`", ";", ":", "'", "\"", "!", "?" - )); - - final public static ArrayList PunctuationFrench = new ArrayList<>(Arrays.asList( - ",", ".", "-", "«", "»", "(", ")", "&", "`", "~", ";", ":", "'", "\"", "!", "?" - )); - - final public static ArrayList PunctuationGerman = new ArrayList<>(Arrays.asList( - ",", ".", "-", "„", "“", "(", ")", "&", "~", "`", "'", "\"", ";", ":", "!", "?" - )); - - final public static ArrayList PunctuationGreek = new ArrayList<>(Arrays.asList( - ",", ".", "-", "«", "»", "(", ")", "&", "~", "`", "'", "\"", "·", ":", "!", GR_QUESTION_MARK - )); - - final public static ArrayList PunctuationIndic = new ArrayList<>(Arrays.asList( - ",", ".", "-", ZWJ, ZWNJ, "(", ")", "।", "॰", "॥", "&", "~", "`", ";", ":", "'", "\"", "!", "?" - )); - - final public static ArrayList PunctuationKorean = new ArrayList<>(Arrays.asList( - ",", ".", "~", "1", "(", ")", "&", "-", "`", ";", ":", "'", "\"", "!", "?" - )); - - final public static ArrayList Currency = new ArrayList<>(Arrays.asList( - "$", "€", "₹", "₿", "₩", "¢", "¤", "₺", "₱", "¥", "₽", "£" - )); - - final public static ArrayList Special = new ArrayList<>(Arrays.asList( - " ", "\n", "@", "_", "#", "%", "[", "]", "{", "}", "§", "|", "^", "<", ">", "\\", "/", "=", "*", "+" - )); - - /** - * The English punctuation filtered to contain only valid email characters. - */ - final public static ArrayList> Email = new ArrayList<>(Arrays.asList( - new ArrayList<>(Arrays.asList("@", "_", "#", "%", "{", "}", "|", "^", "/", "=", "*", "+")), - new ArrayList<>(Arrays.asList(".", "-", "&", "~", "`", "'", "!", "?")) - )); - - /** - * Special characters for phone number fields, including both characters for conveniently typing a phone number: "()-", - * as well as command characters such as "," = "slight pause" and ";" = "wait" used in Japan and some other countries. - */ - final public static ArrayList> Phone = new ArrayList<>(Arrays.asList( - new ArrayList<>(Arrays.asList("+", " ")), - new ArrayList<>(Arrays.asList("-", "(", ")", ".", ";", ",")) - )); - - /** - * Special characters for all kinds of numeric fields: integer, decimal with +/- included as necessary. - */ - public static ArrayList> getNumberSpecialCharacters(boolean decimal, boolean signed) { - ArrayList> keyCharacters = new ArrayList<>(); - keyCharacters.add(signed ? new ArrayList<>(Arrays.asList("-", "+")) : new ArrayList<>()); - if (decimal) { - keyCharacters.add(new ArrayList<>(Arrays.asList(".", ","))); - } - return keyCharacters; - } - - final private static ArrayList TextEmoticons = new ArrayList<>(Arrays.asList( - ":)", ":D", ":P", ";)", "\\m/", ":-O", ":|", ":(" - )); - - final private static ArrayList> Emoji = new ArrayList<>(Arrays.asList( - // positive - new ArrayList<>(Arrays.asList( - "🙂", "😀", "🤣", "🤓", "😎", "😛", "😉" - )), - // negative - new ArrayList<>(Arrays.asList( - "🙁", "😢", "😭", "😱", "😲", "😳", "😐", "😠" - )), - // hands - new ArrayList<>(Arrays.asList( - "👍", "👋", "✌️", "👏", "🖖", "🤘", "🤝", "💪", "👎" - )), - // emotions - new ArrayList<>(Arrays.asList( - "❤", "🤗", "😍", "😘", "😇", "😈", "🍺", "🎉", "🥱", "🤔", "🥶", "😬" - )) - )); - - public static boolean isGraphic(char ch) { - return !(ch < 256 || Character.isLetterOrDigit(ch) || Character.isAlphabetic(ch)); - } - - public static boolean noEmojiSupported() { - return Build.VERSION.SDK_INT < Build.VERSION_CODES.M; - } - - public static ArrayList getEmoji(int level) { - if (noEmojiSupported()) { - return new ArrayList<>(TextEmoticons); - } - - if (level < 0 || level >= Emoji.size()) { - return new ArrayList<>(); - } - - Paint paint = new Paint(); - ArrayList availableEmoji = new ArrayList<>(); - for (String emoji : Emoji.get(level)) { - if (paint.hasGlyph(emoji)) { - availableEmoji.add(emoji); - } - } - - return availableEmoji.isEmpty() ? new ArrayList<>(TextEmoticons) : availableEmoji; - } - - public static int getMaxEmojiLevel() { - return Emoji.size(); - } - - public static boolean isCombiningPunctuation(Language language, char ch) { - return - CombiningPunctuation.contains(ch) - || (LanguageKind.isHebrew(language) && CombiningPunctuationHebrew.contains(ch)); - } -} diff --git a/app/src/main/java/io/github/sspanak/tt9/util/Text.java b/app/src/main/java/io/github/sspanak/tt9/util/Text.java index 35175550..0fb272f3 100644 --- a/app/src/main/java/io/github/sspanak/tt9/util/Text.java +++ b/app/src/main/java/io/github/sspanak/tt9/util/Text.java @@ -6,6 +6,7 @@ import java.util.Locale; import io.github.sspanak.tt9.ime.modes.InputMode; import io.github.sspanak.tt9.languages.Language; +import io.github.sspanak.tt9.util.chars.Characters; public class Text extends TextTools { private final Language language; diff --git a/app/src/main/java/io/github/sspanak/tt9/util/TextTools.java b/app/src/main/java/io/github/sspanak/tt9/util/TextTools.java index 16e6fd43..9646ee7d 100644 --- a/app/src/main/java/io/github/sspanak/tt9/util/TextTools.java +++ b/app/src/main/java/io/github/sspanak/tt9/util/TextTools.java @@ -8,6 +8,8 @@ import java.util.Locale; import java.util.TimeZone; import java.util.regex.Pattern; +import io.github.sspanak.tt9.util.chars.Characters; + public class TextTools { private static final Pattern containsOtherThan1 = Pattern.compile("[02-9]"); private static final Pattern combiningString = Pattern.compile("^\\p{M}+$"); diff --git a/app/src/main/java/io/github/sspanak/tt9/util/chars/Characters.java b/app/src/main/java/io/github/sspanak/tt9/util/chars/Characters.java new file mode 100644 index 00000000..fa7a74b6 --- /dev/null +++ b/app/src/main/java/io/github/sspanak/tt9/util/chars/Characters.java @@ -0,0 +1,43 @@ +package io.github.sspanak.tt9.util.chars; + +import java.util.ArrayList; +import java.util.Arrays; + +public class Characters extends Emoji { + final public static ArrayList Currency = new ArrayList<>(Arrays.asList( + "$", "€", "₹", "₿", "₩", "¢", "¤", "₺", "₱", "¥", "₽", "£" + )); + + final public static ArrayList Special = new ArrayList<>(Arrays.asList( + " ", "\n", "@", "_", "#", "%", "[", "]", "{", "}", "§", "|", "^", "<", ">", "\\", "/", "=", "*", "+" + )); + + /** + * The English punctuation filtered to contain only valid email characters. + */ + final public static ArrayList> Email = new ArrayList<>(Arrays.asList( + new ArrayList<>(Arrays.asList("@", "_", "#", "%", "{", "}", "|", "^", "/", "=", "*", "+")), + new ArrayList<>(Arrays.asList(".", "-", "&", "~", "`", "'", "!", "?")) + )); + + /** + * Special characters for phone number fields, including both characters for conveniently typing a phone number: "()-", + * as well as command characters such as "," = "slight pause" and ";" = "wait" used in Japan and some other countries. + */ + final public static ArrayList> Phone = new ArrayList<>(Arrays.asList( + new ArrayList<>(Arrays.asList("+", " ")), + new ArrayList<>(Arrays.asList("-", "(", ")", ".", ";", ",")) + )); + + /** + * Special characters for all kinds of numeric fields: integer, decimal with +/- included as necessary. + */ + public static ArrayList> getNumberSpecialCharacters(boolean decimal, boolean signed) { + ArrayList> keyCharacters = new ArrayList<>(); + keyCharacters.add(signed ? new ArrayList<>(Arrays.asList("-", "+")) : new ArrayList<>()); + if (decimal) { + keyCharacters.add(new ArrayList<>(Arrays.asList(".", ","))); + } + return keyCharacters; + } +} diff --git a/app/src/main/java/io/github/sspanak/tt9/util/chars/Emoji.java b/app/src/main/java/io/github/sspanak/tt9/util/chars/Emoji.java new file mode 100644 index 00000000..78bff168 --- /dev/null +++ b/app/src/main/java/io/github/sspanak/tt9/util/chars/Emoji.java @@ -0,0 +1,64 @@ +package io.github.sspanak.tt9.util.chars; + +import android.graphics.Paint; +import android.os.Build; + +import java.util.ArrayList; +import java.util.Arrays; + +class Emoji extends Punctuation { + final private static ArrayList TextEmoticons = new ArrayList<>(Arrays.asList( + ":)", ":D", ":P", ";)", "\\m/", ":-O", ":|", ":(" + )); + + final private static ArrayList> Emoji = new ArrayList<>(Arrays.asList( + // positive + new ArrayList<>(Arrays.asList( + "🙂", "😀", "🤣", "🤓", "😎", "😛", "😉" + )), + // negative + new ArrayList<>(Arrays.asList( + "🙁", "😢", "😭", "😱", "😲", "😳", "😐", "😠" + )), + // hands + new ArrayList<>(Arrays.asList( + "👍", "👋", "✌️", "👏", "🖖", "🤘", "🤝", "💪", "👎" + )), + // emotions + new ArrayList<>(Arrays.asList( + "❤", "🤗", "😍", "😘", "😇", "😈", "🍺", "🎉", "🥱", "🤔", "🥶", "😬" + )) + )); + + public static boolean isGraphic(char ch) { + return !(ch < 256 || Character.isLetterOrDigit(ch) || Character.isAlphabetic(ch)); + } + + public static boolean noEmojiSupported() { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.M; + } + + public static ArrayList getEmoji(int level) { + if (noEmojiSupported()) { + return new ArrayList<>(TextEmoticons); + } + + if (level < 0 || level >= Emoji.size()) { + return new ArrayList<>(); + } + + Paint paint = new Paint(); + ArrayList availableEmoji = new ArrayList<>(); + for (String emoji : Emoji.get(level)) { + if (paint.hasGlyph(emoji)) { + availableEmoji.add(emoji); + } + } + + return availableEmoji.isEmpty() ? new ArrayList<>(TextEmoticons) : availableEmoji; + } + + public static int getMaxEmojiLevel() { + return Emoji.size(); + } +} diff --git a/app/src/main/java/io/github/sspanak/tt9/util/chars/Punctuation.java b/app/src/main/java/io/github/sspanak/tt9/util/chars/Punctuation.java new file mode 100644 index 00000000..961bef27 --- /dev/null +++ b/app/src/main/java/io/github/sspanak/tt9/util/chars/Punctuation.java @@ -0,0 +1,75 @@ +package io.github.sspanak.tt9.util.chars; + +import android.graphics.Paint; +import android.os.Build; + +import java.util.ArrayList; +import java.util.Arrays; + +import io.github.sspanak.tt9.languages.Language; +import io.github.sspanak.tt9.languages.LanguageKind; + +class Punctuation { + public static final String GR_QUESTION_MARK = ";"; + public static final String NEW_LINE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && new Paint().hasGlyph("⏎") ? "⏎" : "\\n"; + public static final String ZWJ = "\u200D"; + public static final String ZWJ_GRAPHIC = "ZWJ"; + public static final String ZWNJ = "\u200C"; + public static final String ZWNJ_GRAPHIC = "ZWNJ"; + + final public static ArrayList ArabicNumbers = new ArrayList<>(Arrays.asList( + "٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩" + )); + + final public static ArrayList CombiningPunctuation = new ArrayList<>(Arrays.asList( + ',', '-', '\'', ':', ';', '!', '?', '.' + )); + + final private static ArrayList CombiningPunctuationIndic = new ArrayList<>(Arrays.asList( + '्', '़', 'ऽ', 'ः', '।', '॰', '॥' + )); + + + final private static ArrayList CombiningPunctuationHebrew = new ArrayList<>(Arrays.asList( + ',' , '-', '\'', ':', ';', '!', '?', '.', '"' + )); + + final public static ArrayList PunctuationArabic = new ArrayList<>(Arrays.asList( + "،", ".", "-", "(", ")", "&", "~", "`", "'", "\"", "؛", ":", "!", "؟" + )); + + final public static ArrayList PunctuationEnglish = new ArrayList<>(Arrays.asList( + ",", ".", "-", "(", ")", "&", "~", "`", ";", ":", "'", "\"", "!", "?" + )); + + final public static ArrayList PunctuationFrench = new ArrayList<>(Arrays.asList( + ",", ".", "-", "«", "»", "(", ")", "&", "`", "~", ";", ":", "'", "\"", "!", "?" + )); + + final public static ArrayList PunctuationGerman = new ArrayList<>(Arrays.asList( + ",", ".", "-", "„", "“", "(", ")", "&", "~", "`", "'", "\"", ";", ":", "!", "?" + )); + + final public static ArrayList PunctuationGreek = new ArrayList<>(Arrays.asList( + ",", ".", "-", "«", "»", "(", ")", "&", "~", "`", "'", "\"", "·", ":", "!", GR_QUESTION_MARK + )); + + final public static ArrayList PunctuationIndic = new ArrayList<>(Arrays.asList( + ",", ".", "-", ZWJ, ZWNJ, "(", ")", "।", "॰", "॥", "&", "~", "`", ";", ":", "'", "\"", "!", "?" + )); + + final public static ArrayList PunctuationKorean = new ArrayList<>(Arrays.asList( + ",", ".", "~", "1", "(", ")", "&", "-", "`", ";", ":", "'", "\"", "!", "?" + )); + + public static boolean isCombiningPunctuation(Language language, char ch) { + return + CombiningPunctuation.contains(ch) + || (LanguageKind.isIndic(language) && CombiningPunctuationIndic.contains(ch)) + || (LanguageKind.isHebrew(language) && CombiningPunctuationHebrew.contains(ch)); + } + + public static boolean isCombiningPunctuation(char ch) { + return CombiningPunctuation.contains(ch) || CombiningPunctuationIndic.contains(ch) || CombiningPunctuationHebrew.contains(ch); + } +}