From bd3099ff6f7a860070202c8b3f3929369caed5a4 Mon Sep 17 00:00:00 2001 From: Joel Moberg Date: Tue, 3 Nov 2015 14:21:42 +0100 Subject: [PATCH] openjdk: add infinality patch to improve font-rendering --- .../openjdk/004_add-fontconfig.patch | 14 + .../openjdk/005_enable-infinality.patch | 261 ++++++++++++++++++ pkgs/development/compilers/openjdk/8.nix | 6 +- 3 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 pkgs/development/compilers/openjdk/004_add-fontconfig.patch create mode 100644 pkgs/development/compilers/openjdk/005_enable-infinality.patch diff --git a/pkgs/development/compilers/openjdk/004_add-fontconfig.patch b/pkgs/development/compilers/openjdk/004_add-fontconfig.patch new file mode 100644 index 000000000000..8172bc821905 --- /dev/null +++ b/pkgs/development/compilers/openjdk/004_add-fontconfig.patch @@ -0,0 +1,14 @@ +This patch was downloaded from https://aur.archlinux.org/cgit/aur.git/tree/?h=java8-openjdk +More info can be found at http://www.infinality.net/forum/viewtopic.php?f=2&t=275 +diff -ur a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk +--- a/jdk/make/lib/Awt2dLibraries.gmk 2015-07-13 20:50:59.000000000 +0300 ++++ b/jdk/make/lib/Awt2dLibraries.gmk 2015-08-24 12:12:22.930330643 +0300 +@@ -824,7 +824,7 @@ + LDFLAGS := $(subst -Xlinker -z -Xlinker defs,,$(LDFLAGS_JDKLIB)) $(LDFLAGS_CXX_JDK) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_SUFFIX := $(BUILD_LIBFONTMANAGER_FONTLIB), \ +- LDFLAGS_SUFFIX_linux := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \ ++ LDFLAGS_SUFFIX_linux := -lfontconfig -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \ + LDFLAGS_SUFFIX_solaris := -lawt -lawt_headless -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \ + LDFLAGS_SUFFIX_aix := -lawt -lawt_headless $(LIBM) $(LIBCXX) -ljava -ljvm,\ + LDFLAGS_SUFFIX_macosx := -lawt $(LIBM) $(LIBCXX) -undefined dynamic_lookup \ diff --git a/pkgs/development/compilers/openjdk/005_enable-infinality.patch b/pkgs/development/compilers/openjdk/005_enable-infinality.patch new file mode 100644 index 000000000000..f8de96989967 --- /dev/null +++ b/pkgs/development/compilers/openjdk/005_enable-infinality.patch @@ -0,0 +1,261 @@ +This patch was downloaded from https://aur.archlinux.org/cgit/aur.git/tree/?h=java8-openjdk +More info can be found at http://www.infinality.net/forum/viewtopic.php?f=2&t=275 +diff -ur a/jdk/src/share/native/sun/font/freetypeScaler.c b/jdk/src/share/native/sun/font/freetypeScaler.c +--- a/jdk/src/share/native/sun/font/freetypeScaler.c 2014-09-14 16:28:06.108295959 +0200 ++++ b/jdk/src/share/native/sun/font/freetypeScaler.c 2014-09-14 16:28:45.569693174 +0200 +@@ -23,6 +23,9 @@ + * questions. + */ + ++/* Use Infinality patches as default */ ++#define INFINALITY ++ + #include "jni.h" + #include "jni_util.h" + #include "jlong.h" +@@ -38,6 +41,10 @@ + #include FT_SIZES_H + #include FT_OUTLINE_H + #include FT_SYNTHESIS_H ++#ifdef INFINALITY ++#include FT_LCD_FILTER_H ++#include ++#endif + + #include "fontscaler.h" + +@@ -676,6 +683,147 @@ static void CopyFTSubpixelVToSubpixel(co + } + } + ++#ifdef INFINALITY ++typedef struct { ++ FT_Render_Mode ftRenderMode; ++ int ftLoadFlags; ++ FT_LcdFilter ftLcdFilter; ++} RenderingProperties; ++ ++static FcPattern* matchedPattern(const FcChar8* family, double ptSize) { ++ /* ++ we will create pattern to find our family and size in ++ fontconfig configuration, and then will return it's ++ properties: ++ */ ++ 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); ++ // TODO FcPatternAddInteger(pattern, FC_WEIGHT, weight_value); ++ // TODO FcPatternAddInteger(pattern, FC_SLANT, slant_value); ++ // TODO FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value); ++ // TODO FcPatternAddInteger(pattern, FC_WIDTH, stretch); 100 in most cases ++ FcConfigSubstitute(0, fcPattern, FcMatchPattern); ++ FcConfigSubstitute(0, fcPattern, FcMatchFont); ++ FcDefaultSubstitute(fcPattern); ++ FcResult res; ++ ++ FcPattern *pattern = 0; ++ pattern = FcFontMatch(0, fcPattern, &res); ++ FcPatternDestroy(fcPattern); ++ return pattern; ++} ++ ++static void readFontconfig(const FcChar8* family, double ptSize, jint aaType, RenderingProperties* rp) { ++ ++ FcPattern *pattern = matchedPattern(family, ptSize); ++ ++ int ftLoadFalgs = FT_LOAD_DEFAULT; ++ FT_Render_Mode ftRenderMode; ++ FT_LcdFilter ftLcdFilter; ++ char horizontal = 1; ++ FcBool b; ++ ++ // subpixel order: ++ if (aaType == TEXT_AA_ON) ++ ftRenderMode = FT_RENDER_MODE_NORMAL; ++ else if (aaType == TEXT_AA_OFF) ++ ftRenderMode = FT_RENDER_MODE_MONO; ++ else if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch) ++ if (b) { ++ int subpixel = FC_RGBA_UNKNOWN; ++ FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel); ++ if (subpixel == FC_RGBA_UNKNOWN) ++ subpixel = FC_RGBA_NONE; ++ switch (subpixel) { ++ case FC_RGBA_NONE: ++ ftRenderMode = FT_RENDER_MODE_NORMAL; ++ break; ++ case FC_RGBA_RGB: ++ case FC_RGBA_BGR: ++ ftRenderMode = FT_RENDER_MODE_LCD; ++ horizontal = 1; ++ break; ++ case FC_RGBA_VRGB: ++ case FC_RGBA_VBGR: ++ ftRenderMode = FT_RENDER_MODE_LCD_V; ++ horizontal = 0; ++ break; ++ default: ++ break; ++ } ++ } else { ++ ftRenderMode = FT_RENDER_MODE_NORMAL; ++ } ++ ++ // loading mode: ++ if (aaType == TEXT_AA_OFF) ++ ftLoadFalgs |= FT_LOAD_TARGET_MONO; ++ else { ++ int hint_style = FC_HINT_NONE; ++ FcPatternGetInteger(pattern, FC_HINT_STYLE, 0, &hint_style); ++ switch (hint_style) { ++ case FC_HINT_NONE: ++ ftLoadFalgs |= FT_LOAD_NO_HINTING; ++ break; ++ case FC_HINT_SLIGHT: ++ ftLoadFalgs |= FT_LOAD_TARGET_LIGHT; ++ break; ++ case FC_HINT_MEDIUM: ++ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; ++ break; ++ case FC_HINT_FULL: ++ if (aaType == TEXT_AA_ON) ++ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; ++ else ++ ftLoadFalgs |= horizontal ? FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_LCD_V; ++ break; ++ default: ++ // what else to use as default? ++ ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; ++ break; ++ } ++ } ++ ++ // autohinting: ++ if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch) ++ if (b) ++ ftLoadFalgs |= FT_LOAD_FORCE_AUTOHINT; ++ ++ // LCD filter: ++ int filter = FC_LCD_DEFAULT; ++ FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter); ++ switch (filter) { ++ case FC_LCD_NONE: ++ ftLcdFilter = FT_LCD_FILTER_NONE; ++ break; ++ case FC_LCD_DEFAULT: ++ ftLcdFilter = FT_LCD_FILTER_DEFAULT; ++ break; ++ case FC_LCD_LIGHT: ++ ftLcdFilter = FT_LCD_FILTER_LIGHT; ++ break; ++ case FC_LCD_LEGACY: ++ ftLcdFilter = FT_LCD_FILTER_LEGACY; ++ break; ++ default: ++ // new unknown lcd filter type?! will use default one: ++ ftLcdFilter = FT_LCD_FILTER_DEFAULT; ++ break; ++ } ++ ++ FcPatternDestroy(pattern); ++ ++ rp->ftRenderMode = ftRenderMode; ++ rp->ftLoadFlags = ftLoadFalgs; ++ rp->ftLcdFilter = ftLcdFilter; ++} ++#endif + + /* + * Class: sun_font_FreetypeFontScaler +@@ -691,7 +839,9 @@ Java_sun_font_FreetypeFontScaler_getGlyp + UInt16 width, height; + GlyphInfo *glyphInfo; + int glyph_index; ++#ifndef INFINALITY + int renderFlags = FT_LOAD_RENDER, target; ++#endif + FT_GlyphSlot ftglyph; + + FTScalerContext* context = +@@ -709,6 +859,11 @@ Java_sun_font_FreetypeFontScaler_getGlyp + return ptr_to_jlong(getNullGlyphImage()); + } + ++#ifdef INFINALITY ++ RenderingProperties renderingProperties; ++ readFontconfig((const FcChar8 *) scalerInfo->face->family_name, ++ context->ptsz, context->aaType, &renderingProperties); ++#else + /* if algorithmic styling is required then we do not request bitmap */ + if (context->doBold || context->doItalize) { + renderFlags = FT_LOAD_DEFAULT; +@@ -731,10 +886,17 @@ Java_sun_font_FreetypeFontScaler_getGlyp + target = FT_LOAD_TARGET_LCD_V; + } + renderFlags |= target; ++#endif + + glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); + ++#ifdef INFINALITY ++ FT_Library_SetLcdFilter(scalerInfo->library, renderingProperties.ftLcdFilter); ++ error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags); ++#else + error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); ++#endif ++ + if (error) { + //do not destroy scaler yet. + //this can be problem of particular context (e.g. with bad transform) +@@ -753,9 +915,13 @@ Java_sun_font_FreetypeFontScaler_getGlyp + + /* generate bitmap if it is not done yet + e.g. if algorithmic styling is performed and style was added to outline */ ++#ifdef INFINALITY ++ FT_Render_Glyph(ftglyph, renderingProperties.ftRenderMode); ++#else + if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) { + FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target)); + } ++#endif + + width = (UInt16) ftglyph->bitmap.width; + height = (UInt16) ftglyph->bitmap.rows; +@@ -969,7 +1135,9 @@ Java_sun_font_FreetypeFontScaler_getGlyp + static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D, + FTScalerContext *context, FTScalerInfo* scalerInfo, + jint glyphCode, jfloat xpos, jfloat ypos) { ++#ifndef INFINALITY + int renderFlags; ++#endif + int glyph_index; + FT_Error error; + FT_GlyphSlot ftglyph; +@@ -984,11 +1152,22 @@ static FT_Outline* getFTOutline(JNIEnv* + return NULL; + } + ++#ifdef INFINALITY ++ RenderingProperties renderingProperties; ++ readFontconfig((const FcChar8 *) scalerInfo->face->family_name, ++ context->ptsz, context->aaType, &renderingProperties); ++#else + renderFlags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; ++#endif + + glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); + ++#ifdef INFINALITY ++ error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags); ++#else + error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); ++#endif ++ + if (error) { + return NULL; + } diff --git a/pkgs/development/compilers/openjdk/8.nix b/pkgs/development/compilers/openjdk/8.nix index 845aebdc2505..5d53ed7f025f 100644 --- a/pkgs/development/compilers/openjdk/8.nix +++ b/pkgs/development/compilers/openjdk/8.nix @@ -2,6 +2,7 @@ , alsaLib, bootjdk, cacert, perl, liberation_ttf, fontconfig, zlib , setJavaClassPath , minimal ? false +, enableInfinality ? true # font rendering patch }: let @@ -80,7 +81,10 @@ let ./fix-java-home-jdk8.patch ./read-truststore-from-env-jdk8.patch ./currency-date-range-jdk8.patch - ]; + ] ++ (if enableInfinality then [ + ./004_add-fontconfig.patch + ./005_enable-infinality.patch + ] else []); preConfigure = '' chmod +x configure