天天看點

修改OpenJDK字型渲染,無可見改進

  于網上找到了一段修改OpenJDK字型渲染的博文,實驗之,發現無可見的效果改進。也許以後用得着,同時表示自己已确實編譯測試過,故在此記錄下來。

 參考博文:

https://blog.csdn.net/liberize/article/details/8915482

  • 讀取配置
#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,全清之後再編譯。