< prev index next >

src/java.desktop/share/native/libfontmanager/freetypeScaler.c

Print this page

        

@@ -609,10 +609,16 @@
         contextAwareMetricsX(mx, my), contextAwareMetricsY(mx, my));
 
     return metrics;
 }
 
+static jlong
+    getGlyphImageNativeInternal(
+        JNIEnv *env, jobject scaler, jobject font2D,
+        jlong pScalerContext, jlong pScaler, jint glyphCode,
+        jboolean renderImage);
+
 /*
  * Class:     sun_font_FreetypeFontScaler
  * Method:    getGlyphAdvanceNative
  * Signature: (Lsun/font/Font2D;JI)F
  */

@@ -620,28 +626,27 @@
 Java_sun_font_FreetypeFontScaler_getGlyphAdvanceNative(
         JNIEnv *env, jobject scaler, jobject font2D,
         jlong pScalerContext, jlong pScaler, jint glyphCode) {
 
    /* This method is rarely used because requests for metrics are usually
-      coupled with request for bitmap and to large extend work can be reused
-      (to find out metrics we need to hint glyph).
-      So, we typically go through getGlyphImage code path.
-
-      For initial freetype implementation we delegate
-      all work to getGlyphImage but drop result image.
-      This is waste of work related to scan conversion and conversion from
-      freetype format to our format but for now this seems to be ok.
-
-      NB: investigate performance benefits of refactoring code
-      to avoid unnecesary work with bitmaps. */
+    * coupled with a request for the bitmap and to a large extent the
+    * work can be reused (to find out metrics we may need to hint the glyph).
+    * So, we typically go through the getGlyphImage code path.
+    * When we do get here, we need to pass a parameter which indicates
+    * that we don't need freetype to render the bitmap, and consequently
+    * don't need to allocate our own storage either.
+    * This is also important when enter here requesting metrics for sizes 
+    * of text which a large size would be rejected for a bitmap but we
+    * still need the metrics.
+    */
 
     GlyphInfo *info;
     jfloat advance = 0.0f;
     jlong image;
 
-    image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
-                 env, scaler, font2D, pScalerContext, pScaler, glyphCode);
+    image = getGlyphImageNativeInternal(
+          env, scaler, font2D, pScalerContext, pScaler, glyphCode, JNI_FALSE);
     info = (GlyphInfo*) jlong_to_ptr(image);
 
     if (info != NULL) {
         advance = info->advanceX;
         free(info);

@@ -658,21 +663,16 @@
 JNIEXPORT void JNICALL
 Java_sun_font_FreetypeFontScaler_getGlyphMetricsNative(
         JNIEnv *env, jobject scaler, jobject font2D, jlong pScalerContext,
         jlong pScaler, jint glyphCode, jobject metrics) {
 
-     /* As initial implementation we delegate all work to getGlyphImage
-        but drop result image. This is clearly waste of resorces.
-
-        TODO: investigate performance benefits of refactoring code
-              by avoiding bitmap generation and conversion from FT
-              bitmap format. */
+     /* See the comments in getGlyphMetricsNative. They apply here too. */
      GlyphInfo *info;
 
-     jlong image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
+     jlong image = getGlyphImageNativeInternal(
                                  env, scaler, font2D,
-                                 pScalerContext, pScaler, glyphCode);
+                                 pScalerContext, pScaler, glyphCode, JNI_FALSE);
      info = (GlyphInfo*) jlong_to_ptr(image);
 
      if (info != NULL) {
          (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX);
          (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY);

@@ -802,10 +802,21 @@
 JNIEXPORT jlong JNICALL
 Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
         JNIEnv *env, jobject scaler, jobject font2D,
         jlong pScalerContext, jlong pScaler, jint glyphCode) {
 
+    return getGlyphImageNativeInternal(
+        env, scaler, font2D,
+        pScalerContext, pScaler, glyphCode, JNI_TRUE);
+}
+
+static jlong
+     getGlyphImageNativeInternal(
+        JNIEnv *env, jobject scaler, jobject font2D,
+        jlong pScalerContext, jlong pScaler, jint glyphCode,
+        jboolean renderImage) {
+
     int error, imageSize;
     UInt16 width, height;
     GlyphInfo *glyphInfo;
     int renderFlags = FT_LOAD_DEFAULT, target;
     FT_GlyphSlot ftglyph;

@@ -864,11 +875,11 @@
         FT_GlyphSlot_Oblique(ftglyph);
     }
 
     /* generate bitmap if it is not done yet
      e.g. if algorithmic styling is performed and style was added to outline */
-    if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) {
+    if (renderImage && (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
         FT_BBox bbox;
         FT_Outline_Get_CBox(&(ftglyph->outline), &bbox);
         int w = (int)((bbox.xMax>>6)-(bbox.xMin>>6));
         int h = (int)((bbox.yMax>>6)-(bbox.yMin>>6));
         if (w > MAX_GLYPH_DIM || h > MAX_GLYPH_DIM) {

@@ -879,16 +890,21 @@
         if (error != 0) {
             return ptr_to_jlong(getNullGlyphImage());
         }
     }
 
+    if (renderImage) {
     width  = (UInt16) ftglyph->bitmap.width;
     height = (UInt16) ftglyph->bitmap.rows;
     if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
         glyphInfo = getNullGlyphImage();
         return ptr_to_jlong(glyphInfo);
     }
+     } else {
+        width = 0;
+        height = 0;
+     }
 
 
     imageSize = width*height;
     glyphInfo = (GlyphInfo*) malloc(sizeof(GlyphInfo) + imageSize);
     if (glyphInfo == NULL) {

@@ -898,18 +914,21 @@
     glyphInfo->cellInfo  = NULL;
     glyphInfo->managed   = UNMANAGED_GLYPH;
     glyphInfo->rowBytes  = width;
     glyphInfo->width     = width;
     glyphInfo->height    = height;
+
+    if (renderImage) {
     glyphInfo->topLeftX  = (float)  ftglyph->bitmap_left;
     glyphInfo->topLeftY  = (float) -ftglyph->bitmap_top;
 
     if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD) {
         glyphInfo->width = width/3;
     } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD_V) {
         glyphInfo->height = glyphInfo->height/3;
     }
+    }
 
     if (context->fmType == TEXT_FM_ON) {
         double advh = FTFixedToFloat(ftglyph->linearHoriAdvance);
         glyphInfo->advanceX =
             (float) (advh * FTFixedToFloat(context->transform.xx));
< prev index next >