diff --git a/Makefile b/Makefile index 34c874c..a93a6da 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -BASE = fedora-24 +BASE = fedora-25 DIRS = $(wildcard */) define makerpm = diff --git a/fontconfig-infinality-ultimate/04-Makefile.conf.d.patch b/fontconfig-infinality-ultimate/04-Makefile.conf.d.patch index beb33a5..7ef20c1 100644 --- a/fontconfig-infinality-ultimate/04-Makefile.conf.d.patch +++ b/fontconfig-infinality-ultimate/04-Makefile.conf.d.patch @@ -9,7 +9,7 @@ DATA = $(config_DATA) $(template_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README -@@ -343,25 +343,8 @@ target_alias = @target_alias@ +@@ -343,26 +343,8 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @@ -17,6 +17,7 @@ -DOC_SOURCES = README.in DOC_FILES = $(DOC_SOURCES:.in=) -CONF_LINKS = \ +- 10-hinting-$(PREFERRED_HINTING).conf \ - 10-scale-bitmap-fonts.conf \ - 20-unhint-small-vera.conf \ - 30-urw-aliases.conf \ diff --git a/fontconfig-infinality-ultimate/fontconfig-infinality-ultimate.spec b/fontconfig-infinality-ultimate/fontconfig-infinality-ultimate.spec index 122be95..55b0a3b 100644 --- a/fontconfig-infinality-ultimate/fontconfig-infinality-ultimate.spec +++ b/fontconfig-infinality-ultimate/fontconfig-infinality-ultimate.spec @@ -2,8 +2,8 @@ Summary: Font configuration and customization library Name: fontconfig-infinality-ultimate -Version: 2.11.94 -Release: 5%{?dist} +Version: 2.12.1 +Release: 1%{?dist} # src/ftglue.[ch] is in Public Domain # src/fccache.c contains Public Domain code # fc-case/CaseFolding.txt is in the UCD @@ -17,13 +17,11 @@ Source2: presets.tar.bz2 # https://bugzilla.redhat.com/show_bug.cgi?id=140335 Patch0: fontconfig-sleep-less.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1236034 -Patch1: fontconfig-lock-cache.patch -Patch3: 01-configure.patch -Patch4: 02-configure.ac.patch -Patch5: 03-Makefile.in.patch -Patch6: 04-Makefile.conf.d.patch -Patch7: 05-Makefile.am.in.patch +Patch2: 01-configure.patch +Patch3: 02-configure.ac.patch +Patch4: 03-Makefile.in.patch +Patch5: 04-Makefile.conf.d.patch +Patch6: 05-Makefile.am.in.patch BuildRequires: expat-devel BuildRequires: freetype-devel >= %{freetype_version} @@ -77,12 +75,11 @@ which is useful for developing applications that uses fontconfig. cd .. %setup -q -a 1 -n fontconfig-%{version} %patch0 -p1 -b .sleep-less -%patch1 -p1 -b .lock-cache +%patch2 -p1 %patch3 -p1 %patch4 -p1 %patch5 -p1 %patch6 -p1 -%patch7 -p1 aclocal libtoolize -f diff --git a/freetype-infinality-ultimate/0001-Enable-table-validation-modules.patch b/freetype-infinality-ultimate/0001-Enable-table-validation-modules.patch new file mode 100644 index 0000000..5528870 --- /dev/null +++ b/freetype-infinality-ultimate/0001-Enable-table-validation-modules.patch @@ -0,0 +1,34 @@ +From a7e32953f291c39a8286b87516cd0c0516c2c89b Mon Sep 17 00:00:00 2001 +From: "Jan Alexander Steffens (heftig)" +Date: Tue, 23 Jun 2015 08:40:29 +0200 +Subject: [PATCH 1/4] Enable table validation modules + +--- + modules.cfg | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/modules.cfg b/modules.cfg +index d677565a2bc2b5a2..f19cbec33384a86f 100644 +--- a/modules.cfg ++++ b/modules.cfg +@@ -110,7 +110,7 @@ RASTER_MODULES += smooth + AUX_MODULES += cache + + # TrueType GX/AAT table validation. Needs ftgxval.c below. +-# AUX_MODULES += gxvalid ++AUX_MODULES += gxvalid + + # Support for streams compressed with gzip (files with suffix .gz). + # +@@ -129,7 +129,7 @@ AUX_MODULES += bzip2 + + # OpenType table validation. Needs ftotval.c below. + # +-# AUX_MODULES += otvalid ++AUX_MODULES += otvalid + + # Auxiliary PostScript driver component to share common code. + # +-- +2.9.0 + diff --git a/freetype-infinality-ultimate/03-infinality-2.6.3-2016.03.26.patch b/freetype-infinality-ultimate/0002-infinality-2.6.5-2016.08.18.patch similarity index 93% rename from freetype-infinality-ultimate/03-infinality-2.6.3-2016.03.26.patch rename to freetype-infinality-ultimate/0002-infinality-2.6.5-2016.08.18.patch index 12bbc44..741adb8 100644 --- a/freetype-infinality-ultimate/03-infinality-2.6.3-2016.03.26.patch +++ b/freetype-infinality-ultimate/0002-infinality-2.6.5-2016.08.18.patch @@ -1,8 +1,7 @@ -diff --git a/builds/freetype.mk b/builds/freetype.mk -index 1cc7e29..c73ae68 100644 ---- a/builds/freetype.mk -+++ b/builds/freetype.mk -@@ -161,6 +161,7 @@ FT_CFLAGS = $(CPPFLAGS) \ +diff -ruN freetype-2.6.5-orig/builds/freetype.mk freetype-2.6.5/builds/freetype.mk +--- freetype-2.6.5-orig/builds/freetype.mk 2016-08-18 19:40:29.008037429 +0200 ++++ freetype-2.6.5/builds/freetype.mk 2016-08-18 19:40:37.859037197 +0200 +@@ -161,6 +161,7 @@ $(CFLAGS) \ $DFT2_BUILD_LIBRARY \ $DFT_CONFIG_MODULES_H="" \ @@ -10,10 +9,9 @@ index 1cc7e29..c73ae68 100644 $(FTOPTION_FLAG) -diff --git a/configure b/configure -index fd52581..bb81fb8 100755 ---- a/configure -+++ b/configure +diff -ruN freetype-2.6.5-orig/configure freetype-2.6.5/configure +--- freetype-2.6.5-orig/configure 2016-08-18 19:40:29.076037427 +0200 ++++ freetype-2.6.5/configure 2016-08-18 19:40:37.860037197 +0200 @@ -13,6 +13,8 @@ # Call the `configure' script located in `builds/unix'. # @@ -23,12 +21,12 @@ index fd52581..bb81fb8 100755 rm -f config.mk builds/unix/unix-def.mk builds/unix/unix-cc.mk # respect GNUMAKE environment variable for backwards compatibility -diff --git a/devel/ftoption.h b/devel/ftoption.h ---- a/devel/ftoption.h 2016-03-28 12:09:54.392246487 +0200 -+++ b/devel/ftoption.h 2016-03-28 12:17:20.364039723 +0200 -@@ -604,6 +604,16 @@ FT_BEGIN_HEADER +diff -ruN freetype-2.6.5-orig/devel/ftoption.h freetype-2.6.5/devel/ftoption.h +--- freetype-2.6.5-orig/devel/ftoption.h 2016-08-18 19:40:28.795037435 +0200 ++++ freetype-2.6.5/devel/ftoption.h 2016-08-18 19:40:37.863037197 +0200 +@@ -582,6 +582,16 @@ /* */ - #define TT_CONFIG_OPTION_SUBPIXEL_HINTING + #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER + /*************************************************************************/ + /* */ @@ -43,11 +41,10 @@ diff --git a/devel/ftoption.h b/devel/ftoption.h /*************************************************************************/ /* */ -diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h -index b481f8f..b05932a 100644 ---- a/include/freetype/config/ftoption.h -+++ b/include/freetype/config/ftoption.h -@@ -92,7 +92,7 @@ FT_BEGIN_HEADER +diff -ruN freetype-2.6.5-orig/include/freetype/config/ftoption.h freetype-2.6.5/include/freetype/config/ftoption.h +--- freetype-2.6.5-orig/include/freetype/config/ftoption.h 2016-08-18 19:40:29.125037426 +0200 ++++ freetype-2.6.5/include/freetype/config/ftoption.h 2016-08-18 19:42:32.469034188 +0200 +@@ -92,7 +92,7 @@ /* This is done to allow FreeType clients to run unmodified, forcing */ /* them to display normal gray-level anti-aliased glyphs. */ /* */ @@ -56,12 +53,14 @@ index b481f8f..b05932a 100644 /*************************************************************************/ -@@ -602,7 +602,19 @@ FT_BEGIN_HEADER - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ +@@ -630,9 +630,21 @@ /* */ --/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING + /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ + /* */ +-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ + /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 */ + /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ ++#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 + + + /*************************************************************************/ @@ -77,10 +76,9 @@ index b481f8f..b05932a 100644 /*************************************************************************/ -diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c -index 53851e7..c20e7d3 100644 ---- a/src/autofit/aflatin.c -+++ b/src/autofit/aflatin.c +diff -ruN freetype-2.6.5-orig/src/autofit/aflatin.c freetype-2.6.5/src/autofit/aflatin.c +--- freetype-2.6.5-orig/src/autofit/aflatin.c 2016-08-18 19:40:29.386037419 +0200 ++++ freetype-2.6.5/src/autofit/aflatin.c 2016-08-18 19:40:37.964037194 +0200 @@ -24,7 +24,10 @@ #include "afpic.h" #include "aflatin.h" @@ -166,7 +164,7 @@ index 53851e7..c20e7d3 100644 #endif -@@ -2337,7 +2363,10 @@ +@@ -2398,7 +2424,10 @@ dist = edge->fpos - blue->shoot.org; if ( dist < 0 ) dist = -dist; @@ -178,7 +176,7 @@ index 53851e7..c20e7d3 100644 dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { -@@ -2513,8 +2542,17 @@ +@@ -2574,8 +2603,17 @@ FT_Pos dist = width; FT_Int sign = 0; FT_Int vertical = ( dim == AF_DIMENSION_VERT ); @@ -197,7 +195,7 @@ index 53851e7..c20e7d3 100644 if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || axis->extra_light ) return width; -@@ -2524,9 +2562,73 @@ +@@ -2585,9 +2623,76 @@ dist = -width; sign = 1; } @@ -215,12 +213,15 @@ index 53851e7..c20e7d3 100644 + abs( axis->widths[0].cur - infinality_dist ) < 32 && + axis->widths[0].cur > 52 ) + { -+ if ( strstr( metrics->root.scaler.face->style_name, "Regular" ) || -+ strstr( metrics->root.scaler.face->style_name, "Book" ) || -+ strstr( metrics->root.scaler.face->style_name, "Medium" ) || -+ strcmp( metrics->root.scaler.face->style_name, "Italic" ) == 0 || -+ strcmp( metrics->root.scaler.face->style_name, "Oblique" ) == 0 ) -+ { ++ const char *style_name=metrics->root.scaler.face->style_name; ++ if ( style_name!=NULL && ++ ( strstr( style_name, "Regular" ) || ++ strstr( style_name, "Book" ) || ++ strstr( style_name, "Medium" ) || ++ strcmp( style_name, "Italic" ) == 0 || ++ strcmp( style_name, "Oblique" ) == 0 ) ++ ) ++ { + /* regular weight */ + if ( axis->widths[0].cur < 64 ) + infinality_dist = 64; @@ -272,7 +273,7 @@ index 53851e7..c20e7d3 100644 { /* smooth hinting process: very lightly quantize the stem width */ -@@ -2618,6 +2720,9 @@ +@@ -2679,6 +2784,9 @@ } } else @@ -282,7 +283,7 @@ index 53851e7..c20e7d3 100644 { /* strong hinting process: snap the stem width to integer pixels */ -@@ -2625,7 +2730,10 @@ +@@ -2686,7 +2794,10 @@ dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); @@ -294,7 +295,7 @@ index 53851e7..c20e7d3 100644 if ( vertical ) { /* in the case of vertical hinting, always round */ -@@ -2688,6 +2796,32 @@ +@@ -2749,6 +2860,32 @@ } Done_Width: @@ -327,7 +328,7 @@ index 53851e7..c20e7d3 100644 if ( sign ) dist = -dist; -@@ -2706,6 +2840,8 @@ +@@ -2767,6 +2904,8 @@ FT_Pos dist, base_delta; FT_Pos fitted_width; @@ -336,7 +337,7 @@ index 53851e7..c20e7d3 100644 dist = stem_edge->opos - base_edge->opos; base_delta = base_edge->pos - base_edge->opos; -@@ -3314,8 +3450,11 @@ +@@ -3375,8 +3514,11 @@ int dim; AF_LatinAxis axis; @@ -350,7 +351,7 @@ index 53851e7..c20e7d3 100644 error = af_glyph_hints_reload( hints, outline ); if ( error ) goto Exit; -@@ -3385,7 +3524,11 @@ +@@ -3446,7 +3588,11 @@ } af_glyph_hints_save( hints, outline ); @@ -363,11 +364,10 @@ index 53851e7..c20e7d3 100644 Exit: return error; } -diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h -index dd75ef3..257265e 100644 ---- a/src/autofit/aflatin.h -+++ b/src/autofit/aflatin.h -@@ -64,6 +64,9 @@ FT_BEGIN_HEADER +diff -ruN freetype-2.6.5-orig/src/autofit/aflatin.h freetype-2.6.5/src/autofit/aflatin.h +--- freetype-2.6.5-orig/src/autofit/aflatin.h 2016-08-18 19:40:29.364037420 +0200 ++++ freetype-2.6.5/src/autofit/aflatin.h 2016-08-18 19:40:37.877037196 +0200 +@@ -64,6 +64,9 @@ #define AF_LATIN_MAX_WIDTHS 16 @@ -377,22 +377,33 @@ index dd75ef3..257265e 100644 #define AF_LATIN_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */ #define AF_LATIN_BLUE_TOP ( 1U << 1 ) /* we have a top blue zone */ -diff --git a/src/base/Jamfile b/src/base/Jamfile -index e39fb09..a33e9a1 100644 ---- a/src/base/Jamfile -+++ b/src/base/Jamfile -@@ -56,6 +56,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; - ftglyph - ftgxval - ftinit -+ ftinf - ftlcdfil - ftmm - ftotval -diff --git a/src/base/ftbase.c b/src/base/ftbase.c -index 253dfb7..59d2d17 100644 ---- a/src/base/ftbase.c -+++ b/src/base/ftbase.c +diff -ruN freetype-2.6.5-orig/src/autofit/afmodule.c freetype-2.6.5/src/autofit/afmodule.c +--- freetype-2.6.5-orig/src/autofit/afmodule.c 2016-08-18 19:40:29.387037419 +0200 ++++ freetype-2.6.5/src/autofit/afmodule.c 2016-08-18 19:40:37.952037194 +0200 +@@ -22,6 +22,10 @@ + #include "aferrors.h" + #include "afpic.h" + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "../base/ftinf.h" ++#endif ++ + #ifdef FT_DEBUG_AUTOFIT + + #ifndef FT_MAKE_OPTION_SINGLE_OBJECT +@@ -372,6 +376,9 @@ + module->warping = 0; + #endif + module->no_stem_darkening = TRUE; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if(ftinf) module->no_stem_darkening = !ftinf->stem_darkening_autofit; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + + module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + module->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; +diff -ruN freetype-2.6.5-orig/src/base/ftbase.c freetype-2.6.5/src/base/ftbase.c +--- freetype-2.6.5-orig/src/base/ftbase.c 2016-08-18 19:40:29.502037416 +0200 ++++ freetype-2.6.5/src/base/ftbase.c 2016-08-18 19:40:37.880037196 +0200 @@ -34,6 +34,9 @@ #include "ftstream.c" #include "fttrigon.c" @@ -403,12 +414,10 @@ index 253dfb7..59d2d17 100644 #ifdef FT_MACINTOSH #include "ftmac.c" -diff --git a/src/base/ftinf.c b/src/base/ftinf.c -new file mode 100644 -index 0000000..cef285d ---- /dev/null -+++ b/src/base/ftinf.c -@@ -0,0 +1,359 @@ +diff -ruN freetype-2.6.5-orig/src/base/ftinf.c freetype-2.6.5/src/base/ftinf.c +--- freetype-2.6.5-orig/src/base/ftinf.c 1970-01-01 01:00:00.000000000 +0100 ++++ freetype-2.6.5/src/base/ftinf.c 2016-08-18 19:40:37.954037194 +0200 +@@ -0,0 +1,363 @@ +#include +#include "ftinf.h" +#define true 1 @@ -646,6 +655,10 @@ index 0000000..cef285d + if( s ) sscanf( s, "%d", &_env.stem_snapping_sliding_scale ); + s=getenv( "INFINALITY_FT_STEM_ALIGNMENT_STRENGTH" ); + if( s ) sscanf( s, "%d", &_env.stem_alignment_strength ); ++ s=getenv( "INFINALITY_FT_STEM_DARKENING_AUTOFIT" ); ++ if( s ) _env.stem_darkening_autofit=bool_val( s ); ++ s=getenv( "INFINALITY_FT_STEM_DARKENING_CFF" ); ++ if( s ) _env.stem_darkening_cff=bool_val( s ); + s=getenv( "INFINALITY_FT_STEM_FITTING_STRENGTH" ); + if( s ) sscanf( s, "%d", &_env.stem_fitting_strength ); + s=getenv( "INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH" ); @@ -768,12 +781,10 @@ index 0000000..cef285d + /* point to the combined and checked settings */ + ftinf=&_env; +} -diff --git a/src/base/ftinf.h b/src/base/ftinf.h -new file mode 100644 -index 0000000..dc35f48 ---- /dev/null -+++ b/src/base/ftinf.h -@@ -0,0 +1,64 @@ +diff -ruN freetype-2.6.5-orig/src/base/ftinf.h freetype-2.6.5/src/base/ftinf.h +--- freetype-2.6.5-orig/src/base/ftinf.h 1970-01-01 01:00:00.000000000 +0100 ++++ freetype-2.6.5/src/base/ftinf.h 2016-08-18 19:40:37.956037194 +0200 +@@ -0,0 +1,66 @@ +#ifndef _FTINF_H_ +#define _FTINF_H_ +/* @@ -818,6 +829,8 @@ index 0000000..dc35f48 + int global_embolden_y_value; + int grayscale_filter_strength; + int stem_alignment_strength; ++ int stem_darkening_autofit; ++ int stem_darkening_cff; + int stem_fitting_strength; + int stem_snapping_sliding_scale; + int use_known_settings_on_selected_fonts; @@ -838,14 +851,12 @@ index 0000000..dc35f48 +extern void ftinf_env(); + +#endif -diff --git a/src/base/ftinf_rh.c b/src/base/ftinf_rh.c -new file mode 100644 -index 0000000..4cd6f1a ---- /dev/null -+++ b/src/base/ftinf_rh.c -@@ -0,0 +1,628 @@ +diff -ruN freetype-2.6.5-orig/src/base/ftinf_rh.c freetype-2.6.5/src/base/ftinf_rh.c +--- freetype-2.6.5-orig/src/base/ftinf_rh.c 1970-01-01 01:00:00.000000000 +0100 ++++ freetype-2.6.5/src/base/ftinf_rh.c 2016-08-18 19:40:37.935037195 +0200 +@@ -0,0 +1,626 @@ +/* ANSI-C code produced by gperf version 3.1 */ -+/* Command-line: gperf ftinf_rh.gperf */ ++/* Command-line: gperf --output-file=ftinf_rh.c ftinf_rh.gperf */ +/* Computed positions: -k'1,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -1458,13 +1469,11 @@ index 0000000..4cd6f1a + char buf[max_wlen+1]; + int len=strlen( name ); + if( len <= max_wlen ){ -+ const sa_rules_t *p; + int i; + for( i=0; iformat == FT_GLYPH_FORMAT_OUTLINE ) { /* check that the loaded outline is correct */ -@@ -4727,6 +4787,11 @@ +@@ -4742,6 +4802,11 @@ /* That's ok now */ *alibrary = library; @@ -2715,10 +2709,9 @@ index ea40396..7156a0b 100644 return FT_Err_Ok; #ifdef FT_CONFIG_OPTION_PIC -diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c -index 201ceab..4c8746d 100644 ---- a/src/base/ftoutln.c -+++ b/src/base/ftoutln.c +diff -ruN freetype-2.6.5-orig/src/base/ftoutln.c freetype-2.6.5/src/base/ftoutln.c +--- freetype-2.6.5-orig/src/base/ftoutln.c 2016-08-18 19:40:29.537037415 +0200 ++++ freetype-2.6.5/src/base/ftoutln.c 2016-08-18 19:40:37.905037195 +0200 @@ -29,7 +29,9 @@ #include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H @@ -2745,10 +2738,9 @@ index 201ceab..4c8746d 100644 if ( !outline ) return FT_THROW( Invalid_Outline ); -diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c -index cd68533..aa68c88 100644 ---- a/src/base/ftsynth.c -+++ b/src/base/ftsynth.c +diff -ruN freetype-2.6.5-orig/src/base/ftsynth.c freetype-2.6.5/src/base/ftsynth.c +--- freetype-2.6.5-orig/src/base/ftsynth.c 2016-08-18 19:40:29.519037416 +0200 ++++ freetype-2.6.5/src/base/ftsynth.c 2016-08-18 19:40:37.907037195 +0200 @@ -22,7 +22,9 @@ #include FT_INTERNAL_OBJECTS_H #include FT_OUTLINE_H @@ -2800,11 +2792,21 @@ index cd68533..aa68c88 100644 slot->metrics.horiAdvance += xstr; slot->metrics.vertAdvance += ystr; slot->metrics.horiBearingY += ystr; -diff --git a/src/base/rules.mk b/src/base/rules.mk -index 1852e08..f7ae0e6 100644 ---- a/src/base/rules.mk -+++ b/src/base/rules.mk -@@ -42,6 +42,7 @@ BASE_SRC := $(BASE_DIR)/basepic.c \ +diff -ruN freetype-2.6.5-orig/src/base/Jamfile freetype-2.6.5/src/base/Jamfile +--- freetype-2.6.5-orig/src/base/Jamfile 2016-08-18 19:40:29.499037416 +0200 ++++ freetype-2.6.5/src/base/Jamfile 2016-08-18 19:40:37.878037196 +0200 +@@ -56,6 +56,7 @@ + ftglyph + ftgxval + ftinit ++ ftinf + ftlcdfil + ftmm + ftotval +diff -ruN freetype-2.6.5-orig/src/base/rules.mk freetype-2.6.5/src/base/rules.mk +--- freetype-2.6.5-orig/src/base/rules.mk 2016-08-18 19:40:29.523037415 +0200 ++++ freetype-2.6.5/src/base/rules.mk 2016-08-18 19:40:37.908037195 +0200 +@@ -42,6 +42,7 @@ $(BASE_DIR)/ftdbgmem.c \ $(BASE_DIR)/ftgloadr.c \ $(BASE_DIR)/fthash.c \ @@ -2812,10 +2814,32 @@ index 1852e08..f7ae0e6 100644 $(BASE_DIR)/ftobjs.c \ $(BASE_DIR)/ftoutln.c \ $(BASE_DIR)/ftpic.c \ -diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c -index 3620550..b5b3056 100644 ---- a/src/smooth/ftsmooth.c -+++ b/src/smooth/ftsmooth.c +diff -ruN freetype-2.6.5-orig/src/cff/cffobjs.c freetype-2.6.5/src/cff/cffobjs.c +--- freetype-2.6.5-orig/src/cff/cffobjs.c 2016-08-18 19:40:29.458037417 +0200 ++++ freetype-2.6.5/src/cff/cffobjs.c 2016-08-18 19:40:37.959037194 +0200 +@@ -34,6 +34,9 @@ + + #include "cfferrs.h" + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "../base/ftinf.h" ++#endif + + /*************************************************************************/ + /* */ +@@ -1096,6 +1099,9 @@ + #endif + + driver->no_stem_darkening = TRUE; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if(ftinf) driver->no_stem_darkening = !ftinf->stem_darkening_cff; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + + driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; +diff -ruN freetype-2.6.5-orig/src/smooth/ftsmooth.c freetype-2.6.5/src/smooth/ftsmooth.c +--- freetype-2.6.5-orig/src/smooth/ftsmooth.c 2016-08-18 19:40:29.392037419 +0200 ++++ freetype-2.6.5/src/smooth/ftsmooth.c 2016-08-18 19:40:37.916037195 +0200 @@ -26,6 +26,18 @@ #include "ftsmerrs.h" @@ -2835,72 +2859,10 @@ index 3620550..b5b3056 100644 /* initialize renderer -- init its raster */ static FT_Error -@@ -34,65 +46,2278 @@ - FT_Library library = FT_MODULE_LIBRARY( render ); - +@@ -93,6 +105,2219 @@ + FT_Outline_Get_CBox( &slot->outline, cbox ); + } -- render->clazz->raster_class->raster_reset( render->raster, -- library->raster_pool, -- library->raster_pool_size ); -+ render->clazz->raster_class->raster_reset( render->raster, -+ library->raster_pool, -+ library->raster_pool_size ); -+ -+ return 0; -+ } -+ -+ -+ /* sets render-specific mode */ -+ static FT_Error -+ ft_smooth_set_mode( FT_Renderer render, -+ FT_ULong mode_tag, -+ FT_Pointer data ) -+ { -+ /* we simply pass it to the raster */ -+ return render->clazz->raster_class->raster_set_mode( render->raster, -+ mode_tag, -+ data ); -+ } -+ -+ /* transform a given glyph image */ -+ static FT_Error -+ ft_smooth_transform( FT_Renderer render, -+ FT_GlyphSlot slot, -+ const FT_Matrix* matrix, -+ const FT_Vector* delta ) -+ { -+ FT_Error error = FT_Err_Ok; -+ -+ -+ if ( slot->format != render->glyph_format ) -+ { -+ error = FT_THROW( Invalid_Argument ); -+ goto Exit; -+ } -+ -+ if ( matrix ) -+ FT_Outline_Transform( &slot->outline, matrix ); -+ -+ if ( delta ) -+ FT_Outline_Translate( &slot->outline, delta->x, delta->y ); -+ -+ Exit: -+ return error; -+ } -+ -+ -+ /* return the glyph's control box */ -+ static void -+ ft_smooth_get_cbox( FT_Renderer render, -+ FT_GlyphSlot slot, -+ FT_BBox* cbox ) -+ { -+ FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); -+ -+ if ( slot->format == render->glyph_format ) -+ FT_Outline_Get_CBox( &slot->outline, cbox ); -+ } -+ +#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET + static FT_Fixed FT_FixedFromFloat(float f) + { @@ -4572,45 +4534,23 @@ index 3620550..b5b3056 100644 + /* sort stems in x direction */ + if ( valid_stems > 1 && stems[0].center > stems[1].center ) + swap_stem ( &stems[0], &stems[1] ); - -- return 0; -- } ++ + if ( valid_stems == 0 && known_stem_values->stem_translating != 0 ) + { + *translate_value += known_stem_values->stem_translating; - ++ + if ( strategy_use_strengths ) + { + /* consider 1/2 pixel the max when strength is at 100%, + unless translate is already greater than that */ + FT_Int strength_cutoff = 32; - -- /* sets render-specific mode */ -- static FT_Error -- ft_smooth_set_mode( FT_Renderer render, -- FT_ULong mode_tag, -- FT_Pointer data ) -- { -- /* we simply pass it to the raster */ -- return render->clazz->raster_class->raster_set_mode( render->raster, -- mode_tag, -- data ); -- } - -- /* transform a given glyph image */ -- static FT_Error -- ft_smooth_transform( FT_Renderer render, -- FT_GlyphSlot slot, -- const FT_Matrix* matrix, -- const FT_Vector* delta ) -- { -- FT_Error error = FT_Err_Ok; ++ ++ + if ( abs ( *translate_value ) > strength_cutoff) + strength_cutoff = *translate_value; - ++ + max_strength = ( strength_cutoff * alignment_strength ) / 100; - -- if ( slot->format != render->glyph_format ) ++ + if ( *translate_value < -max_strength ) + *translate_value = -max_strength; + else if ( *translate_value > max_strength ) @@ -4619,8 +4559,7 @@ index 3620550..b5b3056 100644 + } + else + /* Start snapping */ - { -- error = FT_THROW( Invalid_Argument ); ++ { + FT_Int center_offset; + FT_Int modulus; + FT_Int delta, delta2; @@ -5058,19 +4997,13 @@ index 3620550..b5b3056 100644 + printf ( "TRANSLATING -64 " ); + } + } - goto Exit; - } - -- if ( matrix ) -- FT_Outline_Transform( &slot->outline, matrix ); ++ goto Exit; ++ } ++ + Exit: - -- if ( delta ) -- FT_Outline_Translate( &slot->outline, delta->x, delta->y ); ++ +#define transformed_point( point ) point * *scale_value + *translate_value * 12 - -- Exit: -- return error; ++ + if ( strategy_correct_out_of_bounds_outlines ) + { + /* Correct if outside bitmap */ @@ -5092,31 +5025,24 @@ index 3620550..b5b3056 100644 + free ( stem_centers ); + free ( stems ); + free ( leftmost_segment ); - } - - -- /* return the glyph's control box */ ++ } ++ ++ + /* Gamma correction */ - static void -- ft_smooth_get_cbox( FT_Renderer render, -- FT_GlyphSlot slot, -- FT_BBox* cbox ) ++ static void + _ft_lcd_gamma_correction_correction ( FT_Bitmap* bitmap, + FT_Render_Mode mode, + FT_GlyphSlot slot, + float gamma_correction_lt, + float gamma_correction_value ) - { -- FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); ++ { + if ( gamma_correction_value != 1.0 ) + { + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + FT_Byte* line = bitmap->buffer; + float ppem = (float)slot->face->size->metrics.x_ppem; - -- if ( slot->format == render->glyph_format ) -- FT_Outline_Get_CBox( &slot->outline, cbox ); ++ + + if ( !slot->face || !slot->face->size ) return; + @@ -5147,8 +5073,8 @@ index 3620550..b5b3056 100644 + } + } + } - } - ++ } ++ +#endif /* convert a slot's glyph image into a bitmap */ @@ -5209,7 +5135,7 @@ index 3620550..b5b3056 100644 + + FT_Int brightness_value = 0.0; + FT_Int contrast_value = 0.0; -+ + + FT_Int snapping_sliding_scale_value = 0; + + FT_Int global_embolden_x_value = 0; @@ -5268,7 +5194,7 @@ index 3620550..b5b3056 100644 + + brightness_value=ftinf->brightness; + contrast_value=ftinf->contrast; - ++ + windows_style_sharpening_strength=ftinf->windows_style_sharpening_strength; + + /* Decrease effect slightly to have a more linear increase in sharpness */ @@ -5772,11 +5698,10 @@ index 3620550..b5b3056 100644 if ( have_buffer ) { FT_FREE( bitmap->buffer ); -diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c -index 1c1d7de..bd37b44 100644 ---- a/src/truetype/ttinterp.c -+++ b/src/truetype/ttinterp.c -@@ -5610,6 +5610,7 @@ +diff -ruN freetype-2.6.5-orig/src/truetype/ttinterp.c freetype-2.6.5/src/truetype/ttinterp.c +--- freetype-2.6.5-orig/src/truetype/ttinterp.c 2016-08-18 19:40:29.650037412 +0200 ++++ freetype-2.6.5/src/truetype/ttinterp.c 2016-08-18 19:40:37.930037195 +0200 +@@ -5703,6 +5703,7 @@ if ( exc->ignore_x_mode && exc->GS.freeVector.x != 0 && @@ -5784,194 +5709,3 @@ index 1c1d7de..bd37b44 100644 !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; } -diff --git a/src/base/ftinf_rh.c b/src/base/ftinf_rh.c -index 4cd6f1a..606b567 100644 ---- a/src/base/ftinf_rh.c -+++ b/src/base/ftinf_rh.c -@@ -1,5 +1,5 @@ - /* ANSI-C code produced by gperf version 3.1 */ --/* Command-line: gperf ftinf_rh.gperf */ -+/* Command-line: gperf --output-file=ftinf_rh.c ftinf_rh.gperf */ - /* Computed positions: -k'1,$' */ - - #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ -@@ -612,13 +612,11 @@ ftinf_rules( const char *name ){ - char buf[max_wlen+1]; - int len=strlen( name ); - if( len <= max_wlen ){ -- const sa_rules_t *p; - int i; - for( i=0; iwarping = 0; - #endif - module->no_stem_darkening = TRUE; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if(ftinf) module->no_stem_darkening = !ftinf->stem_darkening_autofit; -+#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ - - module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; - module->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; -diff -urN freetype-2.6.2.orig/src/base/ftinf.c freetype-2.6.2/src/base/ftinf.c ---- a/src/base/ftinf.c 2015-12-07 12:42:05.976290812 +0000 -+++ b/src/base/ftinf.c 2015-12-08 09:55:29.149551250 +0000 -@@ -235,6 +235,10 @@ - if( s ) sscanf( s, "%d", &_env.stem_snapping_sliding_scale ); - s=getenv( "INFINALITY_FT_STEM_ALIGNMENT_STRENGTH" ); - if( s ) sscanf( s, "%d", &_env.stem_alignment_strength ); -+ s=getenv( "INFINALITY_FT_STEM_DARKENING_AUTOFIT" ); -+ if( s ) _env.stem_darkening_autofit=bool_val( s ); -+ s=getenv( "INFINALITY_FT_STEM_DARKENING_CFF" ); -+ if( s ) _env.stem_darkening_cff=bool_val( s ); - s=getenv( "INFINALITY_FT_STEM_FITTING_STRENGTH" ); - if( s ) sscanf( s, "%d", &_env.stem_fitting_strength ); - s=getenv( "INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH" ); -diff -urN freetype-2.6.2.orig/src/base/ftinf.h freetype-2.6.2/src/base/ftinf.h ---- a/src/base/ftinf.h 2015-12-07 12:42:05.976290812 +0000 -+++ b/src/base/ftinf.h 2015-12-08 09:53:54.557327499 +0000 -@@ -42,6 +42,8 @@ - int global_embolden_y_value; - int grayscale_filter_strength; - int stem_alignment_strength; -+ int stem_darkening_autofit; -+ int stem_darkening_cff; - int stem_fitting_strength; - int stem_snapping_sliding_scale; - int use_known_settings_on_selected_fonts; -diff -urN freetype-2.6.2.orig/src/cff/cffobjs.c freetype-2.6.2/src/cff/cffobjs.c ---- a/src/cff/cffobjs.c 2015-12-07 12:42:05.972957515 +0000 -+++ b/src/cff/cffobjs.c 2015-12-08 09:56:23.342283975 +0000 -@@ -34,6 +34,9 @@ - - #include "cfferrs.h" - -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+#include "../base/ftinf.h" -+#endif - - /*************************************************************************/ - /* */ -@@ -1053,6 +1056,9 @@ - #endif - - driver->no_stem_darkening = TRUE; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if(ftinf) driver->no_stem_darkening = !ftinf->stem_darkening_cff; -+#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ - - driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; - driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; - -diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c -index 742e767..6f444fa 100644 ---- a/src/autofit/aflatin.c -+++ b/src/autofit/aflatin.c -@@ -2418,12 +2418,15 @@ FT_Pos infinality_cur_width = 0; - abs( axis->widths[0].cur - infinality_dist ) < 32 && - axis->widths[0].cur > 52 ) - { -- if ( strstr( metrics->root.scaler.face->style_name, "Regular" ) || -- strstr( metrics->root.scaler.face->style_name, "Book" ) || -- strstr( metrics->root.scaler.face->style_name, "Medium" ) || -- strcmp( metrics->root.scaler.face->style_name, "Italic" ) == 0 || -- strcmp( metrics->root.scaler.face->style_name, "Oblique" ) == 0 ) -- { -+ const char *style_name=metrics->root.scaler.face->style_name; -+ if ( style_name!=NULL && -+ ( strstr( style_name, "Regular" ) || -+ strstr( style_name, "Book" ) || -+ strstr( style_name, "Medium" ) || -+ strcmp( style_name, "Italic" ) == 0 || -+ strcmp( style_name, "Oblique" ) == 0 ) -+ ) -+ { - /* regular weight */ - if ( axis->widths[0].cur < 64 ) - infinality_dist = 64; diff --git a/freetype-infinality-ultimate/03-infinality-2.7-2016.09.09.patch b/freetype-infinality-ultimate/03-infinality-2.7-2016.09.09.patch new file mode 100644 index 0000000..b55c523 --- /dev/null +++ b/freetype-infinality-ultimate/03-infinality-2.7-2016.09.09.patch @@ -0,0 +1,5702 @@ +diff -ruN freetype-2.7-orig/builds/freetype.mk freetype-2.7/builds/freetype.mk +--- freetype-2.7-orig/builds/freetype.mk 2016-02-03 19:13:58.000000000 +0100 ++++ freetype-2.7/builds/freetype.mk 2016-09-09 16:01:22.458500695 +0200 +@@ -161,6 +161,7 @@ + $(CFLAGS) \ + $DFT2_BUILD_LIBRARY \ + $DFT_CONFIG_MODULES_H="" \ ++ $D_GNU_SOURCE \ + $(FTOPTION_FLAG) + + +diff -ruN freetype-2.7-orig/configure freetype-2.7/configure +--- freetype-2.7-orig/configure 2016-02-03 19:13:58.000000000 +0100 ++++ freetype-2.7/configure 2016-09-09 16:01:22.461834056 +0200 +@@ -13,6 +13,8 @@ + # Call the `configure' script located in `builds/unix'. + # + ++export LDFLAGS="$LDFLAGS -lm" ++ + rm -f config.mk builds/unix/unix-def.mk builds/unix/unix-cc.mk + + # respect GNUMAKE environment variable for backwards compatibility +diff -ruN freetype-2.7-orig/devel/ftoption.h freetype-2.7/devel/ftoption.h +--- freetype-2.7-orig/devel/ftoption.h 2016-09-02 08:19:35.000000000 +0200 ++++ freetype-2.7/devel/ftoption.h 2016-09-09 16:01:22.461834056 +0200 +@@ -626,6 +626,16 @@ + /* */ + #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER + ++ /*************************************************************************/ ++ /* */ ++ /* Define FT_CONFIG_OPTION_INFINALITY_PATCHSET if you want to enable */ ++ /* all additional infinality patches, which are configured via env */ ++ /* variables. */ ++ /* */ ++ /* This option requires TT_CONFIG_OPTION_SUBPIXEL_HINTING to */ ++ /* defined. */ ++ /* */ ++#define FT_CONFIG_OPTION_INFINALITY_PATCHSET + + /*************************************************************************/ + /* */ +diff -ruN freetype-2.7-orig/include/freetype/config/ftoption.h freetype-2.7/include/freetype/config/ftoption.h +--- freetype-2.7-orig/include/freetype/config/ftoption.h 2016-09-02 07:47:15.000000000 +0200 ++++ freetype-2.7/include/freetype/config/ftoption.h 2016-09-09 18:35:36.626205358 +0200 +@@ -122,7 +122,7 @@ + /* This is done to allow FreeType clients to run unmodified, forcing */ + /* them to display normal gray-level anti-aliased glyphs. */ + /* */ +-/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ ++#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + + /*************************************************************************/ +@@ -675,8 +675,8 @@ + /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ + /* */ + /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ +-#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 +-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ ++#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 ++#define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) + + + /*************************************************************************/ +diff -ruN freetype-2.7-orig/src/autofit/aflatin.c freetype-2.7/src/autofit/aflatin.c +--- freetype-2.7-orig/src/autofit/aflatin.c 2016-08-26 11:45:36.000000000 +0200 ++++ freetype-2.7/src/autofit/aflatin.c 2016-09-09 16:01:22.465167416 +0200 +@@ -24,7 +24,10 @@ + #include "afpic.h" + #include "aflatin.h" + #include "aferrors.h" +- ++#include "strings.h" ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "../base/ftinf.h" ++#endif + + #ifdef AF_CONFIG_OPTION_USE_WARPER + #include "afwarp.h" +@@ -40,6 +43,10 @@ + #undef FT_COMPONENT + #define FT_COMPONENT trace_aflatin + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++FT_Pos infinality_cur_width = 0; ++#endif ++ + + /* needed for computation of round vs. flat segments */ + #define FLAT_THRESHOLD( x ) ( x / 14 ) +@@ -1028,7 +1035,10 @@ + FT_Pos delta; + AF_LatinAxis axis; + FT_UInt nn; +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ FT_Bool adjust_heights = FALSE; ++ if(ftinf) adjust_heights=ftinf->autohint_increase_glyph_heights; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + + if ( dim == AF_DIMENSION_HORZ ) + { +@@ -1056,7 +1066,7 @@ + { + AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT]; + AF_LatinBlue blue = NULL; +- ++ int threshold = 40; + + for ( nn = 0; nn < Axis->blue_count; nn++ ) + { +@@ -1066,7 +1076,12 @@ + break; + } + } +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( adjust_heights && ++ metrics->root.scaler.face->size->metrics.x_ppem < 15 && ++ metrics->root.scaler.face->size->metrics.x_ppem > 5 ) ++ threshold = 52; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + if ( blue ) + { + FT_Pos scaled; +@@ -1222,7 +1237,13 @@ + + /* a blue zone is only active if it is less than 3/4 pixels tall */ + dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); ++ ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ /* Do at low ppems ( ~< 200 ), in order to prevent fringes */ ++ if ( dist <= 256 && dist >= -256 ) ++#else + if ( dist <= 48 && dist >= -48 ) ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + { + #if 0 + FT_Pos delta1; +@@ -1273,7 +1294,12 @@ + delta2 = -delta2; + + blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ /* Round to prevent fringes */ ++ blue->shoot.fit = FT_PIX_ROUND( blue->ref.fit - delta2 ); ++#else + blue->shoot.fit = blue->ref.fit - delta2; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + + #endif + +@@ -2407,7 +2433,10 @@ + dist = edge->fpos - blue->shoot.org; + if ( dist < 0 ) + dist = -dist; +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ /* round down to pixels */ ++ /*dist = FT_MulFix( dist, scale ) & ~63;*/ ++#endif + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { +@@ -2583,8 +2612,17 @@ + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = ( dim == AF_DIMENSION_VERT ); ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ FT_Int infinality_dist = 0; ++ FT_UInt autohint_snap_stem_height = 0; ++ if( ftinf ) autohint_snap_stem_height=ftinf->autohint_snap_stem_height; ++ if ( autohint_snap_stem_height > 100 ) ++ autohint_snap_stem_height = 100; ++ else if ( autohint_snap_stem_height < 0 ) ++ autohint_snap_stem_height = 0; + +- ++ if ( autohint_snap_stem_height == 0 ) ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || + axis->extra_light ) + return width; +@@ -2594,9 +2632,76 @@ + dist = -width; + sign = 1; + } ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ /* Calculate snap value differently than standard freetype */ ++ if ( autohint_snap_stem_height > 0 && ++ ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || ++ ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) ) ++ { ++ infinality_dist = af_latin_snap_width( axis->widths, ++ axis->width_count, dist ); ++ ++ if ( metrics->root.scaler.face->size->metrics.x_ppem > 9 && ++ axis->width_count > 0 && ++ abs( axis->widths[0].cur - infinality_dist ) < 32 && ++ axis->widths[0].cur > 52 ) ++ { ++ const char *style_name=metrics->root.scaler.face->style_name; ++ if ( style_name!=NULL && ++ ( strstr( style_name, "Regular" ) || ++ strstr( style_name, "Book" ) || ++ strstr( style_name, "Medium" ) || ++ strcmp( style_name, "Italic" ) == 0 || ++ strcmp( style_name, "Oblique" ) == 0 ) ++ ) ++ { ++ /* regular weight */ ++ if ( axis->widths[0].cur < 64 ) ++ infinality_dist = 64; ++ else if ( axis->widths[0].cur < 88 ) ++ infinality_dist = 64; ++ else if ( axis->widths[0].cur < 160 ) ++ infinality_dist = 128; ++ else if ( axis->widths[0].cur < 240 ) ++ infinality_dist = 190; ++ else infinality_dist = ( infinality_dist ) & ~63; ++ } ++ else ++ { ++ /* bold gets a different threshold */ ++ if ( axis->widths[0].cur < 64 ) ++ infinality_dist = 64 ; ++ else if ( axis->widths[0].cur < 108 ) ++ infinality_dist = 64; ++ else if ( axis->widths[0].cur < 160 ) ++ infinality_dist = 128; ++ else if ( axis->widths[0].cur < 222 ) ++ infinality_dist = 190; ++ else if ( axis->widths[0].cur < 288 ) ++ infinality_dist = 254; ++ else infinality_dist = ( infinality_dist + 16 ) & ~63; ++ } + +- if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || ++ } ++ if ( infinality_dist < 52 ) ++ { ++ if ( metrics->root.scaler.face->size->metrics.x_ppem < 9 ) ++ { ++ if ( infinality_dist < 32 ) ++ infinality_dist = 32; ++ } ++ else ++ infinality_dist = 64; ++ } ++ } ++ else if ( autohint_snap_stem_height < 100 && ++ ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || ++ ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) ) ++#else ++ ++ if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + { + /* smooth hinting process: very lightly quantize the stem width */ + +@@ -2688,6 +2793,9 @@ + } + } + else ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( autohint_snap_stem_height < 100 ) ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + { + /* strong hinting process: snap the stem width to integer pixels */ + +@@ -2695,7 +2803,10 @@ + + + dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( autohint_snap_stem_height > 0 ) ++ goto Done_Width; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + if ( vertical ) + { + /* in the case of vertical hinting, always round */ +@@ -2758,6 +2869,32 @@ + } + + Done_Width: ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( axis->widths[0].cur > 42 ) ++ /* weighted average */ ++ dist = (dist * ( 100 - autohint_snap_stem_height ) ++ + infinality_dist * autohint_snap_stem_height ) / 100; ++ ++ { ++ int factor = 100; ++ if ( axis->standard_width < 100 ) ++ factor = axis->standard_width; ++ ++ if ( metrics->root.scaler.face->size->metrics.x_ppem >= 9 && dist < 52 ) ++ dist += ( (52 - dist) * factor ) / 100; ++ if ( metrics->root.scaler.face->size->metrics.x_ppem < 9 && dist < 32 ) ++ dist += ( (32 - dist) * factor ) / 100; ++ ++ if ( axis->standard_width > 100 && ++ metrics->root.scaler.face->size->metrics.x_ppem >= 11 && ++ dist < 64 ) ++ dist = 64; ++ if ( axis->standard_width > 100 && ++ metrics->root.scaler.face->size->metrics.x_ppem >= 9 && ++ dist < 52 ) ++ dist = 52; ++ } ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + if ( sign ) + dist = -dist; + +@@ -2776,6 +2913,8 @@ + FT_Pos dist, base_delta; + FT_Pos fitted_width; + ++/* if fitted_width causes stem_edge->pos to land basically on top of an existing ++ * stem_edge->pos, then add or remove 64. Need to figure out a way to do this */ + + dist = stem_edge->opos - base_edge->opos; + base_delta = base_edge->pos - base_edge->opos; +@@ -3384,8 +3523,11 @@ + int dim; + + AF_LatinAxis axis; +- +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ FT_Int emboldening_strength = 0; ++ FT_Bool use_various_tweaks = FALSE; ++ if( ftinf ) use_various_tweaks=ftinf->use_various_tweaks; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + error = af_glyph_hints_reload( hints, outline ); + if ( error ) + goto Exit; +@@ -3455,7 +3597,11 @@ + } + + af_glyph_hints_save( hints, outline ); +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ { ++ infinality_cur_width = metrics->axis->widths[0].cur; ++ } ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + Exit: + return error; + } +diff -ruN freetype-2.7-orig/src/autofit/aflatin.h freetype-2.7/src/autofit/aflatin.h +--- freetype-2.7-orig/src/autofit/aflatin.h 2016-03-15 07:53:53.000000000 +0100 ++++ freetype-2.7/src/autofit/aflatin.h 2016-09-09 16:01:22.465167416 +0200 +@@ -64,6 +64,9 @@ + + #define AF_LATIN_MAX_WIDTHS 16 + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ extern FT_Pos infinality_cur_width; ++#endif + + #define AF_LATIN_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */ + #define AF_LATIN_BLUE_TOP ( 1U << 1 ) /* we have a top blue zone */ +diff -ruN freetype-2.7-orig/src/autofit/afmodule.c freetype-2.7/src/autofit/afmodule.c +--- freetype-2.7-orig/src/autofit/afmodule.c 2016-08-26 11:45:36.000000000 +0200 ++++ freetype-2.7/src/autofit/afmodule.c 2016-09-09 16:01:22.465167416 +0200 +@@ -22,6 +22,10 @@ + #include "aferrors.h" + #include "afpic.h" + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "../base/ftinf.h" ++#endif ++ + #ifdef FT_DEBUG_AUTOFIT + + #ifndef FT_MAKE_OPTION_SINGLE_OBJECT +@@ -464,6 +468,9 @@ + module->warping = 0; + #endif + module->no_stem_darkening = TRUE; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if(ftinf) module->no_stem_darkening = !ftinf->stem_darkening_autofit; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + + module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + module->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; +diff -ruN freetype-2.7-orig/src/base/ftbase.c freetype-2.7/src/base/ftbase.c +--- freetype-2.7-orig/src/base/ftbase.c 2016-02-03 19:13:58.000000000 +0100 ++++ freetype-2.7/src/base/ftbase.c 2016-09-09 16:01:22.465167416 +0200 +@@ -34,6 +34,9 @@ + #include "ftstream.c" + #include "fttrigon.c" + #include "ftutil.c" ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "ftinf.c" ++#endif + + #ifdef FT_MACINTOSH + #include "ftmac.c" +diff -ruN freetype-2.7-orig/src/base/ftinf.c freetype-2.7/src/base/ftinf.c +--- freetype-2.7-orig/src/base/ftinf.c 1970-01-01 01:00:00.000000000 +0100 ++++ freetype-2.7/src/base/ftinf.c 2016-09-09 16:01:22.465167416 +0200 +@@ -0,0 +1,363 @@ ++#include ++#include "ftinf.h" ++#define true 1 ++#define false 0 ++ ++#define on 1 ++#define off 0 ++#define end (-128) ++ ++#define sw2pv 18 /* STEM_WIDTH_2_PPEM */ ++#define maxp 100 /* MAX_PPEM */ ++ ++typedef signed char pv; /* ppm and values type */ ++/* the arrays start with existence flag + values */ ++typedef struct sa_rules_s { ++ const char *name; ++ pv always_use_100[1+4+1]; ++ pv brightness[1+2+1]; ++ pv contrast[1+2+1]; ++ pv edge_detection[1+4+1]; ++ pv m[1+4+1]; ++ pv bearing_correction[1+2+1]; ++ pv spacing[1+5+1]; ++ pv start[1+5+1]; ++ pv stem_scaling[1+6+1]; ++ pv stem_translating[1+2+1]; ++ pv stem_translating_only[1+10+1]; ++ pv stem_widths[1+4]; /* these end with maxp */ ++ pv synthesize_stems[1+2+1]; ++} sa_rules_t; ++ ++#pragma GCC diagnostic ignored "-Wpedantic" /* C99 struct initializer tags are needed */ ++#pragma GCC diagnostic ignored "-Wunused-function" ++ ++const ftinf_t *ftinf; ++/* final settings, updated from environment */ ++ftinf_t _env; ++ ++/* rules and hashing function */ ++#include "ftinf_rh.c" ++ ++/* rules selection */ ++void ftinf_fill_stem_values( Stem_Data *stem_values, ++ const char *family, int ppem, int use_known ){ ++ /* set the defaults */ ++ stem_values->bearing_correction = TRUE; ++ stem_values->brightness = 0.0; ++ stem_values->contrast = 0.0; ++ stem_values->edge_detection = FALSE; ++ stem_values->m = -1; ++ stem_values->stem_scaling = -1; ++ stem_values->stem_spacing = -1; ++ stem_values->stem_start = -1; ++ stem_values->stem_translating = 0; ++ stem_values->stem_translating_only = -1024; ++ stem_values->stem_width = -1; ++ stem_values->synth_stems = FALSE; ++ stem_values->use_100 = FALSE; ++ /* pick from known rules if requested and they exist for current family */ ++ if( !use_known ) ++ return; ++ else { ++ const sa_rules_t *r=ftinf_rules( family ); ++ int i; ++ if( r==NULL ) return; ++ if( r->stem_widths[0]==on ) ++ for( i=1; r->stem_widths[i]!=maxp; ++i ) ++ if( ppem < r->stem_widths[i] ){ ++ stem_values->stem_width = i-1; ++ break; ++ } ++ ++ if( r->stem_scaling[0]==on ) ++ for( i=1; r->stem_scaling[i]!=end; i+=2 ) ++ if( ppem==r->stem_scaling[i] ){ ++ stem_values->stem_scaling = r->stem_scaling[i+1]; ++ break; ++ } ++ ++ if( r->m[0]==on ) ++ for( i=1; r->m[i]!=end; i+=2 ) ++ if( ppem==r->m[i] ){ ++ stem_values->m = r->m[i+1]; ++ break; ++ } ++ ++ if( r->stem_translating_only[0]==on ) ++ for( i=1; r->stem_translating_only[i]!=end; i+=2 ) ++ if( ppem==r->stem_translating_only[i] || r->stem_translating_only[i]==0 ){ ++ stem_values->stem_translating_only = r->stem_translating_only[i+1]; ++ break; ++ } ++ ++ if( r->stem_translating[0]==on ) ++ for( i=1; r->stem_translating[i]!=end; i+=2 ) ++ if( ppem==r->stem_translating[i] || r->stem_translating[i]==0 ){ ++ stem_values->stem_translating = r->stem_translating[i+1]; ++ break; ++ } ++ ++ if( r->always_use_100[0]==on ) ++ for( i=1; r->always_use_100[i]!=end; i+=2 ) ++ if( ppem>=r->always_use_100[i] && ppem<=r->always_use_100[i+1] ){ ++ stem_values->use_100 = TRUE; ++ break; ++ } ++ ++ if( r->synthesize_stems[0]==on ) ++ for( i=1; r->synthesize_stems[i]!=end; i+=2 ) ++ if( ppem>=r->synthesize_stems[i] && ppem<=r->synthesize_stems[i+1] ){ ++ stem_values->synth_stems = TRUE; ++ break; ++ } ++ ++ if( r->edge_detection[0]==on ) ++ for( i=1; r->edge_detection[i]!=end; i+=2 ) ++ if( ppem>=r->edge_detection[i] && ppem<=r->edge_detection[i+1] ){ ++ stem_values->edge_detection = TRUE; ++ break; ++ } ++ ++ if( r->bearing_correction[0]==on ) ++ for( i=1; r->bearing_correction[i]!=end; i+=2 ) ++ if( ppem>=r->bearing_correction[i] && ppem<=r->bearing_correction[i+1] ){ ++ stem_values->bearing_correction = FALSE; ++ break; ++ } ++ ++#if(0) ++ if( r->brightness[0]==on ) ++ for( i=1; r->brightness[i]!=end; i+=2 ) ++ if( ppem==r->brightness[i]||r->brightness[i]==0 ){ ++ stem_values->brightness=r->brightness[i+1]*(1.0f/300.0f); ++ break; ++ } ++ ++ if( r->contrast[0]==on ) ++ for( i=1; r->contrast[i]!=end; i+=2 ) ++ if( ppem==r->contrast[i]||r->contrast[i]==0 ){ ++ stem_values->contrast=r->contrast[i+1]*(1.0f/300.0f); ++ break; ++ } ++ if( r->spacing[0]==on ){ ++ /* not used by original code */ ++ } ++ if( r->start[0]==on ){ ++ /* not used by original code */ ++ } ++#endif ++ } ++ return; ++} ++ ++void ftinf_get_bc( const char *family, int ppem, float *brightness, float *contrast ){ ++ const sa_rules_t *r=ftinf_rules( family ); ++ *brightness=0; ++ *contrast=0; ++ if( r ){ ++ int i; ++ if( r->brightness[0]==on ) ++ for( i=1; r->brightness[i]!=end; i+=2 ) ++ if( ppem==r->brightness[i]||r->brightness[i]==0 ){ ++ *brightness=r->brightness[i+1]*(1.0f/300.0f); ++ break; ++ } ++ ++ if( r->contrast[0]==on ) ++ for( i=1; r->contrast[i]!=end; i+=2 ) ++ if( ppem==r->contrast[i]||r->contrast[i]==0 ){ ++ *contrast=r->contrast[i+1]*(1.0f/300.0f); ++ break; ++ } ++ } ++ return; ++} ++ ++static int ++bool_val( const char *s ){ ++ if ( s != NULL ) ++ return strcasecmp(s, "true") == 0 ++ || strcasecmp(s, "1") == 0 ++ || strcasecmp(s, "on") == 0 ++ || strcasecmp(s, "yes") ==0; ++ else ++ return 0; ++} ++ ++static int ++int_val( const char *s, int min, int max ){ ++ int val; ++ sscanf ( s, "%d", &val ); ++ if ( val > max ) ++ val = max; ++ else if ( val < min ) ++ val = min; ++ return val; ++} ++ ++/* settings and hashing function */ ++#include "ftinf_sh.c" ++ ++/* ++ Get active Infinality settings ++ */ ++void ftinf_env(){ ++ const char *s; ++ ftinf=ftinf_settings( getenv( "INFINALITY_FT" ) ); ++ ++ if( ftinf==NULL ){ ++ ftinf=ftinf_settings( "ultimate3" ); ++ /* this should always succeed */ ++#if(0) ++ if( ftinf==NULL ){ ++ /* put an error here */ ++ exit(-1); ++ } ++#endif ++ } ++ _env=ftinf[0]; /* copy as defaults */ ++ ++ /* check if custom environment values are set and update with them */ ++ s=getenv( "INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS" ); ++ if( s ) _env.autohint_increase_glyph_heights=bool_val( s ); ++ s=getenv( "INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT" ); ++ if( s ) _env.autohint_snap_stem_height=int_val( s, 0, 100 ); ++ s=getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); ++ if( s ) _env.use_various_tweaks=bool_val( s ); ++ s=getenv( "INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS" ); ++ if( s ) _env.use_known_settings_on_selected_fonts=bool_val(s); ++#if(0) /* not used (naming error also) */ ++ s=getenv( "INFINALITY_FT_AUTOHINT_MINIMUM_STEM_WIDTH" ); ++ if( s ) _env.autohint_minimum_stem_height=int_val( s, 0, 100 ); ++#endif ++ s=getenv( "INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE" ); ++ if( s ) sscanf( s, "%d", &_env.stem_snapping_sliding_scale ); ++ s=getenv( "INFINALITY_FT_STEM_ALIGNMENT_STRENGTH" ); ++ if( s ) sscanf( s, "%d", &_env.stem_alignment_strength ); ++ s=getenv( "INFINALITY_FT_STEM_DARKENING_AUTOFIT" ); ++ if( s ) _env.stem_darkening_autofit=bool_val( s ); ++ s=getenv( "INFINALITY_FT_STEM_DARKENING_CFF" ); ++ if( s ) _env.stem_darkening_cff=bool_val( s ); ++ s=getenv( "INFINALITY_FT_STEM_FITTING_STRENGTH" ); ++ if( s ) sscanf( s, "%d", &_env.stem_fitting_strength ); ++ s=getenv( "INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH" ); ++ if( s ) _env.chromeos_style_sharpening_strength=int_val( s, 0, 100 ); ++ s=getenv( "INFINALITY_FT_BRIGHTNESS" ); ++ if( s ) sscanf( s, "%d", &_env.brightness ); ++ s=getenv( "INFINALITY_FT_CONTRAST" ); ++ if( s ) sscanf( s, "%d", &_env.contrast ); ++ s=getenv( "INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH" ); ++ if( s ) _env.windows_style_sharpening_strength=int_val( s, 0, 100 ); ++ s=getenv( "INFINALITY_FT_GAMMA_CORRECTION" ); ++ if( s ){ ++ float *f=_env.gamma_correction; ++ sscanf ( s, "%f %f", &f[0], &f[1] ); ++ if( f[1] < 1.0f ) f[1]=1.0f; ++ } ++ s=getenv( "INFINALITY_FT_FRINGE_FILTER_STRENGTH" ); ++ if( s ) sscanf( s, "%d", &_env.fringe_filter_strength ); ++ s=getenv( "INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH" ); ++ if( s ) sscanf( s, "%d", &_env.grayscale_filter_strength ); ++ s=getenv( "INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH" ); ++ if( s ) sscanf( s, "%d", &_env.autohint_horizontal_stem_darken_strength ); ++ s=getenv( "INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH" ); ++ if( s ) sscanf( s, "%d", &_env.autohint_vertical_stem_darken_strength ); ++ s=getenv( "INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE" ); ++ if( s ) sscanf( s, "%d", &_env.global_embolden_x_value ); ++ s=getenv( "INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE" ); ++ if( s ) sscanf( s, "%d", &_env.global_embolden_y_value ); ++ s=getenv( "INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE" ); ++ if( s ) sscanf( s, "%d", &_env.bold_embolden_x_value ); ++ s=getenv( "INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE" ); ++ if( s ) sscanf( s, "%d", &_env.bold_embolden_y_value ); ++ s=getenv( "INFINALITY_FT_FILTER_PARAMS" ); ++ if( s ) { ++ int *f=_env.filter_params; ++ if( sscanf( s, "%d %d %d %d %d", f+1, f+2, f+3, f+4, f+5 )==5 ) ++ f[0]=on; ++ else ++ f[0]=off; /* FIXME: put a warning? */ ++ } ++ /* do the range verifications as in original code */ ++ if ( _env.stem_snapping_sliding_scale > maxp ) ++ _env.stem_snapping_sliding_scale = 0; ++ else if ( _env.stem_snapping_sliding_scale < 0 ) ++ _env.stem_snapping_sliding_scale = 0; ++ if (_env.stem_snapping_sliding_scale < 11 && ++ _env.stem_snapping_sliding_scale > 0 ) ++ _env.stem_snapping_sliding_scale = 11; ++ ++ if ( _env.stem_alignment_strength > 100 ) ++ _env.stem_alignment_strength = 100; ++ else if ( _env.stem_alignment_strength < 0 ) ++ _env.stem_alignment_strength = 0; ++ ++ if ( _env.stem_fitting_strength > 100 ) ++ _env.stem_fitting_strength = 100; ++ else if ( _env.stem_fitting_strength < 0 ) ++ _env.stem_fitting_strength = 0; ++ ++ if ( _env.chromeos_style_sharpening_strength > 100 ) ++ _env.chromeos_style_sharpening_strength = 100; ++ else if ( _env.chromeos_style_sharpening_strength < 0 ) ++ _env.chromeos_style_sharpening_strength = 0; ++ ++ if ( _env.brightness > 100 ) ++ _env.brightness = 100; ++ else if ( _env.brightness < -100 ) ++ _env.brightness = 0; ++ ++ if ( _env.contrast > 100 ) ++ _env.contrast = 100; ++ else if ( _env.contrast < -100 ) ++ _env.contrast = 0; ++ ++ if ( _env.windows_style_sharpening_strength > 100 ) ++ _env.windows_style_sharpening_strength = 100; ++ else if ( _env.windows_style_sharpening_strength < 0 ) ++ _env.windows_style_sharpening_strength = 0; ++ ++ if ( _env.fringe_filter_strength > 100 ) ++ _env.fringe_filter_strength = 100; ++ else if ( _env.fringe_filter_strength < 0 ) ++ _env.fringe_filter_strength = 0; ++ ++ if ( _env.grayscale_filter_strength > 100 ) ++ _env.grayscale_filter_strength = 100; ++ else if ( _env.grayscale_filter_strength < 0 ) ++ _env.grayscale_filter_strength = 0; ++ ++ if ( _env.autohint_horizontal_stem_darken_strength > 100 ) ++ _env.autohint_horizontal_stem_darken_strength = 100; ++ else if ( _env.autohint_horizontal_stem_darken_strength < 0 ) ++ _env.autohint_horizontal_stem_darken_strength = 0; ++ ++ if ( _env.autohint_vertical_stem_darken_strength > 100 ) ++ _env.autohint_vertical_stem_darken_strength = 100; ++ else if ( _env.autohint_horizontal_stem_darken_strength < 0 ) ++ _env.autohint_vertical_stem_darken_strength = 0; ++ ++ if ( _env.global_embolden_x_value > 128 ) ++ _env.global_embolden_x_value = 128; ++ else if ( _env.global_embolden_x_value < -128 ) ++ _env.global_embolden_x_value = -128; ++ ++ if ( _env.global_embolden_y_value > 128 ) ++ _env.global_embolden_y_value = 128; ++ else if ( _env.global_embolden_y_value < -128 ) ++ _env.global_embolden_y_value = -128; ++ ++ if ( _env.bold_embolden_x_value > 128 ) ++ _env.bold_embolden_x_value = 128; ++ else if (_env.bold_embolden_x_value < -128 ) ++ _env.bold_embolden_x_value = -128; ++ ++ if ( _env.bold_embolden_y_value > 128 ) ++ _env.bold_embolden_y_value = 128; ++ else if ( _env.bold_embolden_y_value < -128 ) ++ _env.bold_embolden_y_value = -128; ++ ++ /* point to the combined and checked settings */ ++ ftinf=&_env; ++} +diff -ruN freetype-2.7-orig/src/base/ftinf.h freetype-2.7/src/base/ftinf.h +--- freetype-2.7-orig/src/base/ftinf.h 1970-01-01 01:00:00.000000000 +0100 ++++ freetype-2.7/src/base/ftinf.h 2016-09-09 16:01:22.465167416 +0200 +@@ -0,0 +1,66 @@ ++#ifndef _FTINF_H_ ++#define _FTINF_H_ ++/* ++ Stem snapping rules ++ (base freetype typedefs assumed already included) ++ */ ++typedef struct ++{ ++ FT_Int stem_width; ++ FT_Int stem_spacing; ++ FT_Int stem_start; ++ FT_Int stem_scaling; ++ FT_Int stem_translating_only; ++ FT_Int stem_translating; ++ float brightness; ++ float contrast; ++ FT_Bool use_100; ++ FT_Bool synth_stems; ++ FT_Bool edge_detection; ++ FT_Bool bearing_correction; ++ FT_Int m; ++} Stem_Data; ++ ++/* ++ Infinality settings ++ */ ++typedef struct ftinf_s { ++ const char *name; ++ int autohint_horizontal_stem_darken_strength; ++ int autohint_snap_stem_height; ++ int autohint_increase_glyph_heights; ++ int autohint_vertical_stem_darken_strength; ++ int bold_embolden_x_value; ++ int bold_embolden_y_value; ++ int brightness; ++ int chromeos_style_sharpening_strength; ++ int contrast; ++ int filter_params[6]; /* 1st one used as existence flag */ ++ int fringe_filter_strength; ++ float gamma_correction[2]; ++ int global_embolden_x_value; ++ int global_embolden_y_value; ++ int grayscale_filter_strength; ++ int stem_alignment_strength; ++ int stem_darkening_autofit; ++ int stem_darkening_cff; ++ int stem_fitting_strength; ++ int stem_snapping_sliding_scale; ++ int use_known_settings_on_selected_fonts; ++ int use_various_tweaks; ++ int windows_style_sharpening_strength; ++} ftinf_t; ++ ++extern FT_Pos infinality_cur_width; /* defined in aflatin.c */ ++ ++extern const ftinf_t *ftinf; /* active settings */ ++ ++extern void ftinf_fill_stem_values( Stem_Data *stem_values, ++ const char *family, int ppem, int use_known ); ++extern void ftinf_get_bc( const char *family, int ppem, ++ float *brightness, float *contrast ); ++ ++/* get values from environment (FIXME: maybe update with using user files) */ ++extern void ftinf_env(); ++ ++#endif +diff -ruN freetype-2.7-orig/src/base/ftinf_rh.c freetype-2.7/src/base/ftinf_rh.c +--- freetype-2.7-orig/src/base/ftinf_rh.c 1970-01-01 01:00:00.000000000 +0100 ++++ freetype-2.7/src/base/ftinf_rh.c 2016-09-09 16:01:22.465167416 +0200 +@@ -0,0 +1,626 @@ ++/* ANSI-C code produced by gperf version 3.1 */ ++/* Command-line: gperf --output-file=ftinf_rh.c ftinf_rh.gperf */ ++/* Computed positions: -k'1,$' */ ++ ++#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ ++ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ ++ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ ++ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ ++ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ ++ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ ++ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ ++ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ ++ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ ++ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ ++ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ ++ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ ++ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ ++ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ ++ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ ++ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ ++ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ ++ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ ++ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ ++ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ ++ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ ++ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ ++ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) ++/* The character set is not based on ISO-646. */ ++#error "gperf generated tables don't work with this execution character set. Please report a bug to ." ++#endif ++ ++#line 9 "ftinf_rh.gperf" ++ ++#include ++static const struct sa_rules_s* _rules_get( const char*str, unsigned len ); ++/* maximum key range = 82, duplicates = 0 */ ++ ++#ifdef __GNUC__ ++__inline ++#else ++#ifdef __cplusplus ++inline ++#endif ++#endif ++static unsigned int ++_rules_hash (register const char *str, register unsigned int len) ++{ ++ static const unsigned char asso_values[] = ++ { ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 0, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 5, 45, 5, ++ 35, 25, 35, 35, 50, 45, 85, 85, 0, 25, ++ 40, 5, 0, 85, 50, 20, 20, 0, 10, 10, ++ 85, 10, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, ++ 85, 85, 85, 85, 85, 85 ++ }; ++ return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]]; ++} ++ ++#ifdef __GNUC__ ++__inline ++#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ ++__attribute__ ((__gnu_inline__)) ++#endif ++#endif ++const struct sa_rules_s * ++_rules_get (register const char *str, register unsigned int len) ++{ ++ enum ++ { ++ TOTAL_KEYWORDS = 58, ++ MIN_WORD_LENGTH = 3, ++ MAX_WORD_LENGTH = 24, ++ MIN_HASH_VALUE = 3, ++ MAX_HASH_VALUE = 84 ++ }; ++ ++ static const struct sa_rules_s wordlist[] = ++ { ++#line 15 "ftinf_rh.gperf" ++{ .name="---", ++ .synthesize_stems={on, 13, 13, end} ++}, ++#line 253 "ftinf_rh.gperf" ++{ .name="ubuntu", ++ .always_use_100={on, 12, 13, 15, 15, end} ++}, ++#line 31 "ftinf_rh.gperf" ++{ .name="arial", ++ .always_use_100={on, 0, maxp, end}, ++ .edge_detection={on, 11, 11, 13, 13, end}, ++ .spacing={on, 10, 11, 23, 25, 30, end}, ++ .start={on, 11, 18, 23, 30, 30, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 16, 8, 32, 9, 32, 16, -24, end} ++}, ++#line 87 "ftinf_rh.gperf" ++{ .name="corbel", ++ .stem_translating_only={on, 10, 16, end}, ++ .stem_widths={on, 10, 21, maxp} ++}, ++#line 71 "ftinf_rh.gperf" ++{ .name="canwell", ++ .stem_scaling={on, 13, 0, end} ++}, ++#line 216 "ftinf_rh.gperf" ++{ .name="pragmata", ++ .always_use_100={on, 0, maxp, end} ++}, ++#line 67 "ftinf_rh.gperf" ++{ .name="cantarell", ++ .stem_translating_only={on, 11, 0, 12, 0, end}, ++ .stem_widths={on, 10, 22, maxp,} ++}, ++#line 39 "ftinf_rh.gperf" ++{ .name="arimo", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 8, 8, 32, 9, 32, end} ++}, ++#line 207 "ftinf_rh.gperf" ++{ .name="optima", ++ .brightness={on, 0, -20, end}, ++ .contrast={on, 0, 25, end}, ++ .stem_scaling={on, 17, 1, end}, ++ .stem_translating_only={on, 10, 0, 11, 0, 12, 0, end} ++}, ++#line 63 "ftinf_rh.gperf" ++{ .name="candara", ++ .stem_scaling={on, 14, 1, 17, 1, end}, ++ .stem_translating_only={on, 10, 16, end} ++}, ++#line 77 "ftinf_rh.gperf" ++{ .name="comfortaa", ++ .stem_widths={on, 10, 19, 22, maxp}, ++ .stem_scaling={on, 11, 0, end} ++}, ++#line 161 "ftinf_rh.gperf" ++{ .name="liberation mono", ++ .always_use_100={on, 0, maxp, end} ++}, ++#line 18 "ftinf_rh.gperf" ++{ .name="andale mono", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_scaling={on, 11, 1, end}, ++ .stem_widths={on, 10, 21, maxp,} ++}, ++#line 256 "ftinf_rh.gperf" ++{ .name="verdana", ++ .always_use_100={on, 0, 14, 16, maxp, end}, ++ .stem_scaling={on, 12, 1, 15, 1, end}, ++ .stem_translating_only={on, 8, 16, 15, 16, 14, 32, 18, 32, 19, 24, end} ++}, ++#line 74 "ftinf_rh.gperf" ++{ .name="century gothic", ++ .stem_widths={on, 10, 22, maxp,} ++}, ++#line 91 "ftinf_rh.gperf" ++{ .name="courier new", ++ .always_use_100={on, 12, 12, end}, ++ .edge_detection={on, 10, 12, end}, ++ .m={on, 13, 1, 14, 1, end} ++}, ++#line 23 "ftinf_rh.gperf" ++{ .name="arial narrow", ++ .stem_widths={on, 10, 21, maxp,} ++}, ++#line 185 "ftinf_rh.gperf" ++{ .name="luxi sans", ++ .always_use_100={on, 13, 13, end}, ++ .stem_widths={on, 10, 17, sw2pv, maxp,} ++}, ++#line 225 "ftinf_rh.gperf" ++{ .name="samba", ++ .stem_scaling={on, 11, 0, end} ++}, ++#line 233 "ftinf_rh.gperf" ++{ .name="tahoma", ++ .always_use_100={on, 11, 11, 14, maxp, end}, ++ .edge_detection={on, 11, 11, end}, ++ .spacing={on, 10, 12, 18, 18, 30, end}, ++ .start={on, 14, 17, 30, 100, 100, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 7, 32, 8, 32, 9, 32, end}, ++}, ++#line 164 "ftinf_rh.gperf" ++{ .name="liberation sans narrow", ++ .stem_widths={on,10, 22, maxp,} ++}, ++#line 81 "ftinf_rh.gperf" ++{ .name="consolas", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating_only={on, 8, 32, 9, 32, end}, ++ .stem_widths={on, 10, 20, maxp,}, ++ .stem_scaling={on, 11, 1, end} ++}, ++#line 203 "ftinf_rh.gperf" ++{ .name="open sans", ++ .stem_translating_only={on, 10, 16, 9, 16, end}, ++ .stem_widths={on, 10, 20, maxp,} ++}, ++#line 167 "ftinf_rh.gperf" ++{ .name="liberation sans", ++ .edge_detection={on, 11, 11, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 8, 8, 32, 9, 32, end}, ++ .stem_widths={on,10, 19, maxp,} ++}, ++#line 193 "ftinf_rh.gperf" ++{ .name="monaco", ++ .always_use_100={on, 0, maxp, end} ++}, ++#line 101 "ftinf_rh.gperf" ++{ .name="cousine", ++ .always_use_100={on, 0, maxp, end} ++}, ++#line 176 "ftinf_rh.gperf" ++{ .name="lucida grande", ++ .stem_scaling={on, 13, 1, end}, ++ .stem_translating_only={on, 13, 24, 14, 24, 8, 16, 9, 16, end}, ++ .stem_widths={on, 10, 16, sw2pv, maxp}, ++}, ++#line 173 "ftinf_rh.gperf" ++{ .name="lucida console", ++ .always_use_100={on, 0, maxp, end} ++}, ++#line 196 "ftinf_rh.gperf" ++{ .name="myriad pro", ++ .stem_scaling={on, 14, 1, 17, 1, end}, ++ .stem_translating_only={on, 10, 16, 11, 0, 9, 16, end} ++}, ++#line 26 "ftinf_rh.gperf" ++{ .name="arial unicode ms", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 16, 8, 32, 9, 32, end} ++}, ++#line 213 "ftinf_rh.gperf" ++{ .name="palatino linotype", ++ .edge_detection={on, 0, 100, end} ++}, ++#line 181 "ftinf_rh.gperf" ++{ .name="lucida sans unicode", ++ .stem_translating_only={on, 13, 24, 14, 24, 8, 16, 9, 16, end}, ++ .stem_widths={on,10, 16, sw2pv, maxp,} ++}, ++#line 140 "ftinf_rh.gperf" ++{ .name="futura", ++ .stem_widths={on, 10, 14, sw2pv, maxp,} ++}, ++#line 147 "ftinf_rh.gperf" ++{ .name="georgia", ++ .stem_translating_only={on, 13, 16, 14, 16, 15, 0, end} ++}, ++#line 125 "ftinf_rh.gperf" ++{ .name="freemono", ++ .always_use_100={on, 0, maxp, end} ++}, ++#line 200 "ftinf_rh.gperf" ++{ .name="nina", ++ .stem_scaling={on, 11, 0, 12, 0, 13, 0, end} ++}, ++#line 121 "ftinf_rh.gperf" ++{ .name="essential pragmatapro", ++ .always_use_100={on, 0, maxp, end}, ++ .m={on, 13, 0, 14, 0, end} ++}, ++#line 247 "ftinf_rh.gperf" ++{ .name="trebuchet ms", ++ .always_use_100={on, 13, 13, end}, ++ .stem_scaling={on, 13, 0, 17, 0, 20, 1, end}, ++ .stem_translating_only={on, 10, 16, 11, 0, 8, 32, 9, 32, end}, ++ .stem_widths={on, 10, 17, sw2pv, maxp,} ++}, ++#line 114 "ftinf_rh.gperf" ++{ .name="droid sans mono", ++ .m={on, 12, 0, end} ++}, ++#line 104 "ftinf_rh.gperf" ++{ .name="dejavu sans mono", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating_only={on, 7, 16, 8, 32, 9, 16, end} ++}, ++#line 57 "ftinf_rh.gperf" ++{ .name="calibri", ++ .always_use_100={on, 23, maxp, end}, ++ .stem_scaling={on, 15, 1, 17, 1, 18, 1, end}, ++ .stem_translating_only={on, 10, 16, 15, 0, end}, ++ .stem_widths={on, 1, 10, 19, maxp,} ++}, ++#line 156 "ftinf_rh.gperf" ++{ .name="inconsolata", ++ .stem_scaling={on, 12, 1, 15, 1, end}, ++ .stem_translating_only={on, 10, 24, 9, 32, end}, ++ .stem_widths={on, 10, 23, maxp,}, ++}, ++#line 96 "ftinf_rh.gperf" ++{ .name="courier", ++ .always_use_100={on, 0, maxp, end}, ++ .m={on, 13, 1, 14, 1, end}, ++ .stem_translating_only={on, 13, 16, 15, 0, end} ++}, ++#line 128 "ftinf_rh.gperf" ++{ .name="freesans", ++ .always_use_100={on, 0, maxp, end}, ++ .edge_detection={on, 11, 11, 13, 13, end}, ++ .spacing={on, 10, 12, 18, 18, 30, end}, ++ .start={on, 10, 18, 18, 25, 30, end}, ++ .stem_scaling={on, 16, 0, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 16, 9, 8, end} ++}, ++#line 150 "ftinf_rh.gperf" ++{ .name="gill sans", ++ .stem_widths={on, 10, 17, sw2pv, maxp,} ++}, ++#line 117 "ftinf_rh.gperf" ++{ .name="droid sans", ++ .always_use_100={on, 12, 12, 15, 15, end}, ++ .stem_translating_only={on, 8, 16, 9, 16, end} ++}, ++#line 108 "ftinf_rh.gperf" ++{ .name="dejavu sans", ++ .always_use_100={on, 10, 14, 16, 17, end}, ++ .m={on, 12, 0, end}, ++ .stem_scaling={on, 12, 1, end}, ++ .stem_translating_only={on, 8, 16, 15, -20, end} ++}, ++#line 219 "ftinf_rh.gperf" ++{ .name="raleway", ++ .stem_scaling={on, 15, 0, end} ++}, ++#line 153 "ftinf_rh.gperf" ++{ .name="helvetica cy", ++ .stem_widths={on, 10, 23, maxp,} ++}, ++#line 228 "ftinf_rh.gperf" ++{ .name="segoe ui", ++ .always_use_100={on, 11, 12, 14, 14, end}, ++ .stem_translating_only={on, 10, 0, 7, 32, 8, 16, 9, 24, end}, ++ .stem_widths={on, 10, 23, maxp,} ++}, ++#line 48 "ftinf_rh.gperf" ++{ .name="bitstream vera sans mono", ++ .always_use_100={on, 0, maxp, end} ++}, ++#line 241 "ftinf_rh.gperf" ++{ .name="times new roman", ++ .always_use_100={on, 14, 14, 16, 16, end}, ++ .bearing_correction={0, 100, end}, ++ .stem_scaling={on, 17, 1, end}, ++ .stem_translating_only={on, 17, 8, end} ++}, ++#line 222 "ftinf_rh.gperf" ++{ .name="rokkitt", ++ .stem_widths={on, 10, 21, maxp,} ++}, ++#line 143 "ftinf_rh.gperf" ++{ .name="garamond", ++ .brightness={on, 0, -20, end}, ++ .contrast={on, 0, 25, end} ++}, ++#line 137 "ftinf_rh.gperf" ++{ .name="freeserif", ++ .stem_scaling={on, 13, 1, 17, 1, end} ++}, ++#line 189 "ftinf_rh.gperf" ++{ .name="microsoft sans serif", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating_only={on, 10, 16, 8, 32, 9, 32, end} ++}, ++#line 44 "ftinf_rh.gperf" ++{ .name="baskerville", ++ .brightness={on, 0, -20, end}, ++ .contrast={on, 0, 25, end} ++}, ++#line 51 "ftinf_rh.gperf" ++{ .name="bitstream vera sans", ++ .always_use_100={on, 10, 14, 16, 17, end}, ++ .m={on, 12, 0, end}, ++ .stem_scaling={on ,12, 1, end}, ++ .stem_translating_only={on, 8, 16, end} ++} ++ }; ++ ++ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) ++ { ++ register int key = _rules_hash (str, len); ++ ++ if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) ++ { ++ register const struct sa_rules_s *resword; ++ ++ switch (key - 3) ++ { ++ case 0: ++ resword = &wordlist[0]; ++ goto compare; ++ case 3: ++ resword = &wordlist[1]; ++ goto compare; ++ case 7: ++ resword = &wordlist[2]; ++ goto compare; ++ case 8: ++ resword = &wordlist[3]; ++ goto compare; ++ case 9: ++ resword = &wordlist[4]; ++ goto compare; ++ case 10: ++ resword = &wordlist[5]; ++ goto compare; ++ case 11: ++ resword = &wordlist[6]; ++ goto compare; ++ case 12: ++ resword = &wordlist[7]; ++ goto compare; ++ case 13: ++ resword = &wordlist[8]; ++ goto compare; ++ case 14: ++ resword = &wordlist[9]; ++ goto compare; ++ case 16: ++ resword = &wordlist[10]; ++ goto compare; ++ case 17: ++ resword = &wordlist[11]; ++ goto compare; ++ case 18: ++ resword = &wordlist[12]; ++ goto compare; ++ case 19: ++ resword = &wordlist[13]; ++ goto compare; ++ case 21: ++ resword = &wordlist[14]; ++ goto compare; ++ case 23: ++ resword = &wordlist[15]; ++ goto compare; ++ case 24: ++ resword = &wordlist[16]; ++ goto compare; ++ case 26: ++ resword = &wordlist[17]; ++ goto compare; ++ case 27: ++ resword = &wordlist[18]; ++ goto compare; ++ case 28: ++ resword = &wordlist[19]; ++ goto compare; ++ case 29: ++ resword = &wordlist[20]; ++ goto compare; ++ case 30: ++ resword = &wordlist[21]; ++ goto compare; ++ case 31: ++ resword = &wordlist[22]; ++ goto compare; ++ case 32: ++ resword = &wordlist[23]; ++ goto compare; ++ case 33: ++ resword = &wordlist[24]; ++ goto compare; ++ case 34: ++ resword = &wordlist[25]; ++ goto compare; ++ case 35: ++ resword = &wordlist[26]; ++ goto compare; ++ case 36: ++ resword = &wordlist[27]; ++ goto compare; ++ case 37: ++ resword = &wordlist[28]; ++ goto compare; ++ case 38: ++ resword = &wordlist[29]; ++ goto compare; ++ case 39: ++ resword = &wordlist[30]; ++ goto compare; ++ case 41: ++ resword = &wordlist[31]; ++ goto compare; ++ case 43: ++ resword = &wordlist[32]; ++ goto compare; ++ case 44: ++ resword = &wordlist[33]; ++ goto compare; ++ case 45: ++ resword = &wordlist[34]; ++ goto compare; ++ case 46: ++ resword = &wordlist[35]; ++ goto compare; ++ case 48: ++ resword = &wordlist[36]; ++ goto compare; ++ case 49: ++ resword = &wordlist[37]; ++ goto compare; ++ case 52: ++ resword = &wordlist[38]; ++ goto compare; ++ case 53: ++ resword = &wordlist[39]; ++ goto compare; ++ case 54: ++ resword = &wordlist[40]; ++ goto compare; ++ case 58: ++ resword = &wordlist[41]; ++ goto compare; ++ case 59: ++ resword = &wordlist[42]; ++ goto compare; ++ case 60: ++ resword = &wordlist[43]; ++ goto compare; ++ case 61: ++ resword = &wordlist[44]; ++ goto compare; ++ case 62: ++ resword = &wordlist[45]; ++ goto compare; ++ case 63: ++ resword = &wordlist[46]; ++ goto compare; ++ case 64: ++ resword = &wordlist[47]; ++ goto compare; ++ case 69: ++ resword = &wordlist[48]; ++ goto compare; ++ case 70: ++ resword = &wordlist[49]; ++ goto compare; ++ case 71: ++ resword = &wordlist[50]; ++ goto compare; ++ case 72: ++ resword = &wordlist[51]; ++ goto compare; ++ case 74: ++ resword = &wordlist[52]; ++ goto compare; ++ case 75: ++ resword = &wordlist[53]; ++ goto compare; ++ case 76: ++ resword = &wordlist[54]; ++ goto compare; ++ case 77: ++ resword = &wordlist[55]; ++ goto compare; ++ case 78: ++ resword = &wordlist[56]; ++ goto compare; ++ case 81: ++ resword = &wordlist[57]; ++ goto compare; ++ } ++ return 0; ++ compare: ++ { ++ register const char *s = resword->name; ++ ++ if (*str == *s && !strcmp (str + 1, s + 1)) ++ return resword; ++ } ++ } ++ } ++ return 0; ++} ++#line 261 "ftinf_rh.gperf" ++ ++ ++static const sa_rules_t* ++ftinf_rules( const char *name ){ ++ if( name ){ ++ enum { ++ max_wlen=31 ++ }; ++ char buf[max_wlen+1]; ++ int len=strlen( name ); ++ if( len <= max_wlen ){ ++ int i; ++ for( i=0; i ++static const struct sa_rules_s* _rules_get( const char*str, unsigned len ); ++%} ++struct sa_rules_s; ++%% ++{ .name="---", ++ .synthesize_stems={on, 13, 13, end} ++}, ++{ .name="andale mono", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_scaling={on, 11, 1, end}, ++ .stem_widths={on, 10, 21, maxp,} ++}, ++{ .name="arial narrow", ++ .stem_widths={on, 10, 21, maxp,} ++}, ++{ .name="arial unicode ms", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 16, 8, 32, 9, 32, end} ++}, ++{ .name="arial", ++ .always_use_100={on, 0, maxp, end}, ++ .edge_detection={on, 11, 11, 13, 13, end}, ++ .spacing={on, 10, 11, 23, 25, 30, end}, ++ .start={on, 11, 18, 23, 30, 30, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 16, 8, 32, 9, 32, 16, -24, end} ++}, ++{ .name="arimo", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 8, 8, 32, 9, 32, end} ++}, ++{ .name="baskerville", ++ .brightness={on, 0, -20, end}, ++ .contrast={on, 0, 25, end} ++}, ++{ .name="bitstream vera sans mono", ++ .always_use_100={on, 0, maxp, end} ++}, ++{ .name="bitstream vera sans", ++ .always_use_100={on, 10, 14, 16, 17, end}, ++ .m={on, 12, 0, end}, ++ .stem_scaling={on ,12, 1, end}, ++ .stem_translating_only={on, 8, 16, end} ++}, ++{ .name="calibri", ++ .always_use_100={on, 23, maxp, end}, ++ .stem_scaling={on, 15, 1, 17, 1, 18, 1, end}, ++ .stem_translating_only={on, 10, 16, 15, 0, end}, ++ .stem_widths={on, 1, 10, 19, maxp,} ++}, ++{ .name="candara", ++ .stem_scaling={on, 14, 1, 17, 1, end}, ++ .stem_translating_only={on, 10, 16, end} ++}, ++{ .name="cantarell", ++ .stem_translating_only={on, 11, 0, 12, 0, end}, ++ .stem_widths={on, 10, 22, maxp,} ++}, ++{ .name="canwell", ++ .stem_scaling={on, 13, 0, end} ++}, ++{ .name="century gothic", ++ .stem_widths={on, 10, 22, maxp,} ++}, ++{ .name="comfortaa", ++ .stem_widths={on, 10, 19, 22, maxp}, ++ .stem_scaling={on, 11, 0, end} ++}, ++{ .name="consolas", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating_only={on, 8, 32, 9, 32, end}, ++ .stem_widths={on, 10, 20, maxp,}, ++ .stem_scaling={on, 11, 1, end} ++}, ++{ .name="corbel", ++ .stem_translating_only={on, 10, 16, end}, ++ .stem_widths={on, 10, 21, maxp} ++}, ++{ .name="courier new", ++ .always_use_100={on, 12, 12, end}, ++ .edge_detection={on, 10, 12, end}, ++ .m={on, 13, 1, 14, 1, end} ++}, ++{ .name="courier", ++ .always_use_100={on, 0, maxp, end}, ++ .m={on, 13, 1, 14, 1, end}, ++ .stem_translating_only={on, 13, 16, 15, 0, end} ++}, ++{ .name="cousine", ++ .always_use_100={on, 0, maxp, end} ++}, ++{ .name="dejavu sans mono", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating_only={on, 7, 16, 8, 32, 9, 16, end} ++}, ++{ .name="dejavu sans", ++ .always_use_100={on, 10, 14, 16, 17, end}, ++ .m={on, 12, 0, end}, ++ .stem_scaling={on, 12, 1, end}, ++ .stem_translating_only={on, 8, 16, 15, -20, end} ++}, ++{ .name="droid sans mono", ++ .m={on, 12, 0, end} ++}, ++{ .name="droid sans", ++ .always_use_100={on, 12, 12, 15, 15, end}, ++ .stem_translating_only={on, 8, 16, 9, 16, end} ++}, ++{ .name="essential pragmatapro", ++ .always_use_100={on, 0, maxp, end}, ++ .m={on, 13, 0, 14, 0, end} ++}, ++{ .name="freemono", ++ .always_use_100={on, 0, maxp, end} ++}, ++{ .name="freesans", ++ .always_use_100={on, 0, maxp, end}, ++ .edge_detection={on, 11, 11, 13, 13, end}, ++ .spacing={on, 10, 12, 18, 18, 30, end}, ++ .start={on, 10, 18, 18, 25, 30, end}, ++ .stem_scaling={on, 16, 0, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 16, 9, 8, end} ++}, ++{ .name="freeserif", ++ .stem_scaling={on, 13, 1, 17, 1, end} ++}, ++{ .name="futura", ++ .stem_widths={on, 10, 14, sw2pv, maxp,} ++}, ++{ .name="garamond", ++ .brightness={on, 0, -20, end}, ++ .contrast={on, 0, 25, end} ++}, ++{ .name="georgia", ++ .stem_translating_only={on, 13, 16, 14, 16, 15, 0, end} ++}, ++{ .name="gill sans", ++ .stem_widths={on, 10, 17, sw2pv, maxp,} ++}, ++{ .name="helvetica cy", ++ .stem_widths={on, 10, 23, maxp,} ++}, ++{ .name="inconsolata", ++ .stem_scaling={on, 12, 1, 15, 1, end}, ++ .stem_translating_only={on, 10, 24, 9, 32, end}, ++ .stem_widths={on, 10, 23, maxp,}, ++}, ++{ .name="liberation mono", ++ .always_use_100={on, 0, maxp, end} ++}, ++{ .name="liberation sans narrow", ++ .stem_widths={on,10, 22, maxp,} ++}, ++{ .name="liberation sans", ++ .edge_detection={on, 11, 11, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 10, 8, 8, 32, 9, 32, end}, ++ .stem_widths={on,10, 19, maxp,} ++}, ++{ .name="lucida console", ++ .always_use_100={on, 0, maxp, end} ++}, ++{ .name="lucida grande", ++ .stem_scaling={on, 13, 1, end}, ++ .stem_translating_only={on, 13, 24, 14, 24, 8, 16, 9, 16, end}, ++ .stem_widths={on, 10, 16, sw2pv, maxp}, ++}, ++{ .name="lucida sans unicode", ++ .stem_translating_only={on, 13, 24, 14, 24, 8, 16, 9, 16, end}, ++ .stem_widths={on,10, 16, sw2pv, maxp,} ++}, ++{ .name="luxi sans", ++ .always_use_100={on, 13, 13, end}, ++ .stem_widths={on, 10, 17, sw2pv, maxp,} ++}, ++{ .name="microsoft sans serif", ++ .always_use_100={on, 0, maxp, end}, ++ .stem_translating_only={on, 10, 16, 8, 32, 9, 32, end} ++}, ++{ .name="monaco", ++ .always_use_100={on, 0, maxp, end} ++}, ++{ .name="myriad pro", ++ .stem_scaling={on, 14, 1, 17, 1, end}, ++ .stem_translating_only={on, 10, 16, 11, 0, 9, 16, end} ++}, ++{ .name="nina", ++ .stem_scaling={on, 11, 0, 12, 0, 13, 0, end} ++}, ++{ .name="open sans", ++ .stem_translating_only={on, 10, 16, 9, 16, end}, ++ .stem_widths={on, 10, 20, maxp,} ++}, ++{ .name="optima", ++ .brightness={on, 0, -20, end}, ++ .contrast={on, 0, 25, end}, ++ .stem_scaling={on, 17, 1, end}, ++ .stem_translating_only={on, 10, 0, 11, 0, 12, 0, end} ++}, ++{ .name="palatino linotype", ++ .edge_detection={on, 0, 100, end} ++}, ++{ .name="pragmata", ++ .always_use_100={on, 0, maxp, end} ++}, ++{ .name="raleway", ++ .stem_scaling={on, 15, 0, end} ++}, ++{ .name="rokkitt", ++ .stem_widths={on, 10, 21, maxp,} ++}, ++{ .name="samba", ++ .stem_scaling={on, 11, 0, end} ++}, ++{ .name="segoe ui", ++ .always_use_100={on, 11, 12, 14, 14, end}, ++ .stem_translating_only={on, 10, 0, 7, 32, 8, 16, 9, 24, end}, ++ .stem_widths={on, 10, 23, maxp,} ++}, ++{ .name="tahoma", ++ .always_use_100={on, 11, 11, 14, maxp, end}, ++ .edge_detection={on, 11, 11, end}, ++ .spacing={on, 10, 12, 18, 18, 30, end}, ++ .start={on, 14, 17, 30, 100, 100, end}, ++ .stem_translating={on, 11, 32, end}, ++ .stem_translating_only={on, 7, 32, 8, 32, 9, 32, end}, ++}, ++{ .name="times new roman", ++ .always_use_100={on, 14, 14, 16, 16, end}, ++ .bearing_correction={0, 100, end}, ++ .stem_scaling={on, 17, 1, end}, ++ .stem_translating_only={on, 17, 8, end} ++}, ++{ .name="trebuchet ms", ++ .always_use_100={on, 13, 13, end}, ++ .stem_scaling={on, 13, 0, 17, 0, 20, 1, end}, ++ .stem_translating_only={on, 10, 16, 11, 0, 8, 32, 9, 32, end}, ++ .stem_widths={on, 10, 17, sw2pv, maxp,} ++}, ++{ .name="ubuntu", ++ .always_use_100={on, 12, 13, 15, 15, end} ++}, ++{ .name="verdana", ++ .always_use_100={on, 0, 14, 16, maxp, end}, ++ .stem_scaling={on, 12, 1, 15, 1, end}, ++ .stem_translating_only={on, 8, 16, 15, 16, 14, 32, 18, 32, 19, 24, end} ++}, ++%% ++ ++static const sa_rules_t* ++ftinf_rules( const char *name ){ ++ if( name ){ ++ enum { ++ max_wlen=31 ++ }; ++ char buf[max_wlen+1]; ++ int len=strlen( name ); ++ if( len <= max_wlen ){ ++ int i; ++ for( i=0; i' == 62) && ('?' == 63) && ('A' == 65) \ ++ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ ++ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ ++ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ ++ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ ++ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ ++ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ ++ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ ++ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ ++ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ ++ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ ++ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ ++ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ ++ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ ++ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ ++ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) ++/* The character set is not based on ISO-646. */ ++#error "gperf generated tables don't work with this execution character set. Please report a bug to ." ++#endif ++ ++#line 9 "ftinf_sh.gperf" ++ ++#include ++static const struct ftinf_s* _settings_get( const char*str, unsigned len); ++/* maximum key range = 37, duplicates = 0 */ ++ ++#ifdef __GNUC__ ++__inline ++#else ++#ifdef __cplusplus ++inline ++#endif ++#endif ++static unsigned int ++_settings_hash (register const char *str, register unsigned int len) ++{ ++ static const unsigned char asso_values[] = ++ { ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 13, ++ 8, 30, 25, 20, 40, 10, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 5, 40, 0, ++ 0, 0, 40, 40, 10, 0, 40, 40, 15, 5, ++ 10, 0, 10, 40, 40, 0, 0, 0, 0, 0, ++ 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40 ++ }; ++ return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]]; ++} ++ ++#ifdef __GNUC__ ++__inline ++#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ ++__attribute__ ((__gnu_inline__)) ++#endif ++#endif ++const struct ftinf_s * ++_settings_get (register const char *str, register unsigned int len) ++{ ++ enum ++ { ++ TOTAL_KEYWORDS = 22, ++ MIN_WORD_LENGTH = 3, ++ MAX_WORD_LENGTH = 14, ++ MIN_HASH_VALUE = 3, ++ MAX_HASH_VALUE = 39 ++ }; ++ ++ static const struct ftinf_s wordlist[] = ++ { ++#line 76 "ftinf_sh.gperf" ++{ .name="osx", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_vertical_stem_darken_strength=25, ++ .bold_embolden_x_value=16, ++ .brightness=10, ++ .contrast=20, ++ .filter_params={on, 3, 32, 38, 32, 3}, ++ .gamma_correction={1000, 80}, ++ .global_embolden_y_value=8, ++ .grayscale_filter_strength=25, ++}, ++#line 37 "ftinf_sh.gperf" ++{ .name="ipad", ++ .filter_params={on, 0, 0, 100, 0, 0}, ++ .gamma_correction={1000, 80}, ++ .grayscale_filter_strength=100 ++}, ++#line 114 "ftinf_sh.gperf" ++{ .name="shove", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=100, ++ .stem_fitting_strength=100, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true ++}, ++#line 126 "ftinf_sh.gperf" ++{ .name="ubuntu", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_vertical_stem_darken_strength=25, ++ .brightness=-10, ++ .contrast=15, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={1000, 80}, ++ .use_various_tweaks=true ++}, ++#line 27 "ftinf_sh.gperf" ++{ .name="classic", ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .filter_params={on, 6, 25, 38, 25, 6}, ++ .gamma_correction={0, 100}, ++ .use_various_tweaks=true ++}, ++#line 34 "ftinf_sh.gperf" ++{ .name="disabled", ++ .gamma_correction={0, 100}, ++}, ++#line 100 "ftinf_sh.gperf" ++{ .name="sharpened", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=25, ++ .stem_fitting_strength=25, ++ .stem_snapping_sliding_scale=40, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=65 ++}, ++#line 42 "ftinf_sh.gperf" ++{ .name="infinality", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=25, ++ .stem_fitting_strength=25, ++ .stem_snapping_sliding_scale=40, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=5 ++}, ++#line 15 "ftinf_sh.gperf" ++{ .name="custom", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 8, 24, 48, 24, 8}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=75, ++ .stem_fitting_strength=50, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true ++}, ++#line 180 "ftinf_sh.gperf" ++{ .name="vanilla", ++ .filter_params={on, 6, 25, 38, 25, 6}, ++ .gamma_correction={0, 100}, ++}, ++#line 184 "ftinf_sh.gperf" ++{ .name="windows7light", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .contrast=20, ++ .filter_params={on, 20, 25, 38, 25, 05}, ++ .fringe_filter_strength=100, ++ .gamma_correction={1000, 160}, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=100 ++}, ++#line 226 "ftinf_sh.gperf" ++{ .name="windowsxplight", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .brightness=20, ++ .contrast=30, ++ .filter_params={on, 6, 25, 44, 25, 6}, ++ .fringe_filter_strength=100, ++ .gamma_correction={1000, 120}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=65 ++}, ++#line 64 "ftinf_sh.gperf" ++{ .name="nudge", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=25, ++ .stem_fitting_strength=15, ++ .stem_snapping_sliding_scale=30, ++ .use_various_tweaks=true, ++}, ++#line 144 "ftinf_sh.gperf" ++{ .name="ultimate2", ++ .filter_params={on, 6, 22, 36, 22, 6}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++#line 197 "ftinf_sh.gperf" ++{ .name="windows7", ++ .filter_params={on, 20, 25, 42, 25, 06}, ++ .fringe_filter_strength=100, ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_vertical_stem_darken_strength=25, ++ .windows_style_sharpening_strength=65, ++ .gamma_correction={1000, 120}, ++ .brightness=10, ++ .contrast=20, ++ .use_various_tweaks=true, ++ .autohint_snap_stem_height=100, ++ .use_known_settings_on_selected_fonts=true, ++}, ++#line 210 "ftinf_sh.gperf" ++{ .name="windowsxp", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .brightness=10, ++ .contrast=20, ++ .filter_params={on, 6, 25, 44, 25, 6}, ++ .fringe_filter_strength=100, ++ .gamma_correction={1000, 120}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=65 ++}, ++#line 56 "ftinf_sh.gperf" ++{ .name="linux", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 6, 25, 44, 25, 6}, ++ .gamma_correction={0, 100}, ++ .use_various_tweaks=true ++}, ++#line 135 "ftinf_sh.gperf" ++{ .name="ultimate1", ++ .filter_params={on, 4, 22, 38, 22, 4}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++#line 87 "ftinf_sh.gperf" ++{ .name="push", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=75, ++ .stem_fitting_strength=50, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true ++}, ++#line 171 "ftinf_sh.gperf" ++{ .name="ultimate5", ++ .filter_params={on, 12, 28, 42, 28, 12}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++#line 162 "ftinf_sh.gperf" ++{ .name="ultimate4", ++ .filter_params={on, 10, 25, 37, 25, 10}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++#line 153 "ftinf_sh.gperf" ++{ .name="ultimate3", ++ .filter_params={on, 8, 24, 36, 24, 8}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++} ++ }; ++ ++ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) ++ { ++ register int key = _settings_hash (str, len); ++ ++ if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) ++ { ++ register const struct ftinf_s *resword; ++ ++ switch (key - 3) ++ { ++ case 0: ++ resword = &wordlist[0]; ++ goto compare; ++ case 1: ++ resword = &wordlist[1]; ++ goto compare; ++ case 2: ++ resword = &wordlist[2]; ++ goto compare; ++ case 3: ++ resword = &wordlist[3]; ++ goto compare; ++ case 4: ++ resword = &wordlist[4]; ++ goto compare; ++ case 5: ++ resword = &wordlist[5]; ++ goto compare; ++ case 6: ++ resword = &wordlist[6]; ++ goto compare; ++ case 7: ++ resword = &wordlist[7]; ++ goto compare; ++ case 8: ++ resword = &wordlist[8]; ++ goto compare; ++ case 9: ++ resword = &wordlist[9]; ++ goto compare; ++ case 10: ++ resword = &wordlist[10]; ++ goto compare; ++ case 11: ++ resword = &wordlist[11]; ++ goto compare; ++ case 12: ++ resword = &wordlist[12]; ++ goto compare; ++ case 14: ++ resword = &wordlist[13]; ++ goto compare; ++ case 15: ++ resword = &wordlist[14]; ++ goto compare; ++ case 16: ++ resword = &wordlist[15]; ++ goto compare; ++ case 17: ++ resword = &wordlist[16]; ++ goto compare; ++ case 19: ++ resword = &wordlist[17]; ++ goto compare; ++ case 21: ++ resword = &wordlist[18]; ++ goto compare; ++ case 26: ++ resword = &wordlist[19]; ++ goto compare; ++ case 31: ++ resword = &wordlist[20]; ++ goto compare; ++ case 36: ++ resword = &wordlist[21]; ++ goto compare; ++ } ++ return 0; ++ compare: ++ { ++ register const char *s = resword->name; ++ ++ if (*str == *s && !strcmp (str + 1, s + 1)) ++ return resword; ++ } ++ } ++ } ++ return 0; ++} ++#line 242 "ftinf_sh.gperf" ++ ++ ++static const ftinf_t* ++ftinf_settings( const char *name ){ ++ if( name ){ ++ enum { ++ max_wlen=31 ++ }; ++ char buf[max_wlen+1]; ++ int len=strlen( name ); ++ if( len <= max_wlen ){ ++ int i; ++ for( i=0; i ++static const struct ftinf_s* _settings_get( const char*str, unsigned len); ++%} ++struct ftinf_s; ++%% ++{ .name="custom", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 8, 24, 48, 24, 8}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=75, ++ .stem_fitting_strength=50, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true ++}, ++{ .name="classic", ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .filter_params={on, 6, 25, 38, 25, 6}, ++ .gamma_correction={0, 100}, ++ .use_various_tweaks=true ++}, ++{ .name="disabled", ++ .gamma_correction={0, 100}, ++}, ++{ .name="ipad", ++ .filter_params={on, 0, 0, 100, 0, 0}, ++ .gamma_correction={1000, 80}, ++ .grayscale_filter_strength=100 ++}, ++{ .name="infinality", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=25, ++ .stem_fitting_strength=25, ++ .stem_snapping_sliding_scale=40, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=5 ++}, ++{ .name="linux", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 6, 25, 44, 25, 6}, ++ .gamma_correction={0, 100}, ++ .use_various_tweaks=true ++}, ++{ .name="nudge", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=25, ++ .stem_fitting_strength=15, ++ .stem_snapping_sliding_scale=30, ++ .use_various_tweaks=true, ++}, ++{ .name="osx", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_vertical_stem_darken_strength=25, ++ .bold_embolden_x_value=16, ++ .brightness=10, ++ .contrast=20, ++ .filter_params={on, 3, 32, 38, 32, 3}, ++ .gamma_correction={1000, 80}, ++ .global_embolden_y_value=8, ++ .grayscale_filter_strength=25, ++}, ++{ .name="push", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=75, ++ .stem_fitting_strength=50, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true ++}, ++{ .name="sharpened", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=25, ++ .stem_fitting_strength=25, ++ .stem_snapping_sliding_scale=40, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=65 ++}, ++{ .name="shove", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_increase_glyph_heights=true, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=100, ++ .stem_fitting_strength=100, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true ++}, ++{ .name="ubuntu", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_vertical_stem_darken_strength=25, ++ .brightness=-10, ++ .contrast=15, ++ .filter_params={on, 11, 22, 38, 22, 11}, ++ .gamma_correction={1000, 80}, ++ .use_various_tweaks=true ++}, ++{ .name="ultimate1", ++ .filter_params={on, 4, 22, 38, 22, 4}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++{ .name="ultimate2", ++ .filter_params={on, 6, 22, 36, 22, 6}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++{ .name="ultimate3", ++ .filter_params={on, 8, 24, 36, 24, 8}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++{ .name="ultimate4", ++ .filter_params={on, 10, 25, 37, 25, 10}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++{ .name="ultimate5", ++ .filter_params={on, 12, 28, 42, 28, 12}, ++ .fringe_filter_strength=25, ++ .gamma_correction={0, 100}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=25 ++}, ++{ .name="vanilla", ++ .filter_params={on, 6, 25, 38, 25, 6}, ++ .gamma_correction={0, 100}, ++}, ++{ .name="windows7light", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .contrast=20, ++ .filter_params={on, 20, 25, 38, 25, 05}, ++ .fringe_filter_strength=100, ++ .gamma_correction={1000, 160}, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=100 ++}, ++{ .name="windows7", ++ .filter_params={on, 20, 25, 42, 25, 06}, ++ .fringe_filter_strength=100, ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_vertical_stem_darken_strength=25, ++ .windows_style_sharpening_strength=65, ++ .gamma_correction={1000, 120}, ++ .brightness=10, ++ .contrast=20, ++ .use_various_tweaks=true, ++ .autohint_snap_stem_height=100, ++ .use_known_settings_on_selected_fonts=true, ++}, ++{ .name="windowsxp", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .brightness=10, ++ .contrast=20, ++ .filter_params={on, 6, 25, 44, 25, 6}, ++ .fringe_filter_strength=100, ++ .gamma_correction={1000, 120}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=65 ++}, ++{ .name="windowsxplight", ++ .autohint_horizontal_stem_darken_strength=10, ++ .autohint_snap_stem_height=100, ++ .autohint_vertical_stem_darken_strength=25, ++ .brightness=20, ++ .contrast=30, ++ .filter_params={on, 6, 25, 44, 25, 6}, ++ .fringe_filter_strength=100, ++ .gamma_correction={1000, 120}, ++ .stem_alignment_strength=15, ++ .stem_fitting_strength=15, ++ .stem_snapping_sliding_scale=30, ++ .use_known_settings_on_selected_fonts=true, ++ .use_various_tweaks=true, ++ .windows_style_sharpening_strength=65 ++}, ++%% ++ ++static const ftinf_t* ++ftinf_settings( const char *name ){ ++ if( name ){ ++ enum { ++ max_wlen=31 ++ }; ++ char buf[max_wlen+1]; ++ int len=strlen( name ); ++ if( len <= max_wlen ){ ++ int i; ++ for( i=0; i ++#include ++#include ++#include "ftinf.h" + + #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + +@@ -307,11 +310,36 @@ + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ) + { +- static const FT_Byte default_filter[5] = +- { 0x08, 0x4d, 0x56, 0x4d, 0x08 }; + static const FT_Byte light_filter[5] = + { 0x00, 0x55, 0x56, 0x55, 0x00 }; +- ++#ifndef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ static const FT_Byte default_filter[5] = ++ { 0x08, 0x4d, 0x56, 0x4d, 0x08 }; ++#else ++ FT_Byte default_filter[5]; ++ if( ftinf && ftinf->filter_params[0] ) ++ { ++ const int *f=ftinf->filter_params; ++ /* Assume we were given integers [0-100] get them to [0-255] */ ++ int val; /* 2611=2.55*1024 */ ++ val=(f[1]*2611+512)>>10; if( val > 255 ) val=255; ++ default_filter[0] = (FT_Byte) val; ++ val=(f[2]*2611+512)>>10; if( val > 255 ) val=255; ++ default_filter[1] = (FT_Byte) val; ++ val=(f[3]*2611+512)>>10; if( val > 255 ) val=255; ++ default_filter[2] = (FT_Byte) val; ++ val=(f[4]*2611+512)>>10; if( val > 255 ) val=255; ++ default_filter[3] = (FT_Byte) val; ++ val=(f[5]*2611+512)>>10; if( val > 255 ) val=255; ++ default_filter[4] = (FT_Byte) val; ++ } else { ++ default_filter[0]=0x08; ++ default_filter[1]=0x4d; ++ default_filter[2]=0x56; ++ default_filter[3]=0x4d; ++ default_filter[4]=0x08; ++ } ++#endif + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); +diff -ruN freetype-2.7-orig/src/base/ftobjs.c freetype-2.7/src/base/ftobjs.c +--- freetype-2.7-orig/src/base/ftobjs.c 2016-09-04 11:42:16.000000000 +0200 ++++ freetype-2.7/src/base/ftobjs.c 2016-09-09 16:01:22.465167416 +0200 +@@ -40,7 +40,9 @@ + #ifdef FT_CONFIG_OPTION_MAC_FONTS + #include "ftbase.h" + #endif +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "ftinf.h" ++#endif + + #ifdef FT_DEBUG_LEVEL_TRACE + +@@ -78,6 +80,11 @@ + + #define GRID_FIT_METRICS + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include ++#include ++#include "../autofit/aflatin.h" ++#endif + + /* forward declaration */ + static FT_Error +@@ -554,6 +561,25 @@ + ft_lookup_glyph_renderer( FT_GlyphSlot slot ); + + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ static void ++ ft_glyphslot_enlarge_metrics( FT_GlyphSlot slot, ++ FT_Render_Mode mode ) ++ { ++ FT_Glyph_Metrics* metrics = &slot->metrics; ++ FT_Pos enlarge_cbox = 0; ++ ++ ++ /* enlarge for grayscale rendering */ ++ if ( mode == FT_RENDER_MODE_NORMAL ) ++ enlarge_cbox = 64; ++ ++ metrics->horiBearingX -= enlarge_cbox; ++ metrics->width += 2 * enlarge_cbox; ++ } ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ ++ ++ + #ifdef GRID_FIT_METRICS + static void + ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot, +@@ -612,8 +638,18 @@ + FT_Bool autohint = FALSE; + FT_Module hinter; + TT_Face ttface = (TT_Face)face; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET + ++ FT_Bool use_various_tweaks = FALSE; ++ if( ftinf ) use_various_tweaks=ftinf->use_various_tweaks; + ++ /* Force autohint if no tt instructions */ ++ /* NOTE: NEEDS TO BE RUN LATER IN CODE???? */ ++ /*if ( use_various_tweaks && ++ ttface->num_locations && ++ ttface->max_profile.maxSizeOfInstructions == 0 ) ++ load_flags |= FT_LOAD_FORCE_AUTOHINT;*/ ++#endif + if ( !face || !face->size || !face->glyph ) + return FT_THROW( Invalid_Face_Handle ); + +@@ -701,6 +737,18 @@ + { + FT_AutoHinter_Interface hinting; + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( use_various_tweaks ) ++ { ++ /* Force slight hinting over full hinting always */ ++ load_flags &= ~FT_LOAD_TARGET_LCD; ++ load_flags &= ~FT_LOAD_TARGET_LCD_V; ++ load_flags &= ~FT_LOAD_TARGET_MONO; ++ load_flags &= ~FT_LOAD_TARGET_NORMAL; ++ load_flags |= FT_LOAD_TARGET_LIGHT; ++ /*printf("%d ", load_flags);*/ ++ } ++#endif + + /* try to load embedded bitmaps first if available */ + /* */ +@@ -746,6 +794,18 @@ + if ( error ) + goto Exit; + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ infinality_cur_width = 0; ++ ++ { ++ /* fix for sdl_ttf */ ++ FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); ++ ++ if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) ++ ft_glyphslot_enlarge_metrics( slot, mode ); ++ } ++#endif ++ + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* check that the loaded outline is correct */ +@@ -4785,6 +4845,11 @@ + /* That's ok now */ + *alibrary = library; + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ /* get Infinality settings */ ++ ftinf_env(); ++#endif ++ + return FT_Err_Ok; + + #ifdef FT_CONFIG_OPTION_PIC +diff -ruN freetype-2.7-orig/src/base/ftoutln.c freetype-2.7/src/base/ftoutln.c +--- freetype-2.7-orig/src/base/ftoutln.c 2016-08-26 11:12:02.000000000 +0200 ++++ freetype-2.7/src/base/ftoutln.c 2016-09-09 16:01:22.465167416 +0200 +@@ -29,7 +29,9 @@ + #include FT_INTERNAL_CALC_H + #include FT_INTERNAL_DEBUG_H + #include FT_TRIGONOMETRY_H +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "ftinf.h" ++#endif + + /*************************************************************************/ + /* */ +@@ -913,7 +915,13 @@ + FT_Vector* points; + FT_Int c, first, last; + FT_Int orientation; +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ FT_Bool use_various_tweaks = FALSE; ++ if( ftinf ) use_various_tweaks=ftinf->use_various_tweaks; ++ ++ if ( use_various_tweaks ) ++ ystrength = FT_PIX_FLOOR ( ystrength ); ++#endif + + if ( !outline ) + return FT_THROW( Invalid_Outline ); +diff -ruN freetype-2.7-orig/src/base/ftsynth.c freetype-2.7/src/base/ftsynth.c +--- freetype-2.7-orig/src/base/ftsynth.c 2016-02-03 19:13:58.000000000 +0100 ++++ freetype-2.7/src/base/ftsynth.c 2016-09-09 16:01:22.465167416 +0200 +@@ -22,7 +22,9 @@ + #include FT_INTERNAL_OBJECTS_H + #include FT_OUTLINE_H + #include FT_BITMAP_H +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "ftinf.h" ++#endif + + /*************************************************************************/ + /* */ +@@ -93,7 +95,10 @@ + FT_Face face; + FT_Error error; + FT_Pos xstr, ystr; +- ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ FT_Bool use_various_tweaks = FALSE; ++ if( ftinf ) use_various_tweaks=ftinf->use_various_tweaks; ++#endif + + if ( !slot ) + return; +@@ -111,8 +116,16 @@ + ystr = xstr; + + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) ++ { ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( use_various_tweaks ) ++ (void)FT_Outline_EmboldenXY( &slot->outline, ++ xstr, ++ FT_PIX_FLOOR( ystr ) ); ++ else ++#endif + FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); +- ++ } + else /* slot->format == FT_GLYPH_FORMAT_BITMAP */ + { + /* round to full pixels */ +@@ -150,6 +163,9 @@ + + slot->metrics.width += xstr; + slot->metrics.height += ystr; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( !use_various_tweaks ) ++#endif + slot->metrics.horiAdvance += xstr; + slot->metrics.vertAdvance += ystr; + slot->metrics.horiBearingY += ystr; +diff -ruN freetype-2.7-orig/src/base/Jamfile freetype-2.7/src/base/Jamfile +--- freetype-2.7-orig/src/base/Jamfile 2016-02-03 19:13:58.000000000 +0100 ++++ freetype-2.7/src/base/Jamfile 2016-09-09 16:01:22.465167416 +0200 +@@ -56,6 +56,7 @@ + ftglyph + ftgxval + ftinit ++ ftinf + ftlcdfil + ftmm + ftotval +diff -ruN freetype-2.7-orig/src/base/rules.mk freetype-2.7/src/base/rules.mk +--- freetype-2.7-orig/src/base/rules.mk 2016-02-03 19:13:58.000000000 +0100 ++++ freetype-2.7/src/base/rules.mk 2016-09-09 16:01:22.465167416 +0200 +@@ -42,6 +42,7 @@ + $(BASE_DIR)/ftdbgmem.c \ + $(BASE_DIR)/ftgloadr.c \ + $(BASE_DIR)/fthash.c \ ++ $(BASE_DIR)/ftinf.c \ + $(BASE_DIR)/ftobjs.c \ + $(BASE_DIR)/ftoutln.c \ + $(BASE_DIR)/ftpic.c \ +diff -ruN freetype-2.7-orig/src/cff/cffobjs.c freetype-2.7/src/cff/cffobjs.c +--- freetype-2.7-orig/src/cff/cffobjs.c 2016-08-26 11:45:36.000000000 +0200 ++++ freetype-2.7/src/cff/cffobjs.c 2016-09-09 16:01:22.465167416 +0200 +@@ -34,6 +34,9 @@ + + #include "cfferrs.h" + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include "../base/ftinf.h" ++#endif + + /*************************************************************************/ + /* */ +@@ -1096,6 +1099,9 @@ + #endif + + driver->no_stem_darkening = TRUE; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if(ftinf) driver->no_stem_darkening = !ftinf->stem_darkening_cff; ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + + driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; +diff -ruN freetype-2.7-orig/src/smooth/ftsmooth.c freetype-2.7/src/smooth/ftsmooth.c +--- freetype-2.7-orig/src/smooth/ftsmooth.c 2016-02-03 19:13:58.000000000 +0100 ++++ freetype-2.7/src/smooth/ftsmooth.c 2016-09-09 16:01:22.468500777 +0200 +@@ -26,6 +26,18 @@ + + #include "ftsmerrs.h" + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++#include ++#include FT_BITMAP_H ++#include ++#include ++#include FT_OUTLINE_H ++#include "../base/ftinf.h" ++ ++#define verbose FALSE ++#define STVALUES if (verbose) \ ++ printf ( "scale:%f translate:%ld ", *scale_value, *translate_value ); ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + + /* initialize renderer -- init its raster */ + static FT_Error +@@ -93,6 +105,2219 @@ + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ static FT_Fixed FT_FixedFromFloat(float f) ++ { ++ short value = f; ++ unsigned short fract = (f - value) * 0xFFFF; ++ ++ ++ return (FT_Fixed)((long)value << 16 | (unsigned long)fract ); ++ } ++ ++ ++ /* ChromeOS sharpening algorithm */ ++ /* soften the sub-pixel anti-aliasing and sharpen */ ++ static void ++ _ft_lcd_chromeos_sharpen( FT_Bitmap* bitmap, ++ FT_Render_Mode mode, ++ FT_Byte cutoff, ++ double gamma_value ) ++ { ++ static FT_Bool initialized_gamma = FALSE; ++ static unsigned short gamma_ramp[256]; ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ int ii; ++ ++ if ( !initialized_gamma ) ++ { ++ initialized_gamma = TRUE; ++ /* linear to voltage */ ++ for ( ii = 0; ii < 256; ii++ ) ++ { ++ gamma_ramp[ii] = (unsigned char) ++ ( pow( (double)ii / 255.0, gamma_value ) * 255.0f ); ++ if ( gamma_ramp[ii] < cutoff ) ++ gamma_ramp[ii] = 0; ++ } ++ } ++ ++ /* horizontal in-place sub-pixel sharpening filter */ ++ if ( mode == FT_RENDER_MODE_LCD ) ++ { ++ FT_Byte* line = bitmap->buffer; ++ ++ ++ for ( ; height > 0; height--, line += bitmap->pitch ) ++ { ++ FT_UInt xx; ++ ++ ++ for ( xx = 0; xx < width; xx++ ) ++ line[xx] = gamma_ramp[line[xx]]; ++ } ++ } ++ } ++ ++ /* simple linear scale to handle various sliding values */ ++ float ++ sliding_scale ( int min_value, ++ int max_value, ++ float min_amount, ++ float max_amount, ++ int cur_value ) ++ { ++ ++ float m = ( min_amount - max_amount ) / (float)( min_value - max_value ); ++ float result = ( ( (float)cur_value * m) + ( max_amount - max_value * m ) ) ; ++ ++ if ( min_amount < max_amount ) ++ { ++ if ( result < min_amount ) ++ return min_amount; ++ if ( result > max_amount ) ++ return max_amount; ++ } ++ else ++ { ++ if ( result < max_amount ) ++ return max_amount; ++ if ( result > min_amount ) ++ return min_amount; ++ } ++ ++ return result; ++ } ++ ++ ++ /* brightness and contrast adjustment on the bitmap */ ++ static FT_Bool ++ _ft_bitmap_bc ( FT_Bitmap* bitmap, ++ float brightness, ++ float contrast ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* line = bitmap->buffer; ++ FT_UInt xx; ++ ++ ++ if ( brightness == 0 && contrast == 0 ) ++ return FALSE; ++ ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch ) ++ { ++ for ( xx = 0; xx < width - 1; xx += 1 ) ++ { ++ if ( line[xx] > 0) ++ { ++ float value = (float)( 255 - line[xx] ) / 256.0; ++ FT_Int result = 0; ++ ++ if ( brightness < 0.0 ) ++ value = value * ( 1.0 + brightness ); ++ else ++ value = value + ( ( 1.0 - value ) * brightness ); ++ ++ value = ( value - 0.5 ) * ++ ( tan ( ( contrast + 1.0 ) * 3.141592/4.0 ) ) + 0.5; ++ ++ result = (FT_Int)( 255.0 - value * 256.0 ); ++ ++ if ( result < 0 ) ++ result = 0; ++ if ( result > 255 ) ++ result = 255; ++ ++ line[xx] = result; ++ } ++ } ++ } ++ return TRUE; ++ } ++ ++ ++ /* Filter to mimic Windows-style sharpening */ ++ /* Determined via 100% experimentation. */ ++ static void ++ _ft_lcd_windows_sharpen( FT_Bitmap* bitmap, ++ FT_Render_Mode mode, ++ FT_UInt strength, ++ FT_Library library ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* new_line; ++ FT_Byte* line = bitmap->buffer; ++ FT_Bitmap new_bitmap; ++ ++ ++ FT_Bitmap_New( &new_bitmap ); ++ FT_Bitmap_Copy( library, bitmap, &new_bitmap ); ++ new_line = (&new_bitmap)->buffer; ++ ++ if (strength > 0) ++ for (height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch, new_line += bitmap->pitch ) ++ { ++ FT_UInt xx, threshold = 128; ++ FT_Byte* prevline = line - bitmap->pitch; ++ FT_Byte* nextline = line + bitmap->pitch; ++ FT_Byte* new_prevline = new_line - bitmap->pitch; ++ FT_Byte* new_nextline = new_line + bitmap->pitch; ++ ++ for ( xx = 1; xx < width - 1; xx += 1 ) ++ { ++ /* subpixel grid sp11 sp21 sp31 */ ++ /* where sp22 is sp12 sp22 sp32 */ ++ /* current subpixel. sp13 sp23 sp33 */ ++ ++ FT_Int prevtotal, nexttotal, lefttotal, righttotal, sidesdiff, ++ prevdiff, nextdiff, sp11, sp21, sp31, sp12, sp22, sp32, ++ sp13, sp23, sp33; ++ ++ sp12 = line [xx-1]; ++ sp22 = line [xx]; ++ sp32 = line [xx+1]; ++ ++ if ( height == bitmap->rows ) ++ { ++ prevtotal = sp11 = sp21 = sp31 = 0; ++ prevdiff = sp22; ++ lefttotal = sp12 + sp13; ++ righttotal = sp32 + sp33; ++ } ++ else ++ { ++ prevtotal = prevline[xx-1] + prevline[xx] + prevline[xx+1]; ++ sp11 = prevline [xx-1]; ++ sp21 = prevline [xx]; ++ sp31 = prevline [xx+1]; ++ prevdiff = sp22 - sp21; ++ lefttotal = sp11 + sp12 + sp13; ++ righttotal = sp31 + sp32 + sp33; ++ } ++ ++ if ( height == 1 ) ++ { ++ nexttotal = sp13 = sp23 = sp33 = 0; ++ nextdiff = sp22; ++ lefttotal = sp11 + sp12; ++ righttotal = sp31 + sp32; ++ } ++ else ++ { ++ nexttotal = nextline[xx-1] + nextline[xx] + nextline[xx+1]; ++ sp13 = nextline [xx-1]; ++ sp23 = nextline [xx]; ++ sp33 = nextline [xx+1]; ++ nextdiff = sp23 - sp22; ++ lefttotal = sp11 + sp12 + sp13; ++ righttotal = sp31 + sp32 + sp33; ++ } ++ ++ sidesdiff = lefttotal - righttotal; ++ ++ if ( sidesdiff < 0 ) ++ sidesdiff *= -1; ++ ++ if ( prevdiff < 0 ) ++ prevdiff *= -1; ++ ++ if ( nextdiff < 0 ) ++ nextdiff *= -1; ++ ++ /* if the current pixel is less than threshold, and greater than 0 */ ++ if ( sp22 <= threshold && sp22 > 0 ) ++ { ++ /* A pixel is horizontally isolated if: */ ++ /* 1: All upper adjecent pixels are >= threshold */ ++ if ( prevtotal >= nexttotal && ++ abs( sp11 - sp12 ) > 5 && ++ abs( sp21 - sp22 ) > 5 && ++ abs( sp31 - sp32 ) > 5 && /* not a vert stem end */ ++ sp11 >= threshold && ++ sp21 >= threshold && ++ sp31 >= threshold && ++ abs( sp23 - sp22 ) > 15 ) /* not on a vert stem */ ++ { ++ /* darken upper adjacent subpixel; lighten current */ ++ if ( height != (FT_UInt)bitmap->rows ) ++ new_prevline[xx] += ( ( 255 - new_prevline[xx] ) ++ * strength ) / 100 ; ++ ++ new_line[xx] -= ( new_line[xx] * strength ) / 100; ++ ++ if ( height != 1 && height != (FT_UInt)bitmap->rows ) ++ if ( new_nextline[xx] > 155 + ( 100 - strength ) ) ++ new_prevline[xx] = 255; ++ ++ } ++ else if ( nexttotal > prevtotal && ++ abs( sp13 - sp12 ) > 5 && ++ abs( sp23 - sp22 ) > 5 && ++ abs( sp33 - sp32 ) > 5 && ++ /* 2: All lower adjecent pixels are >= threshold */ ++ sp13 >= threshold && ++ sp23 >= threshold && ++ sp33 >= threshold && ++ abs( sp22 - sp21 ) > 15 ) ++ { ++ /* darken lower adjacent subpixel; lighten current */ ++ if ( height != 1 ) ++ new_nextline[xx] += ( 255 - new_nextline[xx] ) * strength / 100; ++ ++ new_line[xx] -= ( new_line[xx] * strength ) / 100; ++ ++ if ( height != 1 ) ++ if ( new_nextline[xx] > 155 + ( 100 - strength ) ) ++ new_nextline[xx] = 255; ++ ++ } ++ } ++ else if ( sp22 > threshold && sp22 < 255 ) ++ { ++ if ( sp11 <= threshold && ++ abs( sp13 - sp12 ) > 5 && ++ abs( sp23 - sp22 ) > 5 && ++ abs( sp33 - sp32 ) > 5 && ++ sp21 <= threshold && ++ sp31 <= threshold && ++ prevtotal <= nexttotal && ++ abs( sp22 - sp21 ) > 15 ) ++ { ++ /* bring this subpixel 1/3 of the way to 255 at 100% strength */ ++ new_line[xx] += ( strength * ( 255 - new_line[xx] ) ) / 100; ++ ++ if ( height != (FT_UInt)bitmap->rows ) ++ new_prevline[xx] -= ( new_prevline[xx] * strength ) / 300; ++ } ++ else if ( sp13 <= threshold && ++ abs( sp11 - sp12 ) > 5 && ++ abs( sp21 - sp22 ) > 5 && ++ abs( sp31 - sp32 ) > 5 && ++ sp23 <= threshold && ++ sp33 <= threshold && ++ nexttotal < prevtotal && ++ abs( sp23 - sp22 ) > 15 ) ++ { ++ new_line[xx] += ( strength * ( 255 - new_line[xx] ) ) / 100; ++ ++ if ( height != 1 ) ++ new_nextline[xx] -= ( new_nextline[xx] * strength ) / 300; ++ } ++ } ++ } ++ } ++ FT_Bitmap_Copy( library, &new_bitmap, bitmap); ++ FT_Bitmap_Done( library, &new_bitmap ); ++ } ++ ++ ++ static void ++ _ft_lcd_darken_x ( FT_Bitmap* bitmap, ++ FT_Render_Mode mode, ++ FT_UInt strength, ++ FT_Library library ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* new_line; ++ FT_Byte* line = bitmap->buffer; ++ FT_Bitmap new_bitmap; ++ int factor1, factor2; ++ int bias = 0; ++ ++ FT_Bitmap_New( &new_bitmap ); ++ ++ FT_Bitmap_Copy( library, bitmap, &new_bitmap ); ++ new_line = (&new_bitmap)->buffer; ++ ++ if ( strength > 0 ) ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch, new_line += bitmap->pitch ) ++ { ++ FT_UInt xx; ++ FT_Byte* prevline = line - bitmap->pitch; ++ FT_Byte* nextline = line + bitmap->pitch; ++ ++ for ( xx = 1; xx < width - 1; xx += 1 ) ++ { ++ /* subpixel grid sp11 sp21 sp31 */ ++ /* where sp22 is sp12 sp22 sp32 */ ++ /* current subpixel. sp13 sp23 sp33 */ ++ ++ FT_Int sp21, sp12, sp22, sp32, sp23; ++ ++ sp12 = line [xx-1]; ++ sp22 = line [xx]; ++ sp32 = line [xx+1]; ++ ++ if ( height == bitmap->rows ) ++ sp21 = 0; ++ else ++ sp21 = prevline [xx]; ++ ++ if ( height == 1 ) ++ sp23 = 0; ++ else ++ sp23 = nextline [xx]; ++ ++ /* darken subpixel if neighbor above and below are much less than */ ++ /* safer but less effective */ ++ factor1 = 5; ++ factor2 = 5; ++ ++ /* make matches in the middle of glyph slightly darker */ ++ /*if (height > 1 && height < (FT_UInt)bitmap->rows) bias = 1;*/ ++ ++ if ( sp22 > factor1 * sp21 && ++ sp22 > factor1 * sp23 && ++ sp22 > factor2 && ++ sp12 > 16 && ++ sp32 > 16 ) ++ if ( new_line[xx] < ( strength * 255 ) / 100 ) ++ new_line[xx] = (strength * 255 ) / 100 ++ + bias * ( 255 - ( strength * 255 ) / 100 ) / 3; ++ ++ } ++ } ++ FT_Bitmap_Copy( library, &new_bitmap, bitmap ); ++ FT_Bitmap_Done( library, &new_bitmap ); ++ } ++ ++ ++ static void ++ _ft_lcd_darken_y ( FT_Bitmap* bitmap, ++ FT_Render_Mode mode, ++ FT_UInt strength, ++ FT_Library library ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* new_line; ++ FT_Byte* line = bitmap->buffer; ++ FT_Bitmap new_bitmap; ++ ++ ++ FT_Bitmap_New( &new_bitmap ); ++ FT_Bitmap_Copy( library, bitmap, &new_bitmap ); ++ new_line = (&new_bitmap)->buffer; ++ ++ if ( strength > 0 ) ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch, new_line += bitmap->pitch ) ++ { ++ FT_UInt xx; ++ ++ ++ for ( xx = 1; xx < width - 1; xx += 1 ) ++ { ++ if ( line[xx] > line[xx-1] && line[xx] > line[xx+1] ) ++ { ++ if (new_line[xx] > 0) ++ new_line[xx] += ( strength * ( 255 - new_line[xx] ) ) / 100; ++ new_line[xx-1] += ( strength * ( 255 - line[xx-1] ) ) / 100; ++ new_line[xx+1] += ( strength * ( 255 - line[xx+1] ) ) / 100; ++ } ++ } ++ } ++ FT_Bitmap_Copy( library, &new_bitmap, bitmap ); ++ FT_Bitmap_Done( library, &new_bitmap ); ++ } ++ ++ ++ static void ++ _ft_bitmap_cap ( FT_Bitmap* bitmap, ++ FT_UInt strength, ++ FT_Library library ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* new_line; ++ FT_Byte* line = bitmap->buffer; ++ FT_UInt cur_value = 0; ++ FT_Bitmap new_bitmap; ++ ++ ++ FT_Bitmap_New( &new_bitmap ); ++ FT_Bitmap_Copy( library, bitmap, &new_bitmap ); ++ new_line = (&new_bitmap)->buffer; ++ ++ if ( strength > 0 ) ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch, new_line += bitmap->pitch ) ++ { ++ FT_UInt xx; ++ ++ ++ for ( xx = 1; xx < width - 1; xx += 1 ) ++ { ++ cur_value = ( new_line[xx-1] + new_line[xx] + new_line[xx+1] ) / 3; ++ if ( cur_value > ( strength * 255 ) / 100 ) ++ { ++ FT_UInt new_factor = ( strength * 255 ) / 100; ++ new_line[xx] = ( new_line[xx] * new_factor ) / cur_value; ++ new_line[xx+1] = ( new_line[xx+1] * new_factor ) / cur_value; ++ new_line[xx-1] = ( new_line[xx-1] * new_factor ) / cur_value; ++ } ++ } ++ } ++ FT_Bitmap_Copy( library, &new_bitmap, bitmap ); ++ FT_Bitmap_Done( library, &new_bitmap ); ++ } ++ ++ static int ++ pseudo_gamma ( int val, float value ) ++ { ++ return 256 * ( 1.0f - powf( ( 1.0f - val * (1.0f/256.0f) ), 1.0f / value ) ); ++ } ++ ++#if(0) ++ static void ++ _ft_bitmap_embolden ( FT_Bitmap* bitmap, ++ FT_UInt strength, ++ FT_Library library ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* new_line; ++ FT_Byte* line = bitmap->buffer; ++ FT_Bitmap new_bitmap; ++ FT_UInt xx; ++ ++ ++ FT_Bitmap_New(&new_bitmap); ++ FT_Bitmap_Copy(library, bitmap, &new_bitmap); ++ new_line = (&new_bitmap)->buffer; ++ ++ if ( strength > 0 ) ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch, new_line += bitmap->pitch ) ++ { ++ for ( xx = 1; xx < width - 1; xx += 1 ) ++ { ++ FT_Int new_value = 0; ++ ++ ++ new_value = ( strength * line [xx-1] ) / 100 ++ + pseudo_gamma( line [xx], .75 ) ++ + (strength * line [xx+1] ) / 100; ++ if ( new_value > 255 ) ++ new_value = 255; ++ ++ new_line[xx] = new_value; ++ } ++ } ++ FT_Bitmap_Copy( library, &new_bitmap, bitmap ); ++ FT_Bitmap_Done( library, &new_bitmap ); ++ } ++ ++ ++ ++ static void ++ _ft_bitmap_gamma ( FT_Bitmap* bitmap, ++ float strength ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* line = bitmap->buffer; ++ FT_UInt xx; ++ ++ ++ if ( strength > 0 ) ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch ) ++ { ++ ++ for ( xx = 1; xx < width - 1; xx += 1 ) ++ { ++ if ( abs( line[xx-1] - line[xx] ) < 20 || ++ abs( line[xx+1] - line[xx] ) < 20 ) ++ line [xx] = pseudo_gamma( line [xx], strength ) ; ++ } ++ } ++ } ++#endif ++ ++ /* Fringe filter */ ++ static void ++ _ft_lcd_fringe_filter ( FT_Bitmap* bitmap, ++ FT_Render_Mode mode, ++ FT_UInt strength, ++ FT_Library library ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* new_line; ++ FT_Byte* line = bitmap->buffer; ++ FT_Bitmap new_bitmap; ++ ++ ++ FT_Bitmap_New(&new_bitmap); ++ ++ line = bitmap->buffer; ++ FT_Bitmap_Copy( library, bitmap, &new_bitmap ); ++ new_line = (&new_bitmap)->buffer; ++ ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch, new_line += bitmap->pitch ) ++ { ++ /* Threshold set to 1/2 pixel intensity */ ++ FT_UInt xx, threshold = 128; ++ ++ /* Hack to make this work when bitmap is at first or last line */ ++ FT_Int fudge = bitmap->pitch * (height == (FT_UInt)bitmap->rows); ++ ++ FT_Byte* prevline = line - bitmap->pitch + fudge; ++ FT_Byte* nextline = line + bitmap->pitch; ++ ++ ++ for ( xx = 1; xx < width - 1; xx += 1 ) ++ { ++ /* subpixel grid sp11 sp21 sp31 */ ++ /* where sp22 is sp12 sp22 sp32 */ ++ /* current subpixel. sp13 sp23 sp33 */ ++ ++ FT_Int prevtotal, nexttotal, lefttotal, righttotal, sidesdiff, ++ leftdiff, rightdiff, prevdiff, nextdiff, sp11, sp21, sp31, ++ sp12, sp22, sp32, sp13, sp23, sp33; ++ ++ sp12 = line [xx-1]; ++ sp22 = line [xx]; ++ sp32 = line [xx+1]; ++ ++ /* if at max height fake out some values */ ++ if ( height == (FT_UInt)bitmap->rows ) ++ { ++ prevtotal = sp11 = sp21 = sp31 = 0; ++ prevdiff = sp22; ++ lefttotal = sp12 + sp13; ++ righttotal = sp32 + sp33; ++ } ++ else ++ { ++ prevtotal = prevline[xx-1] + prevline[xx] + prevline[xx+1]; ++ sp11 = prevline [xx-1]; ++ sp21 = prevline [xx]; ++ sp31 = prevline [xx+1]; ++ prevdiff = sp22 - sp21; ++ lefttotal = sp11 + sp12 + sp13; ++ righttotal = sp31 + sp32 + sp33; ++ } ++ ++ /* if at min height fake out some values */ ++ if ( height == 1 ) ++ { ++ nexttotal = sp13 = sp23 = sp33 = 0; ++ nextdiff = sp22; ++ lefttotal = sp11 + sp12; ++ righttotal = sp31 + sp32; ++ } ++ else ++ { ++ nexttotal = nextline[xx-1] + nextline[xx] + nextline[xx+1]; ++ sp13 = nextline [xx-1]; ++ sp23 = nextline [xx]; ++ sp33 = nextline [xx+1]; ++ nextdiff = sp23 - sp22; ++ lefttotal = sp11 + sp12 + sp13; ++ righttotal = sp31 + sp32 + sp33; ++ } ++ ++ sidesdiff = lefttotal - righttotal; ++ leftdiff = sp22 - sp12; ++ rightdiff = sp32 - sp22; ++ ++ if ( sidesdiff < 0 ) ++ sidesdiff *= -1; ++ ++ if ( prevdiff < 0 ) ++ prevdiff *= -1; ++ ++ if ( nextdiff < 0 ) ++ nextdiff *= -1; ++ ++ if ( leftdiff < 0 ) ++ leftdiff *= -1; ++ ++ if ( rightdiff < 0 ) ++ rightdiff *= -1; ++ ++ /* if the current subpixel is less than threshold, and varies only ++ slightly to left or right, lighten it */ ++ if ( sp22 <= threshold && sp22 > 0 && ++ ( leftdiff < 10 || rightdiff < 10 ) ) ++ { ++ /* A pixel is horizontally isolated if: */ ++ /* 1: All upper adjecent subpixels are >= threshold and all lower ++ adjacent ones are essentially white */ ++ if ( prevtotal >= nexttotal && ++ sp11 >= threshold && ++ sp21 >= threshold && ++ sp31 >= threshold && ++ sp13 < 2 && ++ sp23 < 2 && ++ sp33 < 2 ) ++ ++ { ++ new_line[xx] -= ( new_line[xx] * strength ) / 100; ++ ++ if ( leftdiff < 10 ) ++ /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */ ++ new_line[xx-1] -= ( new_line[xx-1] * strength ) / 200; ++ ++ if ( rightdiff < 10 ) ++ /* OPPORTUNITY FOR IMPROVEMENT */ ++ new_line[xx+1] -= ( new_line[xx+1] * strength ) / 200; ++ } ++ else if ( nexttotal > prevtotal && ++ /* 2: the inverse of above */ ++ sp13 >= threshold && ++ sp23 >= threshold && ++ sp33 >= threshold && ++ sp11 < 2 && ++ sp21 < 2 && ++ sp31 < 2 ) ++ { ++ new_line[xx] -= ( new_line[xx] * strength ) / 100; ++ ++ if ( leftdiff < 10 ) ++ /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */ ++ new_line[xx-1] -= ( new_line[xx-1] * strength ) / 200; ++ ++ if ( rightdiff < 10 ) ++ /* OPPORTUNITY FOR IMPROVEMENT */ ++ new_line[xx+1] -= ( new_line[xx+1] * strength ) / 200; ++ } ++ } ++ /* otherwise if the current subpixel is more than threshold, and varies ++ slightly to left or right, darken it */ ++ else if ( sp22 > threshold && ++ sp22 < 255 && ++ ( leftdiff < 10 || ++ rightdiff < 10 ) ) ++ { ++ if ( sp11 <= 2 && ++ sp21 <= 2 && ++ sp31 <= 2 && ++ sp13 >= threshold && ++ sp23 >= threshold && ++ sp33 >= threshold && ++ prevtotal < nexttotal ) ++ new_line[xx] += ( ( 255 - new_line[xx] ) * strength ) / 100; ++ ++ else if ( sp13 <= 2 && ++ sp23 <= 2 && ++ sp33 <= 2 && ++ nexttotal < prevtotal && ++ sp11 >= threshold && ++ sp21 >= threshold && ++ sp31 >= threshold ) ++ new_line[xx] += ( ( 255 - new_line[xx] ) * strength ) / 100; ++ ++ } ++ } ++ } ++ FT_Bitmap_Copy( library, &new_bitmap, bitmap ); ++ FT_Bitmap_Done( library, &new_bitmap ); ++ } ++ ++ ++ /* Grayscale filter */ ++ static void ++ _ft_lcd_grayscale_filter ( FT_Bitmap* bitmap, ++ FT_Render_Mode mode, ++ FT_UInt strength, ++ FT_Library library ) ++ { ++ ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* line = bitmap->buffer; ++ ++ ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch ) ++ { ++ FT_UInt xx; ++ ++ ++ for ( xx = 0; xx < width - 1; xx += 3 ) ++ { ++ FT_UInt total = line [xx] + line [xx + 1] + line [xx + 2]; ++ line[xx] = ( ( 100 - strength ) * line[xx] ++ + strength * ( total / 3 ) ) / 100; ++ line[xx+1] = ( ( 100 - strength ) * line[xx+1] ++ + strength * ( total / 3 ) ) / 100; ++ line[xx+2] = ( ( 100 - strength ) * line[xx+2] ++ + strength * ( total / 3 ) ) / 100; ++ } ++ } ++ } ++ ++/* ++ These need to be in sync with params inside ftinf.c ++ (not ideal but perhaps better than making these public) ++ */ ++#define STEM_WIDTH_2_PPEM 18 ++#define MAX_PPEM 100 ++ ++ typedef struct Stem_Segment_ ++ { ++ FT_Long x1; ++ FT_Long x2; ++ FT_Int y; ++ } Stem_Segment; ++ ++ typedef struct Stem_Center_ ++ { ++ FT_Long x; ++ FT_Long y; ++ FT_Long w; ++ FT_Long x1; ++ FT_Long x2; ++ } Stem_Center; ++ ++ typedef struct Stem_ ++ { ++ FT_Long center; ++ FT_Long count; ++ FT_Long rcount; /* used to count within a range in possible stems */ ++ FT_Long width; ++ FT_Long height; ++ FT_Short zone; /* 1 2 or 3 */ ++ FT_Bool generated; ++ } Stem; ++ ++ static void ++ swap_stem ( Stem* s1, Stem* s2 ) ++ { ++ Stem s; ++ s.center = s1->center; ++ s.count = s1->count; ++ s.rcount = s1->rcount; ++ s.width = s1->width; ++ s.zone = s1->zone; ++ s.generated = s1->generated; ++ ++ s1->center = s2->center; ++ s1->count = s2->count; ++ s1->rcount = s2->rcount; ++ s1->width = s2->width; ++ s1->zone = s2->zone; ++ s1->generated = s2->generated; ++ ++ s2->center = s.center; ++ s2->count = s.count; ++ s2->rcount = s.rcount; ++ s2->width = s.width; ++ s2->zone = s.zone; ++ s2->generated = s.generated; ++ } ++ ++ /* Stem alignment for bitmaps; A hack with very nice results */ ++ /* Ideally this could be implemented on the outline, prior to ++ * rasterization. Possible future enhancement is to use the ++ * warper code to achieve this */ ++ static void ++ _lcd_stem_align ( FT_Bitmap* bitmap, ++ FT_Render_Mode mode, ++ FT_GlyphSlot slot, ++ FT_Long* translate_value, ++ float* scale_value, ++ FT_UInt alignment_strength, ++ FT_UInt fitting_strength, ++ float* embolden_value ++ ) ++ { ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ ++ Stem_Segment* segments; ++ Stem_Segment* leftmost_segment; ++ Stem_Segment* rightmost_segment; ++ Stem_Segment* leftmost_segment_not_extrema; ++ Stem_Segment* rightmost_segment_not_extrema; ++ Stem* stems; ++ Stem* possible_stems; ++ Stem* leftmost_stem; ++ Stem* rightmost_stem; ++ Stem_Data* known_stem_values; ++ Stem_Center* centers; ++ FT_Long leftmost_point = width * 256; ++ FT_Long rightmost_point = 0; ++ FT_Long leftmost_point_not_extrema = width * 256; ++ FT_Long rightmost_point_not_extrema = 0; ++ FT_Long num_segments = 0; ++ FT_Long num_centers = 0; ++ FT_Long *stem_centers; ++ FT_UInt h; ++ FT_ULong valid_stems = 0, valid_possible_stems = 0; ++ FT_Long center, stem_matches, stem_matches_ledge; ++ FT_Long stem_matches_redge, next_center, last_matching_center; ++ FT_Long last_matching_ledge, last_matching_redge, this_center; ++ FT_Int max_strength; ++ FT_Byte* line = bitmap->buffer; ++ FT_UInt current_value = 0; ++ FT_UInt xx; ++ FT_Long linearHoriAdvance = slot->linearHoriAdvance >> 10; ++ ++ FT_Int m_horiBearingX = slot->metrics.horiBearingX; ++ FT_Int m_horiAdvance = slot->metrics.horiAdvance; ++ FT_Int m_width = slot->metrics.width; ++ FT_Pos one_pixel = 768; ++ FT_Pos one_third_pixel = 256; ++ FT_Int columns_per_pixel = 3; ++ /*FT_Int extra_columns = 6;*/ ++ ++ /* on / off flags for testing different features */ ++ FT_Bool strategy_translate_using_closest_stem = TRUE; ++ FT_Bool strategy_scale_to_closest_centers = FALSE; ++ FT_Bool strategy_scale_to_closest_centers_up_only = FALSE; ++ FT_Bool strategy_always_use_distance_ceiling = FALSE; ++ FT_Bool strategy_auto_change_center_offset = TRUE; ++ FT_Bool strategy_use_m_control = FALSE; ++ FT_Bool strategy_correct_out_of_bounds_outlines = FALSE; ++ FT_Bool strategy_also_use_edge_detection_for_stems = FALSE; ++ FT_Bool strategy_use_strengths = TRUE; ++ FT_Bool strategy_synthesize_stems = FALSE; ++ FT_Bool strategy_bearing_correction = TRUE; ++ FT_Bool strategy_use_d_correction = TRUE; ++ FT_Bool strategy_fit_to_width = FALSE; ++ /*FT_Bool strategy_center_glyph = FALSE;*/ ++ ++ const FT_Int MIN_PPEM = 7; ++ /*const FT_Int MAX_PPEM = 100;*/ ++ const FT_Int MAX_STEMS = 3; ++ FT_Int ppem = 0; ++ ++ Stem_Data stem_data; ++ ++ /* reset to default */ ++ *scale_value = 1.0; ++ ++ /* Simply return in odd cases where these don't seem to be set */ ++ /* Flash and some pdf viewers will crash otherwise */ ++ if ( !slot->face || ++ !slot->face->size || ++ !slot->face->size->metrics.x_ppem ) ++ return; ++ ++ if ( slot->face->size->metrics.x_ppem > MAX_PPEM ) ++ return; ++ ++ if ( slot->face->size->metrics.x_ppem < MIN_PPEM ) ++ return; ++ ++ if ( !FT_IS_SCALABLE( slot->face ) ) ++ return; ++ ++ ppem = slot->face->size->metrics.x_ppem; ++ ++ if ( ppem < 9 ) ++ return; ++ if ( ppem > 20 ) ++ strategy_use_m_control = TRUE; ++ ++ /* only perform alignment on styles we know, that aren't bold or italic */ ++ /* perhaps detection could be added on those that are not set? */ ++ /* Require certain ppems for narrow and light fonts */ ++ if( slot->face->style_name ) ++ { ++ if ( strcasestr( slot->face->style_name, "Italic" ) || ++ strcasestr( slot->face->style_name, "Oblique" ) || ++ strcasestr( slot->face->style_name, "Script" ) || ++ strcasestr( slot->face->style_name, "Handwriting" ) || ++ strcasestr( slot->face->style_name, "Bold" ) || ++ strcasestr( slot->face->style_name, "Black" ) || ++ ( ( strcasestr( slot->face->style_name, "Extra Thin" ) || ++ strcasestr( slot->face->style_name, "Extra Light" ) ) && ++ ppem < 10 ) || ++ ( strcasestr( slot->face->style_name, "Thin" ) ++ && ppem < 10 ) || ++ ( strcasestr( slot->face->style_name, "Light" ) ++ && ppem < 10 ) || ++ ( strcasestr( slot->face->style_name, "Narrow" ) ++ && ppem < 15 ) || ++ ( strcasestr( slot->face->style_name, "Condensed" ) ++ && ppem < 20 ) ) ++ return; ++ } ++ ++ if( slot->face->family_name ) ++ { ++ if ( strcasestr( slot->face->family_name, "Italic" ) || ++ strcasestr( slot->face->family_name, "Oblique" ) || ++ strcasestr( slot->face->family_name, "Script" ) || ++ strcasestr( slot->face->family_name, "Handwriting" ) || ++ strcasestr( slot->face->family_name, "Bold" ) || ++ strcasestr( slot->face->family_name, "Black" ) || ++ ( ( strcasestr( slot->face->family_name, "Extra Thin" ) || ++ strcasestr( slot->face->family_name, "Extra Light" ) ) && ++ ppem < 10 ) || ++ ( strcasestr( slot->face->family_name, "Thin" ) ++ && ppem < 10 ) || ++ ( strcasestr( slot->face->family_name, "Light" ) ++ && ppem < 10 ) || ++ ( strcasestr( slot->face->family_name, "Narrow" ) ++ && ppem < 15 ) || ++ ( strcasestr( slot->face->family_name, "Condensed" ) ++ && ppem < 20 ) ) ++ return; ++ } ++ else if ( slot->face->style_flags ) ++ { ++ if ( slot->face->style_flags & FT_STYLE_FLAG_ITALIC || ++ slot->face->style_flags & FT_STYLE_FLAG_BOLD || ++ FT_IS_TRICKY( slot->face ) ) ++ return; ++ } ++ else return; ++ ++ if ( mode != FT_RENDER_MODE_LCD ) ++ { ++ columns_per_pixel = 1; ++ one_pixel = 256; ++ one_third_pixel = 85; ++ /*extra_columns = 0;*/ ++ /* until this can be figured out just return */ ++ /* There are issues with missing glyphs */ ++ return; ++ } ++ ++ known_stem_values=&stem_data; ++ if ( ftinf && ftinf->use_known_settings_on_selected_fonts ) ++ { ++ ftinf_fill_stem_values( known_stem_values, slot->face->family_name, ppem, TRUE ); ++ /* translate value may be set for < 10 */ ++ if (known_stem_values->stem_translating_only > -1024 ) ++ { ++ *translate_value = known_stem_values->stem_translating_only; ++ return; ++ } ++ if( known_stem_values->bearing_correction == FALSE ) ++ strategy_bearing_correction = FALSE; ++ } else ++ ftinf_fill_stem_values( known_stem_values, slot->face->family_name, ppem, FALSE ); ++ ++ if ( known_stem_values->use_100 || ++ known_stem_values->m >= 0 ) ++ { ++ alignment_strength = fitting_strength = 100; ++ strategy_use_m_control = TRUE; ++ } ++ ++ if ( known_stem_values->edge_detection ) ++ strategy_also_use_edge_detection_for_stems = TRUE; ++ ++ /* Allocate */ ++ segments = NULL; ++ leftmost_segment = (Stem_Segment*) malloc( 4*sizeof ( Stem_Segment ) ); ++ leftmost_segment_not_extrema = leftmost_segment+1; ++ rightmost_segment = leftmost_segment+2; ++ rightmost_segment_not_extrema = leftmost_segment+3; ++ ++ stems = (Stem*) malloc ( (2*MAX_STEMS+2) * sizeof ( Stem ) ); ++ possible_stems = stems+MAX_STEMS; ++ leftmost_stem = possible_stems+MAX_STEMS; ++ rightmost_stem = leftmost_stem + 1; ++ centers = NULL; ++ ++ if ( verbose ) ++ printf("\n"); ++ ++ /* Initialize */ ++ stem_centers=(FT_Long*)calloc( width * 256, sizeof(stem_centers[0]) ); ++ ++ rightmost_segment->x1 = 0; ++ rightmost_segment->x2 = 0; ++ rightmost_segment->y = 0; ++ leftmost_segment->x1 = 99999999; ++ leftmost_segment->x2 = 0; ++ leftmost_segment->y = 0; ++ ++ rightmost_segment_not_extrema->x1 = 0; ++ rightmost_segment_not_extrema->x2 = 0; ++ rightmost_segment_not_extrema->y = 0; ++ leftmost_segment_not_extrema->x1 = 99999999; ++ leftmost_segment_not_extrema->x2 = 0; ++ leftmost_segment_not_extrema->y = 0; ++ ++ /* Locate stem centers for later processing */ ++ for ( h = (FT_UInt)bitmap->rows; h > 0; h--, line += bitmap->pitch ) ++ { ++ current_value = 0; ++ /* Calculate various sums and stem widths of glyph */ ++ for ( xx = 0; xx < width; xx += 1 ) ++ { ++ /* Reallocate (in blocks of 64) */ ++ if( num_segments % 64 == 0 ) ++ segments = (Stem_Segment*) realloc ++ ( segments, ( num_segments + 64 ) * sizeof ( Stem_Segment ) ); ++ ++ /* if line is white, and now has color, it's the start of a stem */ ++ if ( current_value == 0 && line[xx] > 0 ) ++ { ++ /* start of stem */ ++ segments[num_segments].x1 = 256 * xx + ( 255 - line[xx] ); ++ segments[num_segments].y = h; ++ } ++ ++ /* otherwise, if it's currently black and the new value is 0, ++ it's the end of a stem */ ++ else if ( ( current_value > 0 && line[xx] == 0 ) || ++ ( current_value > 0 && xx == width - 1 ) ) ++ { ++ FT_Long stem_center_x; ++ segments[num_segments].x2 = 256 * ( xx - 1 ) + line[xx-1]; ++ ++ if ( xx == width - 1 ) ++ segments[num_segments].x2 += line[xx]; ++ ++ /*stem center is average of start and end of stem */ ++ stem_center_x = ( segments[num_segments].x2 ++ + segments[num_segments].x1 ) / 2; ++ ++ /* Reallocate (in blocks of 32) */ ++ if( num_centers % 32 == 0 ) ++ centers = (Stem_Center*) realloc ++ ( centers, ( num_centers + 32 ) * sizeof ( Stem_Center ) ); ++ centers[num_centers].x = stem_center_x; ++ centers[num_centers].y = h; ++ centers[num_centers].x1 = segments[num_segments].x1; ++ centers[num_centers].x2 = segments[num_segments].x2; ++ ++ num_centers++; ++ ++ stem_centers[stem_center_x] += 1; ++ ++ /* Find left and rightmost points for later calculations */ ++ /* OR - Favor ones that aren't on the top or bottom if */ ++ /* possible to prevent v and w from getting caught later */ ++ if ( segments[num_segments].x1 < leftmost_segment->x1 || ++ ( segments[num_segments].y > 1 && ++ segments[num_segments].y < height && ++ segments[num_segments].x1 == leftmost_segment->x1 ) ) ++ { ++ leftmost_segment->x1 = segments[num_segments].x1; ++ leftmost_segment->x2 = segments[num_segments].x2; ++ leftmost_segment->y = h; ++ } ++ if ( segments[num_segments].x2 > rightmost_segment->x2 || ++ ( segments[num_segments].y > 1 && ++ segments[num_segments].y < height && ++ segments[num_segments].x1 == rightmost_segment->x1 ) ) ++ { ++ rightmost_segment->x1 = segments[num_segments].x1; ++ rightmost_segment->x2 = segments[num_segments].x2; ++ rightmost_segment->y = h; ++ } ++ ++ if ( segments[num_segments].x1 ++ < leftmost_segment_not_extrema->x1 || ++ ( segments[num_segments].y > 1 && ++ segments[num_segments].y < height && ++ segments[num_segments].x1 ++ == leftmost_segment_not_extrema->x1 && ++ h < (FT_UInt)bitmap->rows && h > 0 ) ) ++ { ++ leftmost_segment_not_extrema->x1 = segments[num_segments].x1; ++ leftmost_segment_not_extrema->x2 = segments[num_segments].x2; ++ leftmost_segment_not_extrema->y = h; ++ } ++ if ( segments[num_segments].x2 ++ > rightmost_segment_not_extrema->x2 || ++ ( segments[num_segments].y > 1 && ++ segments[num_segments].y < height && ++ segments[num_segments].x1 ++ == rightmost_segment_not_extrema->x1 && ++ h < (FT_UInt)bitmap->rows && h > 0 ) ) ++ { ++ rightmost_segment_not_extrema->x1 = segments[num_segments].x1; ++ rightmost_segment_not_extrema->x2 = segments[num_segments].x2; ++ rightmost_segment_not_extrema->y = h; ++ } ++ ++ if ( segments[num_segments].x1 < leftmost_point ) ++ leftmost_point = segments[num_segments].x1; ++ ++ if ( segments[num_segments].x2 > rightmost_point ) ++ rightmost_point = segments[num_segments].x2; ++ ++ if ( segments[num_segments].x1 < leftmost_point_not_extrema && ++ h < (FT_UInt)bitmap->rows && h > 0 ) ++ leftmost_point_not_extrema = segments[num_segments].x1; ++ ++ if ( segments[num_segments].x2 > rightmost_point_not_extrema && ++ h < (FT_UInt)bitmap->rows && h > 0 ) ++ rightmost_point_not_extrema = segments[num_segments].x2; ++ ++ num_segments++; ++ } ++ /* else - other conditions - need some error checking here */ ++ current_value = line[xx]; ++ } ++ } ++ ++ /* initialize */ ++ for ( xx = 0; xx < MAX_STEMS; xx +=1 ) ++ { ++ stems[xx].center = 0; ++ stems[xx].count = 0; ++ stems[xx].width = 0; ++ stems[xx].height = 0; ++ possible_stems[xx].center = 0; ++ possible_stems[xx].count = 0; ++ possible_stems[xx].width = 0; ++ possible_stems[xx].height = 0; ++ } ++ ++ valid_stems = 0; ++ valid_possible_stems = 0; ++ ++ /* Determine which centers belong to stems */ ++ center = 0; ++ ++ while ( center < num_centers ) ++ { ++ /* slope at within which to consider a point part of a stem */ ++ /*const FT_UInt slope = 1; ++ const FT_UInt topslope = (256 * 3) / 10; */ ++ ++ /* 10 to 20 with 4 matches seems good, */ ++ /* but 1 or 2 with 3 stems needs to somehow get included */ ++ FT_Int deviation1 = 5; ++ FT_Int deviation2=-1, requirement1 = 4, stem_match_requirement = 3; ++ FT_Int center_difference_in_height; ++ FT_Int center_difference_in_width, valid_center_average; ++ FT_Int smallest_width_ledge, smallest_width_redge; ++ FT_Int x1_difference_in_width, x2_difference_in_width; ++ FT_Bool no_gap_found = FALSE; ++ FT_Bool no_gap_found_ledge = FALSE; ++ FT_Bool no_gap_found_redge = FALSE; ++ FT_Bool stem_detected = FALSE; ++ FT_Int set_width_to, set_center_to; ++ ++ /* seems to not do damage */ ++ /* May not be effective */ ++ requirement1 = height / 4; ++ if ( requirement1 < 5 ) ++ requirement1 = 5; ++ deviation1 = 20; ++ deviation2 = 20; ++ ++ if ( columns_per_pixel == 1 ) ++ deviation1 = deviation2 = 10; ++ ++ if ( (FT_Int)bitmap->rows <= 6 ) ++ deviation1 = 25; ++ ++ if ( (FT_Int)bitmap->rows <= 6 ) ++ deviation2 = 25; ++ ++ if ( columns_per_pixel == 1 && ++ (FT_Int)bitmap->rows <= 6 ) ++ deviation1 = deviation2 = 12; ++ ++ valid_center_average = 0; ++ ++ no_gap_found = no_gap_found_ledge = no_gap_found_redge = FALSE; ++ stem_detected = FALSE; ++ ++ if ( ppem < 11 ) ++ requirement1 = 4; ++ ++ if ( ppem > 18 ) ++ { ++ stem_match_requirement = height / 4; ++ if ( stem_match_requirement < 3 ) ++ stem_match_requirement = 3; ++ } ++ ++ smallest_width_ledge = smallest_width_redge = width * 256; ++ stem_matches = 0; ++ stem_matches_ledge = 0; ++ stem_matches_redge = 0; ++ last_matching_center = -1; ++ last_matching_ledge = -1; ++ last_matching_redge = -1; ++ ++ /* set currently looked at center to center value */ ++ this_center = center; ++ next_center = 0; ++ ++ /* For each center, compare with all other centers to see if others */ ++ /* match the properties of this one */ ++ while ( next_center < num_centers ) ++ { ++ ++ /* calculate differences */ ++ center_difference_in_width = abs ( centers[this_center].x ++ - centers[next_center].x ); ++ center_difference_in_height = abs ( centers[this_center].y ++ - centers[next_center].y ); ++ x1_difference_in_width = abs ( centers[this_center].x1 ++ - centers[next_center].x1 ); ++ x2_difference_in_width = abs ( centers[this_center].x2 ++ - centers[next_center].x2 ); ++ ++ ++ /* property - stem center points that align */ ++ /* if the center is within range, the center is less than */ ++ /* 1/2 the height away, and at least one edge is also within range */ ++ if ( center_difference_in_width ++ < center_difference_in_height * deviation1 && ++ center_difference_in_height ++ <= (FT_Int)bitmap->rows / 2 && ++ /* prevents w from getting caught ---- but also kills m */ ++ ( x1_difference_in_width ++ < center_difference_in_height * deviation2 || ++ x2_difference_in_width ++ < center_difference_in_height * deviation2 ) ) ++ { ++ stem_matches += 1; ++ valid_center_average += centers[next_center].x; ++ ++ /* try to find where the matching centers are far apart */ ++ if ( last_matching_center >= 0 && ++ abs( centers[last_matching_center].y ++ - centers[next_center].y ) >= (FT_Int)bitmap->rows / 2 ) ++ ++ /* try to find where matching centers are next to each other */ ++ if ( last_matching_center >= 0 && ++ abs( centers[last_matching_center].y ++ - centers[next_center].y ) == 1 ) ++ no_gap_found = TRUE; ++ ++ last_matching_center = next_center; ++ } ++ ++ if ( strategy_also_use_edge_detection_for_stems ) ++ { ++ /* property - stem left edge points that align */ ++ /* if the center is within range, */ ++ /* the center is less than 1/2 the height away */ ++ if ( x1_difference_in_width ++ < center_difference_in_height * deviation1 && ++ center_difference_in_height <= (FT_Int)bitmap->rows / 2 ) ++ { ++ stem_matches_ledge += 1; ++ /* may not need for edges */ ++ /*valid_center_average += centers[next_center].x; */ ++ ++ if ( centers[next_center].x2 - centers[next_center].x1 ++ < smallest_width_ledge ) ++ smallest_width_ledge = centers[next_center].x2 ++ - centers[next_center].x1; ++ ++ /* try to find where the matching centers are far apart */ ++ if ( last_matching_ledge >= 0 && ++ abs( centers[last_matching_ledge].y ++ - centers[next_center].y) ++ >= (FT_Int)bitmap->rows / 2 ) ++ ++ /* try to find where matching centers are next to each other */ ++ if ( last_matching_ledge >= 0 && ++ abs( centers[last_matching_ledge].y ++ - centers[next_center].y ) == 1 ) ++ no_gap_found_ledge = TRUE; ++ last_matching_ledge = next_center; ++ } ++ } ++ ++ if ( strategy_also_use_edge_detection_for_stems ) ++ { ++ /* property - stem right edge points that align */ ++ /* if the center is within range, the center is less than 1/2 */ ++ /* the height away */ ++ if ( x2_difference_in_width ++ < center_difference_in_height * deviation1 && ++ center_difference_in_height ++ <= (FT_Int)bitmap->rows / 2 ) ++ { ++ stem_matches_redge += 1; ++ /* may not need for edges */ ++ /*valid_center_average += centers[next_center].x; */ ++ ++ if ( centers[next_center].x2 - centers[next_center].x1 ++ < smallest_width_redge ) ++ smallest_width_redge = centers[next_center].x2 ++ - centers[next_center].x1; ++ ++ /* try to find where the matching centers are far apart */ ++ if ( last_matching_redge >= 0 && ++ abs( centers[last_matching_redge].y ++ - centers[next_center].y ) >= (FT_Int)bitmap->rows / 2 ) ++ ++ /* try to find where matching centers are next to each other */ ++ if ( last_matching_redge >= 0 && ++ abs( centers[last_matching_redge].y ++ - centers[next_center].y ) == 1 ) ++ no_gap_found_redge = TRUE; ++ ++ last_matching_redge = next_center; ++ } ++ } ++ ++ next_center++; ++ } ++ ++ if ( stem_matches > 0 ) ++ valid_center_average /= stem_matches; ++ ++ if ( ( stem_matches >= stem_match_requirement || ++ ( ( (FT_Int)bitmap->rows <= 6 || ppem < 11 ) && ++ stem_matches >= 2 && ++ abs ( valid_center_average ++ - centers[center].x) < deviation1 /2 ) || ++ /* try to catch tightly aligned stuff where the matching centers */ ++ /* are next to each other only */ ++ ( stem_matches == 2 && ++ abs( valid_center_average ++ - centers[center].x) <= deviation1 /2 && ++ no_gap_found && ++ ppem < 18 ) ) && ++ /* catches things like times 16 u but gets a lot of w's too */ ++ /* stem width is less than 1/3 of the bitmap width, */ ++ /* or bitmap_width is small */ ++ ( centers[center].x2 - centers[center].x1 ++ < (m_horiAdvance * 12) / 2 || ++ m_horiAdvance * 12 <= columns_per_pixel * one_pixel ) ) ++ { ++ stem_detected = TRUE; ++ set_width_to = centers[center].x2 - centers[center].x1; ++ set_center_to = centers[center].x; ++ } ++ ++ /* see if edges found anything */ ++ if ( strategy_also_use_edge_detection_for_stems && !stem_detected ) ++ { ++ /* Require no gap for edges */ ++ /* stem width less than 1/3 bitmap width, or bitmap_width is small */ ++ /* The stem occurs on the left side of glyph only */ ++ if ( ( stem_matches_ledge >= stem_match_requirement && ++ no_gap_found_ledge ) && ++ ( centers[center].x2 - centers[center].x1 ++ < ( m_horiAdvance * 12 ) / 2 || ++ m_horiAdvance * 12 <= columns_per_pixel * one_pixel ) && ++ centers[center].x < ( m_horiAdvance * 12 ) / 2 ) ++ { ++ stem_detected = TRUE; ++ set_width_to = smallest_width_ledge; ++ set_center_to = centers[center].x1 + set_width_to / 2; ++ stem_matches = stem_matches_ledge; ++ } ++ /* Require no gap for edges */ ++ /* stem width is less than 1/3 bitmap width, or bitmap_width is small */ ++ /* The stem occurs on the right side of glyph only */ ++ else if ( ( stem_matches_redge >= stem_match_requirement && ++ no_gap_found_redge ) && ++ ( centers[center].x2 - centers[center].x1 ++ < ( m_horiAdvance * 12 ) / 2 || ++ m_horiAdvance * 12 <= columns_per_pixel * one_pixel ) && ++ centers[center].x > (m_horiAdvance * 12) / 2 ) ++ { ++ stem_detected = TRUE; ++ set_width_to = smallest_width_redge; ++ set_center_to = centers[center].x2 - set_width_to / 2; ++ stem_matches = stem_matches_redge; ++ } ++ } ++ ++ ++ /*store and/or replace highest occurrences with 3 or more centers */ ++ /* because this matched, it will become the top dog regardless */ ++ if ( stem_detected && (stem_matches > possible_stems[0].height) ) ++ { ++ /* if this is the first stem just go ahead */ ++ if ( valid_possible_stems == 0 ) ++ { ++ valid_possible_stems = 1; ++ possible_stems[0].center = set_center_to; ++ possible_stems[0].count = stem_matches; ++ possible_stems[0].width = set_width_to; ++ possible_stems[0].height = stem_matches; ++ } ++ ++ /* otherwise, if there is already a stem */ ++ else if ( valid_possible_stems == 1 ) ++ { ++ /* if stem is within range of existing one, replace existing one */ ++ ++ /* if the stem isn't within the range of this one swap it with */ ++ /* next one first */ ++ if ( abs ( set_center_to - possible_stems[0].center ) ++ >= one_pixel * 2 ) ++ { ++ swap_stem ( &possible_stems[0], &possible_stems[1] ); ++ valid_possible_stems = 2; ++ } ++ possible_stems[0].center = set_center_to; ++ possible_stems[0].count = stem_matches; ++ possible_stems[0].width = set_width_to; ++ possible_stems[0].height = stem_matches; ++ } ++ ++ /* otherwise if there are already 2 stems */ ++ else if ( valid_possible_stems >= 2 ) ++ { ++ /* if the stem is within the range of existing one, replace */ ++ /* existing one */ ++ if ( abs ( set_center_to - possible_stems[0].center ) ++ <= one_pixel * 2 ) ++ { ++ possible_stems[0].center = set_center_to; ++ possible_stems[0].count = stem_matches; ++ possible_stems[0].width = set_width_to; ++ possible_stems[0].height = stem_matches; ++ } ++ /* if the stem isn't within the range of this one */ ++ else ++ { ++ /* see if within range of next one and swap if so and proceed */ ++ /* overwriting it */ ++ if ( abs ( set_center_to - possible_stems[1].center ) ++ <= one_pixel * 2 ) ++ swap_stem ( &possible_stems[0], &possible_stems[1] ); ++ ++ /* otherwise see if in range of third one */ ++ else if ( abs ( set_center_to - possible_stems[2].center ) ++ <= one_pixel * 2 ) ++ swap_stem ( &possible_stems[0], &possible_stems[2] ); ++ ++ /* otherwise this is the new top dog, so demote everything */ ++ else ++ { ++ swap_stem ( &possible_stems[1], &possible_stems[2] ); ++ swap_stem ( &possible_stems[0], &possible_stems[1] ); ++ valid_possible_stems += 1; ++ } ++ possible_stems[0].center = set_center_to; ++ possible_stems[0].count = stem_matches; ++ possible_stems[0].width = set_width_to; ++ possible_stems[0].height = stem_matches; ++ } ++ } ++ } ++ ++ else if ( stem_matches > possible_stems[1].height && ++ set_center_to != 0 ) ++ { ++ ++ /* make sure it doesn't match the first stem */ ++ if ( abs ( set_center_to - possible_stems[0].center ) >= one_pixel * 2 ) ++ { ++ ++ /* if this is the second stem */ ++ if ( valid_possible_stems == 1 ) ++ valid_possible_stems = 2; ++ ++ /* otherwise if there is already a stem here */ ++ else if ( valid_possible_stems >= 2 ) ++ { ++ /* if it doesn't match the second stem, proceed to swap out */ ++ /* with the third. if it does, replace it */ ++ if ( abs ( set_center_to - possible_stems[1].center ) ++ >= one_pixel * 2 ) ++ { ++ swap_stem ( &possible_stems[1], &possible_stems[2] ); ++ valid_possible_stems +=1; ++ } ++ } ++ possible_stems[1].center = set_center_to; ++ possible_stems[1].count = stem_matches; ++ possible_stems[1].width = set_width_to; ++ possible_stems[1].height = stem_matches; ++ } ++ } ++ ++ else if ( stem_matches > possible_stems[2].height && ++ set_center_to != 0 ) ++ { ++ /* if it doesn't match the first or second one */ ++ if ( abs( set_center_to - possible_stems[0].center) >= one_pixel * 2 && ++ abs( set_center_to - possible_stems[1].center) >= one_pixel * 2 ) ++ { ++ if ( valid_possible_stems == 2 ) ++ valid_possible_stems += 1; ++ ++ possible_stems[2].center = set_center_to; ++ possible_stems[2].count = stem_matches; ++ possible_stems[2].width = set_width_to; ++ possible_stems[1].height = stem_matches; ++ } ++ } ++ ++ if ( valid_possible_stems > 3 ) ++ valid_possible_stems = 3; ++ ++ center++; ++ } ++ ++ /* promote to stem */ ++ if ( valid_possible_stems > 0 ) ++ { ++ stems[0].center = possible_stems[0].center; ++ stems[0].count = possible_stems[0].count; ++ stems[0].width = possible_stems[0].width; ++ stems[0].height = possible_stems[0].height; ++ stems[0].generated = FALSE; ++ valid_stems++; ++ } ++ ++ if ( valid_stems == 1 && ++ valid_possible_stems > 1 ) ++ { ++ stems[1].center = possible_stems[1].center; ++ stems[1].count = possible_stems[1].count; ++ stems[1].width = possible_stems[1].width; ++ stems[1].height = possible_stems[1].height; ++ stems[1].generated = FALSE; ++ valid_stems++; ++ } ++ ++ if ( valid_stems == 2 && ++ valid_possible_stems > 2 && ++ possible_stems[2].center != 0 ) ++ { ++ stems[2].center = possible_stems[2].center; ++ stems[2].count = possible_stems[2].count; ++ stems[2].width = possible_stems[2].width; ++ stems[2].height = possible_stems[2].height; ++ stems[2].generated = FALSE; ++ valid_stems++; ++ } ++ ++ /* sort stems in x direction */ ++ if ( valid_stems == 3 ) ++ { ++ if ( stems[0].center > stems[1].center ) ++ swap_stem ( &stems[0], &stems[1] ); ++ ++ if ( stems[0].center > stems[2].center ) ++ swap_stem ( &stems[1], &stems[2] ); ++ ++ if ( stems[1].center > stems[2].center ) ++ swap_stem ( &stems[1], &stems[2] ); ++ ++ if ( stems[0].center > stems[1].center ) ++ swap_stem ( &stems[0], &stems[1] ); ++ ++ /* only look at first and last stem for now */ ++ swap_stem ( &stems[1], &stems[2] ); ++ } ++ ++ /* synthesize stems - Works, but needs work */ ++ if ( ( strategy_synthesize_stems || ++ known_stem_values->synth_stems ) && ++ valid_stems == 0 && ++ ppem > 10 ) ++ { ++ /* if the leftmost segment's leftmost point is the same as the glyph's */ ++ /* leftmost point, and it is of reasonable width, and is not on the */ ++ /* top or bottom of the bitmap */ ++ if ( leftmost_segment_not_extrema->x1 ++ == leftmost_point_not_extrema && ++ abs ( leftmost_segment_not_extrema->x2 ++ - leftmost_segment_not_extrema->x1 ) ++ < ( rightmost_point_not_extrema ++ - leftmost_point_not_extrema ) / 3 && ++ leftmost_segment_not_extrema->y < height && ++ leftmost_segment_not_extrema->y > 1 ) ++ { ++ stems[valid_stems].center = ( leftmost_segment_not_extrema->x2 ++ + leftmost_segment_not_extrema->x1 ) / 2; ++ stems[valid_stems].width = leftmost_segment_not_extrema->x2 ++ - leftmost_segment_not_extrema->x1; ++ stems[valid_stems].generated = TRUE; ++ valid_stems += 1; ++ } ++ ++ ++ if ( rightmost_segment_not_extrema->x2 ++ == rightmost_point_not_extrema && ++ abs ( rightmost_segment_not_extrema->x2 ++ - rightmost_segment_not_extrema->x1 ) ++ < ( rightmost_point_not_extrema ++ - leftmost_point_not_extrema ) / 3 && ++ rightmost_segment_not_extrema->y < height && ++ rightmost_segment_not_extrema->y > 1 ) ++ { ++ stems[valid_stems].center = ( rightmost_segment_not_extrema->x2 ++ + rightmost_segment_not_extrema->x1 ) / 2; ++ stems[valid_stems].width = rightmost_segment_not_extrema->x2 ++ - rightmost_segment_not_extrema->x1; ++ stems[valid_stems].generated = TRUE; ++ valid_stems += 1; ++ } ++ ++ } ++ ++ /* sort stems in x direction */ ++ if ( valid_stems > 1 && stems[0].center > stems[1].center ) ++ swap_stem ( &stems[0], &stems[1] ); ++ ++ if ( valid_stems == 0 && known_stem_values->stem_translating != 0 ) ++ { ++ *translate_value += known_stem_values->stem_translating; ++ ++ if ( strategy_use_strengths ) ++ { ++ /* consider 1/2 pixel the max when strength is at 100%, ++ unless translate is already greater than that */ ++ FT_Int strength_cutoff = 32; ++ ++ ++ if ( abs ( *translate_value ) > strength_cutoff) ++ strength_cutoff = *translate_value; ++ ++ max_strength = ( strength_cutoff * alignment_strength ) / 100; ++ ++ if ( *translate_value < -max_strength ) ++ *translate_value = -max_strength; ++ else if ( *translate_value > max_strength ) ++ *translate_value = max_strength; ++ } ++ } ++ else ++ /* Start snapping */ ++ { ++ FT_Int center_offset; ++ FT_Int modulus; ++ FT_Int delta, delta2; ++ FT_Long stem_distance = 1, new_distance = 1; ++ FT_Int distance_floor, distance_ceiling; ++ FT_Int translate_value2 = 0; ++ FT_Int main_stem = 0; ++ FT_Int lbearing = m_horiBearingX * 12; ++ FT_Int bitmap_stem_location = stems[0].center; ++ FT_Int advance_stem_location = bitmap_stem_location ++ + lbearing - one_pixel; ++ FT_Int advance_width = m_horiAdvance * 12; ++ FT_Int original_advance_width = 12 * ( slot->linearHoriAdvance >> 10 ); ++ FT_Int glyph_width = rightmost_point - leftmost_point; ++ FT_Int stem_width = stems[0].width; ++ FT_Int advance_leftmost_location = leftmost_point ++ + lbearing - one_pixel; ++ FT_Int advance_rightmost_location = rightmost_point ++ + lbearing - one_pixel; ++ ++#define proposed_transformed_point(point) \ ++ point * (float)(new_distance) / (float)(stem_distance) \ ++ + *translate_value * 12 - ( stems[main_stem].center * (float)(new_distance) \ ++ / (float)(stem_distance) - stems[main_stem].center) ++ ++#define proposed_translated_point(point) point + *translate_value * 12 ++ ++ center_offset = one_pixel / 2; /* half pixel */ ++ modulus = one_pixel; /* whole pixel */ ++ ++ /* Determine center_offset via known values */ ++ if ( known_stem_values->stem_width >= 0 ) ++ { ++ if ( known_stem_values->stem_width % 2 == 0 ) ++ center_offset = 0; ++ else ++ center_offset = one_pixel / 2; ++ } ++ /* otherwise do intelligent guessing, if set */ ++ else if ( strategy_auto_change_center_offset && ++ ppem >= STEM_WIDTH_2_PPEM && ++ stems[0].width < one_pixel * 1.45 ) ++ center_offset = one_pixel / 2; ++ else if ( strategy_auto_change_center_offset && ++ ppem >= STEM_WIDTH_2_PPEM && ++ stems[0].width >= one_pixel * 1.45 && ++ stems[0].width < one_pixel * 2.6 ) ++ center_offset = 0; ++ else if ( strategy_auto_change_center_offset && ++ ppem >= STEM_WIDTH_2_PPEM && ++ stems[0].width >= one_pixel * 2.6 && ++ stems[0].width < one_pixel * 3.6 ) ++ center_offset = one_pixel / 2; ++ else if ( strategy_auto_change_center_offset && ++ ppem >= STEM_WIDTH_2_PPEM ) ++ center_offset = ++ ( one_pixel ++ * ( ( ( (int)( stems[0].width + one_pixel / 2 ) ) ++ / one_pixel ) % 2 ) ) / 2; ++ ++ /* Snap to closest translate and scale values by default */ ++ if ( valid_stems >= 1 ) ++ { ++ /* closest snapping point for stem 0 */ ++ delta = ( stems[0].center + center_offset ) % modulus; ++ ++ if ( delta < modulus / 2 ) ++ /* snap left */ ++ *translate_value = -delta / ( columns_per_pixel * 4 ); ++ else ++ /* snap right */ ++ *translate_value = ( modulus - delta ) / ( columns_per_pixel * 4 ); ++ } ++ ++ if ( strategy_use_d_correction ) ++ { ++ /* if the only stem is in the last 1/3 of glyph width, the advance */ ++ /* is 6 pixels, the ppem 11, and doing so doesn't violate bitmap , */ ++ /* boundaries force it to snap right */ ++ if ( valid_stems == 1 && ++ advance_stem_location > (advance_width * 2) / 3 && ++ advance_width == 6 * one_pixel && ++ rightmost_point + modulus - delta ++ <= ( width - (columns_per_pixel * 2) / 3) * 256 && ++ ppem == 11 ) ++ *translate_value = ( modulus - delta ) / ( columns_per_pixel * 4 ); ++ } ++ ++ if ( strategy_use_strengths ) ++ { ++ /* consider 1/2 pixel the max when strength is at 100%, ++ unless translate is already greater than that */ ++ FT_Int strength_cutoff = 32; ++ if ( abs ( *translate_value ) > strength_cutoff ) ++ strength_cutoff = *translate_value; ++ ++ max_strength = ( strength_cutoff * alignment_strength ) / 100; ++ ++ if ( *translate_value < -max_strength ) ++ *translate_value = -max_strength; ++ else if ( *translate_value > max_strength ) ++ *translate_value = max_strength; ++ } ++ ++ /* If 2 stems is detected, scale distance ++ between in order to land on pixels */ ++ if ( valid_stems >= 2 ) ++ { ++ stem_distance = abs ( stems[1].center - stems[0].center ); ++ ++ delta = stem_distance % modulus; ++ new_distance = stem_distance - delta; ++ ++ distance_floor = stem_distance - delta; ++ distance_ceiling = stem_distance + ( modulus - delta ); ++ ++ if ( delta < modulus / 2 ) ++ new_distance = distance_floor; ++ else ++ new_distance = distance_ceiling; ++ ++ if ( columns_per_pixel == 3 && ++ valid_stems == 3 && ++ strategy_use_m_control && ++ ( width - 2 * columns_per_pixel ) > 6 * columns_per_pixel && ++ ppem > 8 && ++ ( advance_stem_location - advance_leftmost_location ) ++ < stems[main_stem].width * 2 ) ++ { ++ /* Possibly use 2 only when compatible widths is on? */ ++ FT_Int mod_factor = 2; ++ ++ if ( verbose ) ++ printf ( "USING M CONTROL "); ++ ++ distance_floor = stem_distance ++ - stem_distance % ( modulus * mod_factor ) ; ++ distance_ceiling = distance_floor + modulus * mod_factor; ++ ++ new_distance = distance_ceiling; ++ ++ /* force certain ideal situations */ ++ /* these 2 are mostly safe to do */ ++ if ( distance_ceiling ++ + one_pixel * columns_per_pixel == advance_width && ++ stem_width < one_pixel * 1.25 ) ++ new_distance = distance_ceiling; ++ /* NEED TO FIGURE OUT A WAY TO DETERMINE WHETHER ++ THAT NUDGE IS UP OR DOWN */ ++ else if ( stem_distance + one_pixel * 2.6 >= advance_width && ++ stem_width < one_pixel * 1.25 ) ++ new_distance = distance_ceiling; ++ ++ if ( proposed_transformed_point ( leftmost_point ) ++ < one_third_pixel * 2 || ++ proposed_transformed_point ( rightmost_point ) ++ > ( width -2 ) * one_third_pixel ) ++ new_distance = distance_floor; ++ ++ /* NEED TO IGNORE SERIF Ms HERE */ ++ /* perhaps check bitmap boundaries instead??? */ ++ if ( strategy_bearing_correction && new_distance == distance_ceiling ) ++ { ++ /* Correct if bearings are made substantially worse ++ (more than 1/3 a pixel beyond advance) */ ++ if ( proposed_transformed_point( advance_rightmost_location ) ++ > advance_width + one_third_pixel && ++ proposed_transformed_point( advance_rightmost_location ) ++ > advance_rightmost_location && ++ -proposed_transformed_point( advance_leftmost_location ) ++ < advance_rightmost_location - advance_width ) ++ new_distance = distance_floor; ++ } ++ ++ if ( known_stem_values->m >= 0 ) ++ { ++ if ( known_stem_values->m == 0 ) ++ new_distance = distance_floor; ++ else ++ new_distance = distance_ceiling; ++ } ++ ++ if ( ( rightmost_point - leftmost_point) - ++ ( ( rightmost_point * *scale_value) ++ - ( leftmost_point * *scale_value ) ) >= one_pixel * 1.5 ) ++ { ++ *scale_value = 1.0; ++ *translate_value = 0; ++ goto Exit; ++ } ++ ++ } ++ else if ( columns_per_pixel == 1 && ++ valid_stems == 3 && ++ strategy_use_m_control && valid_stems == 3 && ++ width >= 6 * columns_per_pixel && ++ ppem > 8 && ++ ( advance_stem_location - advance_leftmost_location ) ++ < stems[main_stem].width * 2 ) ++ { ++ /* Possibly use 2 only when compatible widths is on? */ ++ FT_Int mod_factor = 2; ++ ++ if ( verbose ) ++ printf ("USING M CONTROL "); ++ distance_floor = stem_distance - stem_distance ++ % ( modulus * mod_factor) ; ++ distance_ceiling = distance_floor + modulus * mod_factor; ++ ++ new_distance = distance_ceiling; ++ ++ /* force certain ideal situations */ ++ /* these 2 are mostly safe to do */ ++ if ( distance_ceiling ++ + one_pixel * columns_per_pixel == advance_width && ++ stem_width < one_pixel * 1.25 ) ++ new_distance = distance_ceiling; ++ /* NEED TO FIGURE OUT A WAY TO DETERMINE WHETHER ++ THAT NUDGE IS UP OR DOWN */ ++ else if ( stem_distance + one_pixel * 2.6 >= advance_width && ++ stem_width < one_pixel * 1.25 ) ++ new_distance = distance_ceiling; ++ ++ if ( proposed_transformed_point( leftmost_point ) < 0 || ++ proposed_transformed_point( rightmost_point ) ++ > width * one_pixel - 2 * one_third_pixel ) ++ new_distance = distance_floor; ++ ++ /* NEED TO IGNORE SERIF Ms HERE */ ++ /* perhaps check bitmap boundaries instead??? */ ++ if ( strategy_bearing_correction && new_distance == distance_ceiling ) ++ { ++ /* Correct if bearings are made substantially worse ++ (more than 1/3 a pixel beyond advance) */ ++ if ( proposed_transformed_point( advance_rightmost_location ) ++ > advance_width + one_third_pixel && ++ proposed_transformed_point( advance_rightmost_location ) ++ > advance_rightmost_location && ++ -proposed_transformed_point( advance_leftmost_location ) ++ < advance_rightmost_location - advance_width ) ++ new_distance = distance_floor; ++ } ++ ++ if ( known_stem_values->m >= 0 ) ++ { ++ if ( known_stem_values->m == 0 ) ++ new_distance = distance_floor; ++ else ++ new_distance = distance_ceiling; ++ } ++ ++ ++ if ( ( rightmost_point - leftmost_point ) ++ - ( ( rightmost_point * *scale_value ) ++ - ( leftmost_point * *scale_value ) ) >= one_pixel * 1.5 ) ++ { ++ *scale_value = 1.0; ++ *translate_value = 0; ++ goto Exit; ++ } ++ ++ } ++ else ++ { ++ if ( strategy_fit_to_width ) ++ new_distance = advance_width - 3 * one_pixel; ++ else if ( known_stem_values->stem_scaling >= 0 ) ++ { ++ if ( known_stem_values->stem_scaling > 0 ) ++ new_distance = distance_ceiling; ++ else ++ new_distance = distance_floor; ++ ++ /* enforce advance width boundaries */ ++ /* TOO RESTRICTIVE ON SERIF FONTS */ ++ if ( proposed_transformed_point( advance_rightmost_location ) ++ >= advance_width || ++ proposed_transformed_point( advance_leftmost_location ) ++ <= 0 ) ++ new_distance = distance_floor; ++ ++ /* enforce literal bitmap boundaries if no translate room */ ++ if ( ( proposed_transformed_point(rightmost_point) >= width * 256 ++ || proposed_transformed_point(leftmost_point ) <= one_pixel ) ++ && new_distance + one_pixel * 3 > advance_width ) ++ new_distance = distance_floor; ++ ++ } ++ else if ( strategy_translate_using_closest_stem ) ++ { ++ /* closest snapping point for stem 1 */ ++ delta2 = ( stems[1].center + center_offset ) % modulus; ++ ++ if ( delta2 < modulus / 2 ) ++ /* snap left */ ++ translate_value2 = -delta2 / ( columns_per_pixel * 4 ); ++ else ++ /* snap right */ ++ translate_value2 = ( modulus - delta2 ) ++ / ( columns_per_pixel * 4 ); ++ ++ if ( abs ( translate_value2 ) < abs ( *translate_value ) ) ++ { ++ *translate_value = translate_value2; ++ main_stem = 1; ++ } ++ ++ } ++ else if ( strategy_scale_to_closest_centers ) ++ { ++ /* closest snapping point for stem 0 */ ++ delta = ( stems[0].center + center_offset ) % modulus; ++ delta2 = ( stems[1].center + center_offset ) % modulus; ++ ++ if ( delta < modulus / 2 ) ++ /* stretch left */ ++ new_distance = delta + stem_distance; ++ else ++ /* stretch right */ ++ new_distance = delta - modulus + stem_distance; ++ ++ if ( delta2 < modulus / 2 ) ++ new_distance -= delta2; /* stretch left */ ++ else ++ new_distance += modulus - delta2; /* stretch right */ ++ ++ } ++ else if ( strategy_scale_to_closest_centers_up_only ) ++ { ++ FT_Int net_change = 0; ++ ++ /* closest snapping point for stem 0 */ ++ delta = ( stems[0].center + center_offset ) % modulus; ++ delta2 = ( stems[1].center + center_offset ) % modulus; ++ ++ if ( delta < modulus / 2 ) ++ net_change = delta; /* stretch left */ ++ else ++ net_change = -( modulus - delta ); /* stretch right */ ++ ++ if ( delta2 < modulus / 2 ) ++ net_change -= delta2; /* stretch left */ ++ else ++ net_change += modulus - delta2; /* stretch right */ ++ ++ if ( net_change > 0 && ++ proposed_transformed_point( advance_rightmost_location ) ++ < advance_width && ++ proposed_transformed_point( advance_leftmost_location ) > 0 ) ++ new_distance = distance_ceiling; ++ } ++ ++ else if ( strategy_always_use_distance_ceiling ) ++ { ++ if ( proposed_transformed_point( advance_rightmost_location ) ++ < advance_width && ++ proposed_transformed_point( advance_leftmost_location ) > 0 ) ++ new_distance = distance_ceiling; ++ } ++ } ++ ++ if ( strategy_use_strengths ) ++ { ++ FT_Int strength_cutoff = center_offset; ++ ++ ++ delta2 = new_distance - stem_distance; ++ ++ if ( abs ( delta2 ) > strength_cutoff ) ++ strength_cutoff = delta2; ++ ++ max_strength = ( strength_cutoff * fitting_strength ) / 100; ++ ++ if ( delta2 < -max_strength ) ++ new_distance = stem_distance - max_strength; ++ else if ( delta2 > max_strength ) ++ new_distance = stem_distance + max_strength; ++ } ++ ++ *scale_value = (float)( new_distance ) / (float)( stem_distance ); ++ *translate_value = *translate_value ++ - ( (float)( stems[main_stem].center * (float)new_distance ) ++ / (float)stem_distance - stems[main_stem].center ) / 12; ++ ++ if ( valid_stems == 2 ) ++ *embolden_value = ( 64.0 / *scale_value - 64.0 ); ++ ++ if ( valid_stems == 3 ) ++ *embolden_value = ( 64.0 / *scale_value - 64.0 ) / 1.5; ++ } ++ ++ if ( verbose ) ++ printf ( "%lu stems:", valid_stems ); ++ ++ if ( valid_stems == 1 && verbose ) ++ printf ( "1 stem: bitmapwidth:%d glyphwidth:%f glyph_width:%f center:%f bearing:%f advance:%f lhadvance:%f stemwidth:%f %d %d", ++ (width - 6) / columns_per_pixel, ++ (float)m_width / 64.0, ++ (float)glyph_width / (float)one_pixel, ++ (float)( (float)advance_stem_location ) / (float)one_pixel, ++ (float)m_horiBearingX / 64.0, ++ (float)m_horiAdvance / 64.0, ++ (float)linearHoriAdvance / 64.0, ++ (float)stems[0].width / (float)one_pixel, ++ advance_width, original_advance_width ); ++ else if ( valid_stems >= 2 && verbose ) ++ printf ( "%lu stems: bitmapwidth:%d center1:%f center2:%f difference:%f bearing:%f advance:%f advstemloc:%f ", ++ valid_stems, ++ (width - 6) / columns_per_pixel, ++ ( (float)advance_stem_location ) / (float)one_pixel, ++ ( (float)advance_stem_location ++ + (float)abs ( stems[1].center ++ - stems[0].center) ) / (float)one_pixel, ++ ( (float)abs ( stems[1].center ++ - stems[0].center ) ) / (float)one_pixel, ++ (float)m_horiBearingX / 64.0, ++ (float)m_horiAdvance / 64.0, ++ (float)advance_stem_location / (float)one_pixel ); ++ ++ if ( strategy_bearing_correction ) ++ { ++ /* Correct if negative bearings are made substantially worse */ ++ /* (more than 1/3 a pixel) */ ++ if ( proposed_transformed_point( advance_rightmost_location ) ++ > advance_width && ++ proposed_transformed_point( advance_rightmost_location ) ++ > advance_rightmost_location && ++ -proposed_transformed_point( advance_leftmost_location ) ++ < advance_rightmost_location - advance_width && ++ *translate_value ++ > one_third_pixel / ( columns_per_pixel * 4 ) ) ++ { ++ *translate_value -=64 ; ++ if ( verbose ) ++ printf ( "TRANSLATING -64 " ); ++ } ++ } ++ goto Exit; ++ } ++ ++ Exit: ++ ++#define transformed_point( point ) point * *scale_value + *translate_value * 12 ++ ++ if ( strategy_correct_out_of_bounds_outlines ) ++ { ++ /* Correct if outside bitmap */ ++ if ( transformed_point( rightmost_point ) ++ >= width * 256 - 2 * one_third_pixel && ++ transformed_point( leftmost_point ) ++ > one_pixel + 2 * one_third_pixel ) ++ *translate_value -=64 ; ++ else if ( transformed_point( leftmost_point ) ++ <= one_pixel / 2 && ++ transformed_point( rightmost_point ) ++ <= width * 256 - ( one_pixel + one_pixel / 2 ) ) ++ *translate_value += 64; ++ } ++ ++ STVALUES ++ free ( centers ); ++ free ( segments ); ++ free ( stem_centers ); ++ free ( stems ); ++ free ( leftmost_segment ); ++ } ++ ++ ++ /* Gamma correction */ ++ static void ++ _ft_lcd_gamma_correction_correction ( FT_Bitmap* bitmap, ++ FT_Render_Mode mode, ++ FT_GlyphSlot slot, ++ float gamma_correction_lt, ++ float gamma_correction_value ) ++ { ++ if ( gamma_correction_value != 1.0 ) ++ { ++ FT_UInt width = (FT_UInt)bitmap->width; ++ FT_UInt height = (FT_UInt)bitmap->rows; ++ FT_Byte* line = bitmap->buffer; ++ float ppem = (float)slot->face->size->metrics.x_ppem; ++ ++ ++ if ( !slot->face || !slot->face->size ) return; ++ ++ if ( ppem >= 5 ) ++ for ( height = (FT_UInt)bitmap->rows; ++ height > 0; ++ height--, line += bitmap->pitch ) ++ { ++ FT_UInt xx; ++ ++ ++ for ( xx = 0; xx < width; xx += 1 ) ++ { ++ /*normal*/ ++ /*line[xx] = pseudo_gamma ( line[xx], gamma_correction_value );*/ ++ ++ /* sloped */ ++ /*line[xx] = pseudo_gamma ( line[xx], gamma_correction_value - 5 ++ * (1-gamma_correction_value)/(gamma_correction_lt -5) ++ + ((1-gamma_correction_value)/(gamma_correction_lt -5)) * ppem );*/ ++ ++ /* 1/3-sloped */ ++ line[xx] = pseudo_gamma ( line[xx], gamma_correction_value - 5 ++ * ( ( 1 - gamma_correction_value ) ++ / ( 3 * ( gamma_correction_lt -5 ) ) ) ++ + ( ( 1 - gamma_correction_value ) ++ / ( 3 * ( gamma_correction_lt -5) ) ) * ppem ); ++ } ++ } ++ } ++ } ++ ++#endif + + /* convert a slot's glyph image into a bitmap */ + static FT_Error +@@ -103,25 +2328,162 @@ + FT_Render_Mode required_mode ) + { + FT_Error error; +- FT_Outline* outline = &slot->outline; +- FT_Bitmap* bitmap = &slot->bitmap; +- FT_Memory memory = render->root.memory; ++ FT_Outline* outline = NULL; ++ FT_Outline* outline_orig = NULL; + FT_BBox cbox; +- FT_Pos x_shift = 0; +- FT_Pos y_shift = 0; +- FT_Pos x_left, y_top; +- FT_Pos width, height, pitch; ++ FT_Pos width, height, pitch, ppem; + #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + FT_Pos height_org, width_org; + #endif ++ FT_Bitmap* bitmap = &slot->bitmap; ++ FT_Memory memory = render->root.memory; + FT_Int hmul = ( mode == FT_RENDER_MODE_LCD ); + FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V ); ++ FT_Pos x_shift = 0; ++ FT_Pos y_shift = 0; ++ FT_Pos x_left, y_top; + + FT_Raster_Params params; + +- FT_Bool have_outline_shifted = FALSE; +- FT_Bool have_buffer = FALSE; ++ FT_Bool have_translated_origin = FALSE; ++ FT_Bool have_outline_shifted = FALSE; ++ FT_Bool have_buffer = FALSE; ++ ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ FT_Matrix scaleMat; ++ FT_Long translate_value = 0; ++ float scale_value = 1.0; ++ FT_Int align_called = 0; ++ ++ ++ int chromeos_style_sharpening_strength = 0; ++ int alignment_strength = 0; ++ int fitting_strength = 0; ++ int fringe_filter_strength = 0; ++ int grayscale_filter_strength = 0; ++ ++ int autohint_horizontal_stem_darken_strength = 0; ++ int autohint_vertical_stem_darken_strength = 0; ++ ++ int windows_style_sharpening_strength = 0; ++ float gamma_correction_value = 1; ++ float gamma_correction_lt = 0; ++ ++ FT_Int brightness_value = 0.0; ++ FT_Int contrast_value = 0.0; + ++ FT_Int snapping_sliding_scale_value = 0; ++ ++ FT_Int global_embolden_x_value = 0; ++ FT_Int global_embolden_y_value = 0; ++ ++ FT_Int bold_embolden_x_value = 0; ++ FT_Int bold_embolden_y_value = 0; ++ ++ FT_Byte chromeos_cutoff; ++ double chromeos_gamma_value; ++ ++ float embolden_value = 0.0; ++ FT_Bool autohinted = FALSE; ++ FT_Bool use_various_tweaks = FALSE; ++ FT_Pos cur_width = infinality_cur_width; ++ ++ const FT_Int MIN_PPEM = 1; ++ /*const FT_Int MAX_PPEM = 100; */ ++ ++ FT_Bool use_known_settings_on_selected_fonts; ++ ++ if ( slot->face && ++ slot->face->size && ++ slot->face->size->metrics.x_ppem ) ++ ppem = slot->face->size->metrics.x_ppem; ++ else ++ ppem = 0; ++ ++ if ( cur_width ) ++ { ++ autohinted = TRUE; ++ } ++ if( ftinf ){ ++ const float *f=ftinf->gamma_correction; ++ ++ use_known_settings_on_selected_fonts=ftinf->use_known_settings_on_selected_fonts; ++ use_various_tweaks=ftinf->use_various_tweaks; ++ snapping_sliding_scale_value=ftinf->stem_snapping_sliding_scale; ++ ++ alignment_strength=ftinf->stem_alignment_strength; ++ if ( snapping_sliding_scale_value != 0 ) ++ alignment_strength = sliding_scale(10, snapping_sliding_scale_value, alignment_strength, 100, ppem); ++ ++ fitting_strength=ftinf->stem_fitting_strength; ++ if ( snapping_sliding_scale_value != 0 ) ++ fitting_strength = sliding_scale(10, snapping_sliding_scale_value, fitting_strength, 100, ppem); ++ ++ chromeos_style_sharpening_strength=ftinf->chromeos_style_sharpening_strength; ++ ++ if ( ppem > 10 ) ++ chromeos_style_sharpening_strength = ++ ( chromeos_style_sharpening_strength * ppem ) / 10; ++ ++ if ( chromeos_style_sharpening_strength > 100 ) ++ chromeos_style_sharpening_strength = 100; ++ ++ brightness_value=ftinf->brightness; ++ contrast_value=ftinf->contrast; ++ ++ windows_style_sharpening_strength=ftinf->windows_style_sharpening_strength; ++ ++ /* Decrease effect slightly to have a more linear increase in sharpness */ ++ windows_style_sharpening_strength = ++ ( ( windows_style_sharpening_strength ++ * windows_style_sharpening_strength ) / 100 ++ + windows_style_sharpening_strength ) / 2; ++ ++ gamma_correction_lt = f[0]; ++ gamma_correction_value = f[1] / 100.0f; ++ ++ fringe_filter_strength=ftinf->fringe_filter_strength; ++ grayscale_filter_strength=ftinf->grayscale_filter_strength; ++ ++ autohint_horizontal_stem_darken_strength=ftinf->autohint_horizontal_stem_darken_strength; ++ autohint_vertical_stem_darken_strength=ftinf->autohint_vertical_stem_darken_strength; ++ ++ global_embolden_x_value=ftinf->global_embolden_x_value; ++ global_embolden_y_value=ftinf->global_embolden_y_value; ++ ++ bold_embolden_x_value=ftinf->bold_embolden_x_value; ++ bold_embolden_y_value=ftinf->bold_embolden_y_value; ++ } else { ++ use_known_settings_on_selected_fonts=FALSE; ++ } ++ ++ /* set gamma value to 1 if out of range */ ++ if ( slot->face && ++ slot->face->size && ++ slot->face->size->metrics.x_ppem ) ++ { ++ if ( slot->face->size->metrics.x_ppem >= gamma_correction_lt ) ++ gamma_correction_value = 1; ++ } ++ else ++ gamma_correction_value = 1; ++ ++ if( use_various_tweaks && ++ slot->face && ++ slot->face->style_name ) ++ { ++ /* needs to also check for artifical italics */ ++ if ( strcasestr(slot->face->style_name, "Italic" ) || ++ strcasestr(slot->face->style_name, "Oblique" ) ) ++ { ++ windows_style_sharpening_strength = 0; ++ chromeos_style_sharpening_strength = 0; ++ } ++ } ++ ++ /*if (fitting_strength == 100) scale_value = 1.1;*/ ++ ++#endif + + /* check glyph image format */ + if ( slot->format != render->glyph_format ) +@@ -137,26 +2499,119 @@ + goto Exit; + } + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++RERENDER: ++ if ( align_called == 1 ) ++ { ++ scaleMat.xx = FT_FixedFromFloat(scale_value); ++ scaleMat.xy = 0; ++ scaleMat.yx = 0; ++ scaleMat.yy = ( 1 << 16 ); ++ ++ FT_Outline_Copy(outline_orig, outline); ++ ++ if ( scale_value != 1.0 ) ++ FT_Outline_Transform( outline, &scaleMat ); ++ ++ FT_Outline_Translate( outline, translate_value, 0 ); ++ ++ FT_Outline_EmboldenXY( outline, embolden_value, 0 ); ++ } ++ else ++ { ++#endif ++ outline = &slot->outline; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ /* Need to get this PRIOR to embolden, otherwise bad things happen */ ++ FT_Outline_Get_CBox( outline, &cbox ); ++ ++ /* Various hacks that need to be turned into a new rule set */ ++ /*if ( !autohinted ++ && use_known_settings_on_selected_fonts ++ && mode == FT_RENDER_MODE_LCD ++ && slot->face->family_name ++ && slot->face->style_name ++ && ( strcasestr(slot->face->family_name, "Courier New" ) ++ && ( strcasestr(slot->face->style_name, "Regular" ) ++ || strcasestr(slot->face->style_name, "Italic" ) ) ) ) ++ FT_Outline_Embolden( outline, 24 );*/ ++ ++ if ( slot->face ) ++ { ++ if ( !autohinted && ++ use_known_settings_on_selected_fonts && ++ mode == FT_RENDER_MODE_LCD && ++ slot->face->family_name && ++ slot->face->style_name && ++ strcasestr( slot->face->family_name, "Times New Roman" ) && ++ strcasestr( slot->face->style_name, "Italic" ) ) ++ FT_Outline_EmboldenXY( outline, 12, 0 ); ++ ++ if ( use_known_settings_on_selected_fonts && ++ autohinted && ++ mode == FT_RENDER_MODE_LCD && ++ slot->face->family_name && ++ slot->face->style_name && ++ strcasestr(slot->face->family_name, "FreeSerif" ) && ++ strcasestr(slot->face->style_name, "Italic" ) ) ++ FT_Outline_EmboldenXY( outline, 8, 0 ); ++ ++ if ( global_embolden_x_value != 0 || global_embolden_y_value != 0 ) ++ FT_Outline_EmboldenXY( outline, ++ global_embolden_x_value, ++ global_embolden_y_value ); ++ ++ if ( ( bold_embolden_x_value != 0 || bold_embolden_y_value != 0 ) && ++ ( slot->face->style_name && ++ ( strcasestr(slot->face->style_name, "Bold" ) || ++ strcasestr(slot->face->style_name, "Black" ) || ++ ( slot->face->style_flags && ++ slot->face->style_flags & FT_STYLE_FLAG_BOLD ) ) ) ) ++ FT_Outline_EmboldenXY( outline, ++ bold_embolden_x_value, ++ bold_embolden_y_value ); ++ } ++ ++ FT_Outline_Copy( outline, outline_orig ); ++ } ++ ++ /* translate the outline to the new origin if needed */ ++ if ( align_called == 0 ) ++ { ++ FT_Pos enlarge_cbox = 0; ++ ++ /* enlarge for grayscale rendering */ ++ if ( mode == FT_RENDER_MODE_NORMAL ) ++ enlarge_cbox = 64; ++ ++ if ( origin ) ++ { ++ FT_Outline_Translate( outline, origin->x, origin->y ); ++ have_translated_origin = TRUE; ++ } ++ ++ /* compute the control box, and grid fit it */ ++ /*FT_Outline_Get_CBox( outline, &cbox );*/ ++ ++ cbox.xMin = FT_PIX_FLOOR( cbox.xMin - enlarge_cbox ); ++ cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); ++ cbox.xMax = FT_PIX_CEIL( cbox.xMax + enlarge_cbox ); ++ cbox.yMax = FT_PIX_CEIL( cbox.yMax ); ++#else + if ( origin ) + { +- x_shift = origin->x; +- y_shift = origin->y; ++ FT_Outline_Translate( outline, origin->x, origin->y ); ++ have_translated_origin = TRUE; + } + + /* compute the control box, and grid fit it */ +- /* taking into account the origin shift */ + FT_Outline_Get_CBox( outline, &cbox ); + +- cbox.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift ); +- cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift ); +- cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift ); +- cbox.yMax = FT_PIX_CEIL( cbox.yMax + y_shift ); +- +- x_shift -= cbox.xMin; +- y_shift -= cbox.yMin; +- +- x_left = cbox.xMin >> 6; +- y_top = cbox.yMax >> 6; ++ cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); ++ cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); ++ cbox.xMax = FT_PIX_CEIL( cbox.xMax ); ++ cbox.yMax = FT_PIX_CEIL( cbox.yMax ); ++#endif + + width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6; + height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6; +@@ -166,16 +2621,29 @@ + height_org = height; + #endif + ++ /* release old bitmap buffer */ ++ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ++ { ++ FT_FREE( bitmap->buffer ); ++ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; ++ } ++ ++ /* allocate new one */ + pitch = width; + if ( hmul ) + { +- width *= 3; +- pitch = FT_PAD_CEIL( width, 4 ); ++ width = width * 3; ++ pitch = FT_PAD_CEIL( width, 4 ); + } + + if ( vmul ) + height *= 3; + ++ x_shift = cbox.xMin; ++ y_shift = cbox.yMin; ++ x_left = cbox.xMin >> 6; ++ y_top = cbox.yMax >> 6; ++ + #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + if ( slot->library->lcd_filter_func ) +@@ -185,33 +2653,25 @@ + + if ( hmul ) + { +- x_shift += 64 * ( extra >> 1 ); +- x_left -= extra >> 1; ++ x_shift -= 64 * ( extra >> 1 ); + width += 3 * extra; + pitch = FT_PAD_CEIL( width, 4 ); ++ x_left -= extra >> 1; + } + + if ( vmul ) + { +- y_shift += 64 * ( extra >> 1 ); +- y_top += extra >> 1; ++ y_shift -= 64 * ( extra >> 1 ); + height += 3 * extra; ++ y_top += extra >> 1; + } + } +- + #endif +- +- /* +- * XXX: on 16bit system, we return an error for huge bitmap +- * to prevent an overflow. +- */ +- if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX || +- x_left < FT_INT_MIN || y_top < FT_INT_MIN ) +- { +- error = FT_THROW( Invalid_Pixel_Size ); +- goto Exit; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET + } + ++#endif ++ + /* Required check is (pitch * height < FT_ULONG_MAX), */ + /* but we care realistic cases only. Always pitch <= width. */ + if ( width > 0x7FFF || height > 0x7FFF ) +@@ -222,6 +2682,22 @@ + goto Exit; + } + ++ bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; ++ bitmap->num_grays = 256; ++ bitmap->width = (unsigned int)width; ++ bitmap->rows = (unsigned int)height; ++ bitmap->pitch = pitch; ++ ++ /* translate outline to render it into the bitmap */ ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( align_called == 0 ) ++ { ++#endif ++ FT_Outline_Translate( outline, -x_shift, -y_shift ); ++ have_outline_shifted = TRUE; ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ } ++#endif + /* release old bitmap buffer */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { +@@ -229,7 +2705,6 @@ + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + +- /* allocate new one */ + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)( pitch * height ) ) ) + goto Exit; + else +@@ -237,23 +2712,6 @@ + + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + +- slot->format = FT_GLYPH_FORMAT_BITMAP; +- slot->bitmap_left = (FT_Int)x_left; +- slot->bitmap_top = (FT_Int)y_top; +- +- bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; +- bitmap->num_grays = 256; +- bitmap->width = (unsigned int)width; +- bitmap->rows = (unsigned int)height; +- bitmap->pitch = pitch; +- +- /* translate outline to render it into the bitmap */ +- if ( x_shift || y_shift ) +- { +- FT_Outline_Translate( outline, x_shift, y_shift ); +- have_outline_shifted = TRUE; +- } +- + /* set up parameters */ + params.target = bitmap; + params.source = outline; +@@ -299,9 +2757,153 @@ + if ( error ) + goto Exit; + ++#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET ++ if ( ppem <= MAX_PPEM && ppem >= MIN_PPEM ) ++ { ++ if ( align_called == 0 && cur_width / ppem < 10 && ++ ( alignment_strength > 0 || fitting_strength > 0 ) ) ++ _lcd_stem_align ( bitmap, ++ mode, ++ slot, ++ &translate_value, ++ &scale_value, ++ alignment_strength, ++ fitting_strength, ++ &embolden_value ); ++ ++ if ( align_called == 0 && ++ ( translate_value != 0 || scale_value != 1.0 ) ) ++ { ++ align_called = 1; ++ goto RERENDER; ++ } ++ ++ if ( mode == FT_RENDER_MODE_LCD ) ++ { ++ ++ if ( fringe_filter_strength > 0 /*&& autohinted*/ ) ++ _ft_lcd_fringe_filter( bitmap, ++ mode, ++ fringe_filter_strength, ++ slot->library ); ++ ++ /*if ( autohinted) ++ _ft_lcd_stem_end_filter( bitmap, mode, 100, slot->library );*/ ++ ++ if ( gamma_correction_lt > 0 && gamma_correction_value != 1.0 ) ++ _ft_lcd_gamma_correction_correction( bitmap, ++ mode, ++ slot, ++ gamma_correction_lt, ++ gamma_correction_value ); ++ ++ chromeos_cutoff = (FT_Byte)( 0.5 * 255.0 ) ++ * ( chromeos_style_sharpening_strength / 100.0 ); ++ chromeos_gamma_value = 1; ++ ++ if ( chromeos_style_sharpening_strength > 0 ) ++ _ft_lcd_chromeos_sharpen( bitmap, ++ mode, ++ chromeos_cutoff, ++ chromeos_gamma_value ); ++ ++ if ( ppem > 8 ) ++ if ( windows_style_sharpening_strength > 0 ) ++ _ft_lcd_windows_sharpen( bitmap, ++ mode, ++ windows_style_sharpening_strength, ++ slot->library ); ++ ++ if ( autohinted && ++ ( cur_width * 100 ) / 64 ++ > autohint_horizontal_stem_darken_strength && ++ autohint_horizontal_stem_darken_strength != 0 ) ++ autohint_horizontal_stem_darken_strength = ( cur_width * 100 ) / 64; ++ ++ if ( autohint_horizontal_stem_darken_strength > 100) ++ autohint_horizontal_stem_darken_strength = 100; ++ ++ /* only do on autohinted fonts */ ++ /* Necessary to do on some non-thin fonts, which is why it is outside */ ++ /* of the below conditional */ ++ if ( autohint_horizontal_stem_darken_strength > 0 && autohinted ) ++ _ft_lcd_darken_x ( bitmap, ++ mode, ++ autohint_horizontal_stem_darken_strength, ++ slot->library ); ++ ++ /* Enhance thin fonts */ ++ if ( autohinted ) ++ { ++ /* if forcibly set use that, otherwise make a good estimate */ ++ float contrast, brightness; ++ ftinf_get_bc( slot->face->family_name, ppem, &brightness, &contrast); ++ if ( slot->face && !_ft_bitmap_bc ( bitmap, brightness, contrast ) ) ++ { ++ FT_Bool is_fixed_name = FALSE; ++ ++ if ( slot->face->family_name && ++ strcasestr(slot->face->family_name, "Mono" ) ) ++ is_fixed_name = TRUE; ++ ++ /* Darken vertical stems */ ++ _ft_lcd_darken_y ( bitmap, ++ mode, ++ autohint_vertical_stem_darken_strength, ++ slot->library ); ++ ++ /* Adjust brightness / contrast automatically based on stem width */ ++ if ( cur_width != 0 && cur_width < 30 ) ++ cur_width = 30; ++ ++ if ( cur_width >= 30 && cur_width <= 60 ) ++ { ++ float ppem_factor = sliding_scale ( 5, 11, 0.0, 1.0, ppem ); ++ float brightness_factor = sliding_scale ( 30, 52, -.3, 0.0, ++ cur_width ); ++ float contrast_factor = sliding_scale ( 30, 52, .45, 0.0, ++ cur_width ); ++ _ft_bitmap_bc ( bitmap, ++ ppem_factor * brightness_factor, ++ ppem_factor * contrast_factor ); ++ ++ /* Only cap variable width thin-stemmed fonts */ ++ if ( !FT_IS_FIXED_WIDTH( slot->face ) && !is_fixed_name ) ++ _ft_bitmap_cap ( bitmap, ++ ( cur_width * 150 ) / 64, ++ slot->library ); ++ } ++ } ++ } ++ ++ ++ if ( slot->library->lcd_filter_func ) ++ slot->library->lcd_filter_func( bitmap, mode, slot->library ); ++ ++ if ( grayscale_filter_strength > 0 ) ++ _ft_lcd_grayscale_filter( bitmap, ++ mode, ++ grayscale_filter_strength, ++ slot->library ); ++ ++ } ++ ++ /* Global values */ ++ if ( brightness_value != 0 || contrast_value != 0 ) ++ _ft_bitmap_bc ( bitmap, ++ (float)brightness_value / 300.0, ++ (float)contrast_value / 300.0); ++ ++ FT_Outline_Done( slot->library, outline_orig ); ++ } ++ else if ( mode == FT_RENDER_MODE_LCD && ++ slot->library->lcd_filter_func ) ++ slot->library->lcd_filter_func( bitmap, mode, slot->library ); ++#else + if ( slot->library->lcd_filter_func ) + slot->library->lcd_filter_func( bitmap, mode, slot->library ); + ++#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ + #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + /* render outline into bitmap */ +@@ -359,6 +2961,20 @@ + + #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + ++ /* ++ * XXX: on 16bit system, we return an error for huge bitmap ++ * to prevent an overflow. ++ */ ++ if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ) ++ { ++ error = FT_THROW( Invalid_Pixel_Size ); ++ goto Exit; ++ } ++ ++ slot->format = FT_GLYPH_FORMAT_BITMAP; ++ slot->bitmap_left = (FT_Int)x_left; ++ slot->bitmap_top = (FT_Int)y_top; ++ + /* everything is fine; don't deallocate buffer */ + have_buffer = FALSE; + +@@ -366,7 +2982,9 @@ + + Exit: + if ( have_outline_shifted ) +- FT_Outline_Translate( outline, -x_shift, -y_shift ); ++ FT_Outline_Translate( outline, x_shift, y_shift ); ++ if ( have_translated_origin ) ++ FT_Outline_Translate( outline, -origin->x, -origin->y ); + if ( have_buffer ) + { + FT_FREE( bitmap->buffer ); +diff -ruN freetype-2.7-orig/src/truetype/ttinterp.c freetype-2.7/src/truetype/ttinterp.c +--- freetype-2.7-orig/src/truetype/ttinterp.c 2016-09-08 08:53:04.000000000 +0200 ++++ freetype-2.7/src/truetype/ttinterp.c 2016-09-09 16:01:22.468500777 +0200 +@@ -5721,6 +5721,7 @@ + + if ( exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && ++ exc->GS.freeVector.y == 0 && + !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) + control_value_cutin = 0; + } diff --git a/freetype-infinality-ultimate/freetype-2.2.1-enable-valid.patch b/freetype-infinality-ultimate/freetype-2.2.1-enable-valid.patch index c78b6b7..21d80da 100644 --- a/freetype-infinality-ultimate/freetype-2.2.1-enable-valid.patch +++ b/freetype-infinality-ultimate/freetype-2.2.1-enable-valid.patch @@ -1,18 +1,18 @@ --- freetype-2.2.1/modules.cfg.orig 2006-07-07 21:01:09.000000000 -0400 +++ freetype-2.2.1/modules.cfg 2006-07-07 21:01:54.000000000 -0400 @@ -110,7 +110,7 @@ - AUX_MODULES += cache - # TrueType GX/AAT table validation. Needs ftgxval.c below. + # + # No FT_CONFIG_OPTION_PIC support. -# AUX_MODULES += gxvalid +AUX_MODULES += gxvalid # Support for streams compressed with gzip (files with suffix .gz). # @@ -124,7 +124,7 @@ - # OpenType table validation. Needs ftotval.c below. # + # No FT_CONFIG_OPTION_PIC support. -# AUX_MODULES += otvalid +AUX_MODULES += otvalid diff --git a/freetype-infinality-ultimate/freetype-2.3.0-enable-spr.patch b/freetype-infinality-ultimate/freetype-2.3.0-enable-spr.patch new file mode 100644 index 0000000..991fac6 --- /dev/null +++ b/freetype-infinality-ultimate/freetype-2.3.0-enable-spr.patch @@ -0,0 +1,100 @@ + + + +rpms/freetype.git - freetype + + + + + + + + + + + + +
+ + + + +
+summaryrefslogtreecommitdiffstats
+ + + +
+
+
blob: 8432e28a412f0299957a5a67dd16dbdbe025d326 (plain) + + +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+
--- freetype-2.3.0/include/freetype/config/ftoption.h.spf	2007-01-18 14:27:34.000000000 -0500
++++ freetype-2.3.0/include/freetype/config/ftoption.h	2007-01-18 14:27:48.000000000 -0500
+@@ -92,7 +92,7 @@
+   /* This is done to allow FreeType clients to run unmodified, forcing     */
+   /* them to display normal gray-level anti-aliased glyphs.                */
+   /*                                                                       */
+-/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
++#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+ 
+ 
+   /*************************************************************************/
+
+
+ +
+ + diff --git a/freetype-infinality-ultimate/freetype-2.6.5-libtool.patch b/freetype-infinality-ultimate/freetype-2.6.5-libtool.patch new file mode 100644 index 0000000..ebf8024 --- /dev/null +++ b/freetype-infinality-ultimate/freetype-2.6.5-libtool.patch @@ -0,0 +1,100 @@ + + + +rpms/freetype.git - freetype + + + + + + + + + + + + +
+ + + + +
+summaryrefslogtreecommitdiffstats
+ + + +
+
+
blob: e7d0a5c58b4bbc3fa92dc0d5d137f7a5a7f21576 (plain) + + +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+
--- freetype-2.6.5/builds/unix/freetype-config.in
++++ freetype-2.6.5/builds/unix/freetype-config.in
+@@ -158,7 +154,7 @@ fi
+ 
+ if test "$echo_libtool" = "yes" ; then
+   convlib="libfreetype.la"
+-  echo ${SYSROOT}$libdir/$convlib
++  #echo ${SYSROOT}$libdir/$convlib
+ fi
+ 
+ # EOF
+
+
+ +
+ + diff --git a/freetype-infinality-ultimate/freetype-infinality-ultimate.spec b/freetype-infinality-ultimate/freetype-infinality-ultimate.spec index f240846..2292681 100644 --- a/freetype-infinality-ultimate/freetype-infinality-ultimate.spec +++ b/freetype-infinality-ultimate/freetype-infinality-ultimate.spec @@ -2,7 +2,7 @@ Summary: A free and portable font rendering engine Name: freetype-infinality-ultimate -Version: 2.6.3 +Version: 2.7.1 Release: 1%{?dist} License: (FTL or GPLv2+) and BSD and MIT and Public Domain and zlib with acknowledgement Group: System Environment/Libraries @@ -15,10 +15,14 @@ Source4: infinality-settings.sh Source5: infinality-settings-generic Source6: xft-settings.sh -Patch1: freetype-2.2.1-enable-valid.patch Patch2: 02-upstream-2016.03.26.patch -Patch3: 03-infinality-2.6.3-2016.03.26.patch +Patch3: 0001-Enable-table-validation-modules.patch +Patch4: 0002-infinality-2.6.5-2016.08.18.patch +Patch21: freetype-2.3.0-enable-spr.patch + +# Enable otvalid and gxvalid modules +Patch46: freetype-2.2.1-enable-valid.patch # Enable additional demos Patch47: freetype-2.5.2-more-demos.patch @@ -28,6 +32,8 @@ Patch88: freetype-multilib.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1161963 Patch92: freetype-2.5.3-freetype-config-prefix.patch +Patch93: freetype-2.6.5-libtool.patch + BuildRequires: libX11-devel BuildRequires: libpng-devel BuildRequires: zlib-devel @@ -86,10 +92,15 @@ FreeType. %prep %setup -q -b 1 -a 2 -n freetype-%{version} -%patch1 -p1 -b .enable-valid -%patch2 -p1 -b .upstream +#%patch2 -p1 -b .upstream %patch3 -p1 -b .infinality +%patch4 -p1 -b .infinality +#%patch46 -p1 -b .enable-valid + +%if %{?_with_subpixel_rendering:1}%{!?_with_subpixel_rendering:0} +%patch21 -p1 -b .enable-spr +%endif pushd ft2demos-%{version} %patch47 -p1 -b .more-demos @@ -99,6 +110,8 @@ popd %patch92 -p1 -b .freetype-config-prefix +%patch93 -p1 -b .libtool + cp %{SOURCE4} . cp %{SOURCE5} .