OSDN Git Service

Enable code to run pre-SDK-level 8.
authorJack Palevich <jack.palevich@gmail.com>
Mon, 10 Oct 2011 00:14:21 +0000 (17:14 -0700)
committerJack Palevich <jack.palevich@gmail.com>
Mon, 10 Oct 2011 00:14:21 +0000 (17:14 -0700)
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.

src/jackpal/androidterm/util/PostAndroid3Utils.java [new file with mode: 0644]
src/jackpal/androidterm/util/UnicodeTranscript.java

diff --git a/src/jackpal/androidterm/util/PostAndroid3Utils.java b/src/jackpal/androidterm/util/PostAndroid3Utils.java
new file mode 100644 (file)
index 0000000..080016c
--- /dev/null
@@ -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;
+        }
+    }
+}
index ce0ef1b..c7c834f 100644 (file)
@@ -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 {