Skip to content

Commit accce94

Browse files
author
Jeff Brown
committed
Improve selection of dead key accent chars.
The '^', '`', and '~' characters that we use for circumflex, grave and tilde accents are ugly. Use the appropriate printing modifier characters instead. Bug: 6110399 Change-Id: I53891139ed1cef3010f5319ff49df1eeb1c6feeb
1 parent 9a2bbf6 commit accce94

File tree

1 file changed

+167
-152
lines changed

1 file changed

+167
-152
lines changed

core/java/android/view/KeyCharacterMap.java

Lines changed: 167 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)