-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Recommended implementation of combining characters implementation. (#…
- Loading branch information
1 parent
d521212
commit 4663d35
Showing
5 changed files
with
160 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
shell/platform/android/io/flutter/embedding/engine/android/AndroidKeyProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package io.flutter.embedding.engine.android; | ||
|
||
import android.support.annotation.NonNull; | ||
import android.support.annotation.Nullable; | ||
import android.view.KeyCharacterMap; | ||
import android.view.KeyEvent; | ||
|
||
import io.flutter.embedding.engine.systemchannels.KeyEventChannel; | ||
|
||
public class AndroidKeyProcessor { | ||
private final KeyEventChannel keyEventChannel; | ||
private int combiningCharacter; | ||
|
||
public AndroidKeyProcessor(@NonNull KeyEventChannel keyEventChannel) { | ||
this.keyEventChannel = keyEventChannel; | ||
} | ||
|
||
public void onKeyUp(@NonNull KeyEvent keyEvent) { | ||
Character complexCharacter = applyCombiningCharacterToBaseCharacter(keyEvent.getUnicodeChar()); | ||
keyEventChannel.keyUp( | ||
new KeyEventChannel.FlutterKeyEvent(keyEvent, complexCharacter) | ||
); | ||
} | ||
|
||
public void onKeyDown(@NonNull KeyEvent keyEvent) { | ||
Character complexCharacter = applyCombiningCharacterToBaseCharacter(keyEvent.getUnicodeChar()); | ||
keyEventChannel.keyDown( | ||
new KeyEventChannel.FlutterKeyEvent(keyEvent, complexCharacter) | ||
); | ||
} | ||
|
||
/** | ||
* Applies the given Unicode character in {@code newCharacterCodePoint} to a previously | ||
* entered Unicode combining character and returns the combination of these characters | ||
* if a combination exists. | ||
* <p> | ||
* This method mutates {@link #combiningCharacter} over time to combine characters. | ||
* <p> | ||
* One of the following things happens in this method: | ||
* <ul> | ||
* <li>If no previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint} | ||
* is not a combining character, then {@code newCharacterCodePoint} is returned.</li> | ||
* <li>If no previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint} | ||
* is a combining character, then {@code newCharacterCodePoint} is saved as the | ||
* {@link #combiningCharacter} and null is returned.</li> | ||
* <li>If a previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint} | ||
* is also a combining character, then the {@code newCharacterCodePoint} is combined with | ||
* the existing {@link #combiningCharacter} and null is returned.</li> | ||
* <li>If a previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint} | ||
* is not a combining character, then the {@link #combiningCharacter} is applied to the | ||
* regular {@code newCharacterCodePoint} and the resulting complex character is returned. The | ||
* {@link #combiningCharacter} is cleared.</li> | ||
* </ul> | ||
* <p> | ||
* The following reference explains the concept of a "combining character": | ||
* https://en.wikipedia.org/wiki/Combining_character | ||
*/ | ||
@Nullable | ||
private Character applyCombiningCharacterToBaseCharacter(int newCharacterCodePoint) { | ||
if (newCharacterCodePoint == 0) { | ||
return null; | ||
} | ||
|
||
Character complexCharacter = (char) newCharacterCodePoint; | ||
boolean isNewCodePointACombiningCharacter = (newCharacterCodePoint & KeyCharacterMap.COMBINING_ACCENT) != 0; | ||
if (isNewCodePointACombiningCharacter) { | ||
// If a combining character was entered before, combine this one with that one. | ||
int plainCodePoint = newCharacterCodePoint & KeyCharacterMap.COMBINING_ACCENT_MASK; | ||
if (combiningCharacter != 0) { | ||
combiningCharacter = KeyCharacterMap.getDeadChar(combiningCharacter, plainCodePoint); | ||
} else { | ||
combiningCharacter = plainCodePoint; | ||
} | ||
} else { | ||
// The new character is a regular character. Apply combiningCharacter to it, if it exists. | ||
if (combiningCharacter != 0) { | ||
int combinedChar = KeyCharacterMap.getDeadChar(combiningCharacter, newCharacterCodePoint); | ||
if (combinedChar > 0) { | ||
complexCharacter = (char) combinedChar; | ||
} | ||
combiningCharacter = 0; | ||
} | ||
} | ||
|
||
return complexCharacter; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters