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 Farsi extends LayoutBase {
     29     private static final String LAYOUT_NAME = "farsi";
     30 
     31     public Farsi(final Locale locale) {
     32         super(new FarsiCustomizer(locale), FarsiSymbols.class, FarsiSymbolsShifted.class);
     33     }
     34 
     35     @Override
     36     public String getName() { return LAYOUT_NAME; }
     37 
     38     private static class FarsiCustomizer extends LayoutCustomizer {
     39         FarsiCustomizer(final Locale locale) { super(locale); }
     40 
     41         @Override
     42         public ExpectedKey getAlphabetKey() { return FARSI_ALPHABET_KEY; }
     43 
     44         @Override
     45         public ExpectedKey getSymbolsKey() { return FARSI_SYMBOLS_KEY; }
     46 
     47         @Override
     48         public ExpectedKey getBackToSymbolsKey() { return FARSI_BACK_TO_SYMBOLS_KEY; }
     49 
     50         @Override
     51         public ExpectedKey getCurrencyKey() { return CURRENCY_RIAL; }
     52 
     53         @Override
     54         public ExpectedKey[] getOtherCurrencyKeys() {
     55             return SymbolsShifted.CURRENCIES_OTHER_GENERIC;
     56         }
     57 
     58         @Override
     59         public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) {
     60             return EMPTY_KEYS;
     61         }
     62 
     63         @Override
     64         public ExpectedKey[] getRightShiftKeys(final boolean isPhone) {
     65             return EMPTY_KEYS;
     66         }
     67 
     68         @Override
     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
     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
     91         public ExpectedKey[] getSpaceKeys(final boolean isPhone) {
     92             return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY, key(ZWNJ_KEY, ZWJ_KEY));
     93         }
     94 
     95         @Override
     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
    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
    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 {
    246         public FarsiSymbols(final LayoutCustomizer customizer) {
    247             super(customizer);
    248         }
    249 
    250         @Override
    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 {
    335         public FarsiSymbolsShifted(final LayoutCustomizer customizer) {
    336             super(customizer);
    337         }
    338 
    339         @Override
    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