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