于网上找到了一段修改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,全清之后再编译。