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