@@ -135,6 +135,163 @@ public class KeyCharacterMap implements Parcelable {
135135 */
136136 public static final int MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED = 1 ;
137137
138+ /*
139+ * This bit will be set in the return value of {@link #get(int, int)} if the
140+ * key is a "dead key."
141+ */
142+ public static final int COMBINING_ACCENT = 0x80000000 ;
143+
144+ /**
145+ * Mask the return value from {@link #get(int, int)} with this value to get
146+ * a printable representation of the accent character of a "dead key."
147+ */
148+ public static final int COMBINING_ACCENT_MASK = 0x7FFFFFFF ;
149+
150+ /* Characters used to display placeholders for dead keys. */
151+ private static final int ACCENT_ACUTE = '\u00B4' ;
152+ private static final int ACCENT_GRAVE = '\u02CB' ;
153+ private static final int ACCENT_CIRCUMFLEX = '\u02C6' ;
154+ private static final int ACCENT_TILDE = '\u02DC' ;
155+ private static final int ACCENT_UMLAUT = '\u00A8' ;
156+
157+ /* Legacy dead key display characters used in previous versions of the API.
158+ * We still support these characters by mapping them to their non-legacy version. */
159+ private static final int ACCENT_GRAVE_LEGACY = '`' ;
160+ private static final int ACCENT_CIRCUMFLEX_LEGACY = '^' ;
161+ private static final int ACCENT_TILDE_LEGACY = '~' ;
162+
163+ /**
164+ * Maps Unicode combining diacritical to display-form dead key
165+ * (display character shifted left 16 bits).
166+ */
167+ private static final SparseIntArray COMBINING = new SparseIntArray ();
168+ static {
169+ COMBINING .put ('\u0300' , ACCENT_GRAVE );
170+ COMBINING .put ('\u0301' , ACCENT_ACUTE );
171+ COMBINING .put ('\u0302' , ACCENT_CIRCUMFLEX );
172+ COMBINING .put ('\u0303' , ACCENT_TILDE );
173+ COMBINING .put ('\u0308' , ACCENT_UMLAUT );
174+ }
175+
176+ /**
177+ * Maps combinations of (display-form) dead key and second character
178+ * to combined output character.
179+ */
180+ private static final SparseIntArray DEAD = new SparseIntArray ();
181+ static {
182+ addDeadChar (ACCENT_ACUTE , 'A' , '\u00C1' );
183+ addDeadChar (ACCENT_ACUTE , 'C' , '\u0106' );
184+ addDeadChar (ACCENT_ACUTE , 'E' , '\u00C9' );
185+ addDeadChar (ACCENT_ACUTE , 'G' , '\u01F4' );
186+ addDeadChar (ACCENT_ACUTE , 'I' , '\u00CD' );
187+ addDeadChar (ACCENT_ACUTE , 'K' , '\u1E30' );
188+ addDeadChar (ACCENT_ACUTE , 'L' , '\u0139' );
189+ addDeadChar (ACCENT_ACUTE , 'M' , '\u1E3E' );
190+ addDeadChar (ACCENT_ACUTE , 'N' , '\u0143' );
191+ addDeadChar (ACCENT_ACUTE , 'O' , '\u00D3' );
192+ addDeadChar (ACCENT_ACUTE , 'P' , '\u1E54' );
193+ addDeadChar (ACCENT_ACUTE , 'R' , '\u0154' );
194+ addDeadChar (ACCENT_ACUTE , 'S' , '\u015A' );
195+ addDeadChar (ACCENT_ACUTE , 'U' , '\u00DA' );
196+ addDeadChar (ACCENT_ACUTE , 'W' , '\u1E82' );
197+ addDeadChar (ACCENT_ACUTE , 'Y' , '\u00DD' );
198+ addDeadChar (ACCENT_ACUTE , 'Z' , '\u0179' );
199+ addDeadChar (ACCENT_ACUTE , 'a' , '\u00E1' );
200+ addDeadChar (ACCENT_ACUTE , 'c' , '\u0107' );
201+ addDeadChar (ACCENT_ACUTE , 'e' , '\u00E9' );
202+ addDeadChar (ACCENT_ACUTE , 'g' , '\u01F5' );
203+ addDeadChar (ACCENT_ACUTE , 'i' , '\u00ED' );
204+ addDeadChar (ACCENT_ACUTE , 'k' , '\u1E31' );
205+ addDeadChar (ACCENT_ACUTE , 'l' , '\u013A' );
206+ addDeadChar (ACCENT_ACUTE , 'm' , '\u1E3F' );
207+ addDeadChar (ACCENT_ACUTE , 'n' , '\u0144' );
208+ addDeadChar (ACCENT_ACUTE , 'o' , '\u00F3' );
209+ addDeadChar (ACCENT_ACUTE , 'p' , '\u1E55' );
210+ addDeadChar (ACCENT_ACUTE , 'r' , '\u0155' );
211+ addDeadChar (ACCENT_ACUTE , 's' , '\u015B' );
212+ addDeadChar (ACCENT_ACUTE , 'u' , '\u00FA' );
213+ addDeadChar (ACCENT_ACUTE , 'w' , '\u1E83' );
214+ addDeadChar (ACCENT_ACUTE , 'y' , '\u00FD' );
215+ addDeadChar (ACCENT_ACUTE , 'z' , '\u017A' );
216+ addDeadChar (ACCENT_CIRCUMFLEX , 'A' , '\u00C2' );
217+ addDeadChar (ACCENT_CIRCUMFLEX , 'C' , '\u0108' );
218+ addDeadChar (ACCENT_CIRCUMFLEX , 'E' , '\u00CA' );
219+ addDeadChar (ACCENT_CIRCUMFLEX , 'G' , '\u011C' );
220+ addDeadChar (ACCENT_CIRCUMFLEX , 'H' , '\u0124' );
221+ addDeadChar (ACCENT_CIRCUMFLEX , 'I' , '\u00CE' );
222+ addDeadChar (ACCENT_CIRCUMFLEX , 'J' , '\u0134' );
223+ addDeadChar (ACCENT_CIRCUMFLEX , 'O' , '\u00D4' );
224+ addDeadChar (ACCENT_CIRCUMFLEX , 'S' , '\u015C' );
225+ addDeadChar (ACCENT_CIRCUMFLEX , 'U' , '\u00DB' );
226+ addDeadChar (ACCENT_CIRCUMFLEX , 'W' , '\u0174' );
227+ addDeadChar (ACCENT_CIRCUMFLEX , 'Y' , '\u0176' );
228+ addDeadChar (ACCENT_CIRCUMFLEX , 'Z' , '\u1E90' );
229+ addDeadChar (ACCENT_CIRCUMFLEX , 'a' , '\u00E2' );
230+ addDeadChar (ACCENT_CIRCUMFLEX , 'c' , '\u0109' );
231+ addDeadChar (ACCENT_CIRCUMFLEX , 'e' , '\u00EA' );
232+ addDeadChar (ACCENT_CIRCUMFLEX , 'g' , '\u011D' );
233+ addDeadChar (ACCENT_CIRCUMFLEX , 'h' , '\u0125' );
234+ addDeadChar (ACCENT_CIRCUMFLEX , 'i' , '\u00EE' );
235+ addDeadChar (ACCENT_CIRCUMFLEX , 'j' , '\u0135' );
236+ addDeadChar (ACCENT_CIRCUMFLEX , 'o' , '\u00F4' );
237+ addDeadChar (ACCENT_CIRCUMFLEX , 's' , '\u015D' );
238+ addDeadChar (ACCENT_CIRCUMFLEX , 'u' , '\u00FB' );
239+ addDeadChar (ACCENT_CIRCUMFLEX , 'w' , '\u0175' );
240+ addDeadChar (ACCENT_CIRCUMFLEX , 'y' , '\u0177' );
241+ addDeadChar (ACCENT_CIRCUMFLEX , 'z' , '\u1E91' );
242+ addDeadChar (ACCENT_GRAVE , 'A' , '\u00C0' );
243+ addDeadChar (ACCENT_GRAVE , 'E' , '\u00C8' );
244+ addDeadChar (ACCENT_GRAVE , 'I' , '\u00CC' );
245+ addDeadChar (ACCENT_GRAVE , 'N' , '\u01F8' );
246+ addDeadChar (ACCENT_GRAVE , 'O' , '\u00D2' );
247+ addDeadChar (ACCENT_GRAVE , 'U' , '\u00D9' );
248+ addDeadChar (ACCENT_GRAVE , 'W' , '\u1E80' );
249+ addDeadChar (ACCENT_GRAVE , 'Y' , '\u1EF2' );
250+ addDeadChar (ACCENT_GRAVE , 'a' , '\u00E0' );
251+ addDeadChar (ACCENT_GRAVE , 'e' , '\u00E8' );
252+ addDeadChar (ACCENT_GRAVE , 'i' , '\u00EC' );
253+ addDeadChar (ACCENT_GRAVE , 'n' , '\u01F9' );
254+ addDeadChar (ACCENT_GRAVE , 'o' , '\u00F2' );
255+ addDeadChar (ACCENT_GRAVE , 'u' , '\u00F9' );
256+ addDeadChar (ACCENT_GRAVE , 'w' , '\u1E81' );
257+ addDeadChar (ACCENT_GRAVE , 'y' , '\u1EF3' );
258+ addDeadChar (ACCENT_TILDE , 'A' , '\u00C3' );
259+ addDeadChar (ACCENT_TILDE , 'E' , '\u1EBC' );
260+ addDeadChar (ACCENT_TILDE , 'I' , '\u0128' );
261+ addDeadChar (ACCENT_TILDE , 'N' , '\u00D1' );
262+ addDeadChar (ACCENT_TILDE , 'O' , '\u00D5' );
263+ addDeadChar (ACCENT_TILDE , 'U' , '\u0168' );
264+ addDeadChar (ACCENT_TILDE , 'V' , '\u1E7C' );
265+ addDeadChar (ACCENT_TILDE , 'Y' , '\u1EF8' );
266+ addDeadChar (ACCENT_TILDE , 'a' , '\u00E3' );
267+ addDeadChar (ACCENT_TILDE , 'e' , '\u1EBD' );
268+ addDeadChar (ACCENT_TILDE , 'i' , '\u0129' );
269+ addDeadChar (ACCENT_TILDE , 'n' , '\u00F1' );
270+ addDeadChar (ACCENT_TILDE , 'o' , '\u00F5' );
271+ addDeadChar (ACCENT_TILDE , 'u' , '\u0169' );
272+ addDeadChar (ACCENT_TILDE , 'v' , '\u1E7D' );
273+ addDeadChar (ACCENT_TILDE , 'y' , '\u1EF9' );
274+ addDeadChar (ACCENT_UMLAUT , 'A' , '\u00C4' );
275+ addDeadChar (ACCENT_UMLAUT , 'E' , '\u00CB' );
276+ addDeadChar (ACCENT_UMLAUT , 'H' , '\u1E26' );
277+ addDeadChar (ACCENT_UMLAUT , 'I' , '\u00CF' );
278+ addDeadChar (ACCENT_UMLAUT , 'O' , '\u00D6' );
279+ addDeadChar (ACCENT_UMLAUT , 'U' , '\u00DC' );
280+ addDeadChar (ACCENT_UMLAUT , 'W' , '\u1E84' );
281+ addDeadChar (ACCENT_UMLAUT , 'X' , '\u1E8C' );
282+ addDeadChar (ACCENT_UMLAUT , 'Y' , '\u0178' );
283+ addDeadChar (ACCENT_UMLAUT , 'a' , '\u00E4' );
284+ addDeadChar (ACCENT_UMLAUT , 'e' , '\u00EB' );
285+ addDeadChar (ACCENT_UMLAUT , 'h' , '\u1E27' );
286+ addDeadChar (ACCENT_UMLAUT , 'i' , '\u00EF' );
287+ addDeadChar (ACCENT_UMLAUT , 'o' , '\u00F6' );
288+ addDeadChar (ACCENT_UMLAUT , 't' , '\u1E97' );
289+ addDeadChar (ACCENT_UMLAUT , 'u' , '\u00FC' );
290+ addDeadChar (ACCENT_UMLAUT , 'w' , '\u1E85' );
291+ addDeadChar (ACCENT_UMLAUT , 'x' , '\u1E8D' );
292+ addDeadChar (ACCENT_UMLAUT , 'y' , '\u00FF' );
293+ }
294+
138295 public static final Parcelable .Creator <KeyCharacterMap > CREATOR =
139296 new Parcelable .Creator <KeyCharacterMap >() {
140297 public KeyCharacterMap createFromParcel (Parcel in ) {
@@ -232,7 +389,7 @@ public int get(int keyCode, int metaState) {
232389
233390 int map = COMBINING .get (ch );
234391 if (map != 0 ) {
235- return map ;
392+ return map | COMBINING_ACCENT ;
236393 } else {
237394 return ch ;
238395 }
@@ -346,6 +503,13 @@ public char getDisplayLabel(int keyCode) {
346503 * @return The combined character, or 0 if the characters cannot be combined.
347504 */
348505 public static int getDeadChar (int accent , int c ) {
506+ if (accent == ACCENT_CIRCUMFLEX_LEGACY ) {
507+ accent = ACCENT_CIRCUMFLEX ;
508+ } else if (accent == ACCENT_GRAVE_LEGACY ) {
509+ accent = ACCENT_GRAVE ;
510+ } else if (accent == ACCENT_TILDE_LEGACY ) {
511+ accent = ACCENT_TILDE ;
512+ }
349513 return DEAD .get ((accent << 16 ) | c );
350514 }
351515
@@ -559,157 +723,8 @@ public int describeContents() {
559723 return 0 ;
560724 }
561725
562- /**
563- * Maps Unicode combining diacritical to display-form dead key
564- * (display character shifted left 16 bits).
565- */
566- private static SparseIntArray COMBINING = new SparseIntArray ();
567-
568- /**
569- * Maps combinations of (display-form) dead key and second character
570- * to combined output character.
571- */
572- private static SparseIntArray DEAD = new SparseIntArray ();
573-
574- /*
575- * TODO: Change the table format to support full 21-bit-wide
576- * accent characters and combined characters if ever necessary.
577- */
578- private static final int ACUTE = '\u00B4' << 16 ;
579- private static final int GRAVE = '`' << 16 ;
580- private static final int CIRCUMFLEX = '^' << 16 ;
581- private static final int TILDE = '~' << 16 ;
582- private static final int UMLAUT = '\u00A8' << 16 ;
583-
584- /*
585- * This bit will be set in the return value of {@link #get(int, int)} if the
586- * key is a "dead key."
587- */
588- public static final int COMBINING_ACCENT = 0x80000000 ;
589- /**
590- * Mask the return value from {@link #get(int, int)} with this value to get
591- * a printable representation of the accent character of a "dead key."
592- */
593- public static final int COMBINING_ACCENT_MASK = 0x7FFFFFFF ;
594-
595- static {
596- COMBINING .put ('\u0300' , (GRAVE >> 16 ) | COMBINING_ACCENT );
597- COMBINING .put ('\u0301' , (ACUTE >> 16 ) | COMBINING_ACCENT );
598- COMBINING .put ('\u0302' , (CIRCUMFLEX >> 16 ) | COMBINING_ACCENT );
599- COMBINING .put ('\u0303' , (TILDE >> 16 ) | COMBINING_ACCENT );
600- COMBINING .put ('\u0308' , (UMLAUT >> 16 ) | COMBINING_ACCENT );
601-
602- DEAD .put (ACUTE | 'A' , '\u00C1' );
603- DEAD .put (ACUTE | 'C' , '\u0106' );
604- DEAD .put (ACUTE | 'E' , '\u00C9' );
605- DEAD .put (ACUTE | 'G' , '\u01F4' );
606- DEAD .put (ACUTE | 'I' , '\u00CD' );
607- DEAD .put (ACUTE | 'K' , '\u1E30' );
608- DEAD .put (ACUTE | 'L' , '\u0139' );
609- DEAD .put (ACUTE | 'M' , '\u1E3E' );
610- DEAD .put (ACUTE | 'N' , '\u0143' );
611- DEAD .put (ACUTE | 'O' , '\u00D3' );
612- DEAD .put (ACUTE | 'P' , '\u1E54' );
613- DEAD .put (ACUTE | 'R' , '\u0154' );
614- DEAD .put (ACUTE | 'S' , '\u015A' );
615- DEAD .put (ACUTE | 'U' , '\u00DA' );
616- DEAD .put (ACUTE | 'W' , '\u1E82' );
617- DEAD .put (ACUTE | 'Y' , '\u00DD' );
618- DEAD .put (ACUTE | 'Z' , '\u0179' );
619- DEAD .put (ACUTE | 'a' , '\u00E1' );
620- DEAD .put (ACUTE | 'c' , '\u0107' );
621- DEAD .put (ACUTE | 'e' , '\u00E9' );
622- DEAD .put (ACUTE | 'g' , '\u01F5' );
623- DEAD .put (ACUTE | 'i' , '\u00ED' );
624- DEAD .put (ACUTE | 'k' , '\u1E31' );
625- DEAD .put (ACUTE | 'l' , '\u013A' );
626- DEAD .put (ACUTE | 'm' , '\u1E3F' );
627- DEAD .put (ACUTE | 'n' , '\u0144' );
628- DEAD .put (ACUTE | 'o' , '\u00F3' );
629- DEAD .put (ACUTE | 'p' , '\u1E55' );
630- DEAD .put (ACUTE | 'r' , '\u0155' );
631- DEAD .put (ACUTE | 's' , '\u015B' );
632- DEAD .put (ACUTE | 'u' , '\u00FA' );
633- DEAD .put (ACUTE | 'w' , '\u1E83' );
634- DEAD .put (ACUTE | 'y' , '\u00FD' );
635- DEAD .put (ACUTE | 'z' , '\u017A' );
636- DEAD .put (CIRCUMFLEX | 'A' , '\u00C2' );
637- DEAD .put (CIRCUMFLEX | 'C' , '\u0108' );
638- DEAD .put (CIRCUMFLEX | 'E' , '\u00CA' );
639- DEAD .put (CIRCUMFLEX | 'G' , '\u011C' );
640- DEAD .put (CIRCUMFLEX | 'H' , '\u0124' );
641- DEAD .put (CIRCUMFLEX | 'I' , '\u00CE' );
642- DEAD .put (CIRCUMFLEX | 'J' , '\u0134' );
643- DEAD .put (CIRCUMFLEX | 'O' , '\u00D4' );
644- DEAD .put (CIRCUMFLEX | 'S' , '\u015C' );
645- DEAD .put (CIRCUMFLEX | 'U' , '\u00DB' );
646- DEAD .put (CIRCUMFLEX | 'W' , '\u0174' );
647- DEAD .put (CIRCUMFLEX | 'Y' , '\u0176' );
648- DEAD .put (CIRCUMFLEX | 'Z' , '\u1E90' );
649- DEAD .put (CIRCUMFLEX | 'a' , '\u00E2' );
650- DEAD .put (CIRCUMFLEX | 'c' , '\u0109' );
651- DEAD .put (CIRCUMFLEX | 'e' , '\u00EA' );
652- DEAD .put (CIRCUMFLEX | 'g' , '\u011D' );
653- DEAD .put (CIRCUMFLEX | 'h' , '\u0125' );
654- DEAD .put (CIRCUMFLEX | 'i' , '\u00EE' );
655- DEAD .put (CIRCUMFLEX | 'j' , '\u0135' );
656- DEAD .put (CIRCUMFLEX | 'o' , '\u00F4' );
657- DEAD .put (CIRCUMFLEX | 's' , '\u015D' );
658- DEAD .put (CIRCUMFLEX | 'u' , '\u00FB' );
659- DEAD .put (CIRCUMFLEX | 'w' , '\u0175' );
660- DEAD .put (CIRCUMFLEX | 'y' , '\u0177' );
661- DEAD .put (CIRCUMFLEX | 'z' , '\u1E91' );
662- DEAD .put (GRAVE | 'A' , '\u00C0' );
663- DEAD .put (GRAVE | 'E' , '\u00C8' );
664- DEAD .put (GRAVE | 'I' , '\u00CC' );
665- DEAD .put (GRAVE | 'N' , '\u01F8' );
666- DEAD .put (GRAVE | 'O' , '\u00D2' );
667- DEAD .put (GRAVE | 'U' , '\u00D9' );
668- DEAD .put (GRAVE | 'W' , '\u1E80' );
669- DEAD .put (GRAVE | 'Y' , '\u1EF2' );
670- DEAD .put (GRAVE | 'a' , '\u00E0' );
671- DEAD .put (GRAVE | 'e' , '\u00E8' );
672- DEAD .put (GRAVE | 'i' , '\u00EC' );
673- DEAD .put (GRAVE | 'n' , '\u01F9' );
674- DEAD .put (GRAVE | 'o' , '\u00F2' );
675- DEAD .put (GRAVE | 'u' , '\u00F9' );
676- DEAD .put (GRAVE | 'w' , '\u1E81' );
677- DEAD .put (GRAVE | 'y' , '\u1EF3' );
678- DEAD .put (TILDE | 'A' , '\u00C3' );
679- DEAD .put (TILDE | 'E' , '\u1EBC' );
680- DEAD .put (TILDE | 'I' , '\u0128' );
681- DEAD .put (TILDE | 'N' , '\u00D1' );
682- DEAD .put (TILDE | 'O' , '\u00D5' );
683- DEAD .put (TILDE | 'U' , '\u0168' );
684- DEAD .put (TILDE | 'V' , '\u1E7C' );
685- DEAD .put (TILDE | 'Y' , '\u1EF8' );
686- DEAD .put (TILDE | 'a' , '\u00E3' );
687- DEAD .put (TILDE | 'e' , '\u1EBD' );
688- DEAD .put (TILDE | 'i' , '\u0129' );
689- DEAD .put (TILDE | 'n' , '\u00F1' );
690- DEAD .put (TILDE | 'o' , '\u00F5' );
691- DEAD .put (TILDE | 'u' , '\u0169' );
692- DEAD .put (TILDE | 'v' , '\u1E7D' );
693- DEAD .put (TILDE | 'y' , '\u1EF9' );
694- DEAD .put (UMLAUT | 'A' , '\u00C4' );
695- DEAD .put (UMLAUT | 'E' , '\u00CB' );
696- DEAD .put (UMLAUT | 'H' , '\u1E26' );
697- DEAD .put (UMLAUT | 'I' , '\u00CF' );
698- DEAD .put (UMLAUT | 'O' , '\u00D6' );
699- DEAD .put (UMLAUT | 'U' , '\u00DC' );
700- DEAD .put (UMLAUT | 'W' , '\u1E84' );
701- DEAD .put (UMLAUT | 'X' , '\u1E8C' );
702- DEAD .put (UMLAUT | 'Y' , '\u0178' );
703- DEAD .put (UMLAUT | 'a' , '\u00E4' );
704- DEAD .put (UMLAUT | 'e' , '\u00EB' );
705- DEAD .put (UMLAUT | 'h' , '\u1E27' );
706- DEAD .put (UMLAUT | 'i' , '\u00EF' );
707- DEAD .put (UMLAUT | 'o' , '\u00F6' );
708- DEAD .put (UMLAUT | 't' , '\u1E97' );
709- DEAD .put (UMLAUT | 'u' , '\u00FC' );
710- DEAD .put (UMLAUT | 'w' , '\u1E85' );
711- DEAD .put (UMLAUT | 'x' , '\u1E8D' );
712- DEAD .put (UMLAUT | 'y' , '\u00FF' );
726+ private static void addDeadChar (int accent , int c , char combinedResult ) {
727+ DEAD .put ((accent << 16 ) | c , combinedResult );
713728 }
714729
715730 /**
0 commit comments