|
diff -r 96a023de3ddf openjdk/jdk/make/sun/font/Makefile |
|
--- openjdk/jdk/make/sun/font/Makefile Wed Jun 06 18:39:46 2012 -0700 |
|
+++ openjdk/jdk/make/sun/font/Makefile Fri Jun 08 12:52:01 2012 +0900 |
|
@@ -134,7 +134,7 @@ else |
|
ifeq ($(USING_SYSTEM_FT_LIB), false) |
|
FREETYPE_LIB = $(LIB_LOCATION)/$(LIB_PREFIX)freetype.$(LIBRARY_SUFFIX).6 |
|
endif |
|
- OTHER_LDLIBS += -L$(FREETYPE_LIB_PATH) $(FT2_LIBS) |
|
+ OTHER_LDLIBS += -L$(FREETYPE_LIB_PATH) $(FT2_LIBS) -lfontconfig |
|
endif |
|
|
|
library:: $(FREETYPE_LIB) |
|
diff -r 96a023de3ddf openjdk/jdk/src/share/native/sun/font/freetypeScaler.c |
|
--- openjdk/jdk/src/share/native/sun/font/freetypeScaler.c Wed Jun 06 18:39:46 2012 -0700 |
|
+++ openjdk/jdk/src/share/native/sun/font/freetypeScaler.c Fri Jun 08 12:52:01 2012 +0900 |
|
@@ -38,6 +38,8 @@ |
|
#include FT_SIZES_H |
|
#include FT_OUTLINE_H |
|
#include FT_SYNTHESIS_H |
|
+#include FT_LCD_FILTER_H |
|
+#include <fontconfig/fontconfig.h> |
|
|
|
#include "fontscaler.h" |
|
|
|
@@ -692,6 +694,145 @@ |
|
} |
|
} |
|
|
|
+typedef struct { |
|
+ FT_Render_Mode ftRenderMode; |
|
+ int ftLoadFlags; |
|
+ FT_LcdFilter ftLcdFilter; |
|
+} RenderingProperties; |
|
+ |
|
+static FcPattern* matchedPattern(const FcChar8* family, double ptSize) { |
|
+ /* |
|
+ we will create pattern to find our family and size in |
|
+ fontconfig configuration, and then will return it's |
|
+ properties: |
|
+ */ |
|
+ FcPattern* fcPattern = 0; |
|
+ fcPattern = FcPatternCreate(); |
|
+ FcValue fcValue; |
|
+ fcValue.type = FcTypeString; |
|
+ fcValue.u.s = family; |
|
+ FcPatternAdd(fcPattern, FC_FAMILY, fcValue, FcTrue); |
|
+ FcPatternAddBool(fcPattern, FC_SCALABLE, FcTrue); |
|
+ FcPatternAddDouble(fcPattern, FC_SIZE, ptSize); |
|
+ // TODO FcPatternAddInteger(pattern, FC_WEIGHT, weight_value); |
|
+ // TODO FcPatternAddInteger(pattern, FC_SLANT, slant_value); |
|
+ // TODO FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value); |
|
+ // TODO FcPatternAddInteger(pattern, FC_WIDTH, stretch); 100 in most cases |
|
+ FcConfigSubstitute(0, fcPattern, FcMatchPattern); |
|
+ FcConfigSubstitute(0, fcPattern, FcMatchFont); |
|
+ FcDefaultSubstitute(fcPattern); |
|
+ FcResult res; |
|
+ |
|
+ FcPattern *pattern = 0; |
|
+ pattern = FcFontMatch(0, fcPattern, &res); |
|
+ FcPatternDestroy(fcPattern); |
|
+ return pattern; |
|
+} |
|
+ |
|
+static void readFontconfig(const FcChar8* family, double ptSize, jint aaType, RenderingProperties* rp) { |
|
+ |
|
+ FcPattern *pattern = matchedPattern(family, ptSize); |
|
+ |
|
+ int ftLoadFalgs = FT_LOAD_DEFAULT; |
|
+ FT_Render_Mode ftRenderMode; |
|
+ FT_LcdFilter ftLcdFilter; |
|
+ char horizontal = 1; |
|
+ FcBool b; |
|
+ |
|
+ // subpixel order: |
|
+ if (aaType == TEXT_AA_ON) |
|
+ ftRenderMode = FT_RENDER_MODE_NORMAL; |
|
+ else if (aaType == TEXT_AA_OFF) |
|
+ ftRenderMode = FT_RENDER_MODE_MONO; |
|
+ else if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch) |
|
+ if (b) { |
|
+ int subpixel = FC_RGBA_UNKNOWN; |
|
+ FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel); |
|
+ if (subpixel == FC_RGBA_UNKNOWN) |
|
+ subpixel = FC_RGBA_NONE; |
|
+ switch (subpixel) { |
|
+ case FC_RGBA_NONE: |
|
+ ftRenderMode = FT_RENDER_MODE_NORMAL; |
|
+ break; |
|
+ case FC_RGBA_RGB: |
|
+ case FC_RGBA_BGR: |
|
+ ftRenderMode = FT_RENDER_MODE_LCD; |
|
+ horizontal = 1; |
|
+ break; |
|
+ case FC_RGBA_VRGB: |
|
+ case FC_RGBA_VBGR: |
|
+ ftRenderMode = FT_RENDER_MODE_LCD_V; |
|
+ horizontal = 0; |
|
+ break; |
|
+ default: |
|
+ break; |
|
+ } |
|
+ } else { |
|
+ ftRenderMode = FT_RENDER_MODE_NORMAL; |
|
+ } |
|
+ |
|
+ // loading mode: |
|
+ if (aaType == TEXT_AA_OFF) |
|
+ ftLoadFalgs |= FT_LOAD_TARGET_MONO; |
|
+ else { |
|
+ int hint_style = FC_HINT_NONE; |
|
+ FcPatternGetInteger(pattern, FC_HINT_STYLE, 0, &hint_style); |
|
+ switch (hint_style) { |
|
+ case FC_HINT_NONE: |
|
+ ftLoadFalgs |= FT_LOAD_NO_HINTING; |
|
+ break; |
|
+ case FC_HINT_SLIGHT: |
|
+ ftLoadFalgs |= FT_LOAD_TARGET_LIGHT; |
|
+ break; |
|
+ case FC_HINT_MEDIUM: |
|
+ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; |
|
+ break; |
|
+ case FC_HINT_FULL: |
|
+ if (aaType == TEXT_AA_ON) |
|
+ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; |
|
+ else |
|
+ ftLoadFalgs |= horizontal ? FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_LCD_V; |
|
+ break; |
|
+ default: |
|
+ // what else to use as default? |
|
+ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ // autohinting: |
|
+ if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch) |
|
+ if (b) |
|
+ ftLoadFalgs |= FT_LOAD_FORCE_AUTOHINT; |
|
+ |
|
+ // LCD filter: |
|
+ int filter = FC_LCD_DEFAULT; |
|
+ FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter); |
|
+ switch (filter) { |
|
+ case FC_LCD_NONE: |
|
+ ftLcdFilter = FT_LCD_FILTER_NONE; |
|
+ break; |
|
+ case FC_LCD_DEFAULT: |
|
+ ftLcdFilter = FT_LCD_FILTER_DEFAULT; |
|
+ break; |
|
+ case FC_LCD_LIGHT: |
|
+ ftLcdFilter = FT_LCD_FILTER_LIGHT; |
|
+ break; |
|
+ case FC_LCD_LEGACY: |
|
+ ftLcdFilter = FT_LCD_FILTER_LEGACY; |
|
+ break; |
|
+ default: |
|
+ // new unknown lcd filter type?! will use default one: |
|
+ ftLcdFilter = FT_LCD_FILTER_DEFAULT; |
|
+ break; |
|
+ } |
|
+ |
|
+ FcPatternDestroy(pattern); |
|
+ |
|
+ rp->ftRenderMode = ftRenderMode; |
|
+ rp->ftLoadFlags = ftLoadFalgs; |
|
+ rp->ftLcdFilter = ftLcdFilter; |
|
+} |
|
|
|
/* |
|
* Class: sun_font_FreetypeFontScaler |
|
@@ -707,7 +848,6 @@ |
|
UInt16 width, height; |
|
GlyphInfo *glyphInfo; |
|
int glyph_index; |
|
- int renderFlags = FT_LOAD_RENDER, target; |
|
FT_GlyphSlot ftglyph; |
|
|
|
FTScalerContext* context = |
|
@@ -725,32 +865,15 @@ |
|
return ptr_to_jlong(getNullGlyphImage()); |
|
} |
|
|
|
- /* if algorithmic styling is required then we do not request bitmap */ |
|
- if (context->doBold || context->doItalize) { |
|
- renderFlags = FT_LOAD_DEFAULT; |
|
- } |
|
- |
|
- /* NB: in case of non identity transform |
|
- we might also prefer to disable transform before hinting, |
|
- and apply it explicitly after hinting is performed. |
|
- Or we can disable hinting. */ |
|
- |
|
- /* select appropriate hinting mode */ |
|
- if (context->aaType == TEXT_AA_OFF) { |
|
- target = FT_LOAD_TARGET_MONO; |
|
- } else if (context->aaType == TEXT_AA_ON) { |
|
- target = FT_LOAD_TARGET_NORMAL; |
|
- } else if (context->aaType == TEXT_AA_LCD_HRGB || |
|
- context->aaType == TEXT_AA_LCD_HBGR) { |
|
- target = FT_LOAD_TARGET_LCD; |
|
- } else { |
|
- target = FT_LOAD_TARGET_LCD_V; |
|
- } |
|
- renderFlags |= target; |
|
+ RenderingProperties renderingProperties; |
|
+ readFontconfig((const FcChar8 *) scalerInfo->face->family_name, |
|
+ context->ptsz, context->aaType, &renderingProperties); |
|
|
|
glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); |
|
|
|
- error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); |
|
+ FT_Library_SetLcdFilter(scalerInfo->library, renderingProperties.ftLcdFilter); |
|
+ |
|
+ error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags); |
|
if (error) { |
|
//do not destroy scaler yet. |
|
//this can be problem of particular context (e.g. with bad transform) |
|
@@ -767,11 +890,7 @@ |
|
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) { |
|
- FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target)); |
|
- } |
|
+ FT_Render_Glyph(ftglyph, renderingProperties.ftRenderMode); |
|
|
|
width = (UInt16) ftglyph->bitmap.width; |
|
height = (UInt16) ftglyph->bitmap.rows; |
|
@@ -984,7 +1103,6 @@ |
|
static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D, |
|
FTScalerContext *context, FTScalerInfo* scalerInfo, |
|
jint glyphCode, jfloat xpos, jfloat ypos) { |
|
- int renderFlags; |
|
int glyph_index; |
|
FT_Error error; |
|
FT_GlyphSlot ftglyph; |
|
@@ -999,11 +1117,13 @@ |
|
return NULL; |
|
} |
|
|
|
- renderFlags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; |
|
+ RenderingProperties renderingProperties; |
|
+ readFontconfig((const FcChar8 *) scalerInfo->face->family_name, |
|
+ context->ptsz, context->aaType, &renderingProperties); |
|
|
|
glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); |
|
|
|
- error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); |
|
+ error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags); |
|
if (error) { |
|
return NULL; |
|
} |