summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2010-02-13 00:07:38 -0800
committerKenny Root <kroot@google.com>2010-02-16 15:05:02 -0800
commitbb9a51768d2d9dddbe2394b99a00544a3d144fac (patch)
treea371dec6ecfa79d2205b6306667787cd95356b81 /core/jni
parent4a2d3b15ecca1f4db1e2c935ff36d19838eb5622 (diff)
downloadframeworks_base-bb9a51768d2d9dddbe2394b99a00544a3d144fac.zip
frameworks_base-bb9a51768d2d9dddbe2394b99a00544a3d144fac.tar.gz
frameworks_base-bb9a51768d2d9dddbe2394b99a00544a3d144fac.tar.bz2
Add API to access ICU's East Asian Width
Currently there is no way for an application built against the API to access East Asian Width data from ICU. This adds an API for applications to use to access it for correct drawing of international characters. Change-Id: Iab50698ee555ae2ca8ab4b242cc14aa6e0dc3b48
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/android_text_AndroidCharacter.cpp65
1 files changed, 62 insertions, 3 deletions
diff --git a/core/jni/android_text_AndroidCharacter.cpp b/core/jni/android_text_AndroidCharacter.cpp
index 05d7b73..1353478 100644
--- a/core/jni/android_text_AndroidCharacter.cpp
+++ b/core/jni/android_text_AndroidCharacter.cpp
@@ -23,7 +23,8 @@
#include "utils/Log.h"
#include "unicode/uchar.h"
-#define DIRECTIONALITY_UNDEFINED (-1)
+#define PROPERTY_UNDEFINED (-1)
+
// ICU => JDK mapping
static int directionality_map[U_CHAR_DIRECTION_COUNT] = {
0, // U_LEFT_TO_RIGHT (0) => DIRECTIONALITY_LEFT_TO_RIGHT (0)
@@ -79,7 +80,7 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray, j
(src[i + 1] & 0x3FF);
int dir = u_charDirection(c);
if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
- dir = DIRECTIONALITY_UNDEFINED;
+ dir = PROPERTY_UNDEFINED;
else
dir = directionality_map[dir];
@@ -89,7 +90,7 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray, j
int c = src[i];
int dir = u_charDirection(c);
if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
- dest[i] = DIRECTIONALITY_UNDEFINED;
+ dest[i] = PROPERTY_UNDEFINED;
else
dest[i] = directionality_map[dir];
}
@@ -100,6 +101,60 @@ DIRECTION_END:
env->ReleaseByteArrayElements(destArray, dest, JNI_ABORT);
}
+static jint getEastAsianWidth(JNIEnv* env, jobject obj, jchar input)
+{
+ int width = u_getIntPropertyValue(input, UCHAR_EAST_ASIAN_WIDTH);
+ if (width < 0 || width >= U_EA_COUNT)
+ width = PROPERTY_UNDEFINED;
+
+ return width;
+}
+
+static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
+ int start, int count, jbyteArray destArray)
+{
+ jchar* src = env->GetCharArrayElements(srcArray, NULL);
+ jbyte* dest = env->GetByteArrayElements(destArray, NULL);
+ if (src == NULL || dest == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
+ goto EA_END;
+ }
+
+ if (start < 0 || start > start + count
+ || env->GetArrayLength(srcArray) < (start + count)
+ || env->GetArrayLength(destArray) < count) {
+ jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
+ goto EA_END;
+ }
+
+ for (int i = 0; i < count; i++) {
+ const int srci = start + i;
+ if (src[srci] >= 0xD800 && src[srci] <= 0xDBFF &&
+ i + 1 < count &&
+ src[srci + 1] >= 0xDC00 && src[srci + 1] <= 0xDFFF) {
+ int c = 0x00010000 + ((src[srci] - 0xD800) << 10) +
+ (src[srci + 1] & 0x3FF);
+ int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
+ if (width < 0 || width >= U_EA_COUNT)
+ width = PROPERTY_UNDEFINED;
+
+ dest[i++] = width;
+ dest[i] = width;
+ } else {
+ int c = src[srci];
+ int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
+ if (width < 0 || width >= U_EA_COUNT)
+ width = PROPERTY_UNDEFINED;
+
+ dest[i] = width;
+ }
+ }
+
+EA_END:
+ env->ReleaseCharArrayElements(srcArray, src, JNI_ABORT);
+ env->ReleaseByteArrayElements(destArray, dest, JNI_ABORT);
+}
+
static jboolean mirror(JNIEnv* env, jobject obj, jcharArray charArray, int start, int count)
{
jchar* data = env->GetCharArrayElements(charArray, NULL);
@@ -140,6 +195,10 @@ static jchar getMirror(JNIEnv* env, jobject obj, jchar c)
static JNINativeMethod gMethods[] = {
{ "getDirectionalities", "([C[BI)V",
(void*) getDirectionalities },
+ { "getEastAsianWidth", "(C)I",
+ (void*) getEastAsianWidth },
+ { "getEastAsianWidths", "([CII[B)V",
+ (void*) getEastAsianWidths },
{ "mirror", "([CII)Z",
(void*) mirror },
{ "getMirror", "(C)C",