1--- jdk/src/share/native/sun/font/freetypeScaler.c.orig 2017-01-20 17:04:07 UTC 2+++ jdk/src/share/native/sun/font/freetypeScaler.c 3@@ -42,6 +42,8 @@ 4 #include FT_OUTLINE_H 5 #include FT_SYNTHESIS_H 6 #include FT_MODULE_H 7+#include FT_LCD_FILTER_H 8+#include <fontconfig/fontconfig.h> 9 10 #include "fontscaler.h" 11 12@@ -87,6 +89,133 @@ 13 int ptsz; /* size in points */ 14 } FTScalerContext; 15 16+typedef struct { 17+ FT_Render_Mode ftRenderMode; 18+ int ftLoadFlags; 19+ FT_LcdFilter ftLcdFilter; 20+} RenderingProperties; 21+ 22+static FcPattern* matchedPattern(const FcChar8* family, double ptSize) { 23+ FcPattern* pattern = FcPatternCreate(); 24+ if (!pattern) 25+ return 0; 26+ 27+ FcPatternAddString(pattern, FC_FAMILY, family); 28+ FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); 29+ FcPatternAddDouble(pattern, FC_SIZE, ptSize); 30+ 31+ FcConfigSubstitute(0, pattern, FcMatchPattern); 32+ FcDefaultSubstitute(pattern); 33+ 34+ FcResult res; 35+ FcPattern *match = FcFontMatch(0, pattern, &res); 36+ FcPatternDestroy(pattern); 37+ return (res == FcResultMatch) ? match : NULL; 38+} 39+ 40+static void readFontconfig(const FcChar8* family, double ptSize, jint aaType, RenderingProperties* rp) { 41+ FcPattern *pattern = matchedPattern(family, ptSize); 42+ 43+ FT_Render_Mode ftRenderMode = FT_RENDER_MODE_NORMAL; 44+ int ftLoadFlags = FT_LOAD_DEFAULT; 45+ FT_LcdFilter ftLcdFilter = FT_LCD_FILTER_DEFAULT; 46+ FcBool fcAntialias = 0; 47+ char horizontal = 1; 48+ 49+ // subpixel order 50+ if (aaType == TEXT_AA_ON) 51+ ftRenderMode = FT_RENDER_MODE_NORMAL; 52+ else if (aaType == TEXT_AA_OFF) 53+ ftRenderMode = FT_RENDER_MODE_MONO; 54+ else { 55+ int fcRGBA = FC_RGBA_UNKNOWN; 56+ if (pattern) 57+ FcPatternGetInteger(pattern, FC_RGBA, 0, &fcRGBA); 58+ switch (fcRGBA) { 59+ case FC_RGBA_NONE: 60+ ftRenderMode = FT_RENDER_MODE_NORMAL; 61+ break; 62+ case FC_RGBA_RGB: 63+ case FC_RGBA_BGR: 64+ ftRenderMode = FT_RENDER_MODE_LCD; 65+ horizontal = 1; 66+ break; 67+ case FC_RGBA_VRGB: 68+ case FC_RGBA_VBGR: 69+ ftRenderMode = FT_RENDER_MODE_LCD_V; 70+ horizontal = 0; 71+ break; 72+ default: 73+ ftRenderMode = FT_RENDER_MODE_NORMAL; 74+ break; 75+ } 76+ } 77+ 78+ // loading mode 79+ if (aaType == TEXT_AA_OFF) 80+ ftLoadFlags |= FT_LOAD_TARGET_MONO; 81+ else { 82+ int fcHintStyle = FC_HINT_NONE; 83+ if (pattern) 84+ FcPatternGetInteger(pattern, FC_HINT_STYLE, 0, &fcHintStyle); 85+ switch (fcHintStyle) { 86+ case FC_HINT_NONE: 87+ ftLoadFlags |= FT_LOAD_NO_HINTING; 88+ break; 89+ case FC_HINT_SLIGHT: 90+ ftLoadFlags |= FT_LOAD_TARGET_LIGHT; 91+ break; 92+ case FC_HINT_MEDIUM: 93+ ftLoadFlags |= FT_LOAD_TARGET_NORMAL; 94+ break; 95+ case FC_HINT_FULL: 96+ if (aaType == TEXT_AA_ON) 97+ ftLoadFlags |= FT_LOAD_TARGET_NORMAL; 98+ else 99+ ftLoadFlags |= horizontal ? FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_LCD_V; 100+ break; 101+ default: 102+ ftLoadFlags |= FT_LOAD_TARGET_NORMAL; 103+ break; 104+ } 105+ } 106+ 107+ // autohinting 108+ FcBool fcAutohint = 0; 109+ if (pattern && FcPatternGetBool(pattern, FC_AUTOHINT, 0, &fcAutohint) == FcResultMatch) 110+ if (fcAutohint) 111+ ftLoadFlags |= FT_LOAD_FORCE_AUTOHINT; 112+ 113+ // LCD filter 114+ int fcLCDFilter = FC_LCD_DEFAULT; 115+ if (pattern) 116+ FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &fcLCDFilter); 117+ switch (fcLCDFilter) { 118+ case FC_LCD_NONE: 119+ ftLcdFilter = FT_LCD_FILTER_NONE; 120+ break; 121+ case FC_LCD_DEFAULT: 122+ ftLcdFilter = FT_LCD_FILTER_DEFAULT; 123+ break; 124+ case FC_LCD_LIGHT: 125+ ftLcdFilter = FT_LCD_FILTER_LIGHT; 126+ break; 127+ case FC_LCD_LEGACY: 128+ ftLcdFilter = FT_LCD_FILTER_LEGACY; 129+ break; 130+ default: 131+ ftLcdFilter = FT_LCD_FILTER_DEFAULT; 132+ break; 133+ } 134+ 135+ if (pattern) 136+ FcPatternDestroy(pattern); 137+ 138+ rp->ftRenderMode = ftRenderMode; 139+ rp->ftLoadFlags = ftLoadFlags; 140+ rp->ftLcdFilter = ftLcdFilter; 141+} 142+ 143 #ifdef DEBUG 144 /* These are referenced in the freetype sources if DEBUG macro is defined. 145 To simplify work with debuging version of freetype we define 146@@ -809,31 +938,14 @@ 147 return ptr_to_jlong(getNullGlyphImage()); 148 } 149 150- if (!context->useSbits) { 151- renderFlags |= FT_LOAD_NO_BITMAP; 152- } 153- 154- /* NB: in case of non identity transform 155- we might also prefer to disable transform before hinting, 156- and apply it explicitly after hinting is performed. 157- Or we can disable hinting. */ 158- 159- /* select appropriate hinting mode */ 160- if (context->aaType == TEXT_AA_OFF) { 161- target = FT_LOAD_TARGET_MONO; 162- } else if (context->aaType == TEXT_AA_ON) { 163- target = FT_LOAD_TARGET_NORMAL; 164- } else if (context->aaType == TEXT_AA_LCD_HRGB || 165- context->aaType == TEXT_AA_LCD_HBGR) { 166- target = FT_LOAD_TARGET_LCD; 167- } else { 168- target = FT_LOAD_TARGET_LCD_V; 169- } 170- renderFlags |= target; 171+ RenderingProperties renderingProperties; 172+ readFontconfig((const FcChar8 *) scalerInfo->face->family_name, 173+ context->ptsz, context->aaType, &renderingProperties); 174 175 glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); 176 177- error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); 178+ FT_Library_SetLcdFilter(scalerInfo->library, renderingProperties.ftLcdFilter); 179+ error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags); 180 if (error) { 181 //do not destroy scaler yet. 182 //this can be problem of particular context (e.g. with bad transform) 183@@ -862,10 +974,10 @@ 184 glyphInfo = getNullGlyphImage(); 185 return ptr_to_jlong(glyphInfo); 186 } 187- error = FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target)); 188- if (error != 0) { 189- return ptr_to_jlong(getNullGlyphImage()); 190- } 191+ } 192+ error = FT_Render_Glyph(ftglyph, renderingProperties.ftRenderMode); 193+ if (error != 0) { 194+ return ptr_to_jlong(getNullGlyphImage()); 195 } 196 197 width = (UInt16) ftglyph->bitmap.width; 198@@ -1100,11 +1211,14 @@ 199 return NULL; 200 } 201 202- renderFlags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; 203+ RenderingProperties renderingProperties; 204+ readFontconfig((const FcChar8 *) scalerInfo->face->family_name, 205+ context->ptsz, context->aaType, &renderingProperties); 206 207 glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); 208 209- error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); 210+ error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags); 211+ 212 if (error) { 213 return NULL; 214 } 215--- jdk/make/lib/Awt2dLibraries.gmk.orig 2015-07-18 14:30:01.000000000 -0700 216+++ jdk/make/lib/Awt2dLibraries.gmk 2015-07-18 14:30:08.000000000 -0700 217@@ -943,7 +943,7 @@ 218 LDFLAGS_SUFFIX_linux := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \ 219 LDFLAGS_SUFFIX_solaris := -lawt -lawt_headless -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \ 220 LDFLAGS_SUFFIX_aix := -lawt -lawt_headless $(LIBM) $(LIBCXX) -ljava -ljvm,\ 221- LDFLAGS_SUFFIX_bsd := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \ 222+ LDFLAGS_SUFFIX_bsd := -L%%LOCALBASE%%/lib -lfontconfig -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \ 223 LDFLAGS_SUFFIX_macosx := -lawt $(LIBM) $(LIBCXX) -undefined dynamic_lookup \ 224 -ljava -ljvm, \ 225 LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \ 226