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