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