于网上找到了一段修改OpenJDK字体渲染的博文,实验之,发现无可见的效果改进。也许以后用得着,同时表示自己已确实编译测试过,故在此记录下来。

  参考博文:​​javascript:void(0)​​。

  • 读取配置
#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,全清之后再编译。