Mercurial > hg > icedtea8-forest > jdk
changeset 11915:aab729e0626a icedtea-3.1.0pre03
PR2931, G478960: Provide Infinality Support via fontconfig
Summary: Adapt fontfix patch, which uses fontconfig for font rendering, to apply only when INFINALITY_SUPPORT=true
Contributed-by: Trustin Lee, Aleksandar Antok (fontfix patch from https://gist.github.com/aleksandara/2963640)
author | andrew |
---|---|
date | Sun, 10 Jul 2016 23:03:04 +0100 |
parents | adc500186b23 |
children | 7a8eb1c17b1f |
files | make/lib/Awt2dLibraries.gmk src/share/native/sun/font/freetypeScaler.c |
diffstat | 2 files changed, 184 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/make/lib/Awt2dLibraries.gmk Sun Jul 10 20:43:31 2016 +0100 +++ b/make/lib/Awt2dLibraries.gmk Sun Jul 10 23:03:04 2016 +0100 @@ -900,6 +900,11 @@ LIBFONTMANAGER_EXCLUDE_FILES += freetypeScaler.c else FONT_HEADERS := $(FREETYPE_CFLAGS) + ifeq ($(INFINALITY_SUPPORT),true) + FONT_HEADERS += $(FONTCONFIG_CFLAGS) + INFINALITY_DEFINES := -DINFINALITY + INFINALITY_LIBS := $(FONTCONFIG_LIBS) + endif BUILD_LIBFONTMANAGER_MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libfontmanager/mapfile-vers.openjdk BUILD_LIBFONTMANAGER_FONTLIB := $(FREETYPE_LIBS) endif @@ -922,7 +927,7 @@ BUILD_LIBFONTMANAGER_CFLAGS_COMMON := \ $(X_CFLAGS) \ - -DLE_STANDALONE -DHEADLESS \ + -DLE_STANDALONE -DHEADLESS $(INFINALITY_DEFINES) \ $(FONT_HEADERS) \ -I$(JDK_TOPDIR)/src/share/native/sun/font \ -I$(JDK_TOPDIR)/src/share/native/sun/font/layout \ @@ -955,7 +960,7 @@ MAPFILE := $(BUILD_LIBFONTMANAGER_MAPFILE), \ LDFLAGS := $(subst -Xlinker -z -Xlinker defs,,$(LDFLAGS_JDKLIB)) $(LDFLAGS_CXX_JDK) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := $(BUILD_LIBFONTMANAGER_FONTLIB), \ + LDFLAGS_SUFFIX := $(BUILD_LIBFONTMANAGER_FONTLIB) $(INFINALITY_LIBS), \ LDFLAGS_SUFFIX_linux := -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,\
--- a/src/share/native/sun/font/freetypeScaler.c Sun Jul 10 20:43:31 2016 +0100 +++ b/src/share/native/sun/font/freetypeScaler.c Sun Jul 10 23:03:04 2016 +0100 @@ -38,6 +38,10 @@ #include FT_SIZES_H #include FT_OUTLINE_H #include FT_SYNTHESIS_H +#ifdef INFINALITY +#include FT_LCD_FILTER_H +#include <fontconfig/fontconfig.h> +#endif #include "fontscaler.h" @@ -656,6 +660,147 @@ } } +#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 @@ -671,8 +816,10 @@ UInt16 width, height; GlyphInfo *glyphInfo; int glyph_index; + FT_GlyphSlot ftglyph; +#ifndef INFINALITY int renderFlags = FT_LOAD_RENDER, target; - FT_GlyphSlot ftglyph; +#endif FTScalerContext* context = (FTScalerContext*) jlong_to_ptr(pScalerContext); @@ -689,6 +836,11 @@ 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; @@ -711,10 +863,17 @@ 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) @@ -733,9 +892,13 @@ /* 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; @@ -949,7 +1112,9 @@ 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; @@ -964,11 +1129,22 @@ 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; }