于网上找到了一段修改OpenJDK字体渲染的博文,实验之,发现无可见的效果改进。也许以后用得着,同时表示自己已确实编译测试过,故在此记录下来。
- 读取配置
#include <fontconfig/fontconfig.h> static FcPattern* matchedPattern(const FcChar8* family, double ptSize) { 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); FcConfigSubstitute(0, fcPattern, FcMatchPattern); FcDefaultSubstitute(fcPattern); FcResult res; FcPattern *pattern = 0; pattern = FcFontMatch(0, fcPattern, &res); FcPatternDestroy(fcPattern); return pattern; } typedef struct { FT_Int32 loadFlags; FT_Render_Mode renderMode; FT_LcdFilter lcdFilter; }RenderProperty; static void readFontconfig(FTScalerInfo* scalerInfo, FTScalerContext* context, RenderProperty* rp) { FcPattern *pattern = matchedPattern((const FcChar8 *)scalerInfo->face->family_name, context->ptsz); FT_Int32 load_flags = FT_LOAD_DEFAULT; FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL; FT_LcdFilter lcd_filter = FT_LCD_FILTER_NONE; if (TEXT_AA_OFF == context->aaType) { load_flags = FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO; render_mode = FT_RENDER_MODE_MONO; }else { FcBool hinting = FcTrue; FcPatternGetBool ( pattern, FC_HINTING, 0, &hinting); FcBool autohint = FcFalse; FcPatternGetBool( pattern, FC_AUTOHINT, 0, &autohint); int hint_style = FC_HINT_FULL; FcPatternGetInteger(pattern, FC_HINT_STYLE, 0, &hint_style); if (!hinting || hint_style == FC_HINT_NONE) { load_flags |= FT_LOAD_NO_HINTING; if (autohint) load_flags |= FT_LOAD_FORCE_AUTOHINT; }else if (FC_HINT_NONE < hint_style && hint_style < FC_HINT_FULL) { load_flags |= FT_LOAD_TARGET_LIGHT; render_mode = FT_RENDER_MODE_LIGHT; }else load_flags |= FT_LOAD_TARGET_NORMAL; switch (context->aaType) { case TEXT_AA_LCD_HRGB: case TEXT_AA_LCD_HBGR: load_flags |= FT_LOAD_TARGET_LCD; render_mode = FT_RENDER_MODE_LCD; break; case TEXT_AA_LCD_VRGB: case TEXT_AA_LCD_VBGR: load_flags |= FT_LOAD_TARGET_LCD_V; render_mode = FT_RENDER_MODE_LCD_V; } } if (FT_RENDER_MODE_LCD_V == render_mode || FT_RENDER_MODE_LCD == render_mode) { int lcdfilter = FC_LCD_NONE; FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &lcdfilter); switch (lcdfilter) { case FC_LCD_NONE: lcd_filter = FT_LCD_FILTER_NONE; break; case FC_LCD_LIGHT: lcd_filter = FT_LCD_FILTER_LIGHT; break; case FC_LCD_LEGACY: lcd_filter = FT_LCD_FILTER_LEGACY; break; default: lcd_filter = FT_LCD_FILTER_DEFAULT; } } FcPatternDestroy(pattern); rp->loadFlags = load_flags; rp->renderMode = render_mode; rp->lcdFilter = lcd_filter; }
- 修改渲染代码
//先在函数开始的地方加上这一段,创建一个RenderProperty结构体,用来保存读取的字体配置信息 RenderProperty* rp = NULL; rp = (RenderProperty*) calloc(1, sizeof(RenderProperty)); if (NULL == rp) { return ptr_to_jlong(getNullGlyphImage()); } /**这段要注释掉 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; */ //读取配置,设置lcdfilter readFontconfig(scalerInfo, context, rp); renderFlags |= rp->loadFlags; FT_Library_SetLcdFilter(scalerInfo->library, rp->lcdFilter); glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); ...... if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) { FT_Render_Glyph(ftglyph, rp->renderMode);//renderMode改成读取过来的 } free(rp);
- 编译
修改Awt2dLibraries.gmk,加上-lfontconfig,全清之后再编译。