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 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[] getKeysLeftToSpacebar(final boolean isPhone) { 73 if (isPhone) { 74 // U+060C: "" ARABIC COMMA 75 return joinKeys(key("\u060C", SETTINGS_KEY)); 76 } 77 // U+060C: "" ARABIC COMMA 78 // U+061F: "" ARABIC QUESTION MARK 79 // U+061B: "" ARABIC SEMICOLON 80 return joinKeys(key("\u060C", joinMoreKeys( 81 ":", "!", "\u061F", "\u061B", "-", "\"", "'", SETTINGS_KEY))); 82 } 83 84 @Override 85 public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { 86 if (isPhone) { 87 return super.getKeysRightToSpacebar(isPhone); 88 } 89 // U+060C: "" ARABIC COMMA 90 // U+061F: "" ARABIC QUESTION MARK 91 // U+061B: "" ARABIC SEMICOLON 92 return joinKeys(key(".", getPunctuationMoreKeys(isPhone))); 93 } 94 95 @Override 96 public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { 97 return ARABIC_DIACRITICS; 98 } 99 100 // U+0623: "" ARABIC LETTER ALEF WITH HAMZA ABOVE 101 // U+200C: ZERO WIDTH NON-JOINER 102 // U+0628: "" ARABIC LETTER BEH 103 // U+062C: "" ARABIC LETTER JEEM 104 private static final ExpectedKey ARABIC_ALPHABET_KEY = key( 105 "\u0623\u200C\u0628\u200C\u062C", Constants.CODE_SWITCH_ALPHA_SYMBOL); 106 // U+0663: "" ARABIC-INDIC DIGIT THREE 107 // U+0662: "" ARABIC-INDIC DIGIT TWO 108 // U+0661: "" ARABIC-INDIC DIGIT ONE 109 // U+061F: "" ARABIC QUESTION MARK 110 private static final ExpectedKey ARABIC_SYMBOLS_KEY = key( 111 "\u0663\u0662\u0661\u061F", Constants.CODE_SWITCH_ALPHA_SYMBOL); 112 private static final ExpectedKey ARABIC_BACK_TO_SYMBOLS_KEY = key( 113 "\u0663\u0662\u0661\u061F", Constants.CODE_SHIFT); 114 115 private static final ExpectedKey[] ARABIC_DIACRITICS = { 116 // U+0655: "" ARABIC HAMZA BELOW 117 // U+0654: "" ARABIC HAMZA ABOVE 118 // U+0652: "" ARABIC SUKUN 119 // U+064D: "" ARABIC KASRATAN 120 // U+064C: "" ARABIC DAMMATAN 121 // U+064B: "" ARABIC FATHATAN 122 // U+0651: "" ARABIC SHADDA 123 // U+0656: "" ARABIC SUBSCRIPT ALEF 124 // U+0670: "" ARABIC LETTER SUPERSCRIPT ALEF 125 // U+0653: "" ARABIC MADDAH ABOVE 126 // U+0650: "" ARABIC KASRA 127 // U+064F: "" ARABIC DAMMA 128 // U+064E: "" ARABIC FATHA 129 // U+0640: "" ARABIC TATWEEL 130 moreKey(" \u0655", "\u0655"), moreKey(" \u0654", "\u0654"), 131 moreKey(" \u0652", "\u0652"), moreKey(" \u064D", "\u064D"), 132 moreKey(" \u064C", "\u064C"), moreKey(" \u064B", "\u064B"), 133 moreKey(" \u0651", "\u0651"), moreKey(" \u0656", "\u0656"), 134 moreKey(" \u0670", "\u0670"), moreKey(" \u0653", "\u0653"), 135 moreKey(" \u0650", "\u0650"), moreKey(" \u064F", "\u064F"), 136 moreKey(" \u064E", "\u064E"), moreKey("\u0640\u0640\u0640", "\u0640") 137 }; 138 } 139 140 @Override 141 ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { 142 if (isPhone) { 143 return ALPHABET_COMMON; 144 } else { 145 final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON); 146 // U+0626: "" ARABIC LETTER YEH WITH HAMZA ABOVE 147 builder.insertKeysAtRow(3, 2, "\u0626"); 148 return builder.build(); 149 } 150 } 151 152 @Override 153 ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) { 154 return null; 155 } 156 157 private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder() 158 .setKeysOfRow(1, 159 // U+0636: "" ARABIC LETTER DAD 160 // U+0661: "" ARABIC-INDIC DIGIT ONE 161 key("\u0636", joinMoreKeys("1", "\u0661")), 162 // U+0635: "" ARABIC LETTER SAD 163 // U+0662: "" ARABIC-INDIC DIGIT TWO 164 key("\u0635", joinMoreKeys("2", "\u0662")), 165 // U+062B: "" ARABIC LETTER THEH 166 // U+0663: "" ARABIC-INDIC DIGIT THREE 167 key("\u062B", joinMoreKeys("3", "\u0663")), 168 // U+0642: "" ARABIC LETTER QAF 169 // U+0664: "" ARABIC-INDIC DIGIT FOUR 170 // U+06A8: "" ARABIC LETTER QAF WITH THREE DOTS ABOVE 171 key("\u0642", joinMoreKeys("4", "\u0664", "\u06A8")), 172 // U+0641: "" ARABIC LETTER FEH 173 // U+0665: "" ARABIC-INDIC DIGIT FIVE 174 // U+06A4: "" ARABIC LETTER VEH 175 // U+06A2: "" ARABIC LETTER FEH WITH DOT MOVED BELOW 176 // U+06A5: "" ARABIC LETTER FEH WITH THREE DOTS BELOW 177 key("\u0641", joinMoreKeys("5", "\u0665", "\u06A4", "\u06A2", "\u06A5")), 178 // U+063A: "" ARABIC LETTER GHAIN 179 // U+0666: "" ARABIC-INDIC DIGIT SIX 180 key("\u063A", joinMoreKeys("6", "\u0666")), 181 // U+0639: "" ARABIC LETTER AIN 182 // U+0667: "" ARABIC-INDIC DIGIT SEVEN 183 key("\u0639", joinMoreKeys("7", "\u0667")), 184 // U+0647: "" ARABIC LETTER HEH 185 // U+0668: "" ARABIC-INDIC DIGIT EIGHT 186 // U+FEEB: "" ARABIC LETTER HEH INITIAL FORM 187 // U+0647 U+200D: ARABIC LETTER HEH + ZERO WIDTH JOINER 188 key("\u0647", joinMoreKeys("8", "\u0668", moreKey("\uFEEB", "\u0647\u200D"))), 189 // U+062E: "" ARABIC LETTER KHAH 190 // U+0669: "" ARABIC-INDIC DIGIT NINE 191 key("\u062E", joinMoreKeys("9", "\u0669")), 192 // U+062D: "" ARABIC LETTER HAH 193 // U+0660: "" ARABIC-INDIC DIGIT ZERO 194 key("\u062D", joinMoreKeys("0", "\u0660")), 195 // U+062C: "" ARABIC LETTER JEEM 196 // U+0686: "" ARABIC LETTER TCHEH 197 key("\u062C", moreKey("\u0686"))) 198 .setKeysOfRow(2, 199 // U+0634: "" ARABIC LETTER SHEEN 200 // U+069C: "" ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE 201 key("\u0634", moreKey("\u069C")), 202 // U+0633: "" ARABIC LETTER SEEN 203 "\u0633", 204 // U+064A: "" ARABIC LETTER YEH 205 // U+0626: "" ARABIC LETTER YEH WITH HAMZA ABOVE 206 // U+0649: "" ARABIC LETTER ALEF MAKSURA 207 key("\u064A", joinMoreKeys("\u0626", "\u0649")), 208 // U+0628: "" ARABIC LETTER BEH 209 // U+067E: "" ARABIC LETTER PEH 210 key("\u0628", moreKey("\u067E")), 211 // U+0644: "" ARABIC LETTER LAM 212 // U+FEFB: "" ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM 213 // U+0627: "" ARABIC LETTER ALEF 214 // U+FEF7: "" ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM 215 // U+0623: "" ARABIC LETTER ALEF WITH HAMZA ABOVE 216 // U+FEF9: "" ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM 217 // U+0625: "" ARABIC LETTER ALEF WITH HAMZA BELOW 218 // U+FEF5: "" ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM 219 // U+0622: "" ARABIC LETTER ALEF WITH MADDA ABOVE 220 key("\u0644", 221 moreKey("\uFEFB", "\u0644\u0627"), moreKey("\uFEF7", "\u0644\u0623"), 222 moreKey("\uFEF9", "\u0644\u0625"), moreKey("\uFEF5", "\u0644\u0622")), 223 // U+0627: "" ARABIC LETTER ALEF 224 // U+0622: "" ARABIC LETTER ALEF WITH MADDA ABOVE 225 // U+0621: "" ARABIC LETTER HAMZA 226 // U+0623: "" ARABIC LETTER ALEF WITH HAMZA ABOVE 227 // U+0625: "" ARABIC LETTER ALEF WITH HAMZA BELOW 228 // U+0671: "" ARABIC LETTER ALEF WASLA 229 key("\u0627", joinMoreKeys("\u0622", "\u0621", "\u0623", "\u0625", "\u0671")), 230 // U+062A: "" ARABIC LETTER TEH 231 // U+0646: "" ARABIC LETTER NOON 232 // U+0645: "" ARABIC LETTER MEEM 233 "\u062A", "\u0646", "\u0645", 234 // U+0643: "" ARABIC LETTER KAF 235 // U+06AF: "" ARABIC LETTER GAF 236 // U+06A9: "" ARABIC LETTER KEHEH 237 key("\u0643", joinMoreKeys("\u06AF", "\u06A9")), 238 // U+0637: "" ARABIC LETTER TAH 239 "\u0637") 240 .setKeysOfRow(3, 241 // U+0630: "" ARABIC LETTER THAL 242 // U+0621: "" ARABIC LETTER HAMZA 243 // U+0624: "" ARABIC LETTER WAW WITH HAMZA ABOVE 244 // U+0631: "" ARABIC LETTER REH 245 "\u0630", "\u0621", "\u0624", "\u0631", 246 // U+0649: "" ARABIC LETTER ALEF MAKSURA 247 // U+0626: "" ARABIC LETTER YEH WITH HAMZA ABOVE 248 key("\u0649", moreKey("\u0626")), 249 // U+0629: "" ARABIC LETTER TEH MARBUTA 250 // U+0648: "" ARABIC LETTER WAW 251 "\u0629", "\u0648", 252 // U+0632: "" ARABIC LETTER ZAIN 253 // U+0698: "" ARABIC LETTER JEH 254 key("\u0632", moreKey("\u0698")), 255 // U+0638: "" ARABIC LETTER ZAH 256 // U+062F: "" ARABIC LETTER DAL 257 "\u0638", "\u062F") 258 .build(); 259 260 private static class ArabicSymbols extends RtlSymbols { 261 public ArabicSymbols(final LayoutCustomizer customizer) { 262 super(customizer); 263 } 264 265 @Override 266 public ExpectedKey[][] getLayout(final boolean isPhone) { 267 return new ExpectedKeyboardBuilder(super.getLayout(isPhone)) 268 // U+0661: "" ARABIC-INDIC DIGIT ONE 269 // U+00B9: "" SUPERSCRIPT ONE 270 // U+00BD: "" VULGAR FRACTION ONE HALF 271 // U+2153: "" VULGAR FRACTION ONE THIRD 272 // U+00BC: "" VULGAR FRACTION ONE QUARTER 273 // U+215B: "" VULGAR FRACTION ONE EIGHTH 274 .replaceKeyOfLabel("1", key("\u0661", 275 joinMoreKeys("1", "\u00B9", "\u00BD", "\u2153", "\u00BC", "\u215B"))) 276 // U+0662: "" ARABIC-INDIC DIGIT TWO 277 // U+00B2: "" SUPERSCRIPT TWO 278 // U+2154: "" VULGAR FRACTION TWO THIRDS 279 .replaceKeyOfLabel("2", key("\u0662", joinMoreKeys("2", "\u00B2", "\u2154"))) 280 // U+0663: "" ARABIC-INDIC DIGIT THREE 281 // U+00B3: "" SUPERSCRIPT THREE 282 // U+00BE: "" VULGAR FRACTION THREE QUARTERS 283 // U+215C: "" VULGAR FRACTION THREE EIGHTHS 284 .replaceKeyOfLabel("3", key("\u0663", 285 joinMoreKeys("3", "\u00B3", "\u00BE", "\u215C"))) 286 // U+0664: "" ARABIC-INDIC DIGIT FOUR 287 // U+2074: "" SUPERSCRIPT FOUR 288 .replaceKeyOfLabel("4", key("\u0664", joinMoreKeys("4", "\u2074"))) 289 // U+0665: "" ARABIC-INDIC DIGIT FIVE 290 // U+215D: "" VULGAR FRACTION FIVE EIGHTHS 291 .replaceKeyOfLabel("5", key("\u0665", joinMoreKeys("5", "\u215D"))) 292 // U+0666: "" ARABIC-INDIC DIGIT SIX 293 .replaceKeyOfLabel("6", key("\u0666", moreKey("6"))) 294 // U+0667: "" ARABIC-INDIC DIGIT SEVEN 295 // U+215E: "" VULGAR FRACTION SEVEN EIGHTHS 296 .replaceKeyOfLabel("7", key("\u0667", joinMoreKeys("7", "\u215E"))) 297 // U+0668: "" ARABIC-INDIC DIGIT EIGHT 298 .replaceKeyOfLabel("8", key("\u0668", moreKey("8"))) 299 // U+0669: "" ARABIC-INDIC DIGIT NINE 300 .replaceKeyOfLabel("9", key("\u0669", moreKey("9"))) 301 // U+0660: "" ARABIC-INDIC DIGIT ZERO 302 // U+066B: "" ARABIC DECIMAL SEPARATOR 303 // U+066C: "" ARABIC THOUSANDS SEPARATOR 304 // U+207F: "" SUPERSCRIPT LATIN SMALL LETTER N 305 // U+2205: "" EMPTY SET 306 .replaceKeyOfLabel("0", key("\u0660", 307 joinMoreKeys("0", "\u066B", "\u066C", "\u207F", "\u2205"))) 308 // U+066A: "" ARABIC PERCENT SIGN 309 // U+2030: "" PER MILLE SIGN 310 .replaceKeyOfLabel("%", key("\u066A", joinMoreKeys("%", "\u2030"))) 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 ArabicSymbolsShifted extends RtlSymbolsShifted { 336 public ArabicSymbolsShifted(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 .build(); 349 } 350 } 351 } 352