< 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 >