1This patch was downloaded from https://aur.archlinux.org/cgit/aur.git/tree/?h=java8-openjdk
2More info can be found at http://www.infinality.net/forum/viewtopic.php?f=2&t=275
3diff -ur a/jdk/src/share/native/sun/font/freetypeScaler.c b/jdk/src/share/native/sun/font/freetypeScaler.c
4--- a/jdk/src/share/native/sun/font/freetypeScaler.c 2014-09-14 16:28:06.108295959 +0200
5+++ b/jdk/src/share/native/sun/font/freetypeScaler.c 2014-09-14 16:28:45.569693174 +0200
6@@ -23,6 +23,9 @@
7 * questions.
8 */
9
10+/* Use Infinality patches as default */
11+#define INFINALITY
12+
13 #include "jni.h"
14 #include "jni_util.h"
15 #include "jlong.h"
16@@ -38,6 +41,10 @@
17 #include FT_SIZES_H
18 #include FT_OUTLINE_H
19 #include FT_SYNTHESIS_H
20+#ifdef INFINALITY
21+#include FT_LCD_FILTER_H
22+#include <fontconfig/fontconfig.h>
23+#endif
24
25 #include "fontscaler.h"
26
27@@ -676,6 +683,147 @@ static void CopyFTSubpixelVToSubpixel(co
28 }
29 }
30
31+#ifdef INFINALITY
32+typedef struct {
33+ FT_Render_Mode ftRenderMode;
34+ int ftLoadFlags;
35+ FT_LcdFilter ftLcdFilter;
36+} RenderingProperties;
37+
38+static FcPattern* matchedPattern(const FcChar8* family, double ptSize) {
39+ /*
40+ we will create pattern to find our family and size in
41+ fontconfig configuration, and then will return it's
42+ properties:
43+ */
44+ FcPattern* fcPattern = 0;
45+ fcPattern = FcPatternCreate();
46+ FcValue fcValue;
47+ fcValue.type = FcTypeString;
48+ fcValue.u.s = family;
49+ FcPatternAdd(fcPattern, FC_FAMILY, fcValue, FcTrue);
50+ FcPatternAddBool(fcPattern, FC_SCALABLE, FcTrue);
51+ FcPatternAddDouble(fcPattern, FC_SIZE, ptSize);
52+ // TODO FcPatternAddInteger(pattern, FC_WEIGHT, weight_value);
53+ // TODO FcPatternAddInteger(pattern, FC_SLANT, slant_value);
54+ // TODO FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
55+ // TODO FcPatternAddInteger(pattern, FC_WIDTH, stretch); 100 in most cases
56+ FcConfigSubstitute(0, fcPattern, FcMatchPattern);
57+ FcConfigSubstitute(0, fcPattern, FcMatchFont);
58+ FcDefaultSubstitute(fcPattern);
59+ FcResult res;
60+
61+ FcPattern *pattern = 0;
62+ pattern = FcFontMatch(0, fcPattern, &res);
63+ FcPatternDestroy(fcPattern);
64+ return pattern;
65+}
66+
67+static void readFontconfig(const FcChar8* family, double ptSize, jint aaType, RenderingProperties* rp) {
68+
69+ FcPattern *pattern = matchedPattern(family, ptSize);
70+
71+ int ftLoadFalgs = FT_LOAD_DEFAULT;
72+ FT_Render_Mode ftRenderMode;
73+ FT_LcdFilter ftLcdFilter;
74+ char horizontal = 1;
75+ FcBool b;
76+
77+ // subpixel order:
78+ if (aaType == TEXT_AA_ON)
79+ ftRenderMode = FT_RENDER_MODE_NORMAL;
80+ else if (aaType == TEXT_AA_OFF)
81+ ftRenderMode = FT_RENDER_MODE_MONO;
82+ else if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch)
83+ if (b) {
84+ int subpixel = FC_RGBA_UNKNOWN;
85+ FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel);
86+ if (subpixel == FC_RGBA_UNKNOWN)
87+ subpixel = FC_RGBA_NONE;
88+ switch (subpixel) {
89+ case FC_RGBA_NONE:
90+ ftRenderMode = FT_RENDER_MODE_NORMAL;
91+ break;
92+ case FC_RGBA_RGB:
93+ case FC_RGBA_BGR:
94+ ftRenderMode = FT_RENDER_MODE_LCD;
95+ horizontal = 1;
96+ break;
97+ case FC_RGBA_VRGB:
98+ case FC_RGBA_VBGR:
99+ ftRenderMode = FT_RENDER_MODE_LCD_V;
100+ horizontal = 0;
101+ break;
102+ default:
103+ break;
104+ }
105+ } else {
106+ ftRenderMode = FT_RENDER_MODE_NORMAL;
107+ }
108+
109+ // loading mode:
110+ if (aaType == TEXT_AA_OFF)
111+ ftLoadFalgs |= FT_LOAD_TARGET_MONO;
112+ else {
113+ int hint_style = FC_HINT_NONE;
114+ FcPatternGetInteger(pattern, FC_HINT_STYLE, 0, &hint_style);
115+ switch (hint_style) {
116+ case FC_HINT_NONE:
117+ ftLoadFalgs |= FT_LOAD_NO_HINTING;
118+ break;
119+ case FC_HINT_SLIGHT:
120+ ftLoadFalgs |= FT_LOAD_TARGET_LIGHT;
121+ break;
122+ case FC_HINT_MEDIUM:
123+ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL;
124+ break;
125+ case FC_HINT_FULL:
126+ if (aaType == TEXT_AA_ON)
127+ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL;
128+ else
129+ ftLoadFalgs |= horizontal ? FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_LCD_V;
130+ break;
131+ default:
132+ // what else to use as default?
133+ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL;
134+ break;
135+ }
136+ }
137+
138+ // autohinting:
139+ if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch)
140+ if (b)
141+ ftLoadFalgs |= FT_LOAD_FORCE_AUTOHINT;
142+
143+ // LCD filter:
144+ int filter = FC_LCD_DEFAULT;
145+ FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter);
146+ switch (filter) {
147+ case FC_LCD_NONE:
148+ ftLcdFilter = FT_LCD_FILTER_NONE;
149+ break;
150+ case FC_LCD_DEFAULT:
151+ ftLcdFilter = FT_LCD_FILTER_DEFAULT;
152+ break;
153+ case FC_LCD_LIGHT:
154+ ftLcdFilter = FT_LCD_FILTER_LIGHT;
155+ break;
156+ case FC_LCD_LEGACY:
157+ ftLcdFilter = FT_LCD_FILTER_LEGACY;
158+ break;
159+ default:
160+ // new unknown lcd filter type?! will use default one:
161+ ftLcdFilter = FT_LCD_FILTER_DEFAULT;
162+ break;
163+ }
164+
165+ FcPatternDestroy(pattern);
166+
167+ rp->ftRenderMode = ftRenderMode;
168+ rp->ftLoadFlags = ftLoadFalgs;
169+ rp->ftLcdFilter = ftLcdFilter;
170+}
171+#endif
172
173 /*
174 * Class: sun_font_FreetypeFontScaler
175@@ -691,7 +839,9 @@ Java_sun_font_FreetypeFontScaler_getGlyp
176 UInt16 width, height;
177 GlyphInfo *glyphInfo;
178 int glyph_index;
179+#ifndef INFINALITY
180 int renderFlags = FT_LOAD_RENDER, target;
181+#endif
182 FT_GlyphSlot ftglyph;
183
184 FTScalerContext* context =
185@@ -709,6 +859,11 @@ Java_sun_font_FreetypeFontScaler_getGlyp
186 return ptr_to_jlong(getNullGlyphImage());
187 }
188
189+#ifdef INFINALITY
190+ RenderingProperties renderingProperties;
191+ readFontconfig((const FcChar8 *) scalerInfo->face->family_name,
192+ context->ptsz, context->aaType, &renderingProperties);
193+#else
194 /* if algorithmic styling is required then we do not request bitmap */
195 if (context->doBold || context->doItalize) {
196 renderFlags = FT_LOAD_DEFAULT;
197@@ -731,10 +886,17 @@ Java_sun_font_FreetypeFontScaler_getGlyp
198 target = FT_LOAD_TARGET_LCD_V;
199 }
200 renderFlags |= target;
201+#endif
202
203 glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode);
204
205+#ifdef INFINALITY
206+ FT_Library_SetLcdFilter(scalerInfo->library, renderingProperties.ftLcdFilter);
207+ error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags);
208+#else
209 error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags);
210+#endif
211+
212 if (error) {
213 //do not destroy scaler yet.
214 //this can be problem of particular context (e.g. with bad transform)
215@@ -753,9 +915,13 @@ Java_sun_font_FreetypeFontScaler_getGlyp
216
217 /* generate bitmap if it is not done yet
218 e.g. if algorithmic styling is performed and style was added to outline */
219+#ifdef INFINALITY
220+ FT_Render_Glyph(ftglyph, renderingProperties.ftRenderMode);
221+#else
222 if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) {
223 FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target));
224 }
225+#endif
226
227 width = (UInt16) ftglyph->bitmap.width;
228 height = (UInt16) ftglyph->bitmap.rows;
229@@ -969,7 +1135,9 @@ Java_sun_font_FreetypeFontScaler_getGlyp
230 static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D,
231 FTScalerContext *context, FTScalerInfo* scalerInfo,
232 jint glyphCode, jfloat xpos, jfloat ypos) {
233+#ifndef INFINALITY
234 int renderFlags;
235+#endif
236 int glyph_index;
237 FT_Error error;
238 FT_GlyphSlot ftglyph;
239@@ -984,11 +1152,22 @@ static FT_Outline* getFTOutline(JNIEnv*
240 return NULL;
241 }
242
243+#ifdef INFINALITY
244+ RenderingProperties renderingProperties;
245+ readFontconfig((const FcChar8 *) scalerInfo->face->family_name,
246+ context->ptsz, context->aaType, &renderingProperties);
247+#else
248 renderFlags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;
249+#endif
250
251 glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode);
252
253+#ifdef INFINALITY
254+ error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags);
255+#else
256 error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags);
257+#endif
258+
259 if (error) {
260 return NULL;
261 }