From 22ad15a2e72778cfa3fdf94a3b0c3ec0b5da16f9 Mon Sep 17 00:00:00 2001 From: Jack Palevich Date: Sun, 9 Oct 2011 17:14:21 -0700 Subject: [PATCH] Enable code to run pre-SDK-level 8. Introduce a utility class to deal with post-SDK-level-3 APIs. Cache the SDK level as an integer at start-up. Use reflection to access post-SDK-level-3 APIs. Add early out for space character, which shows up frequently. --- .../androidterm/util/PostAndroid3Utils.java | 65 ++++++++++++++++++++++ .../androidterm/util/UnicodeTranscript.java | 23 ++++---- 2 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 src/jackpal/androidterm/util/PostAndroid3Utils.java diff --git a/src/jackpal/androidterm/util/PostAndroid3Utils.java b/src/jackpal/androidterm/util/PostAndroid3Utils.java new file mode 100644 index 0000000..080016c --- /dev/null +++ b/src/jackpal/androidterm/util/PostAndroid3Utils.java @@ -0,0 +1,65 @@ +package jackpal.androidterm.util; + +import java.lang.reflect.Method; + +import android.text.AndroidCharacter; +import android.util.Log; + +/** + * Provides APIs post Android version 3. + * + */ +public class PostAndroid3Utils { + private static String TAG = "PostAndroid3Utils"; + + public final static int SDK = + Integer.valueOf(android.os.Build.VERSION.SDK); + /** + * Definitions related to android.text.AndroidCharacter + */ + public static class AndroidCharacterComp { + public static final int EAST_ASIAN_WIDTH_NEUTRAL = 0; + public static final int EAST_ASIAN_WIDTH_AMBIGUOUS = 1; + public static final int EAST_ASIAN_WIDTH_HALF_WIDTH = 2; + public static final int EAST_ASIAN_WIDTH_FULL_WIDTH = 3; + public static final int EAST_ASIAN_WIDTH_NARROW = 4; + public static final int EAST_ASIAN_WIDTH_WIDE = 5; + + private static boolean mGetEastAsianWidthInitialized; + private static Method mGetEastAsianWidthMethod; + /** + * Calls AndroidCharacter.getEastAsianWidth if it exists, + * otherwise returns EAST_ASIAN_WIDTH_NARROW. + */ + public static int getEastAsianWidth(char c) { + int result = EAST_ASIAN_WIDTH_NARROW; + if (!mGetEastAsianWidthInitialized) { + mGetEastAsianWidthInitialized = true; + try { + Class[] parameterTypes = new Class[]{ + char.class}; + Method method = AndroidCharacter.class.getMethod( + "getEastAsianWidth", parameterTypes); + if (method.getGenericReturnType() != int.class) { + Log.e(TAG, "Unexpected return type for getEastAsianWidth"); + } else { + mGetEastAsianWidthMethod = method; + } + } catch (NoSuchMethodException e) { + // Pre Android API level 8 + } + } else { + if (mGetEastAsianWidthMethod != null) { + try { + Integer objectResult = (Integer) mGetEastAsianWidthMethod.invoke( + null, new Object[]{new Character(c)}); + result = objectResult.intValue(); + } catch(Exception e) { + Log.e(TAG, "Unexpected exception when calling getEastAsianWidth", e); + } + } + } + return result; + } + } +} diff --git a/src/jackpal/androidterm/util/UnicodeTranscript.java b/src/jackpal/androidterm/util/UnicodeTranscript.java index ce0ef1b..c7c834f 100644 --- a/src/jackpal/androidterm/util/UnicodeTranscript.java +++ b/src/jackpal/androidterm/util/UnicodeTranscript.java @@ -16,7 +16,6 @@ package jackpal.androidterm.util; -import android.text.AndroidCharacter; import android.util.Log; /** @@ -360,6 +359,10 @@ public class UnicodeTranscript { * @return The display width of the Unicode code point. */ public static int charWidth(int codePoint) { + // Early out for spaces + if (codePoint == 32) { + return 1; + } switch (Character.getType(codePoint)) { case Character.CONTROL: case Character.FORMAT: @@ -368,7 +371,7 @@ public class UnicodeTranscript { return 0; } - if (Integer.valueOf(android.os.Build.VERSION.SDK) < 8) { + if (PostAndroid3Utils.SDK < 8) { /* No East Asian wide char support when running on Android < 2.2, because getEastAsianWidth() was introduced in API 8 */ return 1; @@ -376,9 +379,9 @@ public class UnicodeTranscript { if (Character.charCount(codePoint) == 1) { // Android's getEastAsianWidth() only works for BMP characters - switch (AndroidCharacter.getEastAsianWidth((char) codePoint)) { - case AndroidCharacter.EAST_ASIAN_WIDTH_FULL_WIDTH: - case AndroidCharacter.EAST_ASIAN_WIDTH_WIDE: + switch (PostAndroid3Utils.AndroidCharacterComp.getEastAsianWidth((char) codePoint)) { + case PostAndroid3Utils.AndroidCharacterComp.EAST_ASIAN_WIDTH_FULL_WIDTH: + case PostAndroid3Utils.AndroidCharacterComp.EAST_ASIAN_WIDTH_WIDE: return 2; } } else { @@ -405,7 +408,7 @@ public class UnicodeTranscript { * character requested will be followed by a NUL; the contents of the rest * of the array could potentially be garbage. * - * @param row The row number to get (-mActiveTranscriptRows..mScreenRows-1) + * @param row The row number to get (-mActiveTranscriptRows..mScreenRows-1) * @param x1 The first screen position that's wanted * @param x2 One after the last screen position that's wanted * @return A char[] array containing the requested contents @@ -447,7 +450,7 @@ public class UnicodeTranscript { x2 = line.getSpaceUsed(); } int length = x2 - x1; - + if (tmpLine == null || tmpLine.length < length + 1) { tmpLine = new char[length+1]; } @@ -582,7 +585,7 @@ public class UnicodeTranscript { private byte[] allocateColor(int row, int columns) { byte[] color = new byte[columns]; - + // Set all of the columns to the default colors byte defaultColor = encodeColor(mDefaultForeColor, mDefaultBackColor); for (int i = 0; i < columns; ++i) { @@ -777,7 +780,7 @@ class FullUnicodeLine { Character.toChars(codePoint, text, pos); } else { /* Store a combining character at the end of the existing contents, - so that it modifies them */ + so that it modifies them */ Character.toChars(codePoint, text, pos + oldLen); } @@ -805,7 +808,7 @@ class FullUnicodeLine { // Array needs growing char[] newText = new char[text.length + columns]; System.arraycopy(text, 0, newText, 0, nextPos); - + System.arraycopy(text, nextPos, newText, nextPos + 1, spaceUsed - nextPos); mText = text = newText; } else { -- 2.11.0