Home | History | Annotate | Download | only in layout
      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 Arabic extends LayoutBase {
     29     private static final String LAYOUT_NAME = "arabic";
     30 
     31     public Arabic(final Locale locale) {
     32         super(new ArabicCustomizer(locale), ArabicSymbols.class, ArabicSymbolsShifted.class);
     33     }
     34 
     35     @Override
     36     public String getName() { return LAYOUT_NAME; }
     37 
     38     private static class ArabicCustomizer extends LayoutCustomizer {
     39         ArabicCustomizer(final Locale locale) { super(locale); }
     40 
     41         @Override
     42         public ExpectedKey getAlphabetKey() { return ARABIC_ALPHABET_KEY; }
     43 
     44         @Override
     45         public ExpectedKey getSymbolsKey() { return ARABIC_SYMBOLS_KEY; }
     46 
     47         @Override
     48         public ExpectedKey getBackToSymbolsKey() { return ARABIC_BACK_TO_SYMBOLS_KEY; }
     49 
     50         @Override
     51         public ExpectedKey[] getDoubleAngleQuoteKeys() {
     52             return RtlSymbols.DOUBLE_ANGLE_QUOTES_LR_RTL;
     53         }
     54 
     55         @Override
     56         public ExpectedKey[] getSingleAngleQuoteKeys() {
     57             return RtlSymbols.SINGLE_ANGLE_QUOTES_LR_RTL;
     58         }
     59 
     60         @Override
     61         public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) {
     62             return EMPTY_KEYS;
     63         }
     64 
     65         @Override
     66         public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
     67             return EMPTY_KEYS;
     68         }
     69 
     70         @Override
     71         public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) {
     72             if (isPhone) {
     73                 // U+060C: "" ARABIC COMMA
     74                 return joinKeys(key("\u060C", SETTINGS_KEY));
     75             }
     76             // U+060C: "" ARABIC COMMA
     77             // U+061F: "" ARABIC QUESTION MARK
     78             // U+061B: "" ARABIC SEMICOLON
     79             return joinKeys(key("\u060C", joinMoreKeys(
     80                     ":", "!", "\u061F", "\u061B", "-", "\"", "'", SETTINGS_KEY)));
     81         }
     82 
     83         @Override
     84         public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) {
     85             if (isPhone) {
     86                 return super.getKeysRightToSpacebar(isPhone);
     87             }
     88             // U+060C: "" ARABIC COMMA
     89             // U+061F: "" ARABIC QUESTION MARK
     90             // U+061B: "" ARABIC SEMICOLON
     91             return joinKeys(key(".", getPunctuationMoreKeys(isPhone)));
     92         }
     93 
     94         @Override
     95         public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) {
     96             return ARABIC_DIACRITICS;
     97         }
     98 
     99         // U+0623: "" ARABIC LETTER ALEF WITH HAMZA ABOVE
    100         // U+200C: ZERO WIDTH NON-JOINER
    101         // U+0628: "" ARABIC LETTER BEH
    102         // U+062C: "" ARABIC LETTER JEEM
    103         private static final ExpectedKey ARABIC_ALPHABET_KEY = key(
    104                 "\u0623\u200C\u0628\u200C\u062C", Constants.CODE_SWITCH_ALPHA_SYMBOL);
    105         // U+0663: "" ARABIC-INDIC DIGIT THREE
    106         // U+0662: "" ARABIC-INDIC DIGIT TWO
    107         // U+0661: "" ARABIC-INDIC DIGIT ONE
    108         // U+061F: "" ARABIC QUESTION MARK
    109         private static final ExpectedKey ARABIC_SYMBOLS_KEY = key(
    110                 "\u0663\u0662\u0661\u061F", Constants.CODE_SWITCH_ALPHA_SYMBOL);
    111         private static final ExpectedKey ARABIC_BACK_TO_SYMBOLS_KEY = key(
    112                 "\u0663\u0662\u0661\u061F", Constants.CODE_SHIFT);
    113 
    114         private static final ExpectedKey[] ARABIC_DIACRITICS = {
    115                 // U+0655: "" ARABIC HAMZA BELOW
    116                 // U+0654: "" ARABIC HAMZA ABOVE
    117                 // U+0652: "" ARABIC SUKUN
    118                 // U+064D: "" ARABIC KASRATAN
    119                 // U+064C: "" ARABIC DAMMATAN
    120                 // U+064B: "" ARABIC FATHATAN
    121                 // U+0651: "" ARABIC SHADDA
    122                 // U+0656: "" ARABIC SUBSCRIPT ALEF
    123                 // U+0670: "" ARABIC LETTER SUPERSCRIPT ALEF
    124                 // U+0653: "" ARABIC MADDAH ABOVE
    125                 // U+0650: "" ARABIC KASRA
    126                 // U+064F: "" ARABIC DAMMA
    127                 // U+064E: "" ARABIC FATHA
    128                 // U+0640: "" ARABIC TATWEEL
    129                 moreKey(" \u0655", "\u0655"), moreKey(" \u0654", "\u0654"),
    130                 moreKey(" \u0652", "\u0652"), moreKey(" \u064D", "\u064D"),
    131                 moreKey(" \u064C", "\u064C"), moreKey(" \u064B", "\u064B"),
    132                 moreKey(" \u0651", "\u0651"), moreKey(" \u0656", "\u0656"),
    133                 moreKey(" \u0670", "\u0670"), moreKey(" \u0653", "\u0653"),
    134                 moreKey(" \u0650", "\u0650"), moreKey(" \u064F", "\u064F"),
    135                 moreKey(" \u064E", "\u064E"), moreKey("\u0640\u0640\u0640", "\u0640")
    136         };
    137     }
    138 
    139     @Override
    140     ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) {
    141         if (isPhone) {
    142             return ALPHABET_COMMON;
    143         }
    144         final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
    145         // U+0626: "" ARABIC LETTER YEH WITH HAMZA ABOVE
    146         builder.insertKeysAtRow(3, 2, "\u0626");
    147         return builder.build();
    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                     "\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                     // U+0646: "" ARABIC LETTER NOON
    230                     // U+0645: "" ARABIC LETTER MEEM
    231                     "\u062A", "\u0646", "\u0645",
    232                     // U+0643: "" ARABIC LETTER KAF
    233                     // U+06AF: "" ARABIC LETTER GAF
    234                     // U+06A9: "" ARABIC LETTER KEHEH
    235                     key("\u0643", joinMoreKeys("\u06AF", "\u06A9")),
    236                     // U+0637: "" ARABIC LETTER TAH
    237                     "\u0637")
    238             .setKeysOfRow(3,
    239                     // U+0630: "" ARABIC LETTER THAL
    240                     // U+0621: "" ARABIC LETTER HAMZA
    241                     // U+0624: "" ARABIC LETTER WAW WITH HAMZA ABOVE
    242                     // U+0631: "" ARABIC LETTER REH
    243                     "\u0630", "\u0621", "\u0624", "\u0631",
    244                     // U+0649: "" ARABIC LETTER ALEF MAKSURA
    245                     // U+0626: "" ARABIC LETTER YEH WITH HAMZA ABOVE
    246                     key("\u0649", moreKey("\u0626")),
    247                     // U+0629: "" ARABIC LETTER TEH MARBUTA
    248                     // U+0648: "" ARABIC LETTER WAW
    249                     "\u0629", "\u0648",
    250                     // U+0632: "" ARABIC LETTER ZAIN
    251                     // U+0698: "" ARABIC LETTER JEH
    252                     key("\u0632", moreKey("\u0698")),
    253                     // U+0638: "" ARABIC LETTER ZAH
    254                     // U+062F: "" ARABIC LETTER DAL
    255                     "\u0638", "\u062F")
    256             .build();
    257 
    258     private static class ArabicSymbols extends RtlSymbols {
    259         public ArabicSymbols(final LayoutCustomizer customizer) {
    260             super(customizer);
    261         }
    262 
    263         @Override
    264         public ExpectedKey[][] getLayout(final boolean isPhone) {
    265             return new ExpectedKeyboardBuilder(super.getLayout(isPhone))
    266                     // U+0661: "" ARABIC-INDIC DIGIT ONE
    267                     // U+00B9: "" SUPERSCRIPT ONE
    268                     // U+00BD: "" VULGAR FRACTION ONE HALF
    269                     // U+2153: "" VULGAR FRACTION ONE THIRD
    270                     // U+00BC: "" VULGAR FRACTION ONE QUARTER
    271                     // U+215B: "" VULGAR FRACTION ONE EIGHTH
    272                     .replaceKeyOfLabel("1", key("\u0661",
    273                             joinMoreKeys("1", "\u00B9", "\u00BD", "\u2153", "\u00BC", "\u215B")))
    274                     // U+0662: "" ARABIC-INDIC DIGIT TWO
    275                     // U+00B2: "" SUPERSCRIPT TWO
    276                     // U+2154: "" VULGAR FRACTION TWO THIRDS
    277                     .replaceKeyOfLabel("2", key("\u0662", joinMoreKeys("2", "\u00B2", "\u2154")))
    278                     // U+0663: "" ARABIC-INDIC DIGIT THREE
    279                     // U+00B3: "" SUPERSCRIPT THREE
    280                     // U+00BE: "" VULGAR FRACTION THREE QUARTERS
    281                     // U+215C: "" VULGAR FRACTION THREE EIGHTHS
    282                     .replaceKeyOfLabel("3", key("\u0663",
    283                             joinMoreKeys("3", "\u00B3", "\u00BE", "\u215C")))
    284                     // U+0664: "" ARABIC-INDIC DIGIT FOUR
    285                     // U+2074: "" SUPERSCRIPT FOUR
    286                     .replaceKeyOfLabel("4", key("\u0664", joinMoreKeys("4", "\u2074")))
    287                     // U+0665: "" ARABIC-INDIC DIGIT FIVE
    288                     // U+215D: "" VULGAR FRACTION FIVE EIGHTHS
    289                     .replaceKeyOfLabel("5", key("\u0665", joinMoreKeys("5", "\u215D")))
    290                     // U+0666: "" ARABIC-INDIC DIGIT SIX
    291                     .replaceKeyOfLabel("6", key("\u0666", moreKey("6")))
    292                     // U+0667: "" ARABIC-INDIC DIGIT SEVEN
    293                     // U+215E: "" VULGAR FRACTION SEVEN EIGHTHS
    294                     .replaceKeyOfLabel("7", key("\u0667", joinMoreKeys("7", "\u215E")))
    295                     // U+0668: "" ARABIC-INDIC DIGIT EIGHT
    296                     .replaceKeyOfLabel("8", key("\u0668", moreKey("8")))
    297                     // U+0669: "" ARABIC-INDIC DIGIT NINE
    298                     .replaceKeyOfLabel("9", key("\u0669", moreKey("9")))
    299                     // U+0660: "" ARABIC-INDIC DIGIT ZERO
    300                     // U+066B: "" ARABIC DECIMAL SEPARATOR
    301                     // U+066C: "" ARABIC THOUSANDS SEPARATOR
    302                     // U+207F: "" SUPERSCRIPT LATIN SMALL LETTER N
    303                     // U+2205: "" EMPTY SET
    304                     .replaceKeyOfLabel("0", key("\u0660",
    305                             joinMoreKeys("0", "\u066B", "\u066C", "\u207F", "\u2205")))
    306                     // U+066A: "" ARABIC PERCENT SIGN
    307                     // U+2030: "" PER MILLE SIGN
    308                     .replaceKeyOfLabel("%", key("\u066A", joinMoreKeys("%", "\u2030")))
    309                     // U+061B: "" ARABIC SEMICOLON
    310                     .replaceKeyOfLabel(";", key("\u061B", moreKey(";")))
    311                     // U+061F: "" ARABIC QUESTION MARK
    312                     // U+00BF: "" INVERTED QUESTION MARK
    313                     .replaceKeyOfLabel("?", key("\u061F", joinMoreKeys("?", "\u00BF")))
    314                     // U+060C: "" ARABIC COMMA
    315                     .replaceKeyOfLabel(",", "\u060C")
    316                     // U+FD3E: "" ORNATE LEFT PARENTHESIS
    317                     // U+FD3F: "" ORNATE RIGHT PARENTHESIS
    318                     .replaceKeyOfLabel("(", key("(", ")",
    319                             moreKey("\uFD3E", "\uFD3F"), moreKey("<", ">"), moreKey("{", "}"),
    320                             moreKey("[", "]")))
    321                     // U+FD3F: "" ORNATE RIGHT PARENTHESIS
    322                     // U+FD3E: "" ORNATE LEFT PARENTHESIS
    323                     .replaceKeyOfLabel(")", key(")", "(",
    324                             moreKey("\uFD3F", "\uFD3E"), moreKey(">", "<"), moreKey("}", "{"),
    325                             moreKey("]", "[")))
    326                     // U+2605: "" BLACK STAR
    327                     // U+066D: "" ARABIC FIVE POINTED STAR
    328                     .setMoreKeysOf("*", "\u2605", "\u066D")
    329                     .build();
    330         }
    331     }
    332 
    333     private static class ArabicSymbolsShifted extends RtlSymbolsShifted {
    334         public ArabicSymbolsShifted(final LayoutCustomizer customizer) {
    335             super(customizer);
    336         }
    337 
    338         @Override
    339         public ExpectedKey[][] getLayout(final boolean isPhone) {
    340             return new ExpectedKeyboardBuilder(super.getLayout(isPhone))
    341                     // U+2022: "" BULLET
    342                     // U+266A: "" EIGHTH NOTE
    343                     .setMoreKeysOf("\u2022", "\u266A")
    344                     // U+060C: "" ARABIC COMMA
    345                     .replaceKeyOfLabel(",", "\u060C")
    346                     .build();
    347         }
    348     }
    349 }
    350