diff options
Diffstat (limited to 'java')
7 files changed, 104 insertions, 131 deletions
diff --git a/java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml b/java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml index d72f72b92..5a4914245 100644 --- a/java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml +++ b/java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml @@ -22,6 +22,8 @@ <string name="symbols_preceded_by_space">([{&;:!?</string> <!-- Symbols that are normally followed by a space (used to add an auto-space after these) --> <string name="symbols_followed_by_space">.,;:!?)]}&</string> + <!-- Symbols that behave like a single punctuation when typed next to each other --> + <string name="symbols_clustering_together">!?</string> <!-- Symbols that separate words --> <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) --> <string name="symbols_word_separators">"	 
 "()[]{}*&<>+=|.,;:!?/_\"</string> diff --git a/java/res/values/donottranslate-config-spacing-and-punctuations.xml b/java/res/values/donottranslate-config-spacing-and-punctuations.xml index 1be5cf888..2faf578d2 100644 --- a/java/res/values/donottranslate-config-spacing-and-punctuations.xml +++ b/java/res/values/donottranslate-config-spacing-and-punctuations.xml @@ -26,6 +26,8 @@ <string name="symbols_preceded_by_space">([{&</string> <!-- Symbols that are normally followed by a space (used to add an auto-space after these) --> <string name="symbols_followed_by_space">.,;:!?)]}&</string> + <!-- Symbols that behave like a single punctuation when typed next to each other --> + <string name="symbols_clustering_together"></string> <!-- Symbols that separate words --> <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) --> <string name="symbols_word_separators">"	 
 "()[]{}*&<>+=|.,;:!?/_\"</string> diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java index b6fcbd1d6..c6b0d3514 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java @@ -23,7 +23,7 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.personalization.PersonalizationDictionary; +import com.android.inputmethod.latin.personalization.DecayingExpandableBinaryDictionaryBase; import com.android.inputmethod.latin.personalization.PersonalizationHelper; import com.android.inputmethod.latin.personalization.UserHistoryDictionary; import com.android.inputmethod.latin.utils.CollectionUtils; @@ -33,9 +33,11 @@ import com.android.inputmethod.latin.utils.SuggestionResults; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -54,7 +56,7 @@ public class DictionaryFacilitatorForSuggest { // To synchronize assigning mDictionaries to ensure closing dictionaries. private Object mLock = new Object(); - private static final String[] dictTypesOrderedToGetSuggestion = + private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTION = new String[] { Dictionary.TYPE_MAIN, Dictionary.TYPE_USER_HISTORY, @@ -63,6 +65,10 @@ public class DictionaryFacilitatorForSuggest { Dictionary.TYPE_CONTACTS }; + private static final String[] SUB_DICT_TYPES = + Arrays.copyOfRange(DICT_TYPES_ORDERED_TO_GET_SUGGESTION, 1 /* start */, + DICT_TYPES_ORDERED_TO_GET_SUGGESTION.length); + /** * Class contains dictionaries for a locale. */ @@ -78,17 +84,13 @@ public class DictionaryFacilitatorForSuggest { } public Dictionaries(final Locale locale, final Dictionary mainDict, - final ExpandableBinaryDictionary contactsDict, - final ExpandableBinaryDictionary userDict, - final ExpandableBinaryDictionary userHistoryDict, - final ExpandableBinaryDictionary personalizationDict) { + final Map<String, ExpandableBinaryDictionary> subDicts) { mLocale = locale; // Main dictionary can be asynchronously loaded. setMainDict(mainDict); - setSubDict(Dictionary.TYPE_CONTACTS, contactsDict); - setSubDict(Dictionary.TYPE_USER, userDict); - setSubDict(Dictionary.TYPE_USER_HISTORY, userHistoryDict); - setSubDict(Dictionary.TYPE_PERSONALIZATION, personalizationDict); + for (final Map.Entry<String, ExpandableBinaryDictionary> entry : subDicts.entrySet()) { + setSubDict(entry.getKey(), entry.getValue()); + } } private void setSubDict(final String dictType, final ExpandableBinaryDictionary dict) { @@ -142,6 +144,21 @@ public class DictionaryFacilitatorForSuggest { return mDictionaries.mLocale; } + private static ExpandableBinaryDictionary getSubDict(final String dictType, + final Context context, final Locale locale, final File dictFile) { + if (Dictionary.TYPE_CONTACTS.equals(dictType)) { + return new ContactsBinaryDictionary(context, locale, dictFile); + } else if (Dictionary.TYPE_USER.equals(dictType)) { + return new UserBinaryDictionary(context, locale, dictFile); + } else if (Dictionary.TYPE_USER_HISTORY.equals(dictType)) { + return PersonalizationHelper.getUserHistoryDictionary(context, locale); + } else if (Dictionary.TYPE_PERSONALIZATION.equals(dictType)) { + return PersonalizationHelper.getPersonalizationDictionary(context, locale); + } else { + return null; + } + } + public void resetDictionaries(final Context context, final Locale newLocale, final boolean useContactsDict, final boolean usePersonalizedDicts, final boolean forceReloadMainDictionary, @@ -149,11 +166,15 @@ public class DictionaryFacilitatorForSuggest { final boolean localeHasBeenChanged = !newLocale.equals(mDictionaries.mLocale); // We always try to have the main dictionary. Other dictionaries can be unused. final boolean reloadMainDictionary = localeHasBeenChanged || forceReloadMainDictionary; - final boolean closeContactsDictionary = localeHasBeenChanged || !useContactsDict; - final boolean closeUserDictionary = localeHasBeenChanged; - final boolean closeUserHistoryDictionary = localeHasBeenChanged || !usePersonalizedDicts; - final boolean closePersonalizationDictionary = - localeHasBeenChanged || !usePersonalizedDicts; + final Set<String> subDictTypesToUse = CollectionUtils.newHashSet(); + if (useContactsDict) { + subDictTypesToUse.add(Dictionary.TYPE_USER); + } + subDictTypesToUse.add(Dictionary.TYPE_USER); + if (usePersonalizedDicts) { + subDictTypesToUse.add(Dictionary.TYPE_USER_HISTORY); + subDictTypesToUse.add(Dictionary.TYPE_PERSONALIZATION); + } final Dictionary newMainDict; if (reloadMainDictionary) { @@ -163,50 +184,25 @@ public class DictionaryFacilitatorForSuggest { newMainDict = mDictionaries.getMainDict(); } - // Open or move contacts dictionary. - final ExpandableBinaryDictionary newContactsDict; - if (!closeContactsDictionary && mDictionaries.hasDict(Dictionary.TYPE_CONTACTS)) { - newContactsDict = mDictionaries.getSubDict(Dictionary.TYPE_CONTACTS); - } else if (useContactsDict) { - newContactsDict = new ContactsBinaryDictionary(context, newLocale); - } else { - newContactsDict = null; - } - - // Open or move user dictionary. - final ExpandableBinaryDictionary newUserDictionary; - if (!closeUserDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER)) { - newUserDictionary = mDictionaries.getSubDict(Dictionary.TYPE_USER); - } else { - newUserDictionary = new UserBinaryDictionary(context, newLocale); - mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context); - } - - // Open or move user history dictionary. - final ExpandableBinaryDictionary newUserHistoryDict; - if (!closeUserHistoryDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) { - newUserHistoryDict = mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY); - } else if (usePersonalizedDicts) { - newUserHistoryDict = PersonalizationHelper.getUserHistoryDictionary(context, newLocale); - } else { - newUserHistoryDict = null; - } - - // Open or move personalization dictionary. - final ExpandableBinaryDictionary newPersonalizationDict; - if (!closePersonalizationDictionary - && mDictionaries.hasDict(Dictionary.TYPE_PERSONALIZATION)) { - newPersonalizationDict = mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION); - } else if (usePersonalizedDicts) { - newPersonalizationDict = - PersonalizationHelper.getPersonalizationDictionary(context, newLocale); - } else { - newPersonalizationDict = null; + final Map<String, ExpandableBinaryDictionary> subDicts = CollectionUtils.newHashMap(); + for (final String dictType : SUB_DICT_TYPES) { + if (!subDictTypesToUse.contains(dictType)) { + // This dictionary will not be used. + continue; + } + final ExpandableBinaryDictionary dict; + if (!localeHasBeenChanged && mDictionaries.hasDict(dictType)) { + // Continue to use current dictionary. + dict = mDictionaries.getSubDict(dictType); + } else { + // Start to use new dictionary. + dict = getSubDict(dictType, context, newLocale, null /* dictFile */); + } + subDicts.put(dictType, dict); } // Replace Dictionaries. - final Dictionaries newDictionaries = new Dictionaries(newLocale, newMainDict, - newContactsDict, newUserDictionary, newUserHistoryDict, newPersonalizationDict); + final Dictionaries newDictionaries = new Dictionaries(newLocale, newMainDict, subDicts); final Dictionaries oldDictionaries; synchronized (mLock) { oldDictionaries = mDictionaries; @@ -218,22 +214,14 @@ public class DictionaryFacilitatorForSuggest { if (listener != null) { listener.onUpdateMainDictionaryAvailability(hasInitializedMainDictionary()); } - // Clean up old dictionaries. if (reloadMainDictionary) { oldDictionaries.closeDict(Dictionary.TYPE_MAIN); } - if (closeContactsDictionary) { - oldDictionaries.closeDict(Dictionary.TYPE_CONTACTS); - } - if (closeUserDictionary) { - oldDictionaries.closeDict(Dictionary.TYPE_USER); - } - if (closeUserHistoryDictionary) { - oldDictionaries.closeDict(Dictionary.TYPE_USER_HISTORY); - } - if (closePersonalizationDictionary) { - oldDictionaries.closeDict(Dictionary.TYPE_PERSONALIZATION); + for (final String dictType : SUB_DICT_TYPES) { + if (localeHasBeenChanged || !subDictTypesToUse.contains(dictType)) { + oldDictionaries.closeDict(dictType); + } } oldDictionaries.mDictMap.clear(); oldDictionaries.mSubDictMap.clear(); @@ -269,52 +257,28 @@ public class DictionaryFacilitatorForSuggest { final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles, final Map<String, Map<String, String>> additionalDictAttributes) { Dictionary mainDictionary = null; - ContactsBinaryDictionary contactsDictionary = null; - UserBinaryDictionary userDictionary = null; - UserHistoryDictionary userHistoryDictionary = null; - PersonalizationDictionary personalizationDictionary = null; + final Map<String, ExpandableBinaryDictionary> subDicts = CollectionUtils.newHashMap(); for (final String dictType : dictionaryTypes) { if (dictType.equals(Dictionary.TYPE_MAIN)) { mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context, locale); - } else if (dictType.equals(Dictionary.TYPE_USER_HISTORY)) { - userHistoryDictionary = - PersonalizationHelper.getUserHistoryDictionary(context, locale); - // Staring with an empty user history dictionary for testing. - // Testing program may populate this dictionary before actual testing. - userHistoryDictionary.reloadDictionaryIfRequired(); - userHistoryDictionary.waitAllTasksForTests(); + } else { + final File dictFile = dictionaryFiles.get(dictType); + final ExpandableBinaryDictionary dict = getSubDict( + dictType, context, locale, dictFile); if (additionalDictAttributes.containsKey(dictType)) { - userHistoryDictionary.clearAndFlushDictionaryWithAdditionalAttributes( + dict.clearAndFlushDictionaryWithAdditionalAttributes( additionalDictAttributes.get(dictType)); } - } else if (dictType.equals(Dictionary.TYPE_PERSONALIZATION)) { - personalizationDictionary = - PersonalizationHelper.getPersonalizationDictionary(context, locale); - // Staring with an empty personalization dictionary for testing. - // Testing program may populate this dictionary before actual testing. - personalizationDictionary.reloadDictionaryIfRequired(); - personalizationDictionary.waitAllTasksForTests(); - if (additionalDictAttributes.containsKey(dictType)) { - personalizationDictionary.clearAndFlushDictionaryWithAdditionalAttributes( - additionalDictAttributes.get(dictType)); + if (dict == null) { + throw new RuntimeException("Unknown dictionary type: " + dictType); } - } else if (dictType.equals(Dictionary.TYPE_USER)) { - final File file = dictionaryFiles.get(dictType); - userDictionary = new UserBinaryDictionary(context, locale, file); - userDictionary.reloadDictionaryIfRequired(); - userDictionary.waitAllTasksForTests(); - } else if (dictType.equals(Dictionary.TYPE_CONTACTS)) { - final File file = dictionaryFiles.get(dictType); - contactsDictionary = new ContactsBinaryDictionary(context, locale, file); - contactsDictionary.reloadDictionaryIfRequired(); - contactsDictionary.waitAllTasksForTests(); - } else { - throw new RuntimeException("Unknown dictionary type: " + dictType); + dict.reloadDictionaryIfRequired(); + dict.waitAllTasksForTests(); + subDicts.put(dictType, dict); } } - mDictionaries = new Dictionaries(locale, mainDictionary, contactsDictionary, - userDictionary, userHistoryDictionary, personalizationDictionary); + mDictionaries = new Dictionaries(locale, mainDictionary, subDicts); } public void closeDictionaries() { @@ -443,7 +407,7 @@ public class DictionaryFacilitatorForSuggest { final SuggestionResults suggestionResults = new SuggestionResults(dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS); final float[] languageWeight = new float[] { Dictionary.NOT_A_LANGUAGE_WEIGHT }; - for (final String dictType : dictTypesOrderedToGetSuggestion) { + for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTION) { final Dictionary dictionary = dictMap.get(dictType); if (null == dictionary) continue; final ArrayList<SuggestedWordInfo> dictionarySuggestions = diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 550db4a6c..cda429e6a 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -97,6 +97,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { private final ReentrantReadWriteLock mLock; + private Map<String, String> mAdditionalAttributeMap = null; + /* A extension for a binary dictionary file. */ protected static final String DICT_FILE_EXTENSION = ".dict"; @@ -196,6 +198,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { protected Map<String, String> getHeaderAttributeMap() { HashMap<String, String> attributeMap = new HashMap<String, String>(); + if (mAdditionalAttributeMap != null) { + attributeMap.putAll(mAdditionalAttributeMap); + } attributeMap.put(DictionaryHeader.DICTIONARY_ID_KEY, mDictName); attributeMap.put(DictionaryHeader.DICTIONARY_LOCALE_KEY, mLocale.toString()); attributeMap.put(DictionaryHeader.DICTIONARY_VERSION_KEY, @@ -592,6 +597,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } @UsedForTesting + public void clearAndFlushDictionaryWithAdditionalAttributes( + final Map<String, String> attributeMap) { + mAdditionalAttributeMap = attributeMap; + clear(); + } + public void dumpAllWordsForDebug() { reloadDictionaryIfRequired(); asyncExecuteTaskWithLock(mLock.readLock(), new Runnable() { diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index d2100d415..75432fbac 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -784,11 +784,11 @@ public final class InputLogic { // TODO: remove this argument final LatinIME.UIHandler handler) { final int codePoint = inputTransaction.mEvent.mCodePoint; + final SettingsValues settingsValues = inputTransaction.mSettingsValues; boolean didAutoCorrect = false; // We avoid sending spaces in languages without spaces if we were composing. final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint - && !inputTransaction.mSettingsValues.mSpacingAndPunctuations - .mCurrentLanguageHasSpaces + && !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces && mWordComposer.isComposingWord(); if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) { // If we are in the middle of a recorrection, we need to commit the recorrection @@ -798,13 +798,13 @@ public final class InputLogic { } // isComposingWord() may have changed since we stored wasComposing if (mWordComposer.isComposingWord()) { - if (inputTransaction.mSettingsValues.mCorrectionEnabled) { + if (settingsValues.mCorrectionEnabled) { final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR : StringUtils.newSingleCodePointString(codePoint); - commitCurrentAutoCorrection(inputTransaction.mSettingsValues, separator, handler); + commitCurrentAutoCorrection(settingsValues, separator, handler); didAutoCorrect = true; } else { - commitTyped(inputTransaction.mSettingsValues, + commitTyped(settingsValues, StringUtils.newSingleCodePointString(codePoint)); } } @@ -821,20 +821,23 @@ public final class InputLogic { // Double quotes behave like they are usually preceded by space iff we are // not inside a double quote or after a digit. needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit; + } else if (settingsValues.mSpacingAndPunctuations.isClusteringSymbol(codePoint) + && settingsValues.mSpacingAndPunctuations.isClusteringSymbol( + mConnection.getCodePointBeforeCursor())) { + needsPrecedingSpace = false; } else { - needsPrecedingSpace = inputTransaction.mSettingsValues.isUsuallyPrecededBySpace( - codePoint); + needsPrecedingSpace = settingsValues.isUsuallyPrecededBySpace(codePoint); } if (needsPrecedingSpace) { - promotePhantomSpace(inputTransaction.mSettingsValues); + promotePhantomSpace(settingsValues); } if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.latinIME_handleSeparator(codePoint, mWordComposer.isComposingWord()); } if (!shouldAvoidSendingCode) { - sendKeyCodePoint(inputTransaction.mSettingsValues, codePoint); + sendKeyCodePoint(settingsValues, codePoint); } if (Constants.CODE_SPACE == codePoint) { @@ -852,7 +855,7 @@ public final class InputLogic { swapSwapperAndSpace(inputTransaction); mSpaceState = SpaceState.SWAP_PUNCTUATION; } else if ((SpaceState.PHANTOM == inputTransaction.mSpaceState - && inputTransaction.mSettingsValues.isUsuallyFollowedBySpace(codePoint)) + && settingsValues.isUsuallyFollowedBySpace(codePoint)) || (Constants.CODE_DOUBLE_QUOTE == codePoint && isInsideDoubleQuoteOrAfterDigit)) { // If we are in phantom space state, and the user presses a separator, we want to diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java index 352288f8b..38c28a734 100644 --- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java +++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java @@ -18,15 +18,11 @@ package com.android.inputmethod.latin.personalization; import android.content.Context; -import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.ExpandableBinaryDictionary; import com.android.inputmethod.latin.makedict.DictionaryHeader; -import com.android.inputmethod.latin.utils.LanguageModelParam; import java.io.File; -import java.util.ArrayList; import java.util.Locale; import java.util.Map; @@ -47,8 +43,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB /** The locale for this dictionary. */ public final Locale mLocale; - private Map<String, String> mAdditionalAttributeMap = null; - protected DecayingExpandableBinaryDictionaryBase(final Context context, final String dictName, final Locale locale, final String dictionaryType, final File dictFile) { @@ -72,9 +66,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB @Override protected Map<String, String> getHeaderAttributeMap() { final Map<String, String> attributeMap = super.getHeaderAttributeMap(); - if (mAdditionalAttributeMap != null) { - attributeMap.putAll(mAdditionalAttributeMap); - } attributeMap.put(DictionaryHeader.USES_FORGETTING_CURVE_KEY, DictionaryHeader.ATTRIBUTE_VALUE_TRUE); attributeMap.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY, @@ -92,13 +83,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB // No initial contents. } - @UsedForTesting - public void clearAndFlushDictionaryWithAdditionalAttributes( - final Map<String, String> attributeMap) { - mAdditionalAttributeMap = attributeMap; - clear(); - } - /* package */ void runGCIfRequired() { runGCIfRequired(false /* mindsBlockByGC */); } diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java index 796921f71..b8d2a2248 100644 --- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java +++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java @@ -30,6 +30,7 @@ import java.util.Locale; public final class SpacingAndPunctuations { private final int[] mSortedSymbolsPrecededBySpace; private final int[] mSortedSymbolsFollowedBySpace; + private final int[] mSortedSymbolsClusteringTogether; private final int[] mSortedWordConnectors; public final int[] mSortedWordSeparators; public final PunctuationSuggestions mSuggestPuncList; @@ -46,6 +47,8 @@ public final class SpacingAndPunctuations { // To be able to binary search the code point. See {@link #isUsuallyFollowedBySpace(int)}. mSortedSymbolsFollowedBySpace = StringUtils.toSortedCodePointArray( res.getString(R.string.symbols_followed_by_space)); + mSortedSymbolsClusteringTogether = StringUtils.toSortedCodePointArray( + res.getString(R.string.symbols_clustering_together)); // To be able to binary search the code point. See {@link #isWordConnector(int)}. mSortedWordConnectors = StringUtils.toSortedCodePointArray( res.getString(R.string.symbols_word_connectors)); @@ -85,6 +88,10 @@ public final class SpacingAndPunctuations { return Arrays.binarySearch(mSortedSymbolsFollowedBySpace, code) >= 0; } + public boolean isClusteringSymbol(final int code) { + return Arrays.binarySearch(mSortedSymbolsClusteringTogether, code) >= 0; + } + public boolean isSentenceSeparator(final int code) { return code == mSentenceSeparator; } |