mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-23 09:30:53 +00:00
Merge pull request #90 from alexandrius/master
Fix Georgian automatic uppercase since Georgian script doesn't have uppercase
This commit is contained in:
commit
363e27dc5e
5 changed files with 234 additions and 200 deletions
|
@ -36,6 +36,7 @@ import org.dslul.openboard.inputmethod.keyboard.internal.UniqueKeysCache;
|
|||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodSubtype;
|
||||
import org.dslul.openboard.inputmethod.latin.common.StringUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||
|
@ -104,7 +105,9 @@ public final class KeyboardLayoutSet {
|
|||
boolean mProximityCharsCorrectionEnabled;
|
||||
boolean mSupportsSplitLayout;
|
||||
boolean mAllowRedundantMoreKeys;
|
||||
public ElementParams() {}
|
||||
|
||||
public ElementParams() {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Params {
|
||||
|
@ -147,7 +150,7 @@ public final class KeyboardLayoutSet {
|
|||
}
|
||||
|
||||
public static int getScriptId(final Resources resources,
|
||||
@Nonnull final InputMethodSubtype subtype) {
|
||||
@Nonnull final InputMethodSubtype subtype) {
|
||||
final Integer value = sScriptIdsForSubtypes.get(subtype);
|
||||
if (null == value) {
|
||||
final int scriptId = Builder.readScriptId(resources, subtype);
|
||||
|
@ -162,26 +165,28 @@ public final class KeyboardLayoutSet {
|
|||
mParams = params;
|
||||
}
|
||||
|
||||
public static final String LOCALE_GEORGIAN = "ka";
|
||||
|
||||
@Nonnull
|
||||
public Keyboard getKeyboard(final int baseKeyboardLayoutSetElementId) {
|
||||
final int keyboardLayoutSetElementId;
|
||||
switch (mParams.mMode) {
|
||||
case KeyboardId.MODE_PHONE:
|
||||
if (baseKeyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS) {
|
||||
keyboardLayoutSetElementId = KeyboardId.ELEMENT_PHONE_SYMBOLS;
|
||||
} else {
|
||||
keyboardLayoutSetElementId = KeyboardId.ELEMENT_PHONE;
|
||||
}
|
||||
break;
|
||||
case KeyboardId.MODE_NUMBER:
|
||||
case KeyboardId.MODE_DATE:
|
||||
case KeyboardId.MODE_TIME:
|
||||
case KeyboardId.MODE_DATETIME:
|
||||
keyboardLayoutSetElementId = KeyboardId.ELEMENT_NUMBER;
|
||||
break;
|
||||
default:
|
||||
keyboardLayoutSetElementId = baseKeyboardLayoutSetElementId;
|
||||
break;
|
||||
case KeyboardId.MODE_PHONE:
|
||||
if (baseKeyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS) {
|
||||
keyboardLayoutSetElementId = KeyboardId.ELEMENT_PHONE_SYMBOLS;
|
||||
} else {
|
||||
keyboardLayoutSetElementId = KeyboardId.ELEMENT_PHONE;
|
||||
}
|
||||
break;
|
||||
case KeyboardId.MODE_NUMBER:
|
||||
case KeyboardId.MODE_DATE:
|
||||
case KeyboardId.MODE_TIME:
|
||||
case KeyboardId.MODE_DATETIME:
|
||||
keyboardLayoutSetElementId = KeyboardId.ELEMENT_NUMBER;
|
||||
break;
|
||||
default:
|
||||
keyboardLayoutSetElementId = baseKeyboardLayoutSetElementId;
|
||||
break;
|
||||
}
|
||||
|
||||
ElementParams elementParams = mParams.mKeyboardLayoutSetElementIdToParamsMap.get(
|
||||
|
@ -197,6 +202,7 @@ public final class KeyboardLayoutSet {
|
|||
|
||||
mParams.mIsSplitLayoutEnabled = mParams.mIsSplitLayoutEnabledByUser
|
||||
&& elementParams.mSupportsSplitLayout;
|
||||
|
||||
final KeyboardId id = new KeyboardId(keyboardLayoutSetElementId, mParams);
|
||||
try {
|
||||
return getKeyboard(elementParams, id);
|
||||
|
@ -279,8 +285,7 @@ public final class KeyboardLayoutSet {
|
|||
// be locked down.
|
||||
// TODO: Switch to {@code UserManagerCompat.isUserUnlocked()} in the support-v4 library
|
||||
// when it becomes publicly available.
|
||||
@UserManagerCompatUtils.LockState
|
||||
final int lockState = UserManagerCompatUtils.getUserLockState(context);
|
||||
@UserManagerCompatUtils.LockState final int lockState = UserManagerCompatUtils.getUserLockState(context);
|
||||
if (lockState == UserManagerCompatUtils.LOCK_STATE_LOCKED) {
|
||||
params.mNoSettingsKey = true;
|
||||
}
|
||||
|
@ -295,8 +300,7 @@ public final class KeyboardLayoutSet {
|
|||
public Builder setSubtype(@Nonnull final RichInputMethodSubtype subtype) {
|
||||
final boolean asciiCapable = subtype.getmSubtype().isAsciiCapable();
|
||||
// TODO: Consolidate with {@link InputAttributes}.
|
||||
@SuppressWarnings("deprecation")
|
||||
final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
|
||||
@SuppressWarnings("deprecation") final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
|
||||
mPackageName, FORCE_ASCII, mParams.mEditorInfo);
|
||||
final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii(
|
||||
mParams.mEditorInfo.imeOptions)
|
||||
|
@ -361,7 +365,7 @@ public final class KeyboardLayoutSet {
|
|||
}
|
||||
|
||||
private static int readScriptIdFromTagFeature(final Resources resources,
|
||||
final XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||
final XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||
final TypedArray featureAttr = resources.obtainAttributes(Xml.asAttributeSet(parser),
|
||||
R.styleable.KeyboardLayoutSet_Feature);
|
||||
try {
|
||||
|
@ -473,33 +477,33 @@ public final class KeyboardLayoutSet {
|
|||
final int variation = inputType & InputType.TYPE_MASK_VARIATION;
|
||||
|
||||
switch (inputType & InputType.TYPE_MASK_CLASS) {
|
||||
case InputType.TYPE_CLASS_NUMBER:
|
||||
return KeyboardId.MODE_NUMBER;
|
||||
case InputType.TYPE_CLASS_DATETIME:
|
||||
switch (variation) {
|
||||
case InputType.TYPE_DATETIME_VARIATION_DATE:
|
||||
return KeyboardId.MODE_DATE;
|
||||
case InputType.TYPE_DATETIME_VARIATION_TIME:
|
||||
return KeyboardId.MODE_TIME;
|
||||
default: // InputType.TYPE_DATETIME_VARIATION_NORMAL
|
||||
return KeyboardId.MODE_DATETIME;
|
||||
}
|
||||
case InputType.TYPE_CLASS_PHONE:
|
||||
return KeyboardId.MODE_PHONE;
|
||||
case InputType.TYPE_CLASS_TEXT:
|
||||
if (InputTypeUtils.isEmailVariation(variation)) {
|
||||
return KeyboardId.MODE_EMAIL;
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
|
||||
return KeyboardId.MODE_URL;
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
|
||||
return KeyboardId.MODE_IM;
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
|
||||
case InputType.TYPE_CLASS_NUMBER:
|
||||
return KeyboardId.MODE_NUMBER;
|
||||
case InputType.TYPE_CLASS_DATETIME:
|
||||
switch (variation) {
|
||||
case InputType.TYPE_DATETIME_VARIATION_DATE:
|
||||
return KeyboardId.MODE_DATE;
|
||||
case InputType.TYPE_DATETIME_VARIATION_TIME:
|
||||
return KeyboardId.MODE_TIME;
|
||||
default: // InputType.TYPE_DATETIME_VARIATION_NORMAL
|
||||
return KeyboardId.MODE_DATETIME;
|
||||
}
|
||||
case InputType.TYPE_CLASS_PHONE:
|
||||
return KeyboardId.MODE_PHONE;
|
||||
case InputType.TYPE_CLASS_TEXT:
|
||||
if (InputTypeUtils.isEmailVariation(variation)) {
|
||||
return KeyboardId.MODE_EMAIL;
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
|
||||
return KeyboardId.MODE_URL;
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
|
||||
return KeyboardId.MODE_IM;
|
||||
} else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
|
||||
return KeyboardId.MODE_TEXT;
|
||||
} else {
|
||||
return KeyboardId.MODE_TEXT;
|
||||
}
|
||||
default:
|
||||
return KeyboardId.MODE_TEXT;
|
||||
} else {
|
||||
return KeyboardId.MODE_TEXT;
|
||||
}
|
||||
default:
|
||||
return KeyboardId.MODE_TEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
package org.dslul.openboard.inputmethod.latin.common;
|
||||
|
||||
import android.renderscript.Script;
|
||||
|
||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -26,6 +29,7 @@ import javax.annotation.Nonnull;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
public final class StringUtils {
|
||||
|
||||
public static final int CAPITALIZE_NONE = 0; // No caps, or mixed case
|
||||
public static final int CAPITALIZE_FIRST = 1; // First only
|
||||
public static final int CAPITALIZE_ALL = 2; // All caps
|
||||
|
@ -47,8 +51,10 @@ public final class StringUtils {
|
|||
|
||||
// Taken from android.text.TextUtils. We are extensively using this method in many places,
|
||||
// some of which don't have the android libraries available.
|
||||
|
||||
/**
|
||||
* Returns true if the string is null or 0-length.
|
||||
*
|
||||
* @param str the string to be examined
|
||||
* @return true if str is null or zero length
|
||||
*/
|
||||
|
@ -57,18 +63,20 @@ public final class StringUtils {
|
|||
}
|
||||
|
||||
// Taken from android.text.TextUtils to cut the dependency to the Android framework.
|
||||
|
||||
/**
|
||||
* Returns a string containing the tokens joined by delimiters.
|
||||
*
|
||||
* @param delimiter the delimiter
|
||||
* @param tokens an array objects to be joined. Strings will be formed from
|
||||
* the objects by calling object.toString().
|
||||
* @param tokens an array objects to be joined. Strings will be formed from
|
||||
* the objects by calling object.toString().
|
||||
*/
|
||||
@Nonnull
|
||||
public static String join(@Nonnull final CharSequence delimiter,
|
||||
@Nonnull final Iterable<?> tokens) {
|
||||
@Nonnull final Iterable<?> tokens) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean firstTime = true;
|
||||
for (final Object token: tokens) {
|
||||
for (final Object token : tokens) {
|
||||
if (firstTime) {
|
||||
firstTime = false;
|
||||
} else {
|
||||
|
@ -80,10 +88,12 @@ public final class StringUtils {
|
|||
}
|
||||
|
||||
// Taken from android.text.TextUtils to cut the dependency to the Android framework.
|
||||
|
||||
/**
|
||||
* Returns true if a and b are equal, including if they are both null.
|
||||
* <p><i>Note: In platform versions 1.1 and earlier, this method only worked well if
|
||||
* both the arguments were instances of String.</i></p>
|
||||
*
|
||||
* @param a first CharSequence to check
|
||||
* @param b second CharSequence to check
|
||||
* @return true if a and b are equal
|
||||
|
@ -126,7 +136,7 @@ public final class StringUtils {
|
|||
}
|
||||
|
||||
public static boolean containsInArray(@Nonnull final String text,
|
||||
@Nonnull final String[] array) {
|
||||
@Nonnull final String[] array) {
|
||||
for (final String element : array) {
|
||||
if (text.equals(element)) {
|
||||
return true;
|
||||
|
@ -144,7 +154,7 @@ public final class StringUtils {
|
|||
private static final String SEPARATOR_FOR_COMMA_SPLITTABLE_TEXT = ",";
|
||||
|
||||
public static boolean containsInCommaSplittableText(@Nonnull final String text,
|
||||
@Nullable final String extraValues) {
|
||||
@Nullable final String extraValues) {
|
||||
if (isEmpty(extraValues)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -153,7 +163,7 @@ public final class StringUtils {
|
|||
|
||||
@Nonnull
|
||||
public static String removeFromCommaSplittableTextIfExists(@Nonnull final String text,
|
||||
@Nullable final String extraValues) {
|
||||
@Nullable final String extraValues) {
|
||||
if (isEmpty(extraValues)) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
@ -172,7 +182,7 @@ public final class StringUtils {
|
|||
|
||||
/**
|
||||
* Remove duplicates from an array of strings.
|
||||
*
|
||||
* <p>
|
||||
* This method will always keep the first occurrence of all strings at their position
|
||||
* in the array, removing the subsequent ones.
|
||||
*/
|
||||
|
@ -199,7 +209,7 @@ public final class StringUtils {
|
|||
|
||||
@Nonnull
|
||||
public static String capitalizeFirstCodePoint(@Nonnull final String s,
|
||||
@Nonnull final Locale locale) {
|
||||
@Nonnull final Locale locale) {
|
||||
if (s.length() <= 1) {
|
||||
return s.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
||||
}
|
||||
|
@ -212,7 +222,7 @@ public final class StringUtils {
|
|||
|
||||
@Nonnull
|
||||
public static String capitalizeFirstAndDowncaseRest(@Nonnull final String s,
|
||||
@Nonnull final Locale locale) {
|
||||
@Nonnull final Locale locale) {
|
||||
if (s.length() <= 1) {
|
||||
return s.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
||||
}
|
||||
|
@ -238,14 +248,15 @@ public final class StringUtils {
|
|||
|
||||
/**
|
||||
* Converts a range of a string to an array of code points.
|
||||
*
|
||||
* @param charSequence the source string.
|
||||
* @param startIndex the start index inside the string in java chars, inclusive.
|
||||
* @param endIndex the end index inside the string in java chars, exclusive.
|
||||
* @param startIndex the start index inside the string in java chars, inclusive.
|
||||
* @param endIndex the end index inside the string in java chars, exclusive.
|
||||
* @return a new array of code points. At most endIndex - startIndex, but possibly less.
|
||||
*/
|
||||
@Nonnull
|
||||
public static int[] toCodePointArray(@Nonnull final CharSequence charSequence,
|
||||
final int startIndex, final int endIndex) {
|
||||
final int startIndex, final int endIndex) {
|
||||
final int length = charSequence.length();
|
||||
if (length <= 0) {
|
||||
return EMPTY_CODEPOINTS;
|
||||
|
@ -259,7 +270,7 @@ public final class StringUtils {
|
|||
|
||||
/**
|
||||
* Copies the codepoints in a CharSequence to an int array.
|
||||
*
|
||||
* <p>
|
||||
* This method assumes there is enough space in the array to store the code points. The size
|
||||
* can be measured with Character#codePointCount(CharSequence, int, int) before passing to this
|
||||
* method. If the int array is too small, an ArrayIndexOutOfBoundsException will be thrown.
|
||||
|
@ -268,19 +279,19 @@ public final class StringUtils {
|
|||
* This method can optionally downcase code points before copying them, but it pays no attention
|
||||
* to locale while doing so.
|
||||
*
|
||||
* @param destination the int array.
|
||||
* @param destination the int array.
|
||||
* @param charSequence the CharSequence.
|
||||
* @param startIndex the start index inside the string in java chars, inclusive.
|
||||
* @param endIndex the end index inside the string in java chars, exclusive.
|
||||
* @param downCase if this is true, code points will be downcased before being copied.
|
||||
* @param startIndex the start index inside the string in java chars, inclusive.
|
||||
* @param endIndex the end index inside the string in java chars, exclusive.
|
||||
* @param downCase if this is true, code points will be downcased before being copied.
|
||||
* @return the number of copied code points.
|
||||
*/
|
||||
public static int copyCodePointsAndReturnCodePointCount(@Nonnull final int[] destination,
|
||||
@Nonnull final CharSequence charSequence, final int startIndex, final int endIndex,
|
||||
final boolean downCase) {
|
||||
@Nonnull final CharSequence charSequence, final int startIndex, final int endIndex,
|
||||
final boolean downCase) {
|
||||
int destIndex = 0;
|
||||
for (int index = startIndex; index < endIndex;
|
||||
index = Character.offsetByCodePoints(charSequence, index, 1)) {
|
||||
index = Character.offsetByCodePoints(charSequence, index, 1)) {
|
||||
final int codePoint = Character.codePointAt(charSequence, index);
|
||||
// TODO: stop using this, as it's not aware of the locale and does not always do
|
||||
// the right thing.
|
||||
|
@ -301,7 +312,7 @@ public final class StringUtils {
|
|||
* Construct a String from a code point array
|
||||
*
|
||||
* @param codePoints a code point array that is null terminated when its logical length is
|
||||
* shorter than the array length.
|
||||
* shorter than the array length.
|
||||
* @return a string constructed from the code point array.
|
||||
*/
|
||||
@Nonnull
|
||||
|
@ -335,7 +346,7 @@ public final class StringUtils {
|
|||
int capsCount = 1;
|
||||
int letterCount = 1;
|
||||
for (index = text.offsetByCodePoints(index, 1); index < len;
|
||||
index = text.offsetByCodePoints(index, 1)) {
|
||||
index = text.offsetByCodePoints(index, 1)) {
|
||||
if (1 != capsCount && letterCount != capsCount) break;
|
||||
final int codePoint = text.codePointAt(index);
|
||||
if (Character.isUpperCase(codePoint)) {
|
||||
|
@ -381,7 +392,7 @@ public final class StringUtils {
|
|||
}
|
||||
|
||||
public static boolean isIdenticalAfterCapitalizeEachWord(@Nonnull final String text,
|
||||
@Nonnull final int[] sortedSeparators) {
|
||||
@Nonnull final int[] sortedSeparators) {
|
||||
boolean needsCapsNext = true;
|
||||
final int len = text.length();
|
||||
for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
|
||||
|
@ -402,7 +413,7 @@ public final class StringUtils {
|
|||
// which should be capitalized together in *some* cases.
|
||||
@Nonnull
|
||||
public static String capitalizeEachWord(@Nonnull final String text,
|
||||
@Nonnull final int[] sortedSeparators, @Nonnull final Locale locale) {
|
||||
@Nonnull final int[] sortedSeparators, @Nonnull final Locale locale) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
boolean needsCapsNext = true;
|
||||
final int len = text.length();
|
||||
|
@ -421,7 +432,7 @@ public final class StringUtils {
|
|||
|
||||
/**
|
||||
* Approximates whether the text before the cursor looks like a URL.
|
||||
*
|
||||
* <p>
|
||||
* This is not foolproof, but it should work well in the practice.
|
||||
* Essentially it walks backward from the cursor until it finds something that's not a letter,
|
||||
* digit, or common URL symbol like underscore. If it hasn't found a period yet, then it
|
||||
|
@ -430,9 +441,9 @@ public final class StringUtils {
|
|||
* - starts with www and contains a period
|
||||
* - starts with a slash preceded by either a slash, whitespace, or start-of-string
|
||||
* Then it looks like a URL and we return true. Otherwise, we return false.
|
||||
*
|
||||
* <p>
|
||||
* Note: this method is called quite often, and should be fast.
|
||||
*
|
||||
* <p>
|
||||
* TODO: This will return that "abc./def" and ".abc/def" look like URLs to keep down the
|
||||
* code complexity, but ideally it should not. It's acceptable for now.
|
||||
*/
|
||||
|
@ -491,7 +502,7 @@ public final class StringUtils {
|
|||
|
||||
/**
|
||||
* Examines the string and returns whether we're inside a double quote.
|
||||
*
|
||||
* <p>
|
||||
* This is used to decide whether we should put an automatic space before or after a double
|
||||
* quote character. If we're inside a quotation, then we want to close it, so we want a space
|
||||
* after and not before. Otherwise, we want to open the quotation, so we want a space before
|
||||
|
@ -596,10 +607,11 @@ public final class StringUtils {
|
|||
|
||||
@Nullable
|
||||
public static String toTitleCaseOfKeyLabel(@Nullable final String label,
|
||||
@Nonnull final Locale locale) {
|
||||
if (label == null) {
|
||||
@Nonnull final Locale locale) {
|
||||
if (label == null || !ScriptUtils.scriptSupportsUppercase(locale.getLanguage())) {
|
||||
return label;
|
||||
}
|
||||
|
||||
return label.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
||||
}
|
||||
|
||||
|
@ -661,7 +673,7 @@ public final class StringUtils {
|
|||
|
||||
@Nonnull
|
||||
protected String joinStringArray(@Nonnull final String[] stringArray,
|
||||
@Nullable final String delimiter) {
|
||||
@Nullable final String delimiter) {
|
||||
if (delimiter == null) {
|
||||
return Arrays.toString(stringArray);
|
||||
}
|
||||
|
@ -676,6 +688,7 @@ public final class StringUtils {
|
|||
|
||||
/**
|
||||
* Returns whether the last composed word contains line-breaking character (e.g. CR or LF).
|
||||
*
|
||||
* @param text the text to be examined.
|
||||
* @return {@code true} if the last composed word contains line-breaking separator.
|
||||
*/
|
||||
|
|
|
@ -172,7 +172,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public void loadSettings(final Context context, final Locale locale,
|
||||
@Nonnull final InputAttributes inputAttributes) {
|
||||
@Nonnull final InputAttributes inputAttributes) {
|
||||
mSettingsValuesLock.lock();
|
||||
mContext = context;
|
||||
try {
|
||||
|
@ -204,20 +204,20 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
|
||||
// Accessed from the settings interface, hence public
|
||||
public static boolean readKeypressSoundEnabled(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
return prefs.getBoolean(PREF_SOUND_ON,
|
||||
res.getBoolean(R.bool.config_default_sound_enabled));
|
||||
}
|
||||
|
||||
public static boolean readVibrationEnabled(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
final boolean hasVibrator = AudioAndHapticFeedbackManager.getInstance().hasVibrator();
|
||||
return hasVibrator && prefs.getBoolean(PREF_VIBRATE_ON,
|
||||
res.getBoolean(R.bool.config_default_vibration_enabled));
|
||||
}
|
||||
|
||||
public static boolean readAutoCorrectEnabled(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
return prefs.getBoolean(PREF_AUTO_CORRECTION, true);
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public static boolean readBlockPotentiallyOffensive(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
return prefs.getBoolean(PREF_BLOCK_POTENTIALLY_OFFENSIVE,
|
||||
res.getBoolean(R.bool.config_block_potentially_offensive));
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public static boolean readGestureInputEnabled(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
return readFromBuildConfigIfGestureInputEnabled(res)
|
||||
&& prefs.getBoolean(PREF_GESTURE_INPUT, true);
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public static boolean readKeyPreviewPopupEnabled(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
final boolean defaultKeyPreviewPopup = res.getBoolean(
|
||||
R.bool.config_default_key_preview_popup);
|
||||
if (!readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
|
||||
|
@ -259,26 +259,26 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public static int readKeyPreviewPopupDismissDelay(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
return Integer.parseInt(prefs.getString(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
|
||||
Integer.toString(res.getInteger(
|
||||
R.integer.config_key_preview_linger_timeout))));
|
||||
}
|
||||
|
||||
public static String readPrefAdditionalSubtypes(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
final String predefinedPrefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(
|
||||
res.getStringArray(R.array.predefined_subtypes));
|
||||
return prefs.getString(PREF_CUSTOM_INPUT_STYLES, predefinedPrefSubtypes);
|
||||
}
|
||||
|
||||
public static void writePrefAdditionalSubtypes(final SharedPreferences prefs,
|
||||
final String prefSubtypes) {
|
||||
final String prefSubtypes) {
|
||||
prefs.edit().putString(PREF_CUSTOM_INPUT_STYLES, prefSubtypes).apply();
|
||||
}
|
||||
|
||||
public static float readKeypressSoundVolume(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
final float volume = prefs.getFloat(
|
||||
PREF_KEYPRESS_SOUND_VOLUME, UNDEFINED_PREFERENCE_VALUE_FLOAT);
|
||||
return (volume != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? volume
|
||||
|
@ -295,7 +295,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public static int readKeyLongpressTimeout(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
final int milliseconds = prefs.getInt(
|
||||
PREF_KEY_LONGPRESS_TIMEOUT, UNDEFINED_PREFERENCE_VALUE_INT);
|
||||
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
|
||||
|
@ -307,7 +307,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public static int readKeypressVibrationDuration(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
final int milliseconds = prefs.getInt(
|
||||
PREF_VIBRATION_DURATION_SETTINGS, UNDEFINED_PREFERENCE_VALUE_INT);
|
||||
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
|
||||
|
@ -324,19 +324,19 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public static float readKeyPreviewAnimationScale(final SharedPreferences prefs,
|
||||
final String prefKey, final float defaultValue) {
|
||||
final String prefKey, final float defaultValue) {
|
||||
final float fraction = prefs.getFloat(prefKey, UNDEFINED_PREFERENCE_VALUE_FLOAT);
|
||||
return (fraction != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? fraction : defaultValue;
|
||||
}
|
||||
|
||||
public static int readKeyPreviewAnimationDuration(final SharedPreferences prefs,
|
||||
final String prefKey, final int defaultValue) {
|
||||
final String prefKey, final int defaultValue) {
|
||||
final int milliseconds = prefs.getInt(prefKey, UNDEFINED_PREFERENCE_VALUE_INT);
|
||||
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds : defaultValue;
|
||||
}
|
||||
|
||||
public static float readKeyboardHeight(final SharedPreferences prefs,
|
||||
final float defaultValue) {
|
||||
final float defaultValue) {
|
||||
final float percentage = prefs.getFloat(
|
||||
Settings.PREF_KEYBOARD_HEIGHT_SCALE, UNDEFINED_PREFERENCE_VALUE_FLOAT);
|
||||
return (percentage != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? percentage : defaultValue;
|
||||
|
@ -355,7 +355,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
public static boolean readShowSetupWizardIcon(final SharedPreferences prefs,
|
||||
final Context context) {
|
||||
final Context context) {
|
||||
if (!prefs.contains(PREF_SHOW_SETUP_WIZARD_ICON)) {
|
||||
final ApplicationInfo appInfo = context.getApplicationInfo();
|
||||
final boolean isApplicationInSystemImage =
|
||||
|
|
|
@ -28,8 +28,10 @@ import org.dslul.openboard.inputmethod.compat.AppWorkaroundsUtils;
|
|||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
||||
import org.dslul.openboard.inputmethod.latin.common.StringUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.AsyncResultHolder;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.TargetPackageInfoGetterTask;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -118,10 +120,11 @@ public class SettingsValues {
|
|||
public final float mKeyPreviewDismissEndXScale;
|
||||
public final float mKeyPreviewDismissEndYScale;
|
||||
|
||||
@Nullable public final String mAccount;
|
||||
@Nullable
|
||||
public final String mAccount;
|
||||
|
||||
public SettingsValues(final Context context, final SharedPreferences prefs, final Resources res,
|
||||
@Nonnull final InputAttributes inputAttributes) {
|
||||
@Nonnull final InputAttributes inputAttributes) {
|
||||
mLocale = res.getConfiguration().locale;
|
||||
// Get the resources
|
||||
mDelayInMillisecondsToUpdateOldSuggestions =
|
||||
|
@ -132,7 +135,7 @@ public class SettingsValues {
|
|||
mInputAttributes = inputAttributes;
|
||||
|
||||
// Get the settings preferences
|
||||
mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
|
||||
mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true) && ScriptUtils.scriptSupportsUppercase(mLocale.getLanguage());
|
||||
mVibrateOn = Settings.readVibrationEnabled(prefs, res);
|
||||
mSoundOn = Settings.readKeypressSoundEnabled(prefs, res);
|
||||
mKeyPreviewPopupOn = Settings.readKeyPreviewPopupEnabled(prefs, res);
|
||||
|
@ -303,13 +306,13 @@ public class SettingsValues {
|
|||
}
|
||||
|
||||
private static boolean readBigramPredictionEnabled(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
return prefs.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, res.getBoolean(
|
||||
R.bool.config_default_next_word_prediction));
|
||||
}
|
||||
|
||||
private static float readAutoCorrectionThreshold(final Resources res,
|
||||
final String currentAutoCorrectionSetting) {
|
||||
final String currentAutoCorrectionSetting) {
|
||||
final String[] autoCorrectionThresholdValues = res.getStringArray(
|
||||
R.array.auto_correction_threshold_values);
|
||||
// When autoCorrectionThreshold is greater than 1.0, it's like auto correction is off.
|
||||
|
@ -340,7 +343,7 @@ public class SettingsValues {
|
|||
}
|
||||
|
||||
private static boolean needsToShowVoiceInputKey(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final Resources res) {
|
||||
// Migrate preference from {@link Settings#PREF_VOICE_MODE_OBSOLETE} to
|
||||
// {@link Settings#PREF_VOICE_INPUT_KEY}.
|
||||
if (prefs.contains(Settings.PREF_VOICE_MODE_OBSOLETE)) {
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
package org.dslul.openboard.inputmethod.latin.utils;
|
||||
|
||||
|
||||
import androidx.collection.ArraySet;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -47,7 +50,11 @@ public class ScriptUtils {
|
|||
public static final int SCRIPT_THAI = 17;
|
||||
public static final int SCRIPT_BULGARIAN = 18;
|
||||
|
||||
public static final String LANGUAGE_GEORGIAN = "ka";
|
||||
|
||||
private static final TreeMap<String, Integer> mLanguageCodeToScriptCode;
|
||||
private final static ArraySet<String> NON_UPPERCASE_SCRIPTS = new ArraySet<>();
|
||||
|
||||
|
||||
static {
|
||||
mLanguageCodeToScriptCode = new TreeMap<>();
|
||||
|
@ -70,6 +77,13 @@ public class ScriptUtils {
|
|||
mLanguageCodeToScriptCode.put("te", SCRIPT_TELUGU);
|
||||
mLanguageCodeToScriptCode.put("th", SCRIPT_THAI);
|
||||
mLanguageCodeToScriptCode.put("uk", SCRIPT_CYRILLIC);
|
||||
|
||||
NON_UPPERCASE_SCRIPTS.add(LANGUAGE_GEORGIAN);
|
||||
}
|
||||
|
||||
|
||||
public static boolean scriptSupportsUppercase(String language) {
|
||||
return !NON_UPPERCASE_SCRIPTS.contains(language);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -82,102 +96,102 @@ public class ScriptUtils {
|
|||
*/
|
||||
public static boolean isLetterPartOfScript(final int codePoint, final int scriptId) {
|
||||
switch (scriptId) {
|
||||
case SCRIPT_ARABIC:
|
||||
// Arabic letters can be in any of the following blocks:
|
||||
// Arabic U+0600..U+06FF
|
||||
// Arabic Supplement, Thaana U+0750..U+077F, U+0780..U+07BF
|
||||
// Arabic Extended-A U+08A0..U+08FF
|
||||
// Arabic Presentation Forms-A U+FB50..U+FDFF
|
||||
// Arabic Presentation Forms-B U+FE70..U+FEFF
|
||||
return (codePoint >= 0x600 && codePoint <= 0x6FF)
|
||||
|| (codePoint >= 0x750 && codePoint <= 0x7BF)
|
||||
|| (codePoint >= 0x8A0 && codePoint <= 0x8FF)
|
||||
|| (codePoint >= 0xFB50 && codePoint <= 0xFDFF)
|
||||
|| (codePoint >= 0xFE70 && codePoint <= 0xFEFF);
|
||||
case SCRIPT_ARMENIAN:
|
||||
// Armenian letters are in the Armenian unicode block, U+0530..U+058F and
|
||||
// Alphabetic Presentation Forms block, U+FB00..U+FB4F, but only in the Armenian part
|
||||
// of that block, which is U+FB13..U+FB17.
|
||||
return (codePoint >= 0x530 && codePoint <= 0x58F
|
||||
|| codePoint >= 0xFB13 && codePoint <= 0xFB17);
|
||||
case SCRIPT_BENGALI:
|
||||
// Bengali unicode block is U+0980..U+09FF
|
||||
return (codePoint >= 0x980 && codePoint <= 0x9FF);
|
||||
case SCRIPT_BULGARIAN:
|
||||
case SCRIPT_CYRILLIC:
|
||||
// All Cyrillic characters are in the 400~52F block. There are some in the upper
|
||||
// Unicode range, but they are archaic characters that are not used in modern
|
||||
// Russian and are not used by our dictionary.
|
||||
return codePoint >= 0x400 && codePoint <= 0x52F && Character.isLetter(codePoint);
|
||||
case SCRIPT_DEVANAGARI:
|
||||
// Devanagari unicode block is +0900..U+097F
|
||||
return (codePoint >= 0x900 && codePoint <= 0x97F);
|
||||
case SCRIPT_GEORGIAN:
|
||||
// Georgian letters are in the Georgian unicode block, U+10A0..U+10FF,
|
||||
// or Georgian supplement block, U+2D00..U+2D2F
|
||||
return (codePoint >= 0x10A0 && codePoint <= 0x10FF
|
||||
|| codePoint >= 0x2D00 && codePoint <= 0x2D2F);
|
||||
case SCRIPT_GREEK:
|
||||
// Greek letters are either in the 370~3FF range (Greek & Coptic), or in the
|
||||
// 1F00~1FFF range (Greek extended). Our dictionary contains both sort of characters.
|
||||
// Our dictionary also contains a few words with 0xF2; it would be best to check
|
||||
// if that's correct, but a web search does return results for these words so
|
||||
// they are probably okay.
|
||||
return (codePoint >= 0x370 && codePoint <= 0x3FF)
|
||||
|| (codePoint >= 0x1F00 && codePoint <= 0x1FFF)
|
||||
|| codePoint == 0xF2;
|
||||
case SCRIPT_HEBREW:
|
||||
// Hebrew letters are in the Hebrew unicode block, which spans from U+0590 to U+05FF,
|
||||
// or in the Alphabetic Presentation Forms block, U+FB00..U+FB4F, but only in the
|
||||
// Hebrew part of that block, which is U+FB1D..U+FB4F.
|
||||
return (codePoint >= 0x590 && codePoint <= 0x5FF
|
||||
|| codePoint >= 0xFB1D && codePoint <= 0xFB4F);
|
||||
case SCRIPT_KANNADA:
|
||||
// Kannada unicode block is U+0C80..U+0CFF
|
||||
return (codePoint >= 0xC80 && codePoint <= 0xCFF);
|
||||
case SCRIPT_KHMER:
|
||||
// Khmer letters are in unicode block U+1780..U+17FF, and the Khmer symbols block
|
||||
// is U+19E0..U+19FF
|
||||
return (codePoint >= 0x1780 && codePoint <= 0x17FF
|
||||
|| codePoint >= 0x19E0 && codePoint <= 0x19FF);
|
||||
case SCRIPT_LAO:
|
||||
// The Lao block is U+0E80..U+0EFF
|
||||
return (codePoint >= 0xE80 && codePoint <= 0xEFF);
|
||||
case SCRIPT_LATIN:
|
||||
// Our supported latin script dictionaries (EFIGS) at the moment only include
|
||||
// characters in the C0, C1, Latin Extended A and B, IPA extensions unicode
|
||||
// blocks. As it happens, those are back-to-back in the code range 0x40 to 0x2AF,
|
||||
// so the below is a very efficient way to test for it. As for the 0-0x3F, it's
|
||||
// excluded from isLetter anyway.
|
||||
return codePoint <= 0x2AF && Character.isLetter(codePoint);
|
||||
case SCRIPT_MALAYALAM:
|
||||
// Malayalam unicode block is U+0D00..U+0D7F
|
||||
return (codePoint >= 0xD00 && codePoint <= 0xD7F);
|
||||
case SCRIPT_MYANMAR:
|
||||
// Myanmar has three unicode blocks :
|
||||
// Myanmar U+1000..U+109F
|
||||
// Myanmar extended-A U+AA60..U+AA7F
|
||||
// Myanmar extended-B U+A9E0..U+A9FF
|
||||
return (codePoint >= 0x1000 && codePoint <= 0x109F
|
||||
|| codePoint >= 0xAA60 && codePoint <= 0xAA7F
|
||||
|| codePoint >= 0xA9E0 && codePoint <= 0xA9FF);
|
||||
case SCRIPT_SINHALA:
|
||||
// Sinhala unicode block is U+0D80..U+0DFF
|
||||
return (codePoint >= 0xD80 && codePoint <= 0xDFF);
|
||||
case SCRIPT_TAMIL:
|
||||
// Tamil unicode block is U+0B80..U+0BFF
|
||||
return (codePoint >= 0xB80 && codePoint <= 0xBFF);
|
||||
case SCRIPT_TELUGU:
|
||||
// Telugu unicode block is U+0C00..U+0C7F
|
||||
return (codePoint >= 0xC00 && codePoint <= 0xC7F);
|
||||
case SCRIPT_THAI:
|
||||
// Thai unicode block is U+0E00..U+0E7F
|
||||
return (codePoint >= 0xE00 && codePoint <= 0xE7F);
|
||||
case SCRIPT_UNKNOWN:
|
||||
return true;
|
||||
default:
|
||||
// Should never come here
|
||||
throw new RuntimeException("Impossible value of script: " + scriptId);
|
||||
case SCRIPT_ARABIC:
|
||||
// Arabic letters can be in any of the following blocks:
|
||||
// Arabic U+0600..U+06FF
|
||||
// Arabic Supplement, Thaana U+0750..U+077F, U+0780..U+07BF
|
||||
// Arabic Extended-A U+08A0..U+08FF
|
||||
// Arabic Presentation Forms-A U+FB50..U+FDFF
|
||||
// Arabic Presentation Forms-B U+FE70..U+FEFF
|
||||
return (codePoint >= 0x600 && codePoint <= 0x6FF)
|
||||
|| (codePoint >= 0x750 && codePoint <= 0x7BF)
|
||||
|| (codePoint >= 0x8A0 && codePoint <= 0x8FF)
|
||||
|| (codePoint >= 0xFB50 && codePoint <= 0xFDFF)
|
||||
|| (codePoint >= 0xFE70 && codePoint <= 0xFEFF);
|
||||
case SCRIPT_ARMENIAN:
|
||||
// Armenian letters are in the Armenian unicode block, U+0530..U+058F and
|
||||
// Alphabetic Presentation Forms block, U+FB00..U+FB4F, but only in the Armenian part
|
||||
// of that block, which is U+FB13..U+FB17.
|
||||
return (codePoint >= 0x530 && codePoint <= 0x58F
|
||||
|| codePoint >= 0xFB13 && codePoint <= 0xFB17);
|
||||
case SCRIPT_BENGALI:
|
||||
// Bengali unicode block is U+0980..U+09FF
|
||||
return (codePoint >= 0x980 && codePoint <= 0x9FF);
|
||||
case SCRIPT_BULGARIAN:
|
||||
case SCRIPT_CYRILLIC:
|
||||
// All Cyrillic characters are in the 400~52F block. There are some in the upper
|
||||
// Unicode range, but they are archaic characters that are not used in modern
|
||||
// Russian and are not used by our dictionary.
|
||||
return codePoint >= 0x400 && codePoint <= 0x52F && Character.isLetter(codePoint);
|
||||
case SCRIPT_DEVANAGARI:
|
||||
// Devanagari unicode block is +0900..U+097F
|
||||
return (codePoint >= 0x900 && codePoint <= 0x97F);
|
||||
case SCRIPT_GEORGIAN:
|
||||
// Georgian letters are in the Georgian unicode block, U+10A0..U+10FF,
|
||||
// or Georgian supplement block, U+2D00..U+2D2F
|
||||
return (codePoint >= 0x10A0 && codePoint <= 0x10FF
|
||||
|| codePoint >= 0x2D00 && codePoint <= 0x2D2F);
|
||||
case SCRIPT_GREEK:
|
||||
// Greek letters are either in the 370~3FF range (Greek & Coptic), or in the
|
||||
// 1F00~1FFF range (Greek extended). Our dictionary contains both sort of characters.
|
||||
// Our dictionary also contains a few words with 0xF2; it would be best to check
|
||||
// if that's correct, but a web search does return results for these words so
|
||||
// they are probably okay.
|
||||
return (codePoint >= 0x370 && codePoint <= 0x3FF)
|
||||
|| (codePoint >= 0x1F00 && codePoint <= 0x1FFF)
|
||||
|| codePoint == 0xF2;
|
||||
case SCRIPT_HEBREW:
|
||||
// Hebrew letters are in the Hebrew unicode block, which spans from U+0590 to U+05FF,
|
||||
// or in the Alphabetic Presentation Forms block, U+FB00..U+FB4F, but only in the
|
||||
// Hebrew part of that block, which is U+FB1D..U+FB4F.
|
||||
return (codePoint >= 0x590 && codePoint <= 0x5FF
|
||||
|| codePoint >= 0xFB1D && codePoint <= 0xFB4F);
|
||||
case SCRIPT_KANNADA:
|
||||
// Kannada unicode block is U+0C80..U+0CFF
|
||||
return (codePoint >= 0xC80 && codePoint <= 0xCFF);
|
||||
case SCRIPT_KHMER:
|
||||
// Khmer letters are in unicode block U+1780..U+17FF, and the Khmer symbols block
|
||||
// is U+19E0..U+19FF
|
||||
return (codePoint >= 0x1780 && codePoint <= 0x17FF
|
||||
|| codePoint >= 0x19E0 && codePoint <= 0x19FF);
|
||||
case SCRIPT_LAO:
|
||||
// The Lao block is U+0E80..U+0EFF
|
||||
return (codePoint >= 0xE80 && codePoint <= 0xEFF);
|
||||
case SCRIPT_LATIN:
|
||||
// Our supported latin script dictionaries (EFIGS) at the moment only include
|
||||
// characters in the C0, C1, Latin Extended A and B, IPA extensions unicode
|
||||
// blocks. As it happens, those are back-to-back in the code range 0x40 to 0x2AF,
|
||||
// so the below is a very efficient way to test for it. As for the 0-0x3F, it's
|
||||
// excluded from isLetter anyway.
|
||||
return codePoint <= 0x2AF && Character.isLetter(codePoint);
|
||||
case SCRIPT_MALAYALAM:
|
||||
// Malayalam unicode block is U+0D00..U+0D7F
|
||||
return (codePoint >= 0xD00 && codePoint <= 0xD7F);
|
||||
case SCRIPT_MYANMAR:
|
||||
// Myanmar has three unicode blocks :
|
||||
// Myanmar U+1000..U+109F
|
||||
// Myanmar extended-A U+AA60..U+AA7F
|
||||
// Myanmar extended-B U+A9E0..U+A9FF
|
||||
return (codePoint >= 0x1000 && codePoint <= 0x109F
|
||||
|| codePoint >= 0xAA60 && codePoint <= 0xAA7F
|
||||
|| codePoint >= 0xA9E0 && codePoint <= 0xA9FF);
|
||||
case SCRIPT_SINHALA:
|
||||
// Sinhala unicode block is U+0D80..U+0DFF
|
||||
return (codePoint >= 0xD80 && codePoint <= 0xDFF);
|
||||
case SCRIPT_TAMIL:
|
||||
// Tamil unicode block is U+0B80..U+0BFF
|
||||
return (codePoint >= 0xB80 && codePoint <= 0xBFF);
|
||||
case SCRIPT_TELUGU:
|
||||
// Telugu unicode block is U+0C00..U+0C7F
|
||||
return (codePoint >= 0xC00 && codePoint <= 0xC7F);
|
||||
case SCRIPT_THAI:
|
||||
// Thai unicode block is U+0E00..U+0E7F
|
||||
return (codePoint >= 0xE00 && codePoint <= 0xE7F);
|
||||
case SCRIPT_UNKNOWN:
|
||||
return true;
|
||||
default:
|
||||
// Should never come here
|
||||
throw new RuntimeException("Impossible value of script: " + scriptId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue