diff options
author | 2024-12-16 21:45:41 -0500 | |
---|---|---|
committer | 2025-01-11 14:17:35 -0500 | |
commit | e9a0e66716dab4dd3184d009d8920de1961efdfa (patch) | |
tree | 02dcc096643d74645bf28459c2834c3d4a2ad7f2 /java/src/com/android/inputmethod/event/DeadKeyCombiner.java | |
parent | fb3b9360d70596d7e921de8bf7d3ca99564a077e (diff) | |
download | latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.tar.gz latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.tar.xz latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.zip |
Rename to Kelar Keyboard (org.kelar.inputmethod.latin)
Diffstat (limited to 'java/src/com/android/inputmethod/event/DeadKeyCombiner.java')
-rw-r--r-- | java/src/com/android/inputmethod/event/DeadKeyCombiner.java | 303 |
1 files changed, 0 insertions, 303 deletions
diff --git a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java deleted file mode 100644 index 1a28bb1d5..000000000 --- a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.event; - -import android.text.TextUtils; -import android.util.SparseIntArray; - -import com.android.inputmethod.latin.common.Constants; - -import java.text.Normalizer; -import java.util.ArrayList; - -import javax.annotation.Nonnull; - -/** - * A combiner that handles dead keys. - */ -public class DeadKeyCombiner implements Combiner { - - private static class Data { - // This class data taken from KeyCharacterMap.java. - - /* Characters used to display placeholders for dead keys. */ - private static final int ACCENT_ACUTE = '\u00B4'; - private static final int ACCENT_BREVE = '\u02D8'; - private static final int ACCENT_CARON = '\u02C7'; - private static final int ACCENT_CEDILLA = '\u00B8'; - private static final int ACCENT_CIRCUMFLEX = '\u02C6'; - private static final int ACCENT_COMMA_ABOVE = '\u1FBD'; - private static final int ACCENT_COMMA_ABOVE_RIGHT = '\u02BC'; - private static final int ACCENT_DOT_ABOVE = '\u02D9'; - private static final int ACCENT_DOT_BELOW = Constants.CODE_PERIOD; // approximate - private static final int ACCENT_DOUBLE_ACUTE = '\u02DD'; - private static final int ACCENT_GRAVE = '\u02CB'; - private static final int ACCENT_HOOK_ABOVE = '\u02C0'; - private static final int ACCENT_HORN = Constants.CODE_SINGLE_QUOTE; // approximate - private static final int ACCENT_MACRON = '\u00AF'; - private static final int ACCENT_MACRON_BELOW = '\u02CD'; - private static final int ACCENT_OGONEK = '\u02DB'; - private static final int ACCENT_REVERSED_COMMA_ABOVE = '\u02BD'; - private static final int ACCENT_RING_ABOVE = '\u02DA'; - private static final int ACCENT_STROKE = Constants.CODE_DASH; // approximate - private static final int ACCENT_TILDE = '\u02DC'; - private static final int ACCENT_TURNED_COMMA_ABOVE = '\u02BB'; - private static final int ACCENT_UMLAUT = '\u00A8'; - private static final int ACCENT_VERTICAL_LINE_ABOVE = '\u02C8'; - private static final int ACCENT_VERTICAL_LINE_BELOW = '\u02CC'; - - /* Legacy dead key display characters used in previous versions of the API (before L) - * We still support these characters by mapping them to their non-legacy version. */ - private static final int ACCENT_GRAVE_LEGACY = Constants.CODE_GRAVE_ACCENT; - private static final int ACCENT_CIRCUMFLEX_LEGACY = Constants.CODE_CIRCUMFLEX_ACCENT; - private static final int ACCENT_TILDE_LEGACY = Constants.CODE_TILDE; - - /** - * Maps Unicode combining diacritical to display-form dead key. - */ - static final SparseIntArray sCombiningToAccent = new SparseIntArray(); - static final SparseIntArray sAccentToCombining = new SparseIntArray(); - static { - // U+0300: COMBINING GRAVE ACCENT - addCombining('\u0300', ACCENT_GRAVE); - // U+0301: COMBINING ACUTE ACCENT - addCombining('\u0301', ACCENT_ACUTE); - // U+0302: COMBINING CIRCUMFLEX ACCENT - addCombining('\u0302', ACCENT_CIRCUMFLEX); - // U+0303: COMBINING TILDE - addCombining('\u0303', ACCENT_TILDE); - // U+0304: COMBINING MACRON - addCombining('\u0304', ACCENT_MACRON); - // U+0306: COMBINING BREVE - addCombining('\u0306', ACCENT_BREVE); - // U+0307: COMBINING DOT ABOVE - addCombining('\u0307', ACCENT_DOT_ABOVE); - // U+0308: COMBINING DIAERESIS - addCombining('\u0308', ACCENT_UMLAUT); - // U+0309: COMBINING HOOK ABOVE - addCombining('\u0309', ACCENT_HOOK_ABOVE); - // U+030A: COMBINING RING ABOVE - addCombining('\u030A', ACCENT_RING_ABOVE); - // U+030B: COMBINING DOUBLE ACUTE ACCENT - addCombining('\u030B', ACCENT_DOUBLE_ACUTE); - // U+030C: COMBINING CARON - addCombining('\u030C', ACCENT_CARON); - // U+030D: COMBINING VERTICAL LINE ABOVE - addCombining('\u030D', ACCENT_VERTICAL_LINE_ABOVE); - // U+030E: COMBINING DOUBLE VERTICAL LINE ABOVE - //addCombining('\u030E', ACCENT_DOUBLE_VERTICAL_LINE_ABOVE); - // U+030F: COMBINING DOUBLE GRAVE ACCENT - //addCombining('\u030F', ACCENT_DOUBLE_GRAVE); - // U+0310: COMBINING CANDRABINDU - //addCombining('\u0310', ACCENT_CANDRABINDU); - // U+0311: COMBINING INVERTED BREVE - //addCombining('\u0311', ACCENT_INVERTED_BREVE); - // U+0312: COMBINING TURNED COMMA ABOVE - addCombining('\u0312', ACCENT_TURNED_COMMA_ABOVE); - // U+0313: COMBINING COMMA ABOVE - addCombining('\u0313', ACCENT_COMMA_ABOVE); - // U+0314: COMBINING REVERSED COMMA ABOVE - addCombining('\u0314', ACCENT_REVERSED_COMMA_ABOVE); - // U+0315: COMBINING COMMA ABOVE RIGHT - addCombining('\u0315', ACCENT_COMMA_ABOVE_RIGHT); - // U+031B: COMBINING HORN - addCombining('\u031B', ACCENT_HORN); - // U+0323: COMBINING DOT BELOW - addCombining('\u0323', ACCENT_DOT_BELOW); - // U+0326: COMBINING COMMA BELOW - //addCombining('\u0326', ACCENT_COMMA_BELOW); - // U+0327: COMBINING CEDILLA - addCombining('\u0327', ACCENT_CEDILLA); - // U+0328: COMBINING OGONEK - addCombining('\u0328', ACCENT_OGONEK); - // U+0329: COMBINING VERTICAL LINE BELOW - addCombining('\u0329', ACCENT_VERTICAL_LINE_BELOW); - // U+0331: COMBINING MACRON BELOW - addCombining('\u0331', ACCENT_MACRON_BELOW); - // U+0335: COMBINING SHORT STROKE OVERLAY - addCombining('\u0335', ACCENT_STROKE); - // U+0342: COMBINING GREEK PERISPOMENI - //addCombining('\u0342', ACCENT_PERISPOMENI); - // U+0344: COMBINING GREEK DIALYTIKA TONOS - //addCombining('\u0344', ACCENT_DIALYTIKA_TONOS); - // U+0345: COMBINING GREEK YPOGEGRAMMENI - //addCombining('\u0345', ACCENT_YPOGEGRAMMENI); - - // One-way mappings to equivalent preferred accents. - // U+0340: COMBINING GRAVE TONE MARK - sCombiningToAccent.append('\u0340', ACCENT_GRAVE); - // U+0341: COMBINING ACUTE TONE MARK - sCombiningToAccent.append('\u0341', ACCENT_ACUTE); - // U+0343: COMBINING GREEK KORONIS - sCombiningToAccent.append('\u0343', ACCENT_COMMA_ABOVE); - - // One-way legacy mappings to preserve compatibility with older applications. - // U+0300: COMBINING GRAVE ACCENT - sAccentToCombining.append(ACCENT_GRAVE_LEGACY, '\u0300'); - // U+0302: COMBINING CIRCUMFLEX ACCENT - sAccentToCombining.append(ACCENT_CIRCUMFLEX_LEGACY, '\u0302'); - // U+0303: COMBINING TILDE - sAccentToCombining.append(ACCENT_TILDE_LEGACY, '\u0303'); - } - - private static void addCombining(int combining, int accent) { - sCombiningToAccent.append(combining, accent); - sAccentToCombining.append(accent, combining); - } - - // Caution! This may only contain chars, not supplementary code points. It's unlikely - // it will ever need to, but if it does we'll have to change this - private static final SparseIntArray sNonstandardDeadCombinations = new SparseIntArray(); - static { - // Non-standard decompositions. - // Stroke modifier for Finnish multilingual keyboard and others. - // U+0110: LATIN CAPITAL LETTER D WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'D', '\u0110'); - // U+01E4: LATIN CAPITAL LETTER G WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'G', '\u01e4'); - // U+0126: LATIN CAPITAL LETTER H WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'H', '\u0126'); - // U+0197: LATIN CAPITAL LETTER I WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'I', '\u0197'); - // U+0141: LATIN CAPITAL LETTER L WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'L', '\u0141'); - // U+00D8: LATIN CAPITAL LETTER O WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'O', '\u00d8'); - // U+0166: LATIN CAPITAL LETTER T WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'T', '\u0166'); - // U+0111: LATIN SMALL LETTER D WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'd', '\u0111'); - // U+01E5: LATIN SMALL LETTER G WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'g', '\u01e5'); - // U+0127: LATIN SMALL LETTER H WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'h', '\u0127'); - // U+0268: LATIN SMALL LETTER I WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'i', '\u0268'); - // U+0142: LATIN SMALL LETTER L WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'l', '\u0142'); - // U+00F8: LATIN SMALL LETTER O WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 'o', '\u00f8'); - // U+0167: LATIN SMALL LETTER T WITH STROKE - addNonStandardDeadCombination(ACCENT_STROKE, 't', '\u0167'); - } - - private static void addNonStandardDeadCombination(final int deadCodePoint, - final int spacingCodePoint, final int result) { - final int combination = (deadCodePoint << 16) | spacingCodePoint; - sNonstandardDeadCombinations.put(combination, result); - } - - public static final int NOT_A_CHAR = 0; - public static final int BITS_TO_SHIFT_DEAD_CODE_POINT_FOR_NON_STANDARD_COMBINATION = 16; - // Get a non-standard combination - public static char getNonstandardCombination(final int deadCodePoint, - final int spacingCodePoint) { - final int combination = spacingCodePoint | - (deadCodePoint << BITS_TO_SHIFT_DEAD_CODE_POINT_FOR_NON_STANDARD_COMBINATION); - return (char)sNonstandardDeadCombinations.get(combination, NOT_A_CHAR); - } - } - - // TODO: make this a list of events instead - final StringBuilder mDeadSequence = new StringBuilder(); - - @Nonnull - private static Event createEventChainFromSequence(final @Nonnull CharSequence text, - @Nonnull final Event originalEvent) { - int index = text.length(); - if (index <= 0) { - return originalEvent; - } - Event lastEvent = null; - do { - final int codePoint = Character.codePointBefore(text, index); - lastEvent = Event.createHardwareKeypressEvent(codePoint, - originalEvent.mKeyCode, lastEvent, false /* isKeyRepeat */); - index -= Character.charCount(codePoint); - } while (index > 0); - return lastEvent; - } - - @Override - @Nonnull - public Event processEvent(final ArrayList<Event> previousEvents, final Event event) { - if (TextUtils.isEmpty(mDeadSequence)) { - // No dead char is currently being tracked: this is the most common case. - if (event.isDead()) { - // The event was a dead key. Start tracking it. - mDeadSequence.appendCodePoint(event.mCodePoint); - return Event.createConsumedEvent(event); - } - // Regular keystroke when not keeping track of a dead key. Simply said, there are - // no dead keys at all in the current input, so this combiner has nothing to do and - // simply returns the event as is. The majority of events will go through this path. - return event; - } - if (Character.isWhitespace(event.mCodePoint) - || event.mCodePoint == mDeadSequence.codePointBefore(mDeadSequence.length())) { - // When whitespace or twice the same dead key, we should output the dead sequence as is. - final Event resultEvent = createEventChainFromSequence(mDeadSequence.toString(), - event); - mDeadSequence.setLength(0); - return resultEvent; - } - if (event.isFunctionalKeyEvent()) { - if (Constants.CODE_DELETE == event.mKeyCode) { - // Remove the last code point - final int trimIndex = mDeadSequence.length() - Character.charCount( - mDeadSequence.codePointBefore(mDeadSequence.length())); - mDeadSequence.setLength(trimIndex); - return Event.createConsumedEvent(event); - } - return event; - } - if (event.isDead()) { - mDeadSequence.appendCodePoint(event.mCodePoint); - return Event.createConsumedEvent(event); - } - // Combine normally. - final StringBuilder sb = new StringBuilder(); - sb.appendCodePoint(event.mCodePoint); - int codePointIndex = 0; - while (codePointIndex < mDeadSequence.length()) { - final int deadCodePoint = mDeadSequence.codePointAt(codePointIndex); - final char replacementSpacingChar = - Data.getNonstandardCombination(deadCodePoint, event.mCodePoint); - if (Data.NOT_A_CHAR != replacementSpacingChar) { - sb.setCharAt(0, replacementSpacingChar); - } else { - final int combining = Data.sAccentToCombining.get(deadCodePoint); - sb.appendCodePoint(0 == combining ? deadCodePoint : combining); - } - codePointIndex += Character.isSupplementaryCodePoint(deadCodePoint) ? 2 : 1; - } - final String normalizedString = Normalizer.normalize(sb, Normalizer.Form.NFC); - final Event resultEvent = createEventChainFromSequence(normalizedString, event); - mDeadSequence.setLength(0); - return resultEvent; - } - - @Override - public void reset() { - mDeadSequence.setLength(0); - } - - @Override - public CharSequence getCombiningStateFeedback() { - return mDeadSequence; - } -} |