• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.keyboard.layout;
18 
19 import com.android.inputmethod.keyboard.layout.Symbols.RtlSymbols;
20 import com.android.inputmethod.keyboard.layout.SymbolsShifted.RtlSymbolsShifted;
21 import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer;
22 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
23 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
24 import com.android.inputmethod.latin.common.Constants;
25 
26 import java.util.Locale;
27 
28 public final class Farsi extends LayoutBase {
29     private static final String LAYOUT_NAME = "farsi";
30 
Farsi(final Locale locale)31     public Farsi(final Locale locale) {
32         super(new FarsiCustomizer(locale), FarsiSymbols.class, FarsiSymbolsShifted.class);
33     }
34 
35     @Override
getName()36     public String getName() { return LAYOUT_NAME; }
37 
38     private static class FarsiCustomizer extends LayoutCustomizer {
FarsiCustomizer(final Locale locale)39         FarsiCustomizer(final Locale locale) { super(locale); }
40 
41         @Override
getAlphabetKey()42         public ExpectedKey getAlphabetKey() { return FARSI_ALPHABET_KEY; }
43 
44         @Override
getSymbolsKey()45         public ExpectedKey getSymbolsKey() { return FARSI_SYMBOLS_KEY; }
46 
47         @Override
getBackToSymbolsKey()48         public ExpectedKey getBackToSymbolsKey() { return FARSI_BACK_TO_SYMBOLS_KEY; }
49 
50         @Override
getCurrencyKey()51         public ExpectedKey getCurrencyKey() { return CURRENCY_RIAL; }
52 
53         @Override
getOtherCurrencyKeys()54         public ExpectedKey[] getOtherCurrencyKeys() {
55             return SymbolsShifted.CURRENCIES_OTHER_GENERIC;
56         }
57 
58         @Override
getLeftShiftKeys(final boolean isPhone)59         public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) {
60             return EMPTY_KEYS;
61         }
62 
63         @Override
getRightShiftKeys(final boolean isPhone)64         public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
65             return EMPTY_KEYS;
66         }
67 
68         @Override
getKeysLeftToSpacebar(final boolean isPhone)69         public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) {
70             if (isPhone) {
71                 // U+060C: "،" ARABIC COMMA
72                 return joinKeys(key("\u060C", SETTINGS_KEY));
73             }
74             // U+060C: "،" ARABIC COMMA
75             // U+061F: "؟" ARABIC QUESTION MARK
76             // U+061B: "؛" ARABIC SEMICOLON
77             return joinKeys(key("\u060C", joinMoreKeys(
78                     ":", "!", "\u061F", "\u061B", "-", RtlSymbols.DOUBLE_ANGLE_QUOTES_LR_RTL,
79                     SETTINGS_KEY)));
80         }
81 
82         @Override
getKeysRightToSpacebar(final boolean isPhone)83         public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) {
84             if (isPhone) {
85                 return super.getKeysRightToSpacebar(isPhone);
86             }
87             return joinKeys(key(".", getPunctuationMoreKeys(isPhone)));
88         }
89 
90         @Override
getSpaceKeys(final boolean isPhone)91         public ExpectedKey[] getSpaceKeys(final boolean isPhone) {
92             return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY, key(ZWNJ_KEY, ZWJ_KEY));
93         }
94 
95         @Override
getPunctuationMoreKeys(final boolean isPhone)96         public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
97             return FARSI_DIACRITICS;
98         }
99 
100         // U+0627: "ا" ARABIC LETTER ALEF
101         // U+200C: ZERO WIDTH NON-JOINER
102         // U+0628: "ب" ARABIC LETTER BEH
103         // U+067E: "پ" ARABIC LETTER PEH
104         private static final ExpectedKey FARSI_ALPHABET_KEY = key(
105                 "\u0627\u200C\u0628\u200C\u067E", Constants.CODE_SWITCH_ALPHA_SYMBOL);
106         // U+06F3: "۳" EXTENDED ARABIC-INDIC DIGIT THREE
107         // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
108         // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
109         // U+061F: "؟" ARABIC QUESTION MARK
110         private static final ExpectedKey FARSI_SYMBOLS_KEY = key(
111                 "\u06F3\u06F2\u06F1\u061F", Constants.CODE_SWITCH_ALPHA_SYMBOL);
112         private static final ExpectedKey FARSI_BACK_TO_SYMBOLS_KEY = key(
113                 "\u06F3\u06F2\u06F1\u061F", Constants.CODE_SHIFT);
114         // U+FDFC: "﷼" RIAL SIGN
115         private static final ExpectedKey CURRENCY_RIAL = key("\uFDFC",
116                 Symbols.CURRENCY_GENERIC_MORE_KEYS);
117         private static final ExpectedKey[] FARSI_DIACRITICS = {
118                 // U+0655: "ٕ" ARABIC HAMZA BELOW
119                 // U+0652: "ْ" ARABIC SUKUN
120                 // U+0651: "ّ" ARABIC SHADDA
121                 // U+064C: "ٌ" ARABIC DAMMATAN
122                 // U+064D: "ٍ" ARABIC KASRATAN
123                 // U+064B: "ً" ARABIC FATHATAN
124                 // U+0654: "ٔ" ARABIC HAMZA ABOVE
125                 // U+0656: "ٖ" ARABIC SUBSCRIPT ALEF
126                 // U+0670: "ٰ" ARABIC LETTER SUPERSCRIPT ALEF
127                 // U+0653: "ٓ" ARABIC MADDAH ABOVE
128                 // U+064F: "ُ" ARABIC DAMMA
129                 // U+0650: "ِ" ARABIC KASRA
130                 // U+064E: "َ" ARABIC FATHA
131                 // U+0640: "ـ" ARABIC TATWEEL
132                 moreKey(" \u0655", "\u0655"), moreKey(" \u0652", "\u0652"),
133                 moreKey(" \u0651", "\u0651"), moreKey(" \u064C", "\u064C"),
134                 moreKey(" \u064D", "\u064D"), moreKey(" \u064B", "\u064B"),
135                 moreKey(" \u0654", "\u0654"), moreKey(" \u0656", "\u0656"),
136                 moreKey(" \u0670", "\u0670"), moreKey(" \u0653", "\u0653"),
137                 moreKey(" \u064F", "\u064F"), moreKey(" \u0650", "\u0650"),
138                 moreKey(" \u064E", "\u064E"), moreKey("\u0640\u0640\u0640", "\u0640")
139         };
140     }
141 
142     @Override
getCommonAlphabetLayout(final boolean isPhone)143     ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) {
144         if (isPhone) {
145             return ALPHABET_COMMON;
146         }
147         final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
148         // U+0622: "آ" ARABIC LETTER ALEF WITH MADDA ABOVE
149         builder.insertKeysAtRow(3, 10, "\u0622");
150         return builder.build();
151     }
152 
153     @Override
getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId)154     ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) {
155         return null;
156     }
157 
158     private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
159             .setKeysOfRow(1,
160                     // U+0636: "ض" ARABIC LETTER DAD
161                     // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
162                     key("\u0636", joinMoreKeys("\u06F1", "1")),
163                     // U+0635: "ص" ARABIC LETTER SAD
164                     // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
165                     key("\u0635", joinMoreKeys("\u06F2", "2")),
166                     // U+062B: "ث" ARABIC LETTER THEH
167                     // U+06F3: "۳" EXTENDED ARABIC-INDIC DIGIT THREE
168                     key("\u062B", joinMoreKeys("\u06F3", "3")),
169                     // U+0642: "ق" ARABIC LETTER QAF
170                     // U+06F4: "۴" EXTENDED ARABIC-INDIC DIGIT FOUR
171                     key("\u0642", joinMoreKeys("\u06F4", "4")),
172                     // U+0641: "ف" ARABIC LETTER FEH
173                     // U+06F5: "۵" EXTENDED ARABIC-INDIC DIGIT FIVE
174                     key("\u0641", joinMoreKeys("\u06F5", "5")),
175                     // U+063A: "غ" ARABIC LETTER GHAIN
176                     // U+06F6: "۶" EXTENDED ARABIC-INDIC DIGIT SIX
177                     key("\u063A", joinMoreKeys("\u06F6", "6")),
178                     // U+0639: "ع" ARABIC LETTER AIN
179                     // U+06F7: "۷" EXTENDED ARABIC-INDIC DIGIT SEVEN
180                     key("\u0639", joinMoreKeys("\u06F7", "7")),
181                     // U+0647: "ه" ARABIC LETTER HEH
182                     // U+FEEB: "ﻫ" ARABIC LETTER HEH INITIAL FORM
183                     // U+0647/U+200D: ARABIC LETTER HEH + ZERO WIDTH JOINER
184                     // U+0647/U+0654: ARABIC LETTER HEH + ARABIC HAMZA ABOVE
185                     // U+0629: "ة" ARABIC LETTER TEH MARBUTA
186                     // U+06F8: "۸" EXTENDED ARABIC-INDIC DIGIT EIGHT
187                     key("\u0647", joinMoreKeys(moreKey("\uFEEB", "\u0647\u200D"), "\u0647\u0654",
188                             "\u0629", "\u06F8", "8")),
189                     // U+062E: "خ" ARABIC LETTER KHAH
190                     // U+06F9: "۹" EXTENDED ARABIC-INDIC DIGIT NINE
191                     key("\u062E", joinMoreKeys("\u06F9", "9")),
192                     // U+062D: "ح" ARABIC LETTER HAH
193                     // U+06F0: "۰" EXTENDED ARABIC-INDIC DIGIT ZERO
194                     key("\u062D", joinMoreKeys("\u06F0", "0")),
195                     // U+062C: "ج" ARABIC LETTER JEEM
196                     "\u062C")
197             .setKeysOfRow(2,
198                     // U+0634: "ش" ARABIC LETTER SHEEN
199                     // U+0633: "س" ARABIC LETTER SEEN
200                     "\u0634", "\u0633",
201                     // U+06CC: "ی" ARABIC LETTER FARSI YEH
202                     // U+0626: "ئ" ARABIC LETTER YEH WITH HAMZA ABOVE
203                     // U+064A: "ي" ARABIC LETTER YEH
204                     // U+FBE8: "ﯨ" ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM
205                     // U+0649: "ى" ARABIC LETTER ALEF MAKSURA
206                     key("\u06CC", joinMoreKeys("\u0626", "\u064A", moreKey("\uFBE8", "\u0649"))),
207                     // U+0628: "ب" ARABIC LETTER BEH
208                     // U+0644: "ل" ARABIC LETTER LAM
209                     "\u0628", "\u0644",
210                     // U+0627: "ا" ARABIC LETTER ALEF
211                     // U+0671: "ٱ" ARABIC LETTER ALEF WASLA
212                     // U+0621: "ء" ARABIC LETTER HAMZA
213                     // U+0622: "آ" ARABIC LETTER ALEF WITH MADDA ABOVE
214                     // U+0623: "أ" ARABIC LETTER ALEF WITH HAMZA ABOVE
215                     // U+0625: "إ" ARABIC LETTER ALEF WITH HAMZA BELOW
216                     key("\u0627", joinMoreKeys("\u0671", "\u0621", "\u0622", "\u0623", "\u0625")),
217                     // U+062A: "ت" ARABIC LETTER TEH
218                     // U+0629: "ة": ARABIC LETTER TEH MARBUTA
219                     key("\u062A", moreKey("\u0629")),
220                     // U+0646: "ن" ARABIC LETTER NOON
221                     // U+0645: "م" ARABIC LETTER MEEM
222                     "\u0646", "\u0645",
223                     // U+06A9: "ک" ARABIC LETTER KEHEH
224                     // U+0643: "ك" ARABIC LETTER KAF
225                     key("\u06A9", moreKey("\u0643")),
226                     // U+06AF: "گ" ARABIC LETTER GAF
227                     "\u06AF")
228             .setKeysOfRow(3,
229                     // U+0638: "ظ" ARABIC LETTER ZAH
230                     // U+0637: "ط" ARABIC LETTER TAH
231                     // U+0698: "ژ" ARABIC LETTER JEH
232                     // U+0632: "ز" ARABIC LETTER ZAIN
233                     // U+0631: "ر" ARABIC LETTER REH
234                     // U+0630: "ذ" ARABIC LETTER THAL
235                     // U+062F: "د" ARABIC LETTER DAL
236                     // U+067E: "پ" ARABIC LETTER PEH
237                     "\u0638", "\u0637", "\u0698", "\u0632", "\u0631", "\u0630", "\u062F", "\u067E",
238                     // U+0648: "و" ARABIC LETTER WAW
239                     // U+0624: "ؤ" ARABIC LETTER WAW WITH HAMZA ABOVE
240                     key("\u0648", moreKey("\u0624")),
241                     // U+0686: "چ" ARABIC LETTER TCHEH
242                     "\u0686")
243             .build();
244 
245     private static class FarsiSymbols extends RtlSymbols {
FarsiSymbols(final LayoutCustomizer customizer)246         public FarsiSymbols(final LayoutCustomizer customizer) {
247             super(customizer);
248         }
249 
250         @Override
getLayout(final boolean isPhone)251         public ExpectedKey[][] getLayout(final boolean isPhone) {
252             return new ExpectedKeyboardBuilder(super.getLayout(isPhone))
253                     // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
254                     // U+00B9: "¹" SUPERSCRIPT ONE
255                     // U+00BD: "½" VULGAR FRACTION ONE HALF
256                     // U+2153: "⅓" VULGAR FRACTION ONE THIRD
257                     // U+00BC: "¼" VULGAR FRACTION ONE QUARTER
258                     // U+215B: "⅛" VULGAR FRACTION ONE EIGHTH
259                     .replaceKeyOfLabel("1", key("\u06F1",
260                             joinMoreKeys("1", "\u00B9", "\u00BD", "\u2153", "\u00BC", "\u215B")))
261                     // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
262                     // U+00B2: "²" SUPERSCRIPT TWO
263                     // U+2154: "⅔" VULGAR FRACTION TWO THIRDS
264                     .replaceKeyOfLabel("2", key("\u06F2", joinMoreKeys("2", "\u00B2", "\u2154")))
265                     // U+06F3: "۳" EXTENDED ARABIC-INDIC DIGIT THREE
266                     // U+00B3: "³" SUPERSCRIPT THREE
267                     // U+00BE: "¾" VULGAR FRACTION THREE QUARTERS
268                     // U+215C: "⅜" VULGAR FRACTION THREE EIGHTHS
269                     .replaceKeyOfLabel("3", key("\u06F3",
270                             joinMoreKeys("3", "\u00B3", "\u00BE", "\u215C")))
271                     // U+06F4: "۴" EXTENDED ARABIC-INDIC DIGIT FOUR
272                     // U+2074: "⁴" SUPERSCRIPT FOUR
273                     .replaceKeyOfLabel("4", key("\u06F4", joinMoreKeys("4", "\u2074")))
274                     // U+06F5: "۵" EXTENDED ARABIC-INDIC DIGIT FIVE
275                     // U+215D: "⅝" VULGAR FRACTION FIVE EIGHTHS
276                     .replaceKeyOfLabel("5", key("\u06F5", joinMoreKeys("5", "\u215D")))
277                     // U+06F6: "۶" EXTENDED ARABIC-INDIC DIGIT SIX
278                     .replaceKeyOfLabel("6", key("\u06F6", moreKey("6")))
279                     // U+06F7: "۷" EXTENDED ARABIC-INDIC DIGIT SEVEN
280                     // U+215E: "⅞" VULGAR FRACTION SEVEN EIGHTHS
281                     .replaceKeyOfLabel("7", key("\u06F7", joinMoreKeys("7", "\u215E")))
282                     // U+06F8: "۸" EXTENDED ARABIC-INDIC DIGIT EIGHT
283                     .replaceKeyOfLabel("8", key("\u06F8", moreKey("8")))
284                     // U+06F9: "۹" EXTENDED ARABIC-INDIC DIGIT NINE
285                     .replaceKeyOfLabel("9", key("\u06F9", moreKey("9")))
286                     // U+066C: "٬" ARABIC THOUSANDS SEPARATOR
287                     .replaceKeyOfLabel("@", key("\u066C", moreKey("@")))
288                     // U+066B: "٫" ARABIC DECIMAL SEPARATOR
289                     .replaceKeyOfLabel("#", key("\u066B", moreKey("#")))
290                     // U+06F0: "۰" EXTENDED ARABIC-INDIC DIGIT ZERO
291                     // U+066B: "٫" ARABIC DECIMAL SEPARATOR
292                     // U+066C: "٬" ARABIC THOUSANDS SEPARATOR
293                     // U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N
294                     // U+2205: "∅" EMPTY SET
295                     .replaceKeyOfLabel("0", key("\u06F0",
296                             joinMoreKeys("0", "\u066B", "\u066C", "\u207F", "\u2205")))
297                     // U+066A: "٪" ARABIC PERCENT SIGN
298                     // U+2030: "‰" PER MILLE SIGN
299                     .replaceKeyOfLabel("%", key("\u066A", joinMoreKeys("%", "\u2030")))
300                     // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
301                     // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
302                     // U+2264: "≤" LESS-THAN OR EQUAL TO
303                     .replaceKeyOfLabel("\"", key("\u00AB", "\u00BB", joinMoreKeys(
304                             DOUBLE_QUOTES_9LR, DOUBLE_ANGLE_QUOTES_LR_RTL)))
305                     // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
306                     // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
307                     // U+2265: "≥" GREATER-THAN EQUAL TO
308                     .replaceKeyOfLabel("'", key("\u00BB", "\u00AB", joinMoreKeys(
309                             SINGLE_QUOTES_9LR, SINGLE_ANGLE_QUOTES_LR_RTL)))
310                     // U+061B: "؛" ARABIC SEMICOLON
311                     .replaceKeyOfLabel(";", key("\u061B", moreKey(";")))
312                     // U+061F: "؟" ARABIC QUESTION MARK
313                     // U+00BF: "¿" INVERTED QUESTION MARK
314                     .replaceKeyOfLabel("?", key("\u061F", joinMoreKeys("?", "\u00BF")))
315                     // U+060C: "،" ARABIC COMMA
316                     .replaceKeyOfLabel(",", "\u060C")
317                     // U+FD3E: "﴾" ORNATE LEFT PARENTHESIS
318                     // U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS
319                     .replaceKeyOfLabel("(", key("(", ")",
320                             moreKey("\uFD3E", "\uFD3F"), moreKey("<", ">"), moreKey("{", "}"),
321                             moreKey("[", "]")))
322                     // U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS
323                     // U+FD3E: "﴾" ORNATE LEFT PARENTHESIS
324                     .replaceKeyOfLabel(")", key(")", "(",
325                             moreKey("\uFD3F", "\uFD3E"), moreKey(">", "<"), moreKey("}", "{"),
326                             moreKey("]", "[")))
327                     // U+2605: "★" BLACK STAR
328                     // U+066D: "٭" ARABIC FIVE POINTED STAR
329                     .setMoreKeysOf("*", "\u2605", "\u066D")
330                     .build();
331         }
332     }
333 
334     private static class FarsiSymbolsShifted extends RtlSymbolsShifted {
FarsiSymbolsShifted(final LayoutCustomizer customizer)335         public FarsiSymbolsShifted(final LayoutCustomizer customizer) {
336             super(customizer);
337         }
338 
339         @Override
getLayout(final boolean isPhone)340         public ExpectedKey[][] getLayout(final boolean isPhone) {
341             return new ExpectedKeyboardBuilder(super.getLayout(isPhone))
342                     // U+2022: "•" BULLET
343                     // U+266A: "♪" EIGHTH NOTE
344                     .setMoreKeysOf("\u2022", "\u266A")
345                     // U+060C: "،" ARABIC COMMA
346                     .replaceKeyOfLabel(",", "\u060C")
347                     // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
348                     // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
349                     // U+2264: "≤" LESS-THAN OR EQUAL TO
350                     .replaceKeyOfLabel("<", key("\u00AB", "\u00BB",
351                             moreKey("\u2039", "\u203A"), moreKey("\u2264", "\u2265"),
352                             moreKey("<", ">")))
353                     // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
354                     // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
355                     // U+2265: "≥" GREATER-THAN EQUAL TO
356                     .replaceKeyOfLabel(">", key("\u00BB", "\u00AB",
357                             moreKey("\u203A", "\u2039"), moreKey("\u2265", "\u2264"),
358                             moreKey(">", "<")))
359                     .build();
360         }
361     }
362 }
363