1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.latin.settings;
18 
19 import android.content.res.Resources;
20 
21 import com.android.inputmethod.annotations.UsedForTesting;
22 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
23 import com.android.inputmethod.latin.Constants;
24 import com.android.inputmethod.latin.PunctuationSuggestions;
25 import com.android.inputmethod.latin.R;
26 import com.android.inputmethod.latin.utils.StringUtils;
27 
28 import java.util.Arrays;
29 import java.util.Locale;
30 
31 public final class SpacingAndPunctuations {
32     private final int[] mSortedSymbolsPrecededBySpace;
33     private final int[] mSortedSymbolsFollowedBySpace;
34     private final int[] mSortedSymbolsClusteringTogether;
35     private final int[] mSortedWordConnectors;
36     public final int[] mSortedWordSeparators;
37     public final PunctuationSuggestions mSuggestPuncList;
38     private final int mSentenceSeparator;
39     public final String mSentenceSeparatorAndSpace;
40     public final boolean mCurrentLanguageHasSpaces;
41     public final boolean mUsesAmericanTypography;
42     public final boolean mUsesGermanRules;
43 
SpacingAndPunctuations(final Resources res)44     public SpacingAndPunctuations(final Resources res) {
45         // To be able to binary search the code point. See {@link #isUsuallyPrecededBySpace(int)}.
46         mSortedSymbolsPrecededBySpace = StringUtils.toSortedCodePointArray(
47                 res.getString(R.string.symbols_preceded_by_space));
48         // To be able to binary search the code point. See {@link #isUsuallyFollowedBySpace(int)}.
49         mSortedSymbolsFollowedBySpace = StringUtils.toSortedCodePointArray(
50                 res.getString(R.string.symbols_followed_by_space));
51         mSortedSymbolsClusteringTogether = StringUtils.toSortedCodePointArray(
52                 res.getString(R.string.symbols_clustering_together));
53         // To be able to binary search the code point. See {@link #isWordConnector(int)}.
54         mSortedWordConnectors = StringUtils.toSortedCodePointArray(
55                 res.getString(R.string.symbols_word_connectors));
56         mSortedWordSeparators = StringUtils.toSortedCodePointArray(
57                 res.getString(R.string.symbols_word_separators));
58         mSentenceSeparator = res.getInteger(R.integer.sentence_separator);
59         mSentenceSeparatorAndSpace = new String(new int[] {
60                 mSentenceSeparator, Constants.CODE_SPACE }, 0, 2);
61         mCurrentLanguageHasSpaces = res.getBoolean(R.bool.current_language_has_spaces);
62         final Locale locale = res.getConfiguration().locale;
63         // Heuristic: we use American Typography rules because it's the most common rules for all
64         // English variants. German rules (not "German typography") also have small gotchas.
65         mUsesAmericanTypography = Locale.ENGLISH.getLanguage().equals(locale.getLanguage());
66         mUsesGermanRules = Locale.GERMAN.getLanguage().equals(locale.getLanguage());
67         final String[] suggestPuncsSpec = MoreKeySpec.splitKeySpecs(
68                 res.getString(R.string.suggested_punctuations));
69         mSuggestPuncList = PunctuationSuggestions.newPunctuationSuggestions(suggestPuncsSpec);
70     }
71 
72     @UsedForTesting
SpacingAndPunctuations(final SpacingAndPunctuations model, final int[] overrideSortedWordSeparators)73     public SpacingAndPunctuations(final SpacingAndPunctuations model,
74             final int[] overrideSortedWordSeparators) {
75         mSortedSymbolsPrecededBySpace = model.mSortedSymbolsPrecededBySpace;
76         mSortedSymbolsFollowedBySpace = model.mSortedSymbolsFollowedBySpace;
77         mSortedSymbolsClusteringTogether = model.mSortedSymbolsClusteringTogether;
78         mSortedWordConnectors = model.mSortedWordConnectors;
79         mSortedWordSeparators = overrideSortedWordSeparators;
80         mSuggestPuncList = model.mSuggestPuncList;
81         mSentenceSeparator = model.mSentenceSeparator;
82         mSentenceSeparatorAndSpace = model.mSentenceSeparatorAndSpace;
83         mCurrentLanguageHasSpaces = model.mCurrentLanguageHasSpaces;
84         mUsesAmericanTypography = model.mUsesAmericanTypography;
85         mUsesGermanRules = model.mUsesGermanRules;
86     }
87 
isWordSeparator(final int code)88     public boolean isWordSeparator(final int code) {
89         return Arrays.binarySearch(mSortedWordSeparators, code) >= 0;
90     }
91 
isWordConnector(final int code)92     public boolean isWordConnector(final int code) {
93         return Arrays.binarySearch(mSortedWordConnectors, code) >= 0;
94     }
95 
isWordCodePoint(final int code)96     public boolean isWordCodePoint(final int code) {
97         return Character.isLetter(code) || isWordConnector(code);
98     }
99 
isUsuallyPrecededBySpace(final int code)100     public boolean isUsuallyPrecededBySpace(final int code) {
101         return Arrays.binarySearch(mSortedSymbolsPrecededBySpace, code) >= 0;
102     }
103 
isUsuallyFollowedBySpace(final int code)104     public boolean isUsuallyFollowedBySpace(final int code) {
105         return Arrays.binarySearch(mSortedSymbolsFollowedBySpace, code) >= 0;
106     }
107 
isClusteringSymbol(final int code)108     public boolean isClusteringSymbol(final int code) {
109         return Arrays.binarySearch(mSortedSymbolsClusteringTogether, code) >= 0;
110     }
111 
isSentenceSeparator(final int code)112     public boolean isSentenceSeparator(final int code) {
113         return code == mSentenceSeparator;
114     }
115 
dump()116     public String dump() {
117         final StringBuilder sb = new StringBuilder();
118         sb.append("mSortedSymbolsPrecededBySpace = ");
119         sb.append("" + Arrays.toString(mSortedSymbolsPrecededBySpace));
120         sb.append("\n   mSortedSymbolsFollowedBySpace = ");
121         sb.append("" + Arrays.toString(mSortedSymbolsFollowedBySpace));
122         sb.append("\n   mSortedWordConnectors = ");
123         sb.append("" + Arrays.toString(mSortedWordConnectors));
124         sb.append("\n   mSortedWordSeparators = ");
125         sb.append("" + Arrays.toString(mSortedWordSeparators));
126         sb.append("\n   mSuggestPuncList = ");
127         sb.append("" + mSuggestPuncList);
128         sb.append("\n   mSentenceSeparator = ");
129         sb.append("" + mSentenceSeparator);
130         sb.append("\n   mSentenceSeparatorAndSpace = ");
131         sb.append("" + mSentenceSeparatorAndSpace);
132         sb.append("\n   mCurrentLanguageHasSpaces = ");
133         sb.append("" + mCurrentLanguageHasSpaces);
134         sb.append("\n   mUsesAmericanTypography = ");
135         sb.append("" + mUsesAmericanTypography);
136         sb.append("\n   mUsesGermanRules = ");
137         sb.append("" + mUsesGermanRules);
138         return sb.toString();
139     }
140 }
141