changeset 3989:8df5b67cc694

7029934: Xrender: Text is truncated with 64 bit Linux JRE Reviewed-by: bae, flar, ceisserer Contributed-by: linuxhippy@gmail.com
author prr
date Fri, 01 Apr 2011 12:45:45 -0700
parents 81c8b844e917
children 50d62d0a7a2e
files src/solaris/native/sun/java2d/x11/XRBackendNative.c
diffstat 1 files changed, 53 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/solaris/native/sun/java2d/x11/XRBackendNative.c	Thu Mar 31 15:02:57 2011 -0700
+++ b/src/solaris/native/sun/java2d/x11/XRBackendNative.c	Fri Apr 01 12:45:45 2011 -0700
@@ -644,7 +644,7 @@
     for (i=0; i < glyphCnt; i++) {
       GlyphInfo *jginfo = (GlyphInfo *) jlong_to_ptr(glyphInfoPtrs[i]);
 
-      gid[i] = (Glyph) (0xffffffff & ((unsigned int) jginfo->cellInfo));
+      gid[i] = (Glyph) (0x0ffffffffL & ((unsigned long)(jginfo->cellInfo)));
       xginfo[i].x = (-jginfo->topLeftX);
       xginfo[i].y = (-jginfo->topLeftY);
       xginfo[i].width = jginfo->width;
@@ -666,16 +666,56 @@
 JNIEXPORT void JNICALL
 Java_sun_java2d_xr_XRBackendNative_XRFreeGlyphsNative
  (JNIEnv *env, jclass cls, jint glyphSet, jintArray gidArray, jint glyphCnt) {
-    jint *gids;
-    int i;
 
-    if ((gids = (jint *) (*env)->GetPrimitiveArrayCritical(env, gidArray, NULL)) == NULL) {
+    /* The glyph ids are 32 bit but may be stored in a 64 bit long on
+     * a 64 bit architecture. So optimise the 32 bit case to avoid
+     * extra stack or heap allocations by directly referencing the
+     * underlying Java array and only allocate on 64 bit.
+     */
+    if (sizeof(jint) == sizeof(Glyph)) {
+        jint *gids =
+            (*env)->GetPrimitiveArrayCritical(env, gidArray, NULL);
+        if (gids == NULL) {
+            return;
+        } else {
+             XRenderFreeGlyphs(awt_display,
+                               (GlyphSet)glyphSet, (Glyph *)gids, glyphCnt);
+             (*env)->ReleasePrimitiveArrayCritical(env, gidArray,
+                                                   gids, JNI_ABORT);
+        }
         return;
-    }
+    } else {
+        Glyph stack_ids[64];
+        Glyph *gids = NULL;
+        jint* jgids = NULL;
+        int i;
 
-    XRenderFreeGlyphs (awt_display, (GlyphSet) glyphSet, (Glyph *) gids, glyphCnt);
-
-    (*env)->ReleasePrimitiveArrayCritical(env, gidArray, gids, JNI_ABORT);
+        if (glyphCnt <= 64) {
+            gids = stack_ids;
+        } else {
+            gids = (Glyph *)malloc(sizeof(Glyph) * glyphCnt);
+            if (gids == NULL) {
+                return;
+            }
+        }
+        jgids = (*env)->GetPrimitiveArrayCritical(env, gidArray, NULL);
+        if (jgids == NULL) {
+            if (gids != stack_ids) {
+                free(gids);
+            }
+            return;
+        }
+        for (i=0; i < glyphCnt; i++) {
+            gids[i] = jgids[i];
+        }
+        XRenderFreeGlyphs(awt_display,
+                          (GlyphSet) glyphSet, gids, glyphCnt);
+        (*env)->ReleasePrimitiveArrayCritical(env, gidArray,
+                                              jgids, JNI_ABORT);
+        if (gids != stack_ids) {
+            free(gids);
+        }
+    }
 }
 
 JNIEXPORT jint JNICALL
@@ -692,9 +732,9 @@
     jint *ids;
     jint *elts;
     XGlyphElt32 *xelts;
-    Glyph *xids;
+    unsigned int *xids;
     XGlyphElt32 selts[24];
-    Glyph sids[256];
+    unsigned int sids[256];
     int charCnt = 0;
 
     if (eltCnt <= 24) {
@@ -709,7 +749,7 @@
     if (glyphCnt <= 256) {
       xids = &sids[0];
     } else {
-      xids = (Glyph *) malloc(sizeof(Glyph) * glyphCnt);
+      xids = (unsigned int*)malloc(sizeof(unsigned int) * glyphCnt);
       if (xids == NULL) {
           if (xelts != &selts[0]) {
             free(xelts);
@@ -742,7 +782,7 @@
     }
 
     for (i=0; i < glyphCnt; i++) {
-      xids[i] = (Glyph) ids[i];
+      xids[i] = ids[i];
     }
 
     for (i=0; i < eltCnt; i++) {
@@ -750,7 +790,7 @@
       xelts[i].xOff = elts[i*4 + 1];
       xelts[i].yOff = elts[i*4 + 2];
       xelts[i].glyphset = (GlyphSet) elts[i*4 + 3];
-      xelts[i].chars = (unsigned int *) &xids[charCnt];
+      xelts[i].chars = &xids[charCnt];
 
       charCnt += xelts[i].nchars;
     }