src/java.desktop/share/native/libfontmanager/freetypeScaler.c
changeset 59176 f5adbf111424
parent 58685 4b13a908c2d0
equal deleted inserted replaced
59175:d2123a27cfe7 59176:f5adbf111424
   609         contextAwareMetricsX(mx, my), contextAwareMetricsY(mx, my));
   609         contextAwareMetricsX(mx, my), contextAwareMetricsY(mx, my));
   610 
   610 
   611     return metrics;
   611     return metrics;
   612 }
   612 }
   613 
   613 
       
   614 static jlong
       
   615     getGlyphImageNativeInternal(
       
   616         JNIEnv *env, jobject scaler, jobject font2D,
       
   617         jlong pScalerContext, jlong pScaler, jint glyphCode,
       
   618         jboolean renderImage);
       
   619 
   614 /*
   620 /*
   615  * Class:     sun_font_FreetypeFontScaler
   621  * Class:     sun_font_FreetypeFontScaler
   616  * Method:    getGlyphAdvanceNative
   622  * Method:    getGlyphAdvanceNative
   617  * Signature: (Lsun/font/Font2D;JI)F
   623  * Signature: (Lsun/font/Font2D;JI)F
   618  */
   624  */
   620 Java_sun_font_FreetypeFontScaler_getGlyphAdvanceNative(
   626 Java_sun_font_FreetypeFontScaler_getGlyphAdvanceNative(
   621         JNIEnv *env, jobject scaler, jobject font2D,
   627         JNIEnv *env, jobject scaler, jobject font2D,
   622         jlong pScalerContext, jlong pScaler, jint glyphCode) {
   628         jlong pScalerContext, jlong pScaler, jint glyphCode) {
   623 
   629 
   624    /* This method is rarely used because requests for metrics are usually
   630    /* This method is rarely used because requests for metrics are usually
   625       coupled with request for bitmap and to large extend work can be reused
   631     * coupled with a request for the bitmap and to a large extent the
   626       (to find out metrics we need to hint glyph).
   632     * work can be reused (to find out metrics we may need to hint the glyph).
   627       So, we typically go through getGlyphImage code path.
   633     * So, we typically go through the getGlyphImage code path.
   628 
   634     * When we do get here, we need to pass a parameter which indicates
   629       For initial freetype implementation we delegate
   635     * that we don't need freetype to render the bitmap, and consequently
   630       all work to getGlyphImage but drop result image.
   636     * don't need to allocate our own storage either.
   631       This is waste of work related to scan conversion and conversion from
   637     * This is also important when enter here requesting metrics for sizes
   632       freetype format to our format but for now this seems to be ok.
   638     * of text which a large size would be rejected for a bitmap but we
   633 
   639     * still need the metrics.
   634       NB: investigate performance benefits of refactoring code
   640     */
   635       to avoid unnecesary work with bitmaps. */
       
   636 
   641 
   637     GlyphInfo *info;
   642     GlyphInfo *info;
   638     jfloat advance = 0.0f;
   643     jfloat advance = 0.0f;
   639     jlong image;
   644     jlong image;
   640 
   645 
   641     image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
   646     image = getGlyphImageNativeInternal(
   642                  env, scaler, font2D, pScalerContext, pScaler, glyphCode);
   647           env, scaler, font2D, pScalerContext, pScaler, glyphCode, JNI_FALSE);
   643     info = (GlyphInfo*) jlong_to_ptr(image);
   648     info = (GlyphInfo*) jlong_to_ptr(image);
   644 
   649 
   645     if (info != NULL) {
   650     if (info != NULL) {
   646         advance = info->advanceX;
   651         advance = info->advanceX;
   647         free(info);
   652         free(info);
   658 JNIEXPORT void JNICALL
   663 JNIEXPORT void JNICALL
   659 Java_sun_font_FreetypeFontScaler_getGlyphMetricsNative(
   664 Java_sun_font_FreetypeFontScaler_getGlyphMetricsNative(
   660         JNIEnv *env, jobject scaler, jobject font2D, jlong pScalerContext,
   665         JNIEnv *env, jobject scaler, jobject font2D, jlong pScalerContext,
   661         jlong pScaler, jint glyphCode, jobject metrics) {
   666         jlong pScaler, jint glyphCode, jobject metrics) {
   662 
   667 
   663      /* As initial implementation we delegate all work to getGlyphImage
   668      /* See the comments in getGlyphMetricsNative. They apply here too. */
   664         but drop result image. This is clearly waste of resorces.
       
   665 
       
   666         TODO: investigate performance benefits of refactoring code
       
   667               by avoiding bitmap generation and conversion from FT
       
   668               bitmap format. */
       
   669      GlyphInfo *info;
   669      GlyphInfo *info;
   670 
   670 
   671      jlong image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
   671      jlong image = getGlyphImageNativeInternal(
   672                                  env, scaler, font2D,
   672                                  env, scaler, font2D,
   673                                  pScalerContext, pScaler, glyphCode);
   673                                  pScalerContext, pScaler, glyphCode, JNI_FALSE);
   674      info = (GlyphInfo*) jlong_to_ptr(image);
   674      info = (GlyphInfo*) jlong_to_ptr(image);
   675 
   675 
   676      if (info != NULL) {
   676      if (info != NULL) {
   677          (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX);
   677          (*env)->SetFloatField(env, metrics, sunFontIDs.xFID, info->advanceX);
   678          (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY);
   678          (*env)->SetFloatField(env, metrics, sunFontIDs.yFID, info->advanceY);
   801  */
   801  */
   802 JNIEXPORT jlong JNICALL
   802 JNIEXPORT jlong JNICALL
   803 Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
   803 Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
   804         JNIEnv *env, jobject scaler, jobject font2D,
   804         JNIEnv *env, jobject scaler, jobject font2D,
   805         jlong pScalerContext, jlong pScaler, jint glyphCode) {
   805         jlong pScalerContext, jlong pScaler, jint glyphCode) {
       
   806 
       
   807     return getGlyphImageNativeInternal(
       
   808         env, scaler, font2D,
       
   809         pScalerContext, pScaler, glyphCode, JNI_TRUE);
       
   810 }
       
   811 
       
   812 static jlong
       
   813      getGlyphImageNativeInternal(
       
   814         JNIEnv *env, jobject scaler, jobject font2D,
       
   815         jlong pScalerContext, jlong pScaler, jint glyphCode,
       
   816         jboolean renderImage) {
   806 
   817 
   807     int error, imageSize;
   818     int error, imageSize;
   808     UInt16 width, height;
   819     UInt16 width, height;
   809     GlyphInfo *glyphInfo;
   820     GlyphInfo *glyphInfo;
   810     int renderFlags = FT_LOAD_DEFAULT, target;
   821     int renderFlags = FT_LOAD_DEFAULT, target;
   864         FT_GlyphSlot_Oblique(ftglyph);
   875         FT_GlyphSlot_Oblique(ftglyph);
   865     }
   876     }
   866 
   877 
   867     /* generate bitmap if it is not done yet
   878     /* generate bitmap if it is not done yet
   868      e.g. if algorithmic styling is performed and style was added to outline */
   879      e.g. if algorithmic styling is performed and style was added to outline */
   869     if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) {
   880     if (renderImage && (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
   870         FT_BBox bbox;
   881         FT_BBox bbox;
   871         FT_Outline_Get_CBox(&(ftglyph->outline), &bbox);
   882         FT_Outline_Get_CBox(&(ftglyph->outline), &bbox);
   872         int w = (int)((bbox.xMax>>6)-(bbox.xMin>>6));
   883         int w = (int)((bbox.xMax>>6)-(bbox.xMin>>6));
   873         int h = (int)((bbox.yMax>>6)-(bbox.yMin>>6));
   884         int h = (int)((bbox.yMax>>6)-(bbox.yMin>>6));
   874         if (w > MAX_GLYPH_DIM || h > MAX_GLYPH_DIM) {
   885         if (w > MAX_GLYPH_DIM || h > MAX_GLYPH_DIM) {
   879         if (error != 0) {
   890         if (error != 0) {
   880             return ptr_to_jlong(getNullGlyphImage());
   891             return ptr_to_jlong(getNullGlyphImage());
   881         }
   892         }
   882     }
   893     }
   883 
   894 
   884     width  = (UInt16) ftglyph->bitmap.width;
   895     if (renderImage) {
   885     height = (UInt16) ftglyph->bitmap.rows;
   896         width  = (UInt16) ftglyph->bitmap.width;
   886     if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
   897         height = (UInt16) ftglyph->bitmap.rows;
   887         glyphInfo = getNullGlyphImage();
   898             if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
   888         return ptr_to_jlong(glyphInfo);
   899               glyphInfo = getNullGlyphImage();
   889     }
   900               return ptr_to_jlong(glyphInfo);
       
   901             }
       
   902      } else {
       
   903         width = 0;
       
   904         height = 0;
       
   905      }
   890 
   906 
   891 
   907 
   892     imageSize = width*height;
   908     imageSize = width*height;
   893     glyphInfo = (GlyphInfo*) malloc(sizeof(GlyphInfo) + imageSize);
   909     glyphInfo = (GlyphInfo*) malloc(sizeof(GlyphInfo) + imageSize);
   894     if (glyphInfo == NULL) {
   910     if (glyphInfo == NULL) {
   898     glyphInfo->cellInfo  = NULL;
   914     glyphInfo->cellInfo  = NULL;
   899     glyphInfo->managed   = UNMANAGED_GLYPH;
   915     glyphInfo->managed   = UNMANAGED_GLYPH;
   900     glyphInfo->rowBytes  = width;
   916     glyphInfo->rowBytes  = width;
   901     glyphInfo->width     = width;
   917     glyphInfo->width     = width;
   902     glyphInfo->height    = height;
   918     glyphInfo->height    = height;
   903     glyphInfo->topLeftX  = (float)  ftglyph->bitmap_left;
   919 
   904     glyphInfo->topLeftY  = (float) -ftglyph->bitmap_top;
   920     if (renderImage) {
   905 
   921         glyphInfo->topLeftX  = (float)  ftglyph->bitmap_left;
   906     if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD) {
   922         glyphInfo->topLeftY  = (float) -ftglyph->bitmap_top;
   907         glyphInfo->width = width/3;
   923 
   908     } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD_V) {
   924         if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD) {
   909         glyphInfo->height = glyphInfo->height/3;
   925             glyphInfo->width = width/3;
       
   926         } else if (ftglyph->bitmap.pixel_mode ==  FT_PIXEL_MODE_LCD_V) {
       
   927             glyphInfo->height = glyphInfo->height/3;
       
   928         }
   910     }
   929     }
   911 
   930 
   912     if (context->fmType == TEXT_FM_ON) {
   931     if (context->fmType == TEXT_FM_ON) {
   913         double advh = FTFixedToFloat(ftglyph->linearHoriAdvance);
   932         double advh = FTFixedToFloat(ftglyph->linearHoriAdvance);
   914         glyphInfo->advanceX =
   933         glyphInfo->advanceX =