diff options
author | Steve Kondik <shade@chemlab.org> | 2012-12-17 02:11:32 -0800 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2012-12-17 02:53:55 -0800 |
commit | bad440fe256381ba38f6435984476f96dce7ba56 (patch) | |
tree | 18c1e172c6a4b3760e79fa3b68713eb7835c5cdb | |
parent | d4c5fd17a70b96e793bf2c5c6cadfe4a219e5833 (diff) | |
download | android_external_freetype-mr1.1-staging.tar.gz android_external_freetype-mr1.1-staging.tar.bz2 android_external_freetype-mr1.1-staging.zip |
Revert "freetype: Add Infinality patches"cm-10.1.0-RC5cm-10.1.0-RC4cm-10.1.0-RC3cm-10.1.0-RC2cm-10.1.0-RC1cm-10.1-M3cm-10.1-M2cm-10.1-M1mr1.1-staging
* Not currently useful, and causes CTS failure.
This reverts commit 4d3876eef9f90a75f2ae55e880759937482e6b3f.
Change-Id: I1914f8c79e773399d1590011e6db1d63d7be36a8
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | include/freetype/config/ftoption.h | 35 | ||||
-rw-r--r-- | include/freetype/internal/ftobjs.h | 8 | ||||
-rw-r--r-- | src/autofit/aflatin.c | 233 | ||||
-rw-r--r-- | src/base/ftlcdfil.c | 46 | ||||
-rw-r--r-- | src/base/ftobjs.c | 69 | ||||
-rw-r--r-- | src/base/ftoutln.c | 22 | ||||
-rw-r--r-- | src/base/ftsynth.c | 27 | ||||
-rw-r--r-- | src/smooth/ftsmooth.c | 3467 | ||||
-rw-r--r-- | src/truetype/truetype.c | 1 | ||||
-rw-r--r-- | src/truetype/ttgload.c | 148 | ||||
-rw-r--r-- | src/truetype/ttinterp.c | 825 | ||||
-rw-r--r-- | src/truetype/ttinterp.h | 72 | ||||
-rw-r--r-- | src/truetype/ttobjs.h | 3 | ||||
-rw-r--r-- | src/truetype/ttsubpix.c | 261 | ||||
-rw-r--r-- | src/truetype/ttsubpix.h | 778 |
16 files changed, 162 insertions, 5835 deletions
@@ -46,7 +46,7 @@ LOCAL_CFLAGS += "-DFT2_BUILD_LIBRARY" # the following is for testing only, and should not be used in final builds # of the product -LOCAL_CFLAGS += "-DTT_CONFIG_OPTION_BYTECODE_INTERPRETER" +#LOCAL_CFLAGS += "-DTT_CONFIG_OPTION_BYTECODE_INTERPRETER" LOCAL_CFLAGS += -O2 diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index e4b99c2..4414cb0 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -92,7 +92,7 @@ FT_BEGIN_HEADER /* 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 */ /*************************************************************************/ @@ -560,39 +560,6 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ - /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ - /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ -#define TT_CONFIG_OPTION_SUBPIXEL_HINTING - - - /*************************************************************************/ - /* */ - /* 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 - - /*************************************************************************/ - /* */ /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ /* of the TrueType bytecode interpreter is used that doesn't implement */ /* any of the patented opcodes and algorithms. The patents related to */ diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index d4da5da..eee3d24 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -81,14 +81,6 @@ FT_BEGIN_HEADER #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) #define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) - /* - * These are used in ttinterp.c for subpixel hinting with an - * adjustable grids-per-pixel value. - */ -#define FT_PIX_FLOOR_GRID( x, n ) ( (x) & ~( 64 / (n) - 1 ) ) -#define FT_PIX_ROUND_GRID( x, n ) FT_PIX_FLOOR_GRID( (x) + 32 / (n), (n) ) -#define FT_PIX_CEIL_GRID( x, n ) FT_PIX_FLOOR_GRID( (x) + 63 / (n), (n) ) - /* * Return the highest power of 2 that is <= value; this correspond to diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index fdf2dd2..0fd3045 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -22,7 +22,6 @@ #include "aflatin.h" #include "aferrors.h" -#include "strings.h" #ifdef AF_CONFIG_OPTION_USE_WARPER @@ -529,30 +528,7 @@ FT_Pos delta; AF_LatinAxis axis; FT_UInt nn; -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - int checked_adjust_heights_env = 0; - FT_Bool adjust_heights = FALSE; - if ( checked_adjust_heights_env == 0 ) - { - char *adjust_heights_env = getenv( "INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS" ); - if ( adjust_heights_env != NULL ) - { - if ( strcasecmp(adjust_heights_env, "default" ) != 0 ) - { - if ( strcasecmp(adjust_heights_env, "true") == 0) - adjust_heights = TRUE; - else if ( strcasecmp(adjust_heights_env, "1") == 0) - adjust_heights = TRUE; - else if ( strcasecmp(adjust_heights_env, "on") == 0) - adjust_heights = TRUE; - else if ( strcasecmp(adjust_heights_env, "yes") == 0) - adjust_heights = TRUE; - } - } - checked_adjust_heights_env = 1; - } -#endif if ( dim == AF_DIMENSION_HORZ ) { @@ -580,7 +556,7 @@ { AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT]; AF_LatinBlue blue = NULL; - int threshold = 40; + for ( nn = 0; nn < Axis->blue_count; nn++ ) { @@ -590,16 +566,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 + if ( blue ) { FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); - FT_Pos fitted = ( scaled + threshold ) & ~63; + FT_Pos fitted = ( scaled + 40 ) & ~63; + if ( scaled != fitted ) { @@ -654,6 +626,7 @@ AF_LatinBlue blue = &axis->blues[nn]; FT_Pos dist; + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; blue->ref.fit = blue->ref.cur; blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; @@ -662,12 +635,7 @@ /* 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 always, in order to prevent fringes */ -#else if ( dist <= 48 && dist >= -48 ) -#endif { #if 0 FT_Pos delta1; @@ -718,12 +686,7 @@ 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 #endif @@ -1470,8 +1433,6 @@ if ( dist < 0 ) dist = -dist; - /* round down to pixels */ - /*dist = FT_MulFix( dist, scale ) & ~63;*/ dist = FT_MulFix( dist, scale ); if ( dist < best_dist ) { @@ -1634,95 +1595,20 @@ 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; - FT_UInt checked_autohint_snap_stem_height = 0; - - if ( checked_autohint_snap_stem_height == 0) - { - char *autohint_snap_stem_height_env = getenv( "INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT" ); - if ( autohint_snap_stem_height_env != NULL ) - { - sscanf ( autohint_snap_stem_height_env, "%u", &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; - } - checked_autohint_snap_stem_height = 1; - } - - if ( autohint_snap_stem_height == 0 ) -#endif - if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || - axis->extra_light ) - return width; + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || + axis->extra_light ) + return width; if ( dist < 0 ) { dist = -width; sign = 1; } -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - /* Calculate snap value differently than standard freetype */ - if ( /* stem_snap_light*/ 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 ) - { - 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 ) - { - /* 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 (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 + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) { /* smooth hinting process: very lightly quantize the stem width */ @@ -1781,10 +1667,7 @@ dist = ( dist + 32 ) & ~63; } } - else -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - if ( autohint_snap_stem_height < 100 ) -#endif + else { /* strong hinting process: snap the stem width to integer pixels */ @@ -1792,9 +1675,7 @@ 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 + if ( vertical ) { /* in the case of vertical hinting, always round */ @@ -1857,23 +1738,6 @@ } 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 if ( sign ) dist = -dist; @@ -1896,8 +1760,6 @@ (AF_Edge_Flags)base_edge->flags, (AF_Edge_Flags)stem_edge->flags ); -/* 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 */ stem_edge->pos = base_edge->pos + fitted_width; @@ -2372,32 +2234,8 @@ { FT_Error error; int dim; -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - int emboldening_strength = 0; - int checked_use_various_tweaks_env = 0; - FT_Bool use_various_tweaks = FALSE; - if ( checked_use_various_tweaks_env == 0 ) - { - char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); - if ( use_various_tweaks_env != NULL ) - { - if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) - { - if ( strcasecmp(use_various_tweaks_env, "true") == 0) - use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "1") == 0) - use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "on") == 0) - use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) - use_various_tweaks = TRUE; - } - } - checked_use_various_tweaks_env = 1; - } -#endif error = af_glyph_hints_reload( hints, outline ); if ( error ) goto Exit; @@ -2454,54 +2292,7 @@ } } af_glyph_hints_save( hints, outline ); -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -#if 0 - if( metrics->root.scaler.face->style_name ) - { - if ( strcasestr(metrics->root.scaler.face->style_name, "Bold") - || strcasestr(metrics->root.scaler.face->style_name, "Black") - || strcasestr(metrics->root.scaler.face->style_name, "Narrow") - && metrics->root.scaler.face->size->metrics.x_ppem < 15 - || strcasestr(metrics->root.scaler.face->style_name, "Condensed") - && metrics->root.scaler.face->size->metrics.x_ppem < 20 ) - goto Exit; - } - if( metrics->root.scaler.face->family_name ) - { - if ( strcasestr(metrics->root.scaler.face->family_name, "Bold") - || strcasestr(metrics->root.scaler.face->family_name, "Black") - || strcasestr(metrics->root.scaler.face->family_name, "Narrow") - && metrics->root.scaler.face->size->metrics.x_ppem < 15 - || strcasestr(metrics->root.scaler.face->family_name, "Condensed") - && metrics->root.scaler.face->size->metrics.x_ppem < 20 ) - goto Exit; - } - /* if the font is particularly thin, embolden it, up to 1 px */ - if ( use_various_tweaks - && metrics->axis->widths[0].cur <= FT_MulDiv ( autohint_minimum_stem_width, 64, 100) - && !( dim == AF_DIMENSION_VERT ) - && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) - { - if ( metrics->axis->widths[0].cur - / metrics->root.scaler.face->size->metrics.x_ppem < 5 ) - { - emboldening_strength = FT_MulDiv ( autohint_minimum_stem_width, 64, 100) - metrics->axis->widths[0].cur; - if ( metrics->root.scaler.face->size->metrics.x_ppem < 9 ) - emboldening_strength -= 10; - if ( metrics->root.scaler.face->size->metrics.x_ppem < 7 ) - emboldening_strength -= 10; - } - if ( emboldening_strength < 0 ) emboldening_strength = 0; - FT_Outline_Embolden(outline,emboldening_strength); - } -#endif - /* Save this width for use in ftsmooth.c. This is a shameful hack */ - const char* c1 = "CUR_WIDTH"; - char c2[8]; - snprintf(c2,8,"%ld",metrics->axis->widths[0].cur); - setenv(c1, c2, 1); -#endif Exit: return error; } diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c index 09a9551..0da4ba1 100644 --- a/src/base/ftlcdfil.c +++ b/src/base/ftlcdfil.c @@ -21,9 +21,6 @@ #include FT_IMAGE_H #include FT_INTERNAL_OBJECTS_H -#include <math.h> -#include <string.h> -#include <strings.h> #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING @@ -290,51 +287,10 @@ { 0x00, 0x55, 0x56, 0x55, 0x00 }; /* the values here sum up to a value larger than 256, */ /* providing a cheap gamma correction */ - static FT_Byte default_filter[5] = + static const FT_Byte default_filter[5] = { 0x10, 0x40, 0x70, 0x40, 0x10 }; -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - int checked_filter_params_env = 0; - if ( checked_filter_params_env == 0 ) - { - char *filter_params = getenv( "INFINALITY_FT_FILTER_PARAMS" ); - if ( filter_params != NULL && strcmp(filter_params, "") != 0 ) - { - float f1, f2, f3, f4, f5; - if ( strcasecmp(filter_params, "default" ) != 0) - { - int args_assigned = 0; - args_assigned = sscanf ( filter_params, "%f %f %f %f %f", &f1, &f2, &f3, &f4, &f5 ); - - if ( args_assigned == 5 ) - { - if ( f1 + f2 + f3 + f4 + f5 > 5 ) - { - /* Assume we were given integers instead of floats */ - /* 0 to 100 */ - default_filter[0] = (FT_Byte) (f1 * 2.55f + 0.5f); - default_filter[1] = (FT_Byte) (f2 * 2.55f + 0.5f); - default_filter[2] = (FT_Byte) (f3 * 2.55f + 0.5f); - default_filter[3] = (FT_Byte) (f4 * 2.55f + 0.5f); - default_filter[4] = (FT_Byte) (f5 * 2.55f + 0.5f); - } - else - { - /* Assume we were given floating point values */ - /* 0 to 1.0 */ - default_filter[0] = (FT_Byte) (f1 * 255.0f + 0.5f); - default_filter[1] = (FT_Byte) (f2 * 255.0f + 0.5f); - default_filter[2] = (FT_Byte) (f3 * 255.0f + 0.5f); - default_filter[3] = (FT_Byte) (f4 * 255.0f + 0.5f); - default_filter[4] = (FT_Byte) (f5 * 255.0f + 0.5f); - } - } - } - } - checked_filter_params_env = 1; - } -#endif if ( !library ) return FT_Err_Invalid_Argument; diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 66a199a..36ee797 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -513,22 +513,6 @@ 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, @@ -587,33 +571,8 @@ FT_Bool autohint = FALSE; FT_Module hinter; TT_Face ttface = (TT_Face)face; -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - int checked_use_various_tweaks_env = FALSE; - FT_Bool use_various_tweaks = FALSE; - - if ( !checked_use_various_tweaks_env ) - { - char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); - if ( use_various_tweaks_env != NULL ) - { - if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) - { - if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE; - } - } - checked_use_various_tweaks_env = 1; - } - /* Force autohint if no tt instructions */ - 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_Err_Invalid_Face_Handle; @@ -693,18 +652,8 @@ if ( autohint ) { FT_AutoHinter_Service 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 */ /* */ /* XXX: This is really a temporary hack that should disappear */ @@ -742,10 +691,6 @@ } else { -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - char* c1 = "CUR_WIDTH"; - char* c2 = "0"; -#endif error = driver->clazz->load_glyph( slot, face->size, glyph_index, @@ -753,16 +698,6 @@ if ( error ) goto Exit; -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - setenv(c1, c2, 1); - - { - /* fix for sdl_ttf */ - FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); - ft_glyphslot_enlarge_metrics( slot, mode ); - } -#endif - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) { /* check that the loaded outline is correct */ diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index fa4ee0d..76e2b04 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -897,29 +897,7 @@ FT_Vector v_prev, v_first, v_next, v_cur; FT_Int c, n, first; FT_Int orientation; -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - int checked_use_various_tweaks_env = 0; - FT_Bool use_various_tweaks = FALSE; - if ( checked_use_various_tweaks_env == 0 ) - { - char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); - if ( use_various_tweaks_env != NULL ) - { - if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) - { - if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE; - } - } - checked_use_various_tweaks_env = 1; - } - - if ( use_various_tweaks ) - ystrength = FT_PIX_FLOOR ( ystrength ); -#endif if ( !outline ) return FT_Err_Invalid_Argument; diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c index b186d8d..81e2ed2 100644 --- a/src/base/ftsynth.c +++ b/src/base/ftsynth.c @@ -88,26 +88,7 @@ FT_Face face = slot->face; FT_Error error; FT_Pos xstr, ystr; -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - int checked_use_various_tweaks_env = 0; - FT_Bool use_various_tweaks = FALSE; - if ( checked_use_various_tweaks_env == 0 ) - { - char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); - if ( use_various_tweaks_env != NULL ) - { - if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) - { - if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE; - } - } - checked_use_various_tweaks_env = 1; - } -#endif if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && slot->format != FT_GLYPH_FORMAT_BITMAP ) @@ -120,11 +101,6 @@ 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 /* ignore error */ (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); } @@ -165,9 +141,6 @@ 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; diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c index a628dff..00499cc 100644 --- a/src/smooth/ftsmooth.c +++ b/src/smooth/ftsmooth.c @@ -26,16 +26,6 @@ #include "ftsmerrs.h" -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -#include <math.h> -#include "../../include/freetype/ftbitmap.h" -#include "strings.h" -#include "../autofit/aflatin.h" -#include "../../include/freetype/ftoutln.h" - -#define verbose FALSE -#define STVALUES if (verbose) printf ("scale:%f translate:%ld ", *scale_value, *translate_value); -#endif /* initialize renderer -- init its raster */ static FT_Error @@ -103,2763 +93,6 @@ 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); - } - - - int - gamma2 ( int val, float value ) - { - return 256 * (1.0 - pow((1.0 - (float)val/ 256.0) , 1.0/value)); - } - - - - 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 + gamma2(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] = gamma2(line [xx], strength) ; - - } - - } - } - - - /* 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) new_line[xx-1] -= (new_line[xx-1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */ - if (rightdiff < 10) new_line[xx+1] -= (new_line[xx+1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT */ - } - 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) new_line[xx-1] -= (new_line[xx-1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */ - if (rightdiff < 10) new_line[xx+1] -= (new_line[xx+1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT */ - } - } - /* 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; - } - } - } - - - - /*************************************************************************/ - /* */ - /* */ - /* */ - /* */ - /* */ - /* */ - - - typedef struct SA_Rule_ - { - const char family[32]; - const int ppem[5]; - } SA_Rule; - -#define STEM_WIDTH_2_PPEM 18 -#define MAX_PPEM 100 - - - -/* "Font name", {ppem where stem width becomes 1, - * ppem where stem width becomes 2... etc.} */ -/* 100 means auto-calculate */ -#define SNAPPING_STEM_WIDTHS_RULES_SIZE 21 - SA_Rule SNAPPING_STEM_WIDTHS_Rules - [SNAPPING_STEM_WIDTHS_RULES_SIZE] = - { - { "Andale Mono", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Arial Narrow", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Calibri", {10, 19, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Cantarell", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Century Gothic", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Comfortaa", {10, 19, 22, MAX_PPEM, MAX_PPEM} }, - { "Consolas", {10, 20, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Corbel", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Futura", {10, 14, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Gill Sans", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Helvetica CY", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Inconsolata", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Liberation Sans Narrow", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Liberation Sans", {10, 19, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Lucida Grande", {10, 16, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Lucida Sans Unicode", {10, 16, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Luxi Sans", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Open Sans", {10, 20, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Rokkitt", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Segoe UI", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, - { "Trebuchet MS", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, - }; - - -/* "Font name", {ppem, scale_up=1|scale_down=0} */ -#define SNAPPING_STEM_SCALING_RULES_SIZE 31 - SA_Rule SNAPPING_STEM_SCALING_Rules - [SNAPPING_STEM_SCALING_RULES_SIZE] = - { - { "Andale Mono", {11, 1,} }, - { "Bitstream Vera Sans", {12, 1,} }, - { "Calibri", {15, 1,} }, - { "Calibri", {17, 1,} }, - { "Calibri", {18, 1,} }, - { "Candara", {14, 1,} }, - { "Candara", {17, 1,} }, - { "Canwell", {13, 0,} }, - { "Comfortaa", {11, 0,} }, - { "Consolas", {11, 1,} }, - { "DejaVu Sans", {12, 1,} }, - { "Freesans", {16, 0,} }, - { "Freeserif", {13, 1,} }, - { "Freeserif", {17, 1,} }, - { "Inconsolata", {12, 1,} }, - { "Inconsolata", {15, 1,} }, - { "Lucida Grande", {13, 1,} }, - { "Myriad Pro", {14, 1,} }, - { "Myriad Pro", {17, 1,} }, - { "Nina", {11, 0,} }, - { "Nina", {12, 0,} }, - { "Nina", {13, 0,} }, - { "Optima", {17, 1,} }, - { "Raleway", {15, 0,} }, - { "Samba", {11, 0,} }, - { "Times New Roman", {17, 1,} }, - { "Trebuchet MS", {17, 0,} }, - { "Trebuchet MS", {13, 0,} }, - { "Trebuchet MS", {20, 1,} }, - { "Verdana", {12, 1,} }, - { "Verdana", {15, 1,} }, - }; - - -/* "Font name", {ppem, scale_up=1|scale_down=0} */ -#define SNAPPING_M_RULES_SIZE 9 - SA_Rule SNAPPING_M_Rules - [SNAPPING_M_RULES_SIZE] = - { - { "Courier New", {13, 1,} }, - { "Courier New", {14, 1,} }, - { "Courier", {13, 1,} }, - { "Courier", {14, 1,} }, - { "Droid Sans Mono", {12, 0,} }, - { "Bitstream Vera Sans", {12, 0,} }, - { "DejaVu Sans", {12, 0,} }, - { "Essential PragmataPro", {13, 0,} }, - { "Essential PragmataPro", {14, 0,} }, - }; - - -/* "Font name", {ppem, ppem} */ -#define SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE 1 - SA_Rule SNAPPING_SYNTHESIZE_STEMS_Rules - [SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE] = - { - { "---", {13, 13,} }, - }; - - -/* "Font name", {ppem, ppem} */ -#define SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE 1 - SA_Rule SNAPPING_NO_BEARING_CORRECTION_Rules - [SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE] = - { - { "Times New Roman", {0, 100,} }, - }; - - -/* "Font name", {ppem, ppem} */ -#define SNAPPING_EDGE_DETECTION_RULES_SIZE 8 - SA_Rule SNAPPING_EDGE_DETECTION_Rules - [SNAPPING_EDGE_DETECTION_RULES_SIZE] = - { - { "Tahoma", {11, 11,} }, - { "Courier New", {10, 12,} }, - { "Arial", {11, 11,} }, - { "Arial", {13, 13,} }, - { "Liberation Sans", {11, 11,} }, - { "FreeSans", {11, 11,} }, - { "FreeSans", {13, 13,} }, - { "Palatino Linotype", {0, 100,} }, - }; - -/* "Font name", {ppem, translate_value} */ -#define SNAPPING_STEM_TRANSLATING_RULES_SIZE 6 - SA_Rule SNAPPING_STEM_TRANSLATING_Rules - [SNAPPING_STEM_TRANSLATING_RULES_SIZE] = - { - { "Arial", {11, 32,} }, - { "Arial Unicode MS", {11, 32,} }, - { "FreeSans", {11, 32,} }, - { "Arimo", {11, 32,} }, - { "Liberation Sans", {11, 32,} }, - { "Tahoma", {11, 32,} }, - }; - -/* "Font name", {ppem, translate_value} */ -#define SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE 74 - SA_Rule SNAPPING_STEM_TRANSLATING_ONLY_Rules - [SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE] = - { - { "Arial Unicode MS", {10, 16,} }, - { "Arial Unicode MS", {8, 32,} }, - { "Arial Unicode MS", {9, 32,} }, - { "Arial", {10, 16,} }, - { "Arial", {8, 32,} }, - { "Arial", {9, 32,} }, - { "Arial", {16, -24,} }, - { "Arimo", {10, 8,} }, - { "Arimo", {8, 32,} }, - { "Arimo", {9, 32,} }, - { "Bitstream Vera Sans", {8, 16,} }, - { "Calibri", {10, 16,} }, - { "Calibri", {15, 0,} }, - { "Candara", {10, 16,} }, - { "Cantarell", {11, 0} }, - { "Cantarell", {12, 0} }, - { "Consolas", {8, 32,} }, - { "Consolas", {9, 32,} }, - { "Corbel", {10, 16,} }, - { "Courier", {13, 16,} }, - { "Courier", {15, 0,} }, - { "Dejavu Sans Mono", {7, 16,} }, - { "Dejavu Sans Mono", {8, 32,} }, - { "Dejavu Sans Mono", {9, 16,} }, - { "Dejavu Sans", {8, 16,} }, - { "Dejavu Sans", {15, -20,} }, - { "Droid Sans", {8, 16,} }, - { "Droid Sans", {9, 16,} }, - { "Freesans", {10, 16,} }, - { "Freesans", {9, 8,} }, - { "Georgia", {13, 16,} }, - { "Georgia", {14, 16,} }, - { "Georgia", {15, 0,} }, - { "Inconsolata", {10, 24,} }, - { "Inconsolata", {9, 32,} }, - { "Liberation Sans", {10, 8,} }, - { "Liberation Sans", {8, 32,} }, - { "Liberation Sans", {9, 32,} }, - { "Lucida Grande", {13, 24,} }, - { "Lucida Grande", {14, 24,} }, - { "Lucida Grande", {8, 16,} }, - { "Lucida Grande", {9, 16,} }, - { "Lucida Sans Unicode", {13, 24,} }, - { "Lucida Sans Unicode", {14, 24,} }, - { "Lucida Sans Unicode", {8, 16,} }, - { "Lucida Sans Unicode", {9, 16,} }, - { "Microsoft Sans Serif", {10, 16,} }, - { "Microsoft Sans Serif", {8, 32,} }, - { "Microsoft Sans Serif", {9, 32,} }, - { "Myriad Pro", {10, 16,} }, - { "Myriad Pro", {11, 0,} }, - { "Myriad Pro", {9, 16,} }, - { "Open Sans", {10, 16,} }, - { "Open Sans", {9, 16,} }, - { "Optima", {10, 0} }, - { "Optima", {11, 0} }, - { "Optima", {12, 0} }, - { "Segoe UI", {10, 0,} }, - { "Segoe UI", {7, 32,} }, - { "Segoe UI", {8, 16,} }, - { "Segoe UI", {9, 24,} }, - { "Tahoma", {7, 32,} }, - { "Tahoma", {8, 32,} }, - { "Tahoma", {9, 32,} }, - { "Times New Roman", {17, 8,} }, - { "Trebuchet MS", {10, 16,} }, - { "Trebuchet MS", {11, 0,} }, - { "Trebuchet MS", {8, 32,} }, - { "Trebuchet MS", {9, 32,} }, - { "Verdana", {8, 16,} }, - { "Verdana", {15, 16,} }, - { "Verdana", {14, 32,} }, - { "Verdana", {18, 32,} }, - { "Verdana", {19, 24,} }, - }; - - -/* "Font name", {start ppem, end ppem} */ -#define ALWAYS_USE_100_RULES_SIZE 46 - SA_Rule ALWAYS_USE_100_Rules - [ALWAYS_USE_100_RULES_SIZE] = - { - { "Andale Mono", {0, MAX_PPEM,} }, - { "Arial Unicode MS", {0, MAX_PPEM,} }, - { "Arial", {0, MAX_PPEM,} }, - { "Arimo", {0, MAX_PPEM,} }, - { "Bitstream Vera Sans Mono", {0, MAX_PPEM,} }, - { "Bitstream Vera Sans", {10, 14,} }, - { "Bitstream Vera Sans", {16, 17,} }, - { "Calibri", {23, MAX_PPEM,} }, - { "Consolas", {0, MAX_PPEM,} }, - { "Courier New", {12, 12,} }, - { "Courier", {0, MAX_PPEM,} }, - { "Cousine", {0, MAX_PPEM,} }, - { "DejaVu Sans Mono", {0, MAX_PPEM,} }, - { "DejaVu Sans", {10, 14,} }, - { "DejaVu Sans", {16, 17,} }, - { "Droid Sans", {12, 12,} }, - { "Droid Sans", {15, 15,} }, - { "FreeMono", {0, MAX_PPEM,} }, - { "FreeSans", {0, MAX_PPEM,} }, - { "Liberation Mono", {0, MAX_PPEM,} }, - { "Lucida Console", {0, MAX_PPEM,} }, - { "Luxi Sans", {13, 13,} }, - { "Microsoft Sans Serif", {0, MAX_PPEM,} }, - { "Monaco", {0, MAX_PPEM,} }, - { "Segoe UI", {11, 12,} }, - { "Segoe UI", {14, 14,} }, - { "Tahoma", {11, 11,} }, - { "Tahoma", {14, MAX_PPEM,} }, - { "Times New Roman", {14, 14,} }, - { "Times New Roman", {16, 16,} }, - { "Trebuchet MS", {13, 13,} }, - { "Ubuntu", {12, 13,} }, - { "Ubuntu", {15, 15,} }, - { "Verdana", {0, 14,} }, - { "Verdana", {16, MAX_PPEM,} }, - { "Pragmata", {0, MAX_PPEM,} }, - { "Essential PragmataPro", {0, MAX_PPEM,} }, - }; - - - - -#define AUTOHINT_BRIGHTNESS_RULES_SIZE 3 - SA_Rule BRIGHTNESS_Rules - [AUTOHINT_BRIGHTNESS_RULES_SIZE] = - { - { "Baskerville", {0, -20,} }, - { "Garamond", {0, -20,} }, - { "Optima", {0, -20,} }, - }; - -#define AUTOHINT_CONTRAST_RULES_SIZE 3 - SA_Rule CONTRAST_Rules - [AUTOHINT_CONTRAST_RULES_SIZE] = - { - { "Baskerville", {0, 25,} }, - { "Garamond", {0, 25,} }, - { "Optima", {0, 25,} }, - }; - -#if 0 -#define STEM_SPACING_RULES_SIZE 3 - SA_Rule STEM_SPACING_Rules - [STEM_SPACING_RULES_SIZE] = - { - { "Tahoma", {10, 12, 18, 18, 30} }, - { "Arial", {10, 11, 23, 25, 30} }, - { "Freesans", {10, 12, 18, 18, 30} }, - }; - -#define STEM_START_RULES_SIZE 3 - SA_Rule STEM_START_Rules - [STEM_START_RULES_SIZE] = - { - { "Tahoma", {14, 17, 30, 100, 100} }, - { "Arial", {11, 18, 23, 30, 30} }, - { "Freesans", {10, 18, 18, 25, 30} }, - }; -#endif - - typedef struct Stem_Data_ - { - 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; - FT_Int brightness; - FT_Int contrast; - FT_Bool use_100; - FT_Bool synth_stems; - FT_Bool edge_detection; - FT_Bool bearing_correction; - FT_Int m; - } Stem_Data; - - - 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; - } - - - FT_LOCAL_DEF( void ) - sa_fill_known_stem_values ( - FT_String* family, - int ppem, - FT_String* style, - FT_UInt num_stems, - Stem_Data* known_stem_values ) - { - FT_Int i, j; - if (verbose) printf("%s ", family); - - i = 0; - while ( i < SNAPPING_STEM_WIDTHS_RULES_SIZE ) - { - if ( family && - ( strcasecmp( SNAPPING_STEM_WIDTHS_Rules[i].family, family ) == 0 ) ) - { - j = 0; - known_stem_values->stem_width = 1; - - while (j < 4) - { - if (SNAPPING_STEM_WIDTHS_Rules[i].ppem[j] == MAX_PPEM ) - { - known_stem_values->stem_width = -1; /* use default */ - j = 5; - i = SNAPPING_STEM_WIDTHS_RULES_SIZE; - } - else if (ppem < SNAPPING_STEM_WIDTHS_Rules[i].ppem[j]) - { - known_stem_values->stem_width = j; - j = 5; - i = SNAPPING_STEM_WIDTHS_RULES_SIZE; - } - j++; - } - } - i++; - } - - i = 0; - while ( i < SNAPPING_STEM_SCALING_RULES_SIZE ) - { - if ( family && - ( strcasecmp( SNAPPING_STEM_SCALING_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->stem_scaling = -1; /* default */ - - if (ppem == SNAPPING_STEM_SCALING_Rules[i].ppem[0]) - { - known_stem_values->stem_scaling = SNAPPING_STEM_SCALING_Rules[i].ppem[1]; - i = SNAPPING_STEM_SCALING_RULES_SIZE; - } - } - i++; - } - - - i = 0; - while ( i < SNAPPING_M_RULES_SIZE ) - { - if ( family && - ( strcasecmp( SNAPPING_M_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->m = -1; /* default */ - - if (ppem == SNAPPING_M_Rules[i].ppem[0]) - { - known_stem_values->m = SNAPPING_M_Rules[i].ppem[1]; - i = SNAPPING_M_RULES_SIZE; - } - } - i++; - } - - i = 0; - while ( i < SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE ) - { - if ( family && - ( strcasecmp( SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->stem_translating_only = -1024; /* default */ - - if (ppem == SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[0] - || SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[0] == 0) - { - known_stem_values->stem_translating_only = SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[1]; - i = SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE; - } - } - i++; - } - - i = 0; - while ( i < SNAPPING_STEM_TRANSLATING_RULES_SIZE ) - { - if ( family && - ( strcasecmp( SNAPPING_STEM_TRANSLATING_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->stem_translating = 0; /* default */ - - if (ppem == SNAPPING_STEM_TRANSLATING_Rules[i].ppem[0] - || SNAPPING_STEM_TRANSLATING_Rules[i].ppem[0] == 0) - { - known_stem_values->stem_translating = SNAPPING_STEM_TRANSLATING_Rules[i].ppem[1]; - i = SNAPPING_STEM_TRANSLATING_RULES_SIZE; - } - } - i++; - } - - - i = 0; - while ( i < ALWAYS_USE_100_RULES_SIZE ) - { - if ( family && - ( strcasecmp( ALWAYS_USE_100_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->use_100 = FALSE; /* default */ - - if (ppem >= ALWAYS_USE_100_Rules[i].ppem[0] && ppem <= ALWAYS_USE_100_Rules[i].ppem[1] ) - { - known_stem_values->use_100 = TRUE; - i = ALWAYS_USE_100_RULES_SIZE; - } - } - i++; - } - - - i = 0; - while ( i < SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE ) - { - if ( family && - ( strcasecmp( SNAPPING_SYNTHESIZE_STEMS_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->synth_stems = FALSE; /* default */ - - if (ppem >= SNAPPING_SYNTHESIZE_STEMS_Rules[i].ppem[0] && ppem <= SNAPPING_SYNTHESIZE_STEMS_Rules[i].ppem[1] ) - { - known_stem_values->synth_stems = TRUE; - i = SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE; - } - } - i++; - } - - - i = 0; - while ( i < SNAPPING_EDGE_DETECTION_RULES_SIZE ) - { - if ( family && - ( strcasecmp( SNAPPING_EDGE_DETECTION_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->edge_detection = FALSE; /* default */ - - if (ppem >= SNAPPING_EDGE_DETECTION_Rules[i].ppem[0] && ppem <= SNAPPING_EDGE_DETECTION_Rules[i].ppem[1] ) - { - known_stem_values->edge_detection = TRUE; - i = SNAPPING_EDGE_DETECTION_RULES_SIZE; - } - } - i++; - } - - - i = 0; - while ( i < SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE ) - { - if ( family && - ( strcasecmp( SNAPPING_NO_BEARING_CORRECTION_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->bearing_correction = TRUE; /* default */ - - if (ppem >= SNAPPING_NO_BEARING_CORRECTION_Rules[i].ppem[0] && ppem <= SNAPPING_NO_BEARING_CORRECTION_Rules[i].ppem[1] ) - { - known_stem_values->bearing_correction = FALSE; - i = SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE; - } - } - i++; - } - - -#if 0 - i = 0; - while ( i < AUTOHINT_BRIGHTNESS_RULES_SIZE ) - { - if ( family && - ( strcasecmp( BRIGHTNESS_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->brightness = 0.0; - - if (ppem == BRIGHTNESS_Rules[i].ppem[0] || BRIGHTNESS_Rules[i].ppem[0] == 0) - { - known_stem_values->brightness = BRIGHTNESS_Rules[i].ppem[1]; - i = AUTOHINT_BRIGHTNESS_RULES_SIZE; - } - } - i++; - } - - i = 0; - while ( i < AUTOHINT_CONTRAST_RULES_SIZE ) - { - if ( family && - ( strcasecmp( CONTRAST_Rules[i].family, family ) == 0 ) ) - { - known_stem_values->contrast = 0.0; - - if (ppem == CONTRAST_Rules[i].ppem[0] || CONTRAST_Rules[i].ppem[0] == 0) - { - known_stem_values->contrast = CONTRAST_Rules[i].ppem[1]; - i = AUTOHINT_CONTRAST_RULES_SIZE; - } - } - i++; - } - - for ( i = 0; i <= STEM_SPACING_RULES_SIZE; i++ ) - { - if ( family && - ( strcasecmp( STEM_SPACING_Rules[i].family, family ) == 0 ) ) - { - j = 0; - known_stem_values->stem_spacing = 2; /* default */ - - while (j < 4) - { - if (ppem < STEM_SPACING_Rules[i].ppem[j]) - { - known_stem_values->stem_spacing = j; - j = 5; - } - j++; - } - } - } - - - for ( i = 0; i <= STEM_START_RULES_SIZE; i++ ) - { - if ( family && - ( strcasecmp( STEM_START_Rules[i].family, family ) == 0 ) ) - { - j = 0; - known_stem_values->stem_start = 1; /* default */ - - while (j < 4) - { - if (ppem < STEM_START_Rules[i].ppem[j]) - { - known_stem_values->stem_start = j; - j = 5; - } - j++; - } - } - } -#endif - } - - - FT_LOCAL_DEF( FT_Int ) - get_contrast ( - FT_String* family, - int ppem) - { - FT_Int i; - if (verbose) printf("%s ", family); - - i = 0; - while ( i < AUTOHINT_CONTRAST_RULES_SIZE ) - { - if ( family && - ( strcasecmp( CONTRAST_Rules[i].family, family ) == 0 ) ) - { - if (ppem == CONTRAST_Rules[i].ppem[0] || CONTRAST_Rules[i].ppem[0] == 0) - { - return CONTRAST_Rules[i].ppem[1]; - } - } - i++; - } - return 0; - } - - - FT_LOCAL_DEF( FT_Int ) - get_brightness ( - FT_String* family, - int ppem) - { - FT_Int i; - if (verbose) printf("%s ", family); - - i = 0; - while ( i < AUTOHINT_BRIGHTNESS_RULES_SIZE ) - { - if ( family && - ( strcasecmp( BRIGHTNESS_Rules[i].family, family ) == 0 ) ) - { - if (ppem == BRIGHTNESS_Rules[i].ppem[0] || BRIGHTNESS_Rules[i].ppem[0] == 0) - { - return BRIGHTNESS_Rules[i].ppem[1]; - } - } - i++; - } - return 0; - } - - - /* 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[width * 256]; - 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; /*this needs work.. breaks some glyphs like verdana 12 */ - 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;*/ - FT_Bool strategy_use_verdana_12_hack = FALSE; /* not necessary anymore... maybe */ - FT_Bool has_serifs = FALSE; - FT_Bool autohinted = FALSE; - - const FT_Int MIN_PPEM = 7; - /*const FT_Int MAX_PPEM = 100;*/ - const FT_Int MAX_STEMS = 3; - FT_Int ppem = 0; - - int checked_use_known_settings_on_selected_fonts_env = 0; - FT_Bool use_known_settings_on_selected_fonts = FALSE; - - int cur_width; - char *cur_width_env = getenv( "CUR_WIDTH" ); - - if ( cur_width_env != NULL ){ - sscanf ( cur_width_env, "%d", &cur_width ); - if (cur_width != 0) autohinted = TRUE; - } - - /* An incoming scale value of 1.1 indicates to do certain things */ - /*if (*scale_value == 1.1) strategy_use_verdana_12_hack = TRUE;*/ - - /* reset to default */ - *scale_value = 1.0; - - if ( checked_use_known_settings_on_selected_fonts_env == 0 ) - { - char *use_known_settings_on_selected_fonts_env = getenv( "INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS" ); - if ( use_known_settings_on_selected_fonts_env != NULL ) - { - if ( strcasecmp(use_known_settings_on_selected_fonts_env, "default" ) != 0 ) - { - if ( strcasecmp(use_known_settings_on_selected_fonts_env, "true") == 0) - use_known_settings_on_selected_fonts = TRUE; - else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "1") == 0) - use_known_settings_on_selected_fonts = TRUE; - else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "on") == 0) - use_known_settings_on_selected_fonts = TRUE; - else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "yes") == 0) - use_known_settings_on_selected_fonts = TRUE; - } - } - checked_use_known_settings_on_selected_fonts_env = 1; - } - - - /* 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 ( width < 4 ) 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; - - - /* 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( slot->face->family_name ) - { - if ( strcasestr(slot->face->family_name, "Courier") - || strcasestr(slot->face->family_name, "Serif") - || strcasestr(slot->face->family_name, "Times")) - has_serifs = TRUE; - } - - 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*) malloc (columns_per_pixel * sizeof(Stem_Data)); /* only look at top 3 for now */ - known_stem_values->stem_spacing = -1; - known_stem_values->stem_width = -1; - known_stem_values->stem_start = -1; - known_stem_values->stem_scaling = -1; - known_stem_values->stem_translating_only = -1024; - known_stem_values->stem_translating = 0; - known_stem_values->brightness = 0; - known_stem_values->contrast = 0; - known_stem_values->use_100 = FALSE; - known_stem_values->m = -1; - known_stem_values->synth_stems = FALSE; - known_stem_values->bearing_correction = TRUE; - - if (use_known_settings_on_selected_fonts) - { - sa_fill_known_stem_values ( slot->face->family_name, - ppem, slot->face->style_name, - valid_stems, known_stem_values ); - if (verbose) - printf ("width:%d,spacing:%d,start:%d,scaling:%d,translate:%d ", - known_stem_values->stem_width, known_stem_values->stem_spacing, - known_stem_values->stem_start, known_stem_values->stem_scaling, - known_stem_values->stem_translating_only) ; - } - - /* translate value may be set for < 10 */ - if (use_known_settings_on_selected_fonts && known_stem_values->stem_translating_only > -1024 ) - { - *translate_value = known_stem_values->stem_translating_only; - return; - } - - if (use_known_settings_on_selected_fonts && known_stem_values->bearing_correction == FALSE ) - { - strategy_bearing_correction = 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; - } - - if ( ppem < 9 ) return; - if ( ppem > 20 ) strategy_use_m_control = TRUE; - - /* Allocate */ - segments = (Stem_Segment*) malloc( (1) * sizeof (Stem_Segment)); - leftmost_segment = (Stem_Segment*) malloc( sizeof (Stem_Segment)); - leftmost_segment_not_extrema = (Stem_Segment*) malloc( sizeof (Stem_Segment)); - rightmost_segment = (Stem_Segment*) malloc( sizeof (Stem_Segment)); - rightmost_segment_not_extrema = (Stem_Segment*) malloc( sizeof (Stem_Segment)); - - stems = (Stem*) malloc (MAX_STEMS * sizeof(Stem)); - possible_stems = (Stem*) malloc (MAX_STEMS * sizeof(Stem)); - leftmost_stem = (Stem*) malloc ( sizeof(Stem)); - rightmost_stem = (Stem*) malloc ( sizeof(Stem)); - centers = (Stem_Center*) malloc ( (1) * sizeof(Stem_Center)); - - if (verbose) printf("\n"); - - /* Initialize */ - for ( xx = 0; xx < width * 256; xx += 1 ) - { - stem_centers[xx] = 0; - } - for ( xx = 0; xx < num_segments; xx += 1 ) - { - segments[xx].x1 = 0; - segments[xx].x2 = 0; - segments[xx].y = 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 */ - segments = (Stem_Segment*) realloc( segments, (num_segments + 1) * 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/*, stem_width*/; - 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; - /*stem_width = segments[num_segments].x2 - segments[num_segments].x1;*/ - /* Reallocate */ - centers = (Stem_Center*) realloc ( centers, (num_centers + 1) * 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; */ - FT_Int deviation1 = 5; /* 10 to 20 wiith 4 matches seems good, but 1 or 2 with 3 stems needs to somehow get included */ - FT_Int deviation2=-1, requirement1 = 4, stem_match_requirement = 3; - FT_Int best_height = 0, 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 large_gap_found = FALSE, no_gap_found = FALSE; - FT_Bool large_gap_found_ledge = FALSE, no_gap_found_ledge = FALSE; - FT_Bool large_gap_found_redge = FALSE, 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; - } - - /* THIS WORKS, BUT NEED TO PUNISH DIAGONALS like W */ - /*requirement2 = height / 5; - if (requirement2 < 3) requirement2 = 3; - deviation2 = 1 ;*/ - valid_center_average = 0; - /* if (deviation2 < 1) deviation2 = 1;*/ - - large_gap_found = large_gap_found_ledge = large_gap_found_redge = FALSE; - 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) - large_gap_found = TRUE; - /* 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) - large_gap_found_ledge = TRUE; - /* 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) - large_gap_found_redge = TRUE; - /* 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; - - best_height = stem_matches; - - /* new version */ - 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; - best_height = stem_matches; - set_center_to = centers[center].x; - - } - /* see if edges found anything */ - if (strategy_also_use_edge_detection_for_stems && !stem_detected) - { - if (( - /* Require no gap for edges */ - stem_matches_ledge >= stem_match_requirement && no_gap_found_ledge - /* 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) - /* The stem occurs on the left side of glyph only */ - && centers[center].x < (m_horiAdvance * 12) / 2 - - ) - { - stem_detected = TRUE; - set_width_to = smallest_width_ledge; - best_height = stem_matches_ledge; - set_center_to = centers[center].x1 + set_width_to / 2; - stem_matches = stem_matches_ledge; - } - else if (( - /* Require no gap for edges */ - stem_matches_redge >= stem_match_requirement && no_gap_found_redge - /* 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) - /* The stem occurs on the right side of glyph only */ - && centers[center].x > (m_horiAdvance * 12) / 2 - ) - { - stem_detected = TRUE; - set_width_to = smallest_width_redge; - best_height = stem_matches_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 ) - if ( 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 the stem is within the 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] ); - } - - if (strategy_use_verdana_12_hack - && strcasestr(slot->face->family_name, "Verdana") - && ppem == 12 - && valid_stems == 1 - && (stems[0].center + m_horiBearingX * 12 - one_pixel < m_horiAdvance * 4 - ||stems[0].center + m_horiBearingX * 12 - one_pixel > m_horiAdvance * 8) ) - { - if (stems[0].center + m_horiBearingX * 12 - one_pixel < m_horiAdvance * 4) - { - stems[1].center = rightmost_point - one_pixel / 2; - stems[1].width = 1; - stems[1].generated = TRUE; - valid_stems += 1; - } - else - { - stems[1].center = leftmost_point + one_pixel / 2; - stems[1].width = 1; - stems[1].generated = TRUE; - valid_stems += 1; - } - strategy_always_use_distance_ceiling = TRUE; - } - - /* 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 ) *translate_value = ( - delta ) / (columns_per_pixel * 4); /* snap left */ - else *translate_value = (modulus -delta) / (columns_per_pixel * 4); /* snap right */ - } - - 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 && valid_stems == 3 - && (width - 2 * columns_per_pixel) > 6 * columns_per_pixel - && ppem > 8 - && (advance_stem_location - advance_leftmost_location) < stems[main_stem].width * 2 ) - { - FT_Int mod_factor = 2; /*Possibly use 2 only when compatible widths is on? */ - - 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 ) - { - FT_Int mod_factor = 2; /*Possibly use 2 only when compatible widths is on? */ - - 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 there is 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 ) translate_value2 = ( - delta2 ) / (columns_per_pixel * 4); /* snap left */ - else translate_value2 = (modulus -delta2) / (columns_per_pixel * 4); /* snap right */ - - 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 ) new_distance = delta + stem_distance; /* stretch left */ - else new_distance = delta - modulus + stem_distance; /* stretch right */ - - 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 + 0) / (float)(stem_distance + 0 ); - *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 "); - } - } - - if ( strategy_use_verdana_12_hack - && strcasestr(slot->face->family_name, "Verdana") - && ppem == 12 - && *scale_value == 1.0 && valid_stems == 0 - && height < 8 - && advance_rightmost_location * 1.1 < advance_width ) - *scale_value = 1.1; - - 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(segments); - free(leftmost_segment); - free(rightmost_segment); - - free(known_stem_values); - free(stems); - free(possible_stems); - free(leftmost_stem); - free(rightmost_stem); - - free(centers); - - } - - - /* 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] = gamma2 ( line[xx], gamma_correction_value );*/ - - /* sloped */ - /*line[xx] = gamma2 ( 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] = gamma2 ( 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 @@ -2871,406 +104,19 @@ { FT_Error error; FT_Outline* outline = NULL; - FT_Outline* outline_orig = NULL; FT_BBox cbox; - FT_Pos width=0, height=0, pitch=0, ppem; + FT_Pos width, height, pitch; #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING FT_Pos height_org, width_org; #endif - FT_Bitmap* bitmap = 0; - FT_Memory memory = 0; + FT_Bitmap* bitmap; + FT_Memory memory; FT_Int hmul = mode == FT_RENDER_MODE_LCD; FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; - FT_Pos x_shift = 0, y_shift = 0, x_left = 0, y_top = 0; + FT_Pos x_shift, y_shift, x_left, y_top; FT_Raster_Params params; -#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 checked_chromeos_style_sharpening_strength = 0; - int alignment_strength = 0; - int fitting_strength = 0; - FT_UInt checked_alignment_strength = 0; - FT_UInt checked_fitting_strength = 0; - FT_UInt checked_fringe_filter_strength = 0; - int fringe_filter_strength = 0; - FT_UInt checked_grayscale_filter_strength = 0; - int grayscale_filter_strength = 0; - - FT_UInt checked_autohint_horizontal_stem_darken_strength = 0; - int autohint_horizontal_stem_darken_strength = 0; - - FT_UInt checked_autohint_vertical_stem_darken_strength = 0; - int autohint_vertical_stem_darken_strength = 0; - - int windows_style_sharpening_strength = 0; - FT_UInt checked_windows_style_sharpening_strength = 0; - float gamma_correction_value = 1; - float gamma_correction_lt = 0; - FT_UInt checked_gamma_correction_value = 0; - - FT_Int brightness_value = 0.0; - FT_UInt checked_brightness_value = 0; - - FT_Int contrast_value = 0.0; - FT_UInt checked_contrast_value = 0; - - FT_Int snapping_sliding_scale_value = 0; - FT_UInt checked_snapping_sliding_scale_value = 0; - - FT_Int global_embolden_x_value = 0; - FT_UInt checked_global_embolden_x_value = 0; - - FT_Int global_embolden_y_value = 0; - FT_UInt checked_global_embolden_y_value = 0; - - FT_Int bold_embolden_x_value = 0; - FT_UInt checked_bold_embolden_x_value = 0; - - FT_Int bold_embolden_y_value = 0; - FT_UInt checked_bold_embolden_y_value = 0; - - FT_Byte chromeos_cutoff; - double chromeos_gamma_value; - - float embolden_value = 0.0; - FT_Bool autohinted = FALSE; - - FT_UInt autohint_minimum_stem_height = 0; - FT_UInt checked_autohint_minimum_stem_height = 0; - - int checked_use_various_tweaks_env = 0; - FT_Bool use_various_tweaks = FALSE; - - int cur_width; - char *cur_width_env = getenv( "CUR_WIDTH" ); - - const FT_Int MIN_PPEM = 1; - /*const FT_Int MAX_PPEM = 100; */ - - int checked_use_known_settings_on_selected_fonts_env = 0; - FT_Bool use_known_settings_on_selected_fonts = FALSE; - - 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_env != NULL ){ - sscanf ( cur_width_env, "%d", &cur_width ); - if (cur_width != 0) autohinted = TRUE; - } - - if ( checked_use_known_settings_on_selected_fonts_env == 0 ) - { - char *use_known_settings_on_selected_fonts_env = getenv( "INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS" ); - if ( use_known_settings_on_selected_fonts_env != NULL ) - { - if ( strcasecmp(use_known_settings_on_selected_fonts_env, "default" ) != 0 ) - { - if ( strcasecmp(use_known_settings_on_selected_fonts_env, "true") == 0) - use_known_settings_on_selected_fonts = TRUE; - else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "1") == 0) - use_known_settings_on_selected_fonts = TRUE; - else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "on") == 0) - use_known_settings_on_selected_fonts = TRUE; - else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "yes") == 0) - use_known_settings_on_selected_fonts = TRUE; - } - } - checked_use_known_settings_on_selected_fonts_env = 1; - } - - if ( checked_use_various_tweaks_env == 0 ) - { - char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); - if ( use_various_tweaks_env != NULL ) - { - if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) - { - if ( strcasecmp(use_various_tweaks_env, "true") == 0) - use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "1") == 0) - use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "on") == 0) - use_various_tweaks = TRUE; - else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) - use_various_tweaks = TRUE; - } - } - checked_use_various_tweaks_env = 1; - } - - if ( checked_autohint_minimum_stem_height == 0) - { - char *autohint_minimum_stem_height_env = getenv( "INFINALITY_FT_AUTOHINT_MINIMUM_STEM_WIDTH" ); - if ( autohint_minimum_stem_height_env != NULL ) - { - sscanf ( autohint_minimum_stem_height_env, "%u", &autohint_minimum_stem_height ); - if (autohint_minimum_stem_height > 100 ) autohint_minimum_stem_height = 100; - else if (autohint_minimum_stem_height < 0 ) autohint_minimum_stem_height = 0; - } - checked_autohint_minimum_stem_height = 1; - } - - if ( checked_snapping_sliding_scale_value == 0) - { - char *snapping_sliding_scale_env = getenv ( "INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE" ); - if ( snapping_sliding_scale_env != NULL ) - { - sscanf ( snapping_sliding_scale_env, "%d", &snapping_sliding_scale_value ); - if (snapping_sliding_scale_value > MAX_PPEM ) snapping_sliding_scale_value = 0; - else if (snapping_sliding_scale_value < 0 ) snapping_sliding_scale_value = 0; - - if (snapping_sliding_scale_value < 11 && snapping_sliding_scale_value > 0 ) snapping_sliding_scale_value = 11; - } - checked_snapping_sliding_scale_value = 1; - } - - if ( checked_alignment_strength == 0) - { - char *alignment_strength_env = getenv ( "INFINALITY_FT_STEM_ALIGNMENT_STRENGTH" ); - if ( alignment_strength_env != NULL ) - { - sscanf ( alignment_strength_env, "%d", &alignment_strength ); - if (alignment_strength > 100 ) alignment_strength = 100; - else if (alignment_strength < 0 ) alignment_strength = 0; - } - if (alignment_strength > 100 ) alignment_strength = 100; - checked_alignment_strength = 1; - if (snapping_sliding_scale_value != 0) - alignment_strength = sliding_scale ( 10, snapping_sliding_scale_value, alignment_strength, 100, ppem); - } - - if ( checked_fitting_strength == 0) - { - char *fitting_strength_env = getenv( "INFINALITY_FT_STEM_FITTING_STRENGTH" ); - if ( fitting_strength_env != NULL ) - { - sscanf ( fitting_strength_env, "%d", &fitting_strength ); - if (fitting_strength > 100 ) fitting_strength = 100; - else if (fitting_strength < 0 ) fitting_strength = 0; - } - if (fitting_strength > 100 ) fitting_strength = 100; - checked_fitting_strength = 1; - if (snapping_sliding_scale_value != 0) - fitting_strength = sliding_scale ( 10, snapping_sliding_scale_value, fitting_strength, 100, ppem); - } - - if ( checked_chromeos_style_sharpening_strength == 0) - { - char *chromeos_style_sharpening_strength_env = getenv( "INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH" ); - if ( chromeos_style_sharpening_strength_env != NULL ) - { - sscanf ( chromeos_style_sharpening_strength_env, "%d", &chromeos_style_sharpening_strength ); - if (chromeos_style_sharpening_strength > 100 ) - chromeos_style_sharpening_strength = 100; - else if (chromeos_style_sharpening_strength < 0 ) - chromeos_style_sharpening_strength = 0; - } - if (ppem > 10) - chromeos_style_sharpening_strength = - (chromeos_style_sharpening_strength * ppem) / 10; - if (chromeos_style_sharpening_strength > 100 ) - chromeos_style_sharpening_strength = 100; - checked_chromeos_style_sharpening_strength = 1; - } - - - if ( checked_brightness_value == 0) - { - char *brightness_env = getenv( "INFINALITY_FT_BRIGHTNESS" ); - if ( brightness_env != NULL ) - { - sscanf ( brightness_env, "%d", &brightness_value ); - if (brightness_value > 100 ) - brightness_value = 100; - else if (brightness_value < -100 ) - brightness_value = 0; - } - checked_brightness_value = 1; - } - - if ( checked_contrast_value == 0) - { - char *contrast_env = getenv( "INFINALITY_FT_CONTRAST" ); - if ( contrast_env != NULL ) - { - sscanf ( contrast_env, "%d", &contrast_value ); - if (contrast_value > 100 ) - contrast_value = 100; - else if (contrast_value < -100 ) - contrast_value = 100; - } - checked_contrast_value = 1; - } - - if ( checked_windows_style_sharpening_strength == 0) - { - char *windows_style_sharpening_strength_env = getenv( "INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH" ); - if ( windows_style_sharpening_strength_env != NULL ) - { - sscanf ( windows_style_sharpening_strength_env, "%d", &windows_style_sharpening_strength ); - if (windows_style_sharpening_strength > 100 ) windows_style_sharpening_strength = 100; - else if (windows_style_sharpening_strength < 0 ) windows_style_sharpening_strength = 0; - } - /* Decrease the effect slightly in order 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; - checked_windows_style_sharpening_strength = 1; - } - - if ( checked_gamma_correction_value == 0 ) - { - char *gamma_correction_value_env = getenv( "INFINALITY_FT_GAMMA_CORRECTION" ); - if ( gamma_correction_value_env != NULL ) - { - float f1, f2; - - if ( strcasecmp(gamma_correction_value_env, "default" ) != 0) - { - sscanf ( gamma_correction_value_env, "%f %f", &f1, &f2 ); - gamma_correction_lt = f1; - gamma_correction_value = f2 / 100.0; - } - if ( gamma_correction_value < .01 ) gamma_correction_value = 1.0; - } - checked_gamma_correction_value = 1; - } - - /* 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 ( checked_fringe_filter_strength == 0) - { - char *fringe_filter_strength_env = getenv( "INFINALITY_FT_FRINGE_FILTER_STRENGTH" ); - if ( fringe_filter_strength_env != NULL ) - { - sscanf ( fringe_filter_strength_env, "%d", &fringe_filter_strength ); - if (fringe_filter_strength > 100 ) fringe_filter_strength = 100; - else if (fringe_filter_strength < 0 ) fringe_filter_strength = 0; - } - checked_fringe_filter_strength = 1; - } - - - if ( checked_grayscale_filter_strength == 0) - { - char *grayscale_filter_strength_env = getenv( "INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH" ); - if ( grayscale_filter_strength_env != NULL ) - { - sscanf ( grayscale_filter_strength_env, "%d", &grayscale_filter_strength ); - if (grayscale_filter_strength > 100 ) grayscale_filter_strength = 100; - else if (grayscale_filter_strength < 0 ) grayscale_filter_strength = 0; - } - checked_grayscale_filter_strength = 1; - } - - - if ( checked_autohint_horizontal_stem_darken_strength == 0) - { - char *autohint_horizontal_stem_darken_strength_env = getenv( "INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH" ); - if ( autohint_horizontal_stem_darken_strength_env != NULL ) - { - sscanf ( autohint_horizontal_stem_darken_strength_env, "%d", &autohint_horizontal_stem_darken_strength ); - if (autohint_horizontal_stem_darken_strength > 100 ) autohint_horizontal_stem_darken_strength = 100; - else if (autohint_horizontal_stem_darken_strength < 0 ) autohint_horizontal_stem_darken_strength = 0; - } - checked_autohint_horizontal_stem_darken_strength = 1; - } - - if ( checked_autohint_vertical_stem_darken_strength == 0) - { - char *autohint_vertical_stem_darken_strength_env = getenv( "INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH" ); - if ( autohint_vertical_stem_darken_strength_env != NULL ) - { - sscanf ( autohint_vertical_stem_darken_strength_env, "%d", &autohint_vertical_stem_darken_strength ); - if (autohint_vertical_stem_darken_strength > 100 ) autohint_vertical_stem_darken_strength = 100; - else if (autohint_horizontal_stem_darken_strength < 0 ) autohint_vertical_stem_darken_strength = 0; - } - checked_autohint_vertical_stem_darken_strength = 1; - } - - if ( checked_global_embolden_x_value == 0) - { - char *global_embolden_x_env = getenv ( "INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE" ); - if ( global_embolden_x_env != NULL ) - { - sscanf ( global_embolden_x_env, "%d", &global_embolden_x_value ); - if (global_embolden_x_value > 128 ) global_embolden_x_value = 128; - else if (global_embolden_x_value < -128 ) global_embolden_x_value = -128; - } - checked_global_embolden_x_value = 1; - } - - if ( checked_global_embolden_y_value == 0) - { - char *global_embolden_y_env = getenv ( "INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE" ); - if ( global_embolden_y_env != NULL ) - { - sscanf ( global_embolden_y_env, "%d", &global_embolden_y_value ); - if (global_embolden_y_value > 128 ) global_embolden_y_value = 128; - else if (global_embolden_y_value < -128 ) global_embolden_y_value = -128; - } - checked_global_embolden_y_value = 1; - } - - - if ( checked_bold_embolden_x_value == 0) - { - char *bold_embolden_x_env = getenv ( "INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE" ); - if ( bold_embolden_x_env != NULL ) - { - sscanf ( bold_embolden_x_env, "%d", &bold_embolden_x_value ); - if (bold_embolden_x_value > 128 ) bold_embolden_x_value = 128; - else if (bold_embolden_x_value < -128 ) bold_embolden_x_value = -128; - - } - checked_bold_embolden_x_value = 1; - } - - if ( checked_bold_embolden_y_value == 0) - { - char *bold_embolden_y_env = getenv ( "INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE" ); - if ( bold_embolden_y_env != NULL ) - { - sscanf ( bold_embolden_y_env, "%d", &bold_embolden_y_value ); - if (bold_embolden_y_value > 128 ) bold_embolden_y_value = 128; - else if (bold_embolden_y_value < -128 ) bold_embolden_y_value = -128; - - } - checked_bold_embolden_y_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 ) @@ -3283,174 +129,92 @@ if ( mode != required_mode ) return Smooth_Err_Cannot_Render_Glyph; -#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); + outline = &slot->outline; - FT_Outline_Copy(outline_orig, outline); + /* translate the outline to the new origin if needed */ + if ( origin ) + FT_Outline_Translate( outline, origin->x, origin->y ); - if (scale_value != 1.0) - FT_Outline_Transform( outline, &scaleMat ); + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); - FT_Outline_Translate( outline, translate_value+0, 0 ); + 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 ); - FT_Outline_EmboldenXY( outline, embolden_value, 0 ); - } - else + if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) { -#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 (!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); + FT_ERROR(( "ft_smooth_render_generic: glyph too large:" + " xMin = %d, xMax = %d\n", + cbox.xMin >> 6, cbox.xMax >> 6 )); + return Smooth_Err_Raster_Overflow; } + else + width = ( cbox.xMax - cbox.xMin ) >> 6; - /* translate the outline to the new origin if needed */ - if (align_called == 0) + if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) { - 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 ); + FT_ERROR(( "ft_smooth_render_generic: glyph too large:" + " yMin = %d, yMax = %d\n", + cbox.yMin >> 6, cbox.yMax >> 6 )); + return Smooth_Err_Raster_Overflow; + } + else + height = ( cbox.yMax - cbox.yMin ) >> 6; - /* compute the control box, and grid fit it */ - /*FT_Outline_Get_CBox( outline, &cbox );*/ + bitmap = &slot->bitmap; + memory = render->root.memory; - 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 ) - FT_Outline_Translate( outline, origin->x, origin->y ); +#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + width_org = width; + height_org = height; +#endif - /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); + /* release old bitmap buffer */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } - 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 + /* allocate new one */ + pitch = width; + if ( hmul ) + { + width = width * 3; + pitch = FT_PAD_CEIL( width, 4 ); + } - if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large:" - " xMin = %d, xMax = %d\n", - cbox.xMin >> 6, cbox.xMax >> 6 )); - return Smooth_Err_Raster_Overflow; - } - else - width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + if ( vmul ) + height *= 3; - if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large:" - " yMin = %d, yMax = %d\n", - cbox.yMin >> 6, cbox.yMax >> 6 )); - return Smooth_Err_Raster_Overflow; - } - else - height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + x_shift = (FT_Int) cbox.xMin; + y_shift = (FT_Int) cbox.yMin; + x_left = (FT_Int)( cbox.xMin >> 6 ); + y_top = (FT_Int)( cbox.yMax >> 6 ); - bitmap = &slot->bitmap; - memory = render->root.memory; +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING -#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - width_org = width; - height_org = height; -#endif + if ( slot->library->lcd_filter_func ) + { + FT_Int extra = slot->library->lcd_extra; - /* 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 = width * 3; - pitch = FT_PAD_CEIL( width, 4 ); + x_shift -= 64 * ( extra >> 1 ); + width += 3 * extra; + pitch = FT_PAD_CEIL( width, 4 ); + x_left -= extra >> 1; } if ( vmul ) - height *= 3; - - x_shift = (FT_Int) cbox.xMin; - y_shift = (FT_Int) cbox.yMin; - x_left = (FT_Int)( cbox.xMin >> 6 ); - y_top = (FT_Int)( cbox.yMax >> 6 ); - -#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - - if ( slot->library->lcd_filter_func ) { - FT_Int extra = slot->library->lcd_extra; - - - if ( hmul ) - { - 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 ); - height += 3 * extra; - y_top += extra >> 1; - } + y_shift -= 64 * ( extra >> 1 ); + height += 3 * extra; + y_top += extra >> 1; } -#endif -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET } #endif @@ -3475,9 +239,6 @@ RERENDER: 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 ); if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) @@ -3527,107 +288,9 @@ RERENDER: vec->y /= 3; } -#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - if ( ppem <= MAX_PPEM && ppem >= MIN_PPEM ) - { - if ( align_called == 0 && (alignment_strength > 0 || fitting_strength > 0)) - _lcd_stem_align ( bitmap, mode, slot, &translate_value, &scale_value, - alignment_strength, fitting_strength, &embolden_value ); - - if ((translate_value != 0 || scale_value != 1.0) && align_called == 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 */ - if ( !_ft_bitmap_bc ( bitmap, (float)get_brightness(slot->face->family_name, ppem) / 300.0, - (float)get_contrast(slot->face->family_name, ppem) / 300.0)) - { - 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 and 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 */ diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c index a6e4ba7..4bd1209 100644 --- a/src/truetype/truetype.c +++ b/src/truetype/truetype.c @@ -27,7 +27,6 @@ #ifdef TT_USE_BYTECODE_INTERPRETER #include "ttinterp.c" -#include "ttsubpix.c" #endif #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 5b7cbe9..22cbc09 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -32,7 +32,6 @@ #endif #include "tterrors.h" -#include "ttsubpix.h" /*************************************************************************/ @@ -150,15 +149,6 @@ loader->top_bearing = top_bearing; loader->vadvance = advance_height; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( loader->exec ) - loader->exec->sph_tweak_flags = 0; - - /* this may not be the right place for this, but it works */ - if ( loader->exec && loader->exec->ignore_x_mode ) - sph_set_tweaks( loader, glyph_index ); -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - if ( !loader->linear_def ) { loader->linear_def = 1; @@ -823,13 +813,6 @@ loader->pp4 = zone->cur[zone->n_points - 1]; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) - FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 ); - - else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) - FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); -#endif return TT_Err_Ok; } @@ -852,13 +835,6 @@ FT_Outline* outline; FT_Int n_points; - TT_Face face = (TT_Face)loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_String* family = face->root.family_name; - int ppem = loader->size->metrics.x_ppem; - FT_String* style = face->root.style_name; - float x_scale_factor = 1.0; -#endif outline = &gloader->current.outline; n_points = outline->n_points; @@ -913,26 +889,6 @@ loader->zone.n_points + 4 ); } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* scale, but only if enabled and only if TT hinting is being used */ - if ( IS_HINTED( loader->load_flags ) ) - x_scale_factor = scale_test_tweak( face, family, ppem, style, - loader->glyph_index, X_SCALING_Rules, - X_SCALING_RULES_SIZE ); - /* scale the glyph */ - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || - x_scale_factor != 1.0 ) - { - FT_Vector* vec = outline->points; - FT_Vector* limit = outline->points + n_points; - FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale * x_scale_factor; - FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; - - /* compensate for any scaling by de/emboldening */ - if ( x_scale_factor != 1.0 && ppem > 11 ) - FT_Outline_EmboldenXY( outline, - (FT_Int) ( 16.0 * (float)ppem * ( 1.0 - x_scale_factor) ), 0 ); -#else /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { @@ -940,7 +896,7 @@ FT_Vector* limit = outline->points + n_points; FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; -#endif + for ( ; vec < limit; vec++ ) { @@ -1692,26 +1648,12 @@ { FT_Byte* widthp; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Bool ignore_x_mode; - - - ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) != - FT_RENDER_MODE_MONO ); -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ widthp = tt_face_get_device_metrics( face, size->root.metrics.x_ppem, glyph_index ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( widthp && - ( ( ignore_x_mode && loader->exec->compatible_widths ) || - !ignore_x_mode || - SPH_OPTION_BITMAP_WIDTHS ) ) -#else if ( widthp ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ glyph->metrics.horiAdvance = *widthp << 6; } @@ -1906,15 +1848,6 @@ { TT_ExecContext exec; FT_Bool grayscale; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Bool subpixel_hinting; - FT_Bool grayscale_hinting; -#if 0 - FT_Bool compatible_widths; - FT_Bool symmetrical_smoothing; - FT_Bool bgr; -#endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ if ( !size->cvt_ready ) @@ -1932,88 +1865,11 @@ if ( !exec ) return TT_Err_Could_Not_Find_Context; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) - != FT_RENDER_MODE_MONO ) && - SPH_OPTION_SET_SUBPIXEL ); - - if ( subpixel_hinting ) - grayscale = grayscale_hinting = FALSE; - - else if ( SPH_OPTION_SET_GRAYSCALE ) - { - grayscale = grayscale_hinting = TRUE; - subpixel_hinting = FALSE; - } - - if ( FT_IS_TRICKY( glyph->face ) ) - { - subpixel_hinting = grayscale_hinting = FALSE; - } - - exec->ignore_x_mode = subpixel_hinting || grayscale_hinting; - exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) - exec->rasterizer_version = 35; - -#if 1 - exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; - exec->symmetrical_smoothing = FALSE; - exec->bgr = FALSE; -#else /* 0 */ - exec->compatible_widths = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_COMPATIBLE_WIDTHS ); - exec->symmetrical_smoothing = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_SYMMETRICAL_SMOOTHING ); - exec->bgr = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_BGR ); -#endif /* 0 */ - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - TT_Load_Context( exec, face, size ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - /* a change from mono to subpixel rendering (and vice versa) */ - /* requires a re-execution of the CVT program */ - if ( subpixel_hinting != exec->subpixel_hinting ) - { - FT_UInt i; - - - exec->subpixel_hinting = subpixel_hinting; - - for ( i = 0; i < size->cvt_size; i++ ) - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - tt_size_run_prep( size, pedantic ); - } - - /* a change from mono to grayscale rendering (and vice versa) */ - /* requires a re-execution of the CVT program */ - if ( grayscale != exec->grayscale_hinting ) - { - FT_UInt i; - - - exec->grayscale_hinting = grayscale_hinting; - - for ( i = 0; i < size->cvt_size; i++ ) - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - tt_size_run_prep( size, pedantic ); - } - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* a change from mono to grayscale rendering (and vice versa) */ /* requires a re-execution of the CVT program */ if ( grayscale != exec->grayscale ) @@ -2031,8 +1887,6 @@ tt_size_run_prep( size, pedantic ); } -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* see whether the cvt program has disabled hinting */ if ( exec->GS.instruct_control & 1 ) load_flags |= FT_LOAD_NO_HINTING; diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index b1bc6c0..3a8680f 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -27,16 +27,13 @@ #include FT_SYSTEM_H #include "ttinterp.h" + #include "tterrors.h" -#include "ttsubpix.h" #ifdef TT_USE_BYTECODE_INTERPRETER -#define xxxSPH_DEBUG -#define xxxSPH_DEBUG_MORE_VERBOSE - #define TT_MULFIX FT_MulFix #define TT_MULDIV FT_MulDiv #define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round @@ -156,11 +153,11 @@ #define NORMalize( x, y, v ) \ Normalize( EXEC_ARG_ x, y, v ) -#define SET_SuperRound( scale, flags, res ) \ - SetSuperRound( EXEC_ARG_ scale, flags, res ) +#define SET_SuperRound( scale, flags ) \ + SetSuperRound( EXEC_ARG_ scale, flags ) -#define ROUND_None( d, c, e ) \ - Round_None( EXEC_ARG_ d, c, e ) +#define ROUND_None( d, c ) \ + Round_None( EXEC_ARG_ d, c ) #define INS_Goto_CodeRange( range, ip ) \ Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) @@ -171,8 +168,8 @@ #define CUR_Func_move_orig( z, p, d ) \ CUR.func_move_orig( EXEC_ARG_ z, p, d ) -#define CUR_Func_round( d, c, e ) \ - CUR.func_round( EXEC_ARG_ d, c, e ) +#define CUR_Func_round( d, c ) \ + CUR.func_round( EXEC_ARG_ d, c ) #define CUR_Func_read_cvt( index ) \ CUR.func_read_cvt( EXEC_ARG_ index ) @@ -1853,10 +1850,6 @@ if ( v != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ zone->cur[point].x += TT_MULDIV( distance, v * 0x10000L, CUR.F_dot_P ); @@ -1939,10 +1932,6 @@ { FT_UNUSED_EXEC; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVEX ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ zone->cur[point].x += distance; zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -2005,8 +1994,6 @@ /* */ /* compensation :: The engine compensation. */ /* */ - /* resolution :: The number of grid lines per pixel. */ - /* */ /* <Return> */ /* The compensated distance. */ /* */ @@ -2018,13 +2005,11 @@ /* */ static FT_F26Dot6 Round_None( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ) + FT_F26Dot6 compensation ) { FT_F26Dot6 val; FT_UNUSED_EXEC; - FT_UNUSED( resolution ); if ( distance >= 0 ) @@ -2039,7 +2024,6 @@ if ( val > 0 ) val = 0; } - return val; } @@ -2057,15 +2041,12 @@ /* */ /* compensation :: The engine compensation. */ /* */ - /* resolution :: The number of grid lines per pixel. */ - /* */ /* <Return> */ /* Rounded distance. */ /* */ static FT_F26Dot6 Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ) + FT_F26Dot6 compensation ) { FT_F26Dot6 val; @@ -2074,15 +2055,15 @@ if ( distance >= 0 ) { - val = distance + compensation + 32 / resolution; + val = distance + compensation + 32; if ( distance && val > 0 ) - val &= ~( 64 / resolution - 1 ); + val &= ~63; else val = 0; } else { - val = -FT_PIX_ROUND_GRID( compensation - distance, resolution ); + val = -FT_PIX_ROUND( compensation - distance ); if ( val > 0 ) val = 0; } @@ -2104,15 +2085,12 @@ /* */ /* compensation :: The engine compensation. */ /* */ - /* resolution :: The number of grid lines per pixel. */ - /* */ /* <Return> */ /* Rounded distance. */ /* */ static FT_F26Dot6 Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ) + FT_F26Dot6 compensation ) { FT_F26Dot6 val; @@ -2121,15 +2099,13 @@ if ( distance >= 0 ) { - val = FT_PIX_FLOOR_GRID( distance + compensation, resolution ) + - 32 / resolution; + val = FT_PIX_FLOOR( distance + compensation ) + 32; if ( distance && val < 0 ) val = 0; } else { - val = -( FT_PIX_FLOOR_GRID( compensation - distance, resolution ) + - 32 / resolution ); + val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); if ( val > 0 ) val = 0; } @@ -2151,15 +2127,12 @@ /* */ /* compensation :: The engine compensation. */ /* */ - /* resolution :: The number of grid lines per pixel. */ - /* */ /* <Return> */ /* Rounded distance. */ /* */ static FT_F26Dot6 Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ) + FT_F26Dot6 compensation ) { FT_F26Dot6 val; @@ -2170,13 +2143,13 @@ { val = distance + compensation; if ( distance && val > 0 ) - val &= ~( 64 / resolution - 1 ); + val &= ~63; else val = 0; } else { - val = -( ( compensation - distance ) & -( 64 / resolution ) ); + val = -( ( compensation - distance ) & -64 ); if ( val > 0 ) val = 0; } @@ -2198,15 +2171,12 @@ /* */ /* compensation :: The engine compensation. */ /* */ - /* resolution :: The number of grid lines per pixel. */ - /* */ /* <Return> */ /* Rounded distance. */ /* */ static FT_F26Dot6 Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ) + FT_F26Dot6 compensation ) { FT_F26Dot6 val; @@ -2215,15 +2185,15 @@ if ( distance >= 0 ) { - val = distance + compensation + ( 64 / resolution - 1 ); + val = distance + compensation + 63; if ( distance && val > 0 ) - val &= ~( 64 / resolution - 1 ); + val &= ~63; else val = 0; } else { - val = -FT_PIX_CEIL_GRID( compensation - distance, resolution ); + val = - FT_PIX_CEIL( compensation - distance ); if ( val > 0 ) val = 0; } @@ -2245,15 +2215,12 @@ /* */ /* compensation :: The engine compensation. */ /* */ - /* resolution :: The number of grid lines per pixel. */ - /* */ /* <Return> */ /* Rounded distance. */ /* */ static FT_F26Dot6 Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ) + FT_F26Dot6 compensation ) { FT_F26Dot6 val; @@ -2262,15 +2229,15 @@ if ( distance >= 0 ) { - val = distance + compensation + 16 / resolution; + val = distance + compensation + 16; if ( distance && val > 0 ) - val &= ~( 32 / resolution - 1 ); + val &= ~31; else val = 0; } else { - val = -FT_PAD_ROUND( compensation - distance, 32 / resolution ); + val = -FT_PAD_ROUND( compensation - distance, 32 ); if ( val > 0 ) val = 0; } @@ -2292,8 +2259,6 @@ /* */ /* compensation :: The engine compensation. */ /* */ - /* resolution :: The number of grid lines per pixel. */ - /* */ /* <Return> */ /* Rounded distance. */ /* */ @@ -2305,13 +2270,10 @@ /* */ static FT_F26Dot6 Round_Super( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ) + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED( resolution ); - if ( distance >= 0 ) { @@ -2347,8 +2309,6 @@ /* */ /* compensation :: The engine compensation. */ /* */ - /* resolution :: The number of grid lines per pixel. */ - /* */ /* <Return> */ /* Rounded distance. */ /* */ @@ -2358,13 +2318,10 @@ /* */ static FT_F26Dot6 Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ) + FT_F26Dot6 compensation ) { FT_F26Dot6 val; - FT_UNUSED( resolution ); - if ( distance >= 0 ) { @@ -2447,19 +2404,13 @@ /* Sets Super Round parameters. */ /* */ /* <Input> */ - /* GridPeriod :: The grid period. */ - /* */ - /* selector :: The SROUND opcode. */ - /* */ - /* resolution :: The number of grid lines per pixel. */ + /* GridPeriod :: Grid period */ + /* selector :: SROUND opcode */ /* */ static void SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, - FT_Long selector, - FT_Int resolution ) + FT_Long selector ) { - FT_UNUSED( resolution ); - switch ( (FT_Int)( selector & 0xC0 ) ) { case 0: @@ -3129,13 +3080,13 @@ #define DO_SROUND \ - SET_SuperRound( 0x4000, args[0], 1 ); \ + SET_SuperRound( 0x4000, args[0] ); \ CUR.GS.round_state = TT_Round_Super; \ CUR.func_round = (TT_Round_Func)Round_Super; #define DO_S45ROUND \ - SET_SuperRound( 0x2D41, args[0], 1 ); \ + SET_SuperRound( 0x2D41, args[0] ); \ CUR.GS.round_state = TT_Round_Super_45; \ CUR.func_round = (TT_Round_Func)Round_Super_45; @@ -3306,12 +3257,12 @@ args[0] = ( args[0] != args[1] ); -#define DO_ODD \ - args[0] = ( ( CUR_Func_round( args[0], 0, 1 ) & 127 ) == 64 ); +#define DO_ODD \ + args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); -#define DO_EVEN \ - args[0] = ( ( CUR_Func_round( args[0], 0, 1 ) & 127 ) == 0 ); +#define DO_EVEN \ + args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); #define DO_AND \ @@ -3360,34 +3311,6 @@ #define DO_CEILING \ args[0] = FT_PIX_CEIL( args[0] ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - -#define DO_RS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDSL( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - ARRAY_BOUND_ERROR; \ - else \ - args[0] = 0; \ - } \ - else \ - { \ - /* subpixel hinting - avoid Typeman Dstroke and */ \ - /* IStroke and Vacuform rounds */ \ - \ - if ( CUR.compatibility_mode && \ - ( I == 24 || I == 22 || I == 8 ) ) \ - args[0] = 0; \ - else \ - args[0] = CUR.storage[I]; \ - } \ - } - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ #define DO_RS \ { \ @@ -3407,8 +3330,6 @@ args[0] = CUR.storage[I]; \ } -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - #define DO_WS \ { \ @@ -3484,17 +3405,15 @@ CUR.error = TT_Err_Debug_OpCode; -#define DO_ROUND \ - args[0] = CUR_Func_round( \ - args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x68], \ - 1 ); +#define DO_ROUND \ + args[0] = CUR_Func_round( \ + args[0], \ + CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); -#define DO_NROUND \ - args[0] = ROUND_None( args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x6C], \ - 1 ); +#define DO_NROUND \ + args[0] = ROUND_None( args[0], \ + CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); #define DO_MAX \ @@ -4668,24 +4587,6 @@ TT_DefRecord* rec; TT_DefRecord* limit; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -#if 0 - int opcode_pattern[4][12] = { - /* VacuFormRound function */ - {0x45,0x23,0x46,0x60,0x20}, - /* inline delta function 1 */ - {0x4B,0x53,0x23,0x4B,0x51,0x5A,0x58,0x38,0x1B,0x21,0x21,0x59}, - /* inline delta function 2 */ - {0x4B,0x54,0x58,0x38,0x1B,0x5A,0x21,0x21,0x59}, - /* diagonal stroke function */ - {0x20,0x20,0x40,0x60,0x47,0x40,0x23,0x42}, - }; - int opcode_patterns = 4; - int i; - int opcode_pointer[4] = {0,0,0,0}; -#endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* some font programs are broken enough to redefine functions! */ /* We will then parse the current table. */ @@ -4719,11 +4620,10 @@ return; } - rec->range = CUR.curRange; - rec->opc = (FT_UInt16)n; - rec->start = CUR.IP + 1; - rec->active = TRUE; - rec->inline_delta = FALSE; + rec->range = CUR.curRange; + rec->opc = (FT_UInt16)n; + rec->start = CUR.IP + 1; + rec->active = TRUE; if ( n > CUR.maxFunc ) CUR.maxFunc = (FT_UInt16)n; @@ -4733,78 +4633,6 @@ while ( SKIP_Code() == SUCCESS ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -#if 0 -#ifdef SPH_DEBUG_MORE_VERBOSE - printf ("Opcode: %d ", CUR.opcode); -#endif - - for ( i = 0; i < opcode_patterns; i++ ) - { - if ( CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) - { -#ifdef SPH_DEBUG_MORE_VERBOSE - printf( "function %d, opcode ptrn: %d" - " op# %d: %d FOUND \n", - n, i, opcode_pointer[i], CUR.opcode ); -#endif - opcode_pointer[i] += 1; - - if ( i == 0 && opcode_pointer[0] == 5 ) - { - - CUR.inline_delta_funcs[CUR.num_delta_funcs] = n; - CUR.num_delta_funcs++; -#ifdef SPH_DEBUG - printf( "Vacuform Round FUNCTION %d detected\n", n); -#endif - /*rec->active = FALSE;*/ - opcode_pointer[i] = 0; - } - - if ( i == 1 && opcode_pointer[1] == 12 ) - { - CUR.inline_delta_funcs[CUR.num_delta_funcs] = n; - CUR.num_delta_funcs++; -#ifdef SPH_DEBUG - printf( "inline delta FUNCTION1 %d detected\n", - n, CUR.num_delta_funcs); -#endif - rec->inline_delta = TRUE; - opcode_pointer[i] = 0; - } - - if ( i == 2 && opcode_pointer[1] == 9 ) - { - CUR.inline_delta_funcs[CUR.num_delta_funcs] = n; - CUR.num_delta_funcs++; - rec->inline_delta = TRUE; -#ifdef SPH_DEBUG - printf( "inline delta2 FUNCTION2 %d detected\n", - n, CUR.num_delta_funcs); -#endif - opcode_pointer[i] = 0; - } - - if ( i == 4 && opcode_pointer[1] == 8 ) - { - CUR.inline_delta_funcs[CUR.num_delta_funcs] = n; - CUR.num_delta_funcs++; - /*rec->active = FALSE;*/ -#ifdef SPH_DEBUG - printf( "diagonal stroke function %d detected\n", - n, CUR.num_delta_funcs); -#endif - opcode_pointer[i] = 0; - } - } - - else - opcode_pointer[i] = 0; - } -#endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - switch ( CUR.opcode ) { case 0x89: /* IDEF */ @@ -4848,15 +4676,6 @@ CUR.step_ins = FALSE; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* - * CUR.ignore_x_mode may be turned off prior to function calls. This - * ensures it is turned back on. - */ - CUR.ignore_x_mode = ( CUR.subpixel_hinting || CUR.grayscale_hinting ) - && !( CUR.sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING ); -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - if ( pRec->Cur_Count > 0 ) { CUR.callTop++; @@ -4890,10 +4709,6 @@ TT_CallRec* pCrec; TT_DefRecord* def; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Bool oldF; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* first of all, check the index */ @@ -4931,20 +4746,6 @@ if ( !def->active ) goto Fail; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* This is test code used to detect inline delta functions */ - oldF = def->inline_delta; - if ( CUR.ignore_x_mode ) - { - if ( def->inline_delta ) - CUR.in_delta_function = TRUE; - } - -#ifdef SPH_DEBUG - printf("Entering function %d\n", F); -#endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* check the call stack */ if ( CUR.callTop >= CUR.callSize ) { @@ -4966,13 +4767,6 @@ def->start ); CUR.step_ins = FALSE; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - CUR.in_delta_function = oldF; - -#ifdef SPH_DEBUG - printf("Leaving function %d\n", F); -#endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ return; Fail: @@ -4993,10 +4787,6 @@ TT_CallRec* pCrec; TT_DefRecord* def; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Bool oldF; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* first of all, check the index */ F = args[1]; @@ -5033,15 +4823,6 @@ if ( !def->active ) goto Fail; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - oldF = def->inline_delta; - if ( CUR.ignore_x_mode ) - { - if ( def->inline_delta ) - CUR.in_delta_function = TRUE; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* check stack */ if ( CUR.callTop >= CUR.callSize ) { @@ -5065,11 +4846,6 @@ CUR.step_ins = FALSE; } - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - CUR.in_delta_function = oldF; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - return; Fail: @@ -5419,12 +5195,6 @@ } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( CUR.ignore_x_mode && FT_ABS( D ) == 64 ) - D += 1; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - args[0] = D; } @@ -5921,12 +5691,7 @@ if ( CUR.GS.freeVector.x != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !CUR.ignore_x_mode || - ( CUR.ignore_x_mode && - ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_MOVE_ZP2 ) ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - CUR.zp2.cur[point].x += dx; + CUR.zp2.cur[point].x += dx; if ( touch ) CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -6107,9 +5872,6 @@ { FT_F26Dot6 dx, dy; FT_UShort point; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Int B1, B2; -#endif if ( CUR.top < CUR.GS.loop + 1 ) @@ -6155,77 +5917,7 @@ } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - { - /* If not using ignore_x_mode rendering, allow ZP2 move. */ - /* If inline deltas aren't allowed, skip ZP2 move. */ - /* If using ignore_x_mode rendering, allow ZP2 point move if: */ - /* - freedom vector is y and compatibility_mode is off */ - /* - the glyph is composite and the move is in the Y direction */ - /* - the glyph is specifically set to allow SHPIX moves */ - /* - the move is on a previously Y-touched point */ - - if ( CUR.ignore_x_mode ) - { - /* save point for later comparison */ - if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp2.cur[point].y; - else - B1 = CUR.zp2.cur[point].x; - - if ( CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_INLINE_DELTAS ) ) - goto Skip; - - if ( CUR.ignore_x_mode && - !CUR.compatibility_mode && CUR.GS.freeVector.y != 0 ) - MOVE_Zp2_Point( point, dx, dy, TRUE ); - - else if ( CUR.ignore_x_mode && CUR.compatibility_mode ) - { - if ( CUR.ignore_x_mode && - ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) - { - dx = FT_PIX_ROUND ( B1 + dx ) - B1; - dy = FT_PIX_ROUND ( B1 + dy ) - B1; - } - - if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && - ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || - ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || - ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) - ) - MOVE_Zp2_Point( point, dx, dy, TRUE ); - } - - /* save new point */ - if ( CUR.GS.freeVector.y != 0 ) - B2 = CUR.zp2.cur[point].y; - else B2 = CUR.zp2.cur[point].x; - - /* reverse any disallowed moves */ - if ( ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - CUR.GS.freeVector.y != 0 && - B1 % 64 != 0 && - B2 % 64 != 0 && B1 != B2 ) || - ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) && - CUR.GS.freeVector.y != 0 && - B1 % 64 == 0 && - B2 % 64 != 0 && B1 != B2 ) ) - { -#ifdef SPH_DEBUG - printf( "Reversing ZP2 move\n" ); -#endif - MOVE_Zp2_Point( point, -dx, -dy, TRUE ); - } - } - else - MOVE_Zp2_Point( point, dx, dy, TRUE ); - } - Skip: -#else MOVE_Zp2_Point( point, dx, dy, TRUE ); -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ CUR.GS.loop--; } @@ -6247,18 +5939,7 @@ { FT_UShort point; FT_F26Dot6 distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Int gridlines_per_pixel = 1; - - if ( CUR.ignore_x_mode ) - { - if ( CUR.GS.freeVector.x != 0 ) - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; - else if ( CUR.GS.freeVector.y != 0 ) - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ point = (FT_UShort)args[0]; @@ -6282,15 +5963,6 @@ distance = CUR_Func_project( CUR.zp1.cur + point, CUR.zp0.cur + CUR.GS.rp0 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.x != 0 && - FT_ABS( distance - args[1] ) >= - CUR.GS.control_value_cutin / gridlines_per_pixel ) - distance = args[1]; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - CUR_Func_move( &CUR.zp1, point, args[1] - distance ); CUR.GS.rp1 = CUR.GS.rp0; @@ -6313,21 +5985,7 @@ FT_UShort point; FT_F26Dot6 cur_dist, distance; - FT_Int gridlines_per_pixel = 1; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode ) - { - if ( CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; - - else if ( CUR.GS.freeVector.y != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ point = (FT_UShort)args[0]; @@ -6342,8 +6000,7 @@ { cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); distance = CUR_Func_round( cur_dist, - CUR.tt_metrics.compensations[0], - gridlines_per_pixel ) - cur_dist; + CUR.tt_metrics.compensations[0] ) - cur_dist; } else distance = 0; @@ -6368,22 +6025,8 @@ FT_UShort point; FT_F26Dot6 distance, org_dist; - FT_Int gridlines_per_pixel = 1; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode ) - { - if ( CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; - - else if ( CUR.GS.freeVector.y != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - cvtEntry = (FT_ULong)args[1]; point = (FT_UShort)args[0]; @@ -6419,34 +6062,21 @@ if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* only adjust legacy fonts x otherwise breaks Calibri italic */ - if ( CUR.compatibility_mode ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.x ); CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.y ), CUR.zp0.cur[point] = CUR.zp0.org[point]; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( distance > 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && - CUR.GS.freeVector.y != 0 ) - distance = 0 ; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ { - if ( FT_ABS( distance - org_dist ) > - CUR.GS.control_value_cutin / gridlines_per_pixel ) + if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) distance = org_dist; - distance = CUR_Func_round( distance, - CUR.tt_metrics.compensations[0], - gridlines_per_pixel ); + distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); } CUR_Func_move( &CUR.zp0, point, distance - org_dist ); @@ -6468,24 +6098,6 @@ { FT_UShort point; FT_F26Dot6 org_dist, distance; - FT_Int minimum_distance_factor = 64; - FT_Int gridlines_per_pixel = 1; - - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode ) - { - if ( CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - { - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; - minimum_distance_factor = 64 - gridlines_per_pixel / 3; - } - else if ( CUR.GS.freeVector.y != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ point = (FT_UShort)args[0]; @@ -6551,13 +6163,11 @@ if ( ( CUR.opcode & 4 ) != 0 ) distance = CUR_Func_round( org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3], - gridlines_per_pixel ); + CUR.tt_metrics.compensations[CUR.opcode & 3] ); else distance = ROUND_None( org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3], - gridlines_per_pixel ); + CUR.tt_metrics.compensations[CUR.opcode & 3] ); /* minimum distance flag */ @@ -6565,17 +6175,13 @@ { if ( org_dist >= 0 ) { - if ( distance < FT_MulDiv( minimum_distance_factor, - CUR.GS.minimum_distance, 64 ) ) - distance = FT_MulDiv( minimum_distance_factor, - CUR.GS.minimum_distance, 64 ); + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; } else { - if ( distance > -FT_MulDiv( minimum_distance_factor, - CUR.GS.minimum_distance, 64 ) ) - distance = -FT_MulDiv( minimum_distance_factor, - CUR.GS.minimum_distance, 64 ); + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; } } @@ -6612,37 +6218,10 @@ cur_dist, org_dist; - FT_Int minimum_distance_factor = 64; - FT_Int gridlines_per_pixel = 1; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_Int B1; - FT_Int B2; - FT_Bool reverse_move = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ point = (FT_UShort)args[0]; cvtEntry = (FT_ULong)( args[1] + 1 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode ) - { - if ( CUR.GS.freeVector.x != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - { - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; - /* high value emboldens glyphs at lower ppems (< 14); */ - /* Courier looks better with 52 -- */ - /* MS ClearType Rasterizer supposedly uses 32 */ - minimum_distance_factor = 64 - gridlines_per_pixel / 3; - } - - else if ( CUR.GS.freeVector.y != 0 && - !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ if ( BOUNDS( point, CUR.zp1.n_points ) || @@ -6658,10 +6237,6 @@ cvt_dist = 0; else cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.sph_tweak_flags & SPH_TWEAK_MIRP_CVT_ZERO ) - cvt_dist = 0; -#endif /* single width test */ @@ -6699,15 +6274,8 @@ if ( ( org_dist ^ cvt_dist ) < 0 ) cvt_dist = -cvt_dist; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) - { - if ( cur_dist < -64 ) cvt_dist -= 16; - else if ( cur_dist > 64 && cur_dist < 84) cvt_dist += 32; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* control value cut-in and round */ + + /* control value cutin and round */ if ( ( CUR.opcode & 4 ) != 0 ) { @@ -6728,21 +6296,18 @@ /* `ttinst2.doc', version 1.66, is thus incorrect since */ /* it implies `>=' instead of `>'. */ - if ( FT_ABS( cvt_dist - org_dist ) > - CUR.GS.control_value_cutin / gridlines_per_pixel ) + if ( FT_ABS( cvt_dist - org_dist ) > CUR.GS.control_value_cutin ) cvt_dist = org_dist; } distance = CUR_Func_round( cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3], - gridlines_per_pixel ); + CUR.tt_metrics.compensations[CUR.opcode & 3] ); } else distance = ROUND_None( cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3], - gridlines_per_pixel ); + CUR.tt_metrics.compensations[CUR.opcode & 3] ); /* minimum distance test */ @@ -6750,63 +6315,18 @@ { if ( org_dist >= 0 ) { - if ( distance < FT_MulDiv( minimum_distance_factor, - CUR.GS.minimum_distance, 64 ) ) - distance = FT_MulDiv( minimum_distance_factor, - CUR.GS.minimum_distance, 64 ); + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; } else { - if ( distance > -FT_MulDiv( minimum_distance_factor, - CUR.GS.minimum_distance, 64 ) ) - distance = -FT_MulDiv( minimum_distance_factor, - CUR.GS.minimum_distance, 64 ); + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - B1 = CUR.zp1.cur[point].y; - - /* Round moves if necessary */ - if ( CUR.ignore_x_mode && - CUR.GS.freeVector.y != 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) - distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; - - if ( CUR.GS.freeVector.y != 0 && - ( CUR.opcode & 16 ) == 0 && - ( CUR.opcode & 8 ) == 0 && - ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) - distance +=64; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - B2 = CUR.zp1.cur[point].y; - - /* Reverse move if necessary */ - if ( CUR.ignore_x_mode ) - { - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) && - CUR.GS.freeVector.y != 0 && B1 % 64 == 0 && B2 % 64 != 0 ) - reverse_move = TRUE; - - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - CUR.GS.freeVector.y != 0 && B2 % 64 != 0 && B1 % 64 != 0 ) - reverse_move = TRUE; - - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_DELTAP_SKIP_EXAGGERATED_VALUES ) && - !reverse_move && - abs ( B1 - B2 ) >= 64 ) - reverse_move = TRUE; - } - - if ( reverse_move ) - CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) ); - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - Fail: CUR.GS.rp1 = CUR.GS.rp0; @@ -6830,14 +6350,8 @@ FT_F26Dot6 distance; FT_UNUSED_ARG; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode && CUR.iup_called && - ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) - { - CUR.error = TT_Err_Invalid_Reference; - goto Fail; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + if ( CUR.top < CUR.GS.loop || BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) { @@ -7332,15 +6846,6 @@ contour = 0; point = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode ) - { - CUR.iup_called = 1; - if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) - return; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - do { end_point = CUR.pts.contours[contour] - CUR.pts.first_point; @@ -7410,9 +6915,7 @@ FT_UShort A; FT_ULong C; FT_Long B; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_UShort B1, B2; -#endif + #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING /* Delta hinting is covered by US Patent 5159668. */ @@ -7485,67 +6988,7 @@ B++; B = B * 64 / ( 1L << CUR.GS.delta_shift ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* - * Allow delta move if - * - * - not using ignore_x_mode rendering - * - glyph is specifically set to allow it - * - glyph is composite and freedom vector is not subpixel vector - */ - if ( !CUR.ignore_x_mode || - ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || - ( CUR.is_composite && CUR.GS.freeVector.y != 0 )) - CUR_Func_move( &CUR.zp0, A, B ); - - /* Otherwise apply subpixel hinting and compatibility mode rules */ - else if ( CUR.ignore_x_mode ) - { - if ( CUR.GS.freeVector.y != 0 ) - B1 = CUR.zp0.cur[A].y; - else - B1 = CUR.zp0.cur[A].x; - - /* Standard Subpixel Hinting: Allow y move */ - if ( !CUR.compatibility_mode && CUR.GS.freeVector.y != 0 ) - CUR_Func_move( &CUR.zp0, A, B ); - - /* Compatibility Mode: Allow x or y move if point touched in - Y direction */ - else if ( CUR.compatibility_mode && - !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP )) - { - /* save the y value of the point now; compare after move */ - B1 = CUR.zp0.cur[A].y; - - if ( ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) - B = FT_PIX_ROUND( B1 + B ) - B1; - - /* - * Allow delta move if using compatibility_mode, IUP has not - * been called, and point is touched on Y. - */ - if ( !CUR.iup_called && - ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) - CUR_Func_move( &CUR.zp0, A, B ); - } - B2 = CUR.zp0.cur[A].y; - - /* Reverse this move if it results in a disallowed move */ - if ( CUR.GS.freeVector.y != 0 && - ( ( ( CUR.sph_tweak_flags & - SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) && - B1 % 64 == 0 && - B2 % 64 != 0 ) || - ( ( CUR.sph_tweak_flags & - SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - B1 % 64 != 0 && - B2 % 64 != 0 ))) - CUR_Func_move( &CUR.zp0, A, -B ); - } -#else CUR_Func_move( &CUR.zp0, A, B ); -#endif /* *TT_CONFIG_OPTION_SUBPIXEL_HINTING */ } } else @@ -7671,116 +7114,26 @@ Ins_GETINFO( INS_ARG ) { FT_Long K; + + K = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /********************************/ - /* RASTERIZER VERSION */ - /* Selector Bit: 0 */ - /* Return Bit(s): 0-7 */ - /* */ - if ( ( args[0] & 1 ) != 0 && CUR.ignore_x_mode ) - { - K = CUR.rasterizer_version; -#ifdef SPH_DEBUG_MORE_VERBOSE - printf(" SETTING AS %d\n", CUR.rasterizer_version ); -#endif - } - else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + /* We return MS rasterizer version 1.7 for the font scaler. */ if ( ( args[0] & 1 ) != 0 ) K = 35; - /********************************/ - /* GLYPH ROTATED */ - /* Selector Bit: 1 */ - /* Return Bit(s): 8 */ - /* */ + /* Has the glyph been rotated? */ if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) K |= 0x80; - /********************************/ - /* GLYPH STRETCHED */ - /* Selector Bit: 2 */ - /* Return Bit(s): 9 */ - /* */ + /* Has the glyph been stretched? */ if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) K |= 1 << 8; - /********************************/ - /* HINTING FOR GRAYSCALE */ - /* Selector Bit: 5 */ - /* Return Bit(s): 12 */ - /* */ + /* Are we hinting for grayscale? */ if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) K |= 1 << 12; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode && CUR.rasterizer_version >= 35 ) - { - /********************************/ - /* HINTING FOR GRAYSCALE */ - /* Selector Bit: 5 */ - /* Return Bit(s): 12 */ - /* */ - if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting ) - K |= 1 << 12; - - /********************************/ - /* HINTING FOR SUBPIXEL */ - /* Selector Bit: 6 */ - /* Return Bit(s): 13 */ - /* */ - if ( ( args[0] & 64 ) != 0 && - CUR.subpixel_hinting && - CUR.rasterizer_version >= 37 ) - { - K |= 1 << 13; - - /* the stuff below is irrelevant if subpixel_hinting is not set */ - - /********************************/ - /* COMPATIBLE WIDTHS ENABLED */ - /* Selector Bit: 7 */ - /* Return Bit(s): 14 */ - /* */ - /* Functionality still needs to be added */ - if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) - K |= 1 << 14; - - /********************************/ - /* SYMMETRICAL SMOOTHING */ - /* Selector Bit: 8 */ - /* Return Bit(s): 15 */ - /* */ - /* Functionality still needs to be added */ - if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing ) - K |= 1 << 15; - - /********************************/ - /* HINTING FOR BGR? */ - /* Selector Bit: 9 */ - /* Return Bit(s): 16 */ - /* */ - /* Functionality still needs to be added */ - if ( ( args[0] & 512 ) != 0 && CUR.bgr ) - K |= 1 << 16; - - if ( CUR.rasterizer_version >= 38 ) - { - - /********************************/ - /* SUBPIXEL POSITIONED? */ - /* Selector Bit: 10 */ - /* Return Bit(s): 17 */ - /* */ - /* Functionality still needs to be added */ - if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned ) - K |= 1 << 17; - } - } - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ args[0] = K; } @@ -8156,15 +7509,6 @@ cur = *exc; #endif -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode ) - { - /* ensure some variables are set for this run */ - CUR.iup_called = FALSE; - CUR.in_delta_function = FALSE; - } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - /* set CVT functions */ CUR.tt_metrics.ratio = 0; if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) @@ -8436,13 +7780,7 @@ break; case 0x2B: /* CALL */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !CUR.ignore_x_mode || - !CUR.iup_called || - ( CUR.iup_called && - !( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - Ins_CALL( EXEC_ARG_ args ); + Ins_CALL( EXEC_ARG_ args ); break; case 0x2C: /* FDEF */ @@ -8461,9 +7799,6 @@ case 0x30: /* IUP */ case 0x31: /* IUP */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( CUR.ignore_x_mode ) CUR.iup_called = TRUE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ Ins_IUP( EXEC_ARG_ args ); break; @@ -8623,12 +7958,6 @@ break; case 0x5D: /* DELTAP1 */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !CUR.ignore_x_mode || - !CUR.iup_called || - ( CUR.iup_called && - !( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ Ins_DELTAP( EXEC_ARG_ args ); break; diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h index 9ee2b48..6d0fc03 100644 --- a/src/truetype/ttinterp.h +++ b/src/truetype/ttinterp.h @@ -68,8 +68,7 @@ FT_BEGIN_HEADER /* Rounding function */ typedef FT_F26Dot6 (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation, - FT_Int resolution ); + FT_F26Dot6 compensation ); /* Point displacement along the freedom vector routine */ typedef void @@ -108,44 +107,6 @@ FT_BEGIN_HEADER } TT_CallRec, *TT_CallStack; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - /*************************************************************************/ - /* */ - /* This structure defines a rule used to tweak subpixel hinting for */ - /* various fonts. "", 0, "", NULL value indicates to match any value. */ - /* */ - - typedef struct SPH_TweakRule_ - { - const char family[32]; - const int ppem; - const char style[32]; - const FT_ULong glyph; - - } SPH_TweakRule; - - - typedef struct SPH_ScaleRule_ - { - const char family[32]; - const int ppem; - const char style[32]; - const FT_ULong glyph; - const float scale; - } SPH_ScaleRule; - -#define MAX_CLASS_MEMBERS 100 - - typedef struct Font_Class_ - { - const char name[32]; - const char member[MAX_CLASS_MEMBERS][32]; - } Font_Class; - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - /*************************************************************************/ /* */ /* The main structure for the interpreter which collects all necessary */ @@ -257,37 +218,6 @@ FT_BEGIN_HEADER FT_Bool grayscale; /* are we hinting for grayscale? */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Round_Func func_round_sphn; /* subpixel rounding function */ - - FT_Bool grayscale_hinting; /* Using grayscale hinting? */ - FT_Bool subpixel_hinting; /* Using subpixel hinting? */ - FT_Bool native_hinting; /* Using native hinting? */ - FT_Bool ignore_x_mode; /* Standard rendering mode for */ - /* subpixel hinting. On if gray */ - /* or subpixel hinting is on ) */ - FT_Bool compatibility_mode;/* Additional exceptions to */ - /* native TT rules for legacy */ - /* fonts. Implies ignore_x_mode. */ - - /* The following 3 aren't fully implemented but here for MS rasterizer */ - /* compatibility. */ - FT_Bool compatible_widths; /* compatible widths? */ - FT_Bool symmetrical_smoothing;/* symmetrical_smoothing? */ - FT_Bool bgr; /* bgr instead of rgb? */ - FT_Bool subpixel_positioned; /* MS DW subpixel positioned */ - - FT_Int rasterizer_version; /* MS rasterizer version */ - - FT_Bool iup_called; /* IUP called for glyph? */ - FT_Bool in_delta_function; /* inside an inline delta func? */ - - FT_ULong sph_tweak_flags; /* flags to control hint tweaks */ - - FT_Int num_delta_funcs; - FT_ULong inline_delta_funcs[5]; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - } TT_ExecContextRec; diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index 49d5b3f..47e4129 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -178,7 +178,6 @@ FT_BEGIN_HEADER FT_Long end; /* where does it end? */ FT_UInt opc; /* function #, or instruction code */ FT_Bool active; /* is it active? */ - FT_Bool inline_delta; /* is function that defines inline delta? */ } TT_DefRecord, *TT_DefArray; @@ -191,7 +190,7 @@ FT_BEGIN_HEADER { FT_Fixed xx, xy; /* transformation matrix coefficients */ FT_Fixed yx, yy; - FT_F26Dot6 ox, oy; /* offsets */ + FT_F26Dot6 ox, oy; /* offsets */ } TT_Transform; diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c deleted file mode 100644 index 2dc6c2f..0000000 --- a/src/truetype/ttsubpix.c +++ /dev/null @@ -1,261 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsubpix.c */ -/* */ -/* TrueType Subpixel Hinting. */ -/* */ -/* Copyright 2010-2011 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_TAGS_H -#include FT_OUTLINE_H - -#include "ttsubpix.h" - - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - FT_LOCAL_DEF( FT_Bool ) - is_member_of_family_class( const FT_String* detected_font_name, - const FT_String* rule_font_name ) - { - FT_UInt i, j; - - /* If font name matches rule family */ - if ( strcmp( detected_font_name, rule_font_name ) == 0 ) return TRUE; - - /* If font name is a wildcard "" */ - if ( strcmp( rule_font_name, "" ) == 0 ) return TRUE; - - /* If font name is contained in a class list */ - for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ ) - { - if ( strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 ) - { - for ( j = 0; j < MAX_CLASS_MEMBERS; j++ ) - { - if ( strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 ) - continue; - if ( strcmp( FAMILY_CLASS_Rules[i].member[j], detected_font_name ) == 0 ) - return TRUE; - } - } - } - return FALSE; - } - - - FT_LOCAL_DEF( FT_Bool ) - is_member_of_style_class( const FT_String* detected_font_style, - const FT_String* rule_font_style ) - { - FT_UInt i, j; - - /* If font style matches rule style */ - if ( strcmp( detected_font_style, rule_font_style ) == 0 ) return TRUE; - - /* If font style is a wildcard "" */ - if ( strcmp( rule_font_style, "" ) == 0 ) return TRUE; - - /* If font style is contained in a class list */ - for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ ) - { - if ( strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 ) - { - for ( j = 0; j < MAX_CLASS_MEMBERS; j++ ) - { - if ( strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 ) - continue; - if ( strcmp( STYLE_CLASS_Rules[i].member[j], detected_font_style ) == 0 ) - return TRUE; - } - } - } - return FALSE; - } - - - FT_LOCAL_DEF( FT_Bool ) - sph_test_tweak( TT_Face face, - FT_String* family, - int ppem, - FT_String* style, - FT_UInt glyph_index, - SPH_TweakRule* rule, - FT_UInt num_rules ) - { - FT_UInt i; - - - /* rule checks may be able to be optimized further */ - for ( i = 0; i < num_rules; i++ ) - { - if ( family && - ( is_member_of_family_class ( family, rule[i].family ) ) ) - if ( rule[i].ppem == 0 || - rule[i].ppem == ppem ) - if ( style && - is_member_of_style_class ( style, rule[i].style ) ) - if ( rule[i].glyph == 0 || - FT_Get_Char_Index( (FT_Face)face, - rule[i].glyph ) == glyph_index ) - return TRUE; - } - return FALSE; - } - - - FT_LOCAL_DEF( float ) - scale_test_tweak( TT_Face face, - FT_String* family, - int ppem, - FT_String* style, - FT_UInt glyph_index, - SPH_ScaleRule* rule, - FT_UInt num_rules ) - { - FT_UInt i; - - - /* rule checks may be able to be optimized further */ - for ( i = 0; i < num_rules; i++ ) - { - if ( family && - ( is_member_of_family_class ( family, rule[i].family ) ) ) - if ( rule[i].ppem == 0 || - rule[i].ppem == ppem ) - if ( style && - is_member_of_style_class( style, rule[i].style ) ) - if ( rule[i].glyph == 0 || - FT_Get_Char_Index( (FT_Face)face, - rule[i].glyph ) == glyph_index ) - return rule[i].scale; - } - return 1.0; - } - -#define TWEAK_RULES( x ) \ - if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ - x##_Rules, x##_RULES_SIZE ) ) \ - loader->exec->sph_tweak_flags |= SPH_TWEAK_##x; - -#define TWEAK_RULES_EXCEPTIONS( x ) \ - if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ - x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \ - loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x; - - FT_LOCAL_DEF( void ) - sph_set_tweaks( TT_Loader loader, - FT_UInt glyph_index ) - { - TT_Face face = (TT_Face)loader->face; - FT_String* family = face->root.family_name; - int ppem = loader->size->metrics.x_ppem; - FT_String* style = face->root.style_name; - - /* Don't apply rules if style isn't set */ - if ( !face->root.style_name ) return; - -#ifdef SPH_DEBUG_MORE_VERBOSE - printf( "%s,%d,%s,%c=%d ", family, ppem, style, glyph_index, glyph_index ); -#endif - - TWEAK_RULES( PIXEL_HINTING ); - - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING ) - { - loader->exec->ignore_x_mode = FALSE; - return; - } - - TWEAK_RULES( ALLOW_X_DMOVE ); - TWEAK_RULES( ALLOW_X_DMOVEX ); - TWEAK_RULES( ALLOW_X_MOVE_ZP2 ); - TWEAK_RULES( ALWAYS_DO_DELTAP ); - TWEAK_RULES( ALWAYS_SKIP_DELTAP ); - TWEAK_RULES( DEEMBOLDEN ); - TWEAK_RULES( DELTAP_SKIP_EXAGGERATED_VALUES ); - TWEAK_RULES( DO_SHPIX ); - TWEAK_RULES( EMBOLDEN ); - TWEAK_RULES( MIAP_HACK ); - TWEAK_RULES( NORMAL_ROUND ); - TWEAK_RULES( NO_ALIGNRP_AFTER_IUP ); - TWEAK_RULES( NO_CALL_AFTER_IUP ); - TWEAK_RULES( NO_DELTAP_AFTER_IUP ); - TWEAK_RULES( RASTERIZER_35 ); - TWEAK_RULES( SKIP_INLINE_DELTAS ); - TWEAK_RULES( SKIP_IUP ); - TWEAK_RULES( MIRP_CVT_ZERO ); - - TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES ); - - TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES ); - - TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES ); - - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) - { - if ( loader->exec->rasterizer_version != 35 ) - { - loader->exec->rasterizer_version = 35; - /* must re-execute fpgm */ - loader->exec->size->cvt_ready = FALSE; - tt_size_ready_bytecode( loader->exec->size, - FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); - } - } - else - { - if ( loader->exec->rasterizer_version == 35 ) - { - loader->exec->rasterizer_version = 37; - /* must re-execute fpgm */ - loader->exec->size->cvt_ready = FALSE; - tt_size_ready_bytecode( loader->exec->size, - FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); - } - } - - if ( IS_HINTED( loader->load_flags ) ) - { - TWEAK_RULES( TIMES_NEW_ROMAN_HACK ); - TWEAK_RULES( COURIER_NEW_2_HACK ); - } - - if ( sph_test_tweak( face, family, ppem, style, glyph_index, - COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) ) - { - loader->exec->compatibility_mode |= TRUE; - loader->exec->ignore_x_mode |= TRUE; - } - else - loader->exec->compatibility_mode &= FALSE; - - if ( IS_HINTED( loader->load_flags ) ) - { - if ( sph_test_tweak( face, family, ppem, style, glyph_index, - COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) ) - loader->exec->compatible_widths |= TRUE; - } - } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -/* END */ diff --git a/src/truetype/ttsubpix.h b/src/truetype/ttsubpix.h deleted file mode 100644 index df23040..0000000 --- a/src/truetype/ttsubpix.h +++ /dev/null @@ -1,778 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsubpix.h */ -/* */ -/* TrueType Subpixel Hinting. */ -/* */ -/* Copyright 2010-2011 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#ifndef __TTSUBPIX_H__ -#define __TTSUBPIX_H__ - -#include <ft2build.h> -#include "ttobjs.h" -#include "ttinterp.h" - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - - /*************************************************************************/ - /* */ - /* Tweak flags that are set for each glyph by the below rules */ - /* */ - /* */ -#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001 -#define SPH_TWEAK_ALLOW_X_DMOVEX 0x0000002 -#define SPH_TWEAK_ALLOW_X_MOVE_ZP2 0x0000004 -#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000008 -#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000010 -#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000020 -#define SPH_TWEAK_DEEMBOLDEN 0x0000040 -#define SPH_TWEAK_DELTAP_SKIP_EXAGGERATED_VALUES 0x0000080 -#define SPH_TWEAK_DO_SHPIX 0x0000100 -#define SPH_TWEAK_EMBOLDEN 0x0000200 -#define SPH_TWEAK_MIAP_HACK 0x0000400 -#define SPH_TWEAK_NORMAL_ROUND 0x0000800 -#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0001000 -#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0002000 -#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0004000 -#define SPH_TWEAK_PIXEL_HINTING 0x0008000 -#define SPH_TWEAK_RASTERIZER_35 0x0010000 -#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0020000 -#define SPH_TWEAK_SKIP_INLINE_DELTAS 0x0040000 -#define SPH_TWEAK_SKIP_IUP 0x0080000 -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0100000 -#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0200000 -#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0400000 -#define SPH_TWEAK_MIRP_CVT_ZERO 0x0800000 - - - FT_LOCAL( FT_Bool ) - sph_test_tweak( TT_Face face, - FT_String* family, - int ppem, - FT_String* style, - FT_UInt glyph_index, - SPH_TweakRule* rule, - FT_UInt num_rules ); - - FT_LOCAL_DEF( float ) - scale_test_tweak( TT_Face face, - FT_String* family, - int ppem, - FT_String* style, - FT_UInt glyph_index, - SPH_ScaleRule* rule, - FT_UInt num_rules ); - - FT_LOCAL( void ) - sph_set_tweaks( TT_Loader loader, - FT_UInt glyph_index ); - - - /*************************************************************************/ - /* */ - /* These rules affect how the TT Interpreter does hinting, with the */ - /* goal of doing subpixel hinting by (in general) ignoring x moves. */ - /* Some of these rules are fixes that go above and beyond the */ - /* stated techniques in the MS whitepaper on Cleartype, due to */ - /* artifacts in many glyphs. So, these rules make some glyphs render */ - /* better than they do in the MS rasterizer. */ - /* */ - /* "" string or 0 int/char indicates to apply to all glyphs. */ - /* "-" used as dummy placeholders, but any non-matching string works. */ - /* */ - /* Some of this could arguably be implemented in fontconfig, however: */ - /* */ - /* - Fontconfig can't set things on a glyph-by-glyph basis. */ - /* - The tweaks that happen here are very low-level, from an average */ - /* user's point of view and are best implemented in the hinter */ - /* */ - /* The goal is to make the subpixel hinting techniques as generalized */ - /* as possible across all fonts to prevent the need for extra rules such */ - /* as these. */ - /* */ - /* The rule structure is designed so that entirely new rules can easily */ - /* be added when a new compatibility feature is discovered. */ - /* */ - /* The rule structures could also use some enhancement to handle ranges. */ - /* */ - /* ****************** WORK IN PROGRESS ******************* */ - /* */ - -#define SPH_OPTION_BITMAP_WIDTHS FALSE -#define SPH_OPTION_SET_SUBPIXEL TRUE -#define SPH_OPTION_SET_GRAYSCALE FALSE -#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE -#define SPH_OPTION_SET_RASTERIZER_VERSION 37 -#define SPH_OPTION_GRIDLINES_PER_PIXEL_X 64 -#define SPH_OPTION_GRIDLINES_PER_PIXEL_Y 1 - -#define MAX_CLASS_MEMBERS 100 - -/* Define this to force natural (i.e. not bitmap-compatible) widths. */ -/* The default leans strongly towards natural widths except for a few */ -/* legacy fonts where a selective combination produces nicer results. */ -/* #define FORCE_NATURAL_WIDTHS */ - - - /* These are "classes" of fonts that can be grouped together and used in */ - /* rules below. A blank entry "" is required at the end of these! */ -#define FAMILY_CLASS_RULES_SIZE 7 - Font_Class FAMILY_CLASS_Rules - [FAMILY_CLASS_RULES_SIZE] = - { - { "MS Legacy Fonts", { "Aharoni", - "Andale Mono", - "Andalus", - "Angsana New", - "AngsanaUPC", - "Arabic Transparent", - "Arial Black", - "Arial Narrow", - "Arial Unicode MS", - "Arial", - "Batang", - "Browallia New", - "BrowalliaUPC", - "Comic Sans MS", - "Cordia New", - "CordiaUPC", - "Courier New", - "DFKai-SB", - "David Transparent", - "David", - "DilleniaUPC", - "Estrangelo Edessa", - "EucrosiaUPC", - "FangSong_GB2312", - "Fixed Miriam Transparent", - "FrankRuehl", - "Franklin Gothic Medium", - "FreesiaUPC", - "Garamond", - "Gautami", - "Georgia", - "Gulim", - "Impact", - "IrisUPC", - "JasmineUPC", - "KaiTi_GB2312", - "KodchiangUPC", - "Latha", - "Levenim MT", - "LilyUPC", - "Lucida Console", - "Lucida Sans Unicode", - "MS Gothic", - "MS Mincho", - "MV Boli", - "Mangal", - "Marlett", - "Microsoft Sans Serif", - "Mingliu", - "Miriam Fixed", - "Miriam Transparent", - "Miriam", - "Narkisim", - "Palatino Linotype", - "Raavi", - "Rod Transparent", - "Rod", - "Shruti", - "SimHei", - "Simplified Arabic Fixed", - "Simplified Arabic", - "Simsun", - "Sylfaen", - "Symbol", - "Tahoma", - "Times New Roman", - "Traditional Arabic", - "Trebuchet MS", - "Tunga", - "Verdana", - "Webdings", - "Wingdings", "", }, }, - { "Core MS Legacy Fonts", { "Arial Black", - "Arial Narrow", - "Arial Unicode MS", - "Arial", - "Comic Sans MS", - "Courier New", - "Garamond", - "Georgia", - "Impact", - "Lucida Console", - "Lucida Sans Unicode", - "Microsoft Sans Serif", - "Palatino Linotype", - "Tahoma", - "Times New Roman", - "Trebuchet MS", - "Verdana", "", }, }, - { "Apple Legacy Fonts", { "Geneva", - "Times", - "Monaco", - "Century", - "Chalkboard", - "Lobster", - "Century Gothic", - "Optima", - "Lucida Grande", - "Gill Sans", - "Baskerville", - "Helvetica", - "Helvetica Neue", "", }, }, - { "Legacy Sans Fonts", { "Andale Mono", - "Arial Unicode MS", - "Arial", - "Century Gothic", - "Comic Sans MS", - "Franklin Gothic Medium", - "Geneva", - "Lucida Console", - "Lucida Grande", - "Lucida Sans Unicode", - "Microsoft Sans Serif", - "Monaco", - "Tahoma", - "Trebuchet MS", - "Verdana", "", }, }, - { "Misc Legacy Fonts", { "Dark Courier", "", }, }, - { "Verdana Clones", { "DejaVu Sans", - "Bitstream Vera Sans", "", }, }, - { "Verdana and Clones", { "DejaVu Sans", - "Bitstream Vera Sans", - "Verdana", "", }, }, -}; - - - /* Define "classes" of styles that can be grouped together and used in */ - /* rules below. A blank entry "" is required at the end of these! */ -#define STYLE_CLASS_RULES_SIZE 5 - Font_Class STYLE_CLASS_Rules - [STYLE_CLASS_RULES_SIZE] = - { - { "Regular Class", { "Regular", - "Book", - "Medium", - "Roman", - "Normal", "", }, }, - { "Regular/Italic Class", { "Regular", - "Book", - "Medium", - "Italic", - "Oblique", - "Roman", - "Normal", "", }, }, - { "Bold/BoldItalic Class", { "Bold", - "Bold Italic", - "Black", "", }, }, - { "Bold/Italic/BoldItalic Class", { "Bold", - "Bold Italic", - "Black", - "Italic", - "Oblique", "", }, }, - { "Regular/Bold Class", { "Regular", - "Book", - "Medium", - "Normal", - "Roman", - "Bold", - "Black", "", }, }, - }; - - - - /* Special fixes for known legacy fonts */ - /* This is the primary workhorse rule for legacy fonts */ -#define COMPATIBILITY_MODE_RULES_SIZE 4 - SPH_TweakRule COMPATIBILITY_MODE_Rules - [COMPATIBILITY_MODE_RULES_SIZE] = - { - { "MS Legacy Fonts", 0, "", 0 }, - { "Apple Legacy Fonts", 0, "", 0 }, - { "Misc Legacy Fonts", 0, "", 0 }, - { "Verdana Clones", 0, "", 0 }, - }; - - - /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting */ -#define PIXEL_HINTING_RULES_SIZE 4 - SPH_TweakRule PIXEL_HINTING_Rules - [PIXEL_HINTING_RULES_SIZE] = - { - /* These characters are almost always safe */ - { "", 0, "", '<' }, - { "", 0, "", '>' }, - /* Fixes the vanishing stem */ - { "Times New Roman", 0, "Bold", 'A' }, - { "Times New Roman", 0, "Bold", 'V' }, - }; - - - /* According to Greg Hitchcock and the MS whitepaper, this should work */ - /* on all legacy MS fonts, but creates artifacts with some. Only using */ - /* where absolutely necessary. */ -#define SKIP_INLINE_DELTAS_RULES_SIZE 1 - SPH_TweakRule SKIP_INLINE_DELTAS_Rules - [SKIP_INLINE_DELTAS_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */ -#define DO_SHPIX_RULES_SIZE 1 - SPH_TweakRule DO_SHPIX_Rules - [DO_SHPIX_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Skip Y moves that start with a point that is not on a Y pixel */ - /* boundary and don't move that point to a Y pixel boundary. */ -#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 8 - SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules - [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = - { - /* fix vwxyz thinness*/ - { "Consolas", 0, "Regular", 0 }, - /* fix tiny gap at top of m */ - { "Arial", 0, "Regular", 'm' }, - /* Fix thin middle stems */ - { "Core MS Legacy Fonts", 0, "Regular/Bold Class", 'N' }, - { "Lucida Grande", 0, "", 'N' }, - { "Legacy Sans Fonts", 0, "", L'и' }, - { "Verdana Clones", 0, "",'N' }, - { "Ubuntu", 0, "Regular Class", 'N' }, - /* Fix misshapen x */ - { "Verdana", 0, "Bold", 'x' }, - }; - -#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 4 - SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - { "Tahoma", 0, "", 'N' }, - { "Comic Sans MS", 0, "", 'N' }, - { "Verdana", 0, "Regular/Bold Class", 'N' }, - { "Verdana", 11, "Bold", 'x' }, - }; - - - - /* Skip Y moves that move a point off a Y pixel boundary */ - /* This fixes Tahoma, Trebuchet oddities and some issues with `$' */ -#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 5 - SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules - [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = - { - { "MS Legacy Fonts", 0, "", 0 }, - { "Apple Legacy Fonts", 0, "", 0 }, - { "Misc Legacy Fonts", 0, "", 0 }, - { "Ubuntu", 0, "Regular Class", 0 }, - { "Verdana Clones", 0, "", 0 }, - }; - - -#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Round moves that don't move a point to a Y pixel boundary */ -#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 3 - SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules - [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = - { - /* Droid font instructions don't snap Y to pixels */ - { "Droid Sans", 0, "Regular/Italic Class", 0 }, - { "Droid Sans Mono", 0, "", 0 }, - { "Ubuntu", 0, "", 0 }, - }; - -#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 3 - SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions - [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - { "Droid Sans", 12, "Bold", 0 }, - { "Droid Sans", 13, "Bold", 0 }, - { "Droid Sans", 16, "Bold", 0 }, - }; - - /* Allow a Direct_Move_X along X freedom vector if matched */ -#define ALLOW_X_DMOVEX_RULES_SIZE 2 - SPH_TweakRule ALLOW_X_DMOVEX_Rules - [ALLOW_X_DMOVEX_RULES_SIZE] = - { - /* Creates a more consistent appearance for these */ - { "Arial", 13, "Regular", 'e' }, - { "Arial", 13, "Regular", 'o' }, - }; - - /* Allow a Direct_Move along X freedom vector if matched */ -#define ALLOW_X_DMOVE_RULES_SIZE 3 - SPH_TweakRule ALLOW_X_DMOVE_Rules - [ALLOW_X_DMOVE_RULES_SIZE] = - { - /* Creates a more consistent appearance for these */ - { "Arial", 13, "Regular", 'e' }, - { "Arial", 13, "Regular", 'o' }, - /* Fixes vanishing diagonal in 4 */ - { "Verdana", 0, "Regular", '4' }, - }; - - /* Allow a ZP2 move along freedom vector if matched; */ - /* This is called from SHP, SHPIX, SHC, SHZ */ -#define ALLOW_X_MOVE_ZP2_RULES_SIZE 1 - SPH_TweakRule ALLOW_X_MOVE_ZP2_Rules - [ALLOW_X_MOVE_ZP2_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - /* Return MS rasterizer version 35 if matched */ -#define RASTERIZER_35_RULES_SIZE 8 - SPH_TweakRule RASTERIZER_35_Rules - [RASTERIZER_35_RULES_SIZE] = - { - /* This seems to be the only way to make these look good */ - { "Times New Roman", 0, "Regular", 'i' }, - { "Times New Roman", 0, "Regular", 'j' }, - { "Times New Roman", 0, "Regular", 'm' }, - { "Times New Roman", 0, "Regular", 'r' }, - { "Times New Roman", 0, "Regular", 'a' }, - { "Times New Roman", 0, "Regular", 'n' }, - { "Times New Roman", 0, "Regular", 'p' }, - { "Times", 0, "", 0 }, - }; - - /* Don't round to the subpixel grid. Round to pixel grid. */ -#define NORMAL_ROUND_RULES_SIZE 2 - SPH_TweakRule NORMAL_ROUND_Rules - [NORMAL_ROUND_RULES_SIZE] = - { - /* Fix point "explosions" */ - { "Courier New", 0, "", 0 }, - { "Verdana", 10, "Regular", '4' }, - }; - - /* Skip IUP instructions if matched */ -#define SKIP_IUP_RULES_SIZE 1 - SPH_TweakRule SKIP_IUP_Rules - [SKIP_IUP_RULES_SIZE] = - { - { "Arial", 13, "Regular", 'a' }, - }; - - /* Skip MIAP Twilight hack if matched */ -#define MIAP_HACK_RULES_SIZE 1 - SPH_TweakRule MIAP_HACK_Rules - [MIAP_HACK_RULES_SIZE] = - { - { "Geneva", 12, "", 0 }, - }; - - /* Skip DELTAP instructions if matched */ -#define ALWAYS_SKIP_DELTAP_RULES_SIZE 13 - SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules - [ALWAYS_SKIP_DELTAP_RULES_SIZE] = - { - { "Georgia", 0, "Regular", 'k' }, - /* fixes problems with W M w */ - { "Trebuchet MS", 0, "Italic", 0 }, - { "Trebuchet MS", 14, "Regular", 'e' }, - { "Arial", 11, "Regular", 's' }, - { "Verdana", 10, "Regular", 0 }, - { "Verdana", 9, "Regular", 0 }, - { "Legacy Sans Fonts", 0, "", L'й' }, - { "Arial", 10, "Regular", '6' }, - { "Arial", 0, "Bold/BoldItalic Class", 'a' }, - /* Make horizontal stems consistent with the rest */ - { "Arial", 24, "Bold", 's' }, - { "Arial", 25, "Bold", 's' }, - { "Arial", 24, "Bold", 'a' }, - { "Arial", 25, "Bold", 'a' }, - }; - - /* Always do DELTAP instructions if matched */ -#define ALWAYS_DO_DELTAP_RULES_SIZE 2 - SPH_TweakRule ALWAYS_DO_DELTAP_Rules - [ALWAYS_DO_DELTAP_RULES_SIZE] = - { - { "Verdana Clones", 17, "Regular Class", 'K' }, - { "Verdana Clones", 17, "Regular Class", 'k' }, - }; - - /* Do an extra RTG instruction in DELTAP if matched */ -#define DELTAP_RTG_RULES_SIZE 1 - SPH_TweakRule DELTAP_RTG_Rules - [DELTAP_RTG_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - /* Force CVT distance to zero in MIRP */ -#define MIRP_CVT_ZERO_RULES_SIZE 1 - SPH_TweakRule MIRP_CVT_ZERO_Rules - [MIRP_CVT_ZERO_RULES_SIZE] = - { - { "Verdana", 0, "Regular", 0 }, - }; - - /* Skip moves that meet or exceed 1 pixel */ -#define DELTAP_SKIP_EXAGGERATED_VALUES_RULES_SIZE 2 - SPH_TweakRule DELTAP_SKIP_EXAGGERATED_VALUES_Rules - [DELTAP_SKIP_EXAGGERATED_VALUES_RULES_SIZE] = - { - /* Fix vanishing stems */ - { "Ubuntu", 0, "Regular", 'M' }, - /* Fix X at larger ppems */ - { "Segoe UI", 0, "Light", 0 }, - }; - - /* Don't allow ALIGNRP after IUP */ -#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE 4 - SPH_TweakRule NO_ALIGNRP_AFTER_IUP_Rules - [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] = - { - /* Prevent creation of dents in outline */ - { "Courier New", 0, "Bold", 'C' }, - { "Courier New", 0, "Bold", 'D' }, - { "Courier New", 0, "Bold", 'Q' }, - { "Courier New", 0, "Bold", '0' }, - }; - - /* Don't allow DELTAP after IUP */ -#define NO_DELTAP_AFTER_IUP_RULES_SIZE 2 - SPH_TweakRule NO_DELTAP_AFTER_IUP_Rules - [NO_DELTAP_AFTER_IUP_RULES_SIZE] = - { - { "Arial", 0, "Bold", 'N' }, - { "Verdana", 0, "Regular", '4' }, - }; - - /* Don't allow CALL after IUP */ -#define NO_CALL_AFTER_IUP_RULES_SIZE 4 - SPH_TweakRule NO_CALL_AFTER_IUP_Rules - [NO_CALL_AFTER_IUP_RULES_SIZE] = - { - /* Prevent creation of dents in outline */ - { "Courier New", 0, "Bold", 'O' }, - { "Courier New", 0, "Bold", 'Q' }, - { "Courier New", 0, "Bold", 'k' }, - { "Courier New", 0, "Bold Italic", 'M' }, - }; - - /* De-embolden these glyphs slightly */ -#define DEEMBOLDEN_RULES_SIZE 9 - SPH_TweakRule DEEMBOLDEN_Rules - [DEEMBOLDEN_RULES_SIZE] = - { - { "Courier New", 0, "Bold", 'A' }, - { "Courier New", 0, "Bold", 'W' }, - { "Courier New", 0, "Bold", 'w' }, - { "Courier New", 0, "Bold", 'M' }, - { "Courier New", 0, "Bold", 'X' }, - { "Courier New", 0, "Bold", 'K' }, - { "Courier New", 0, "Bold", 'x' }, - { "Courier New", 0, "Bold", 'z' }, - { "Courier New", 0, "Bold", 'v' }, - }; - - /* Embolden these glyphs slightly */ -#define EMBOLDEN_RULES_SIZE 5 - SPH_TweakRule EMBOLDEN_Rules - [EMBOLDEN_RULES_SIZE] = - { - { "Courier New", 12, "Italic", 'z' }, - { "Courier New", 11, "Italic", 'z' }, - { "Courier New", 10, "Italic", 'z' }, - { "Courier New", 0, "Regular", 0 }, - { "Courier New", 0, "Italic", 0 }, - }; - - /* Do an extra RDTG instruction in DELTAP if matched */ -#define DELTAP_RDTG_RULES_SIZE 1 - SPH_TweakRule DELTAP_RDTG_Rules - [DELTAP_RDTG_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7 */ - /* similar to Windows XP. */ -#define TIMES_NEW_ROMAN_HACK_RULES_SIZE 12 - SPH_TweakRule TIMES_NEW_ROMAN_HACK_Rules - [TIMES_NEW_ROMAN_HACK_RULES_SIZE] = - { - { "Times New Roman", 16, "Italic", '2' }, - { "Times New Roman", 16, "Italic", '5' }, - { "Times New Roman", 16, "Italic", '7' }, - { "Times New Roman", 16, "Regular", '2' }, - { "Times New Roman", 16, "Regular", '5' }, - { "Times New Roman", 16, "Regular", '7' }, - { "Times New Roman", 17, "Italic", '2' }, - { "Times New Roman", 17, "Italic", '5' }, - { "Times New Roman", 17, "Italic", '7' }, - { "Times New Roman", 17, "Regular", '2' }, - { "Times New Roman", 17, "Regular", '5' }, - { "Times New Roman", 17, "Regular", '7' }, - }; - - - /* This fudges distance on 2 to get rid of the vanishing stem issue. */ - /* A real solution to this is certainly welcome. */ -#define COURIER_NEW_2_HACK_RULES_SIZE 15 - SPH_TweakRule COURIER_NEW_2_HACK_Rules - [COURIER_NEW_2_HACK_RULES_SIZE] = - { - { "Courier New", 10, "Regular", '2' }, - { "Courier New", 11, "Regular", '2' }, - { "Courier New", 12, "Regular", '2' }, - { "Courier New", 13, "Regular", '2' }, - { "Courier New", 14, "Regular", '2' }, - { "Courier New", 15, "Regular", '2' }, - { "Courier New", 16, "Regular", '2' }, - { "Courier New", 17, "Regular", '2' }, - { "Courier New", 18, "Regular", '2' }, - { "Courier New", 19, "Regular", '2' }, - { "Courier New", 20, "Regular", '2' }, - { "Courier New", 21, "Regular", '2' }, - { "Courier New", 22, "Regular", '2' }, - { "Courier New", 23, "Regular", '2' }, - { "Courier New", 24, "Regular", '2' }, - }; - - -#ifndef FORCE_NATURAL_WIDTHS - - /* Use compatible widths with these glyphs. Compatible widths is always */ - /* on when doing B/W TrueType instructing, but is used selectively here, */ - /* typically on glyphs with 3 or more vertical stems. */ -#define COMPATIBLE_WIDTHS_RULES_SIZE 36 - SPH_TweakRule COMPATIBLE_WIDTHS_Rules - [COMPATIBLE_WIDTHS_RULES_SIZE] = - { - { "Arial Unicode MS", 12, "Regular Class", 'm' }, - { "Arial Unicode MS", 14, "Regular Class", 'm' }, - { "Arial", 10, "Regular Class", L'ш' }, - { "Arial", 11, "Regular Class", 'm' }, - { "Arial", 12, "Regular Class", 'm' }, - { "Arial", 12, "Regular Class", L'ш' }, - { "Arial", 13, "Regular Class", L'ш' }, - { "Arial", 14, "Regular Class", 'm' }, - { "Arial", 14, "Regular Class", L'ш' }, - { "Arial", 15, "Regular Class", L'ш' }, - { "Arial", 17, "Regular Class", 'm' }, - { "DejaVu Sans", 15, "Regular Class", 0 }, - { "Microsoft Sans Serif", 11, "Regular Class", 0 }, - { "Microsoft Sans Serif", 12, "Regular Class", 0 }, - { "Segoe UI", 11, "Regular Class", 0 }, - { "Segoe UI", 12, "Regular Class", 'm' }, - { "Segoe UI", 14, "Regular Class", 'm' }, - { "Tahoma", 11, "Regular Class", 0 }, - { "Times New Roman", 16, "Regular Class", 'c' }, - { "Times New Roman", 16, "Regular Class", 'm' }, - { "Times New Roman", 16, "Regular Class", 'o' }, - { "Times New Roman", 16, "Regular Class", 'w' }, - { "Trebuchet MS", 12, "Regular Class", 0 }, - { "Trebuchet MS", 14, "Regular Class", 0 }, - { "Trebuchet MS", 15, "Regular Class", 0 }, - { "Ubuntu", 12, "Regular Class", 'm' }, - { "Verdana", 10, "Regular Class", L'ш' }, - { "Verdana", 11, "Regular Class", L'ш' }, - { "Verdana and Clones", 12, "Regular Class", 'm' }, - { "Verdana and Clones", 12, "Regular Class", 'l' }, - { "Verdana and Clones", 12, "Regular Class", 'i' }, - { "Verdana and Clones", 12, "Regular Class", 'j' }, - { "Verdana and Clones", 13, "Regular Class", 'l' }, - { "Verdana and Clones", 13, "Regular Class", 'i' }, - { "Verdana and Clones", 13, "Regular Class", 'j' }, - { "Verdana and Clones", 14, "Regular Class", 'm' }, - }; - - - /* Scaling slightly in the x-direction prior to hinting results in */ - /* more visually pleasing glyphs in certain cases. */ - /* This sometimes needs to be coordinated with compatible width rules. */ -#define X_SCALING_RULES_SIZE 40 - SPH_ScaleRule X_SCALING_Rules - [X_SCALING_RULES_SIZE] = - { - { "DejaVu Sans", 12, "Regular Class", 'm', .95 }, - { "Verdana and Clones", 12, "Regular Class", 'a', 1.1 }, - { "Arial", 11, "Regular Class", 'm', .975 }, - { "Arial", 12, "Regular Class", 'm', 1.05 }, - { "Arial", 13, "Regular Class", L'л', .95 }, - { "Arial", 14, "Regular Class", 'm', .95 }, - { "Arial", 15, "Regular Class", L'л', .925 }, - { "Bitstream Vera Sans", 10, "Regular Class", 0, 1.1 }, - { "Bitstream Vera Sans", 12, "Regular Class", 0, 1.05}, - { "Bitstream Vera Sans", 16, "Regular Class", 0, 1.05 }, - { "Bitstream Vera Sans", 9, "Regular Class", 0, 1.05}, - { "DejaVu Sans", 12, "Regular Class", 'l', .975 }, - { "DejaVu Sans", 12, "Regular Class", 'i', .975 }, - { "DejaVu Sans", 12, "Regular Class", 'j', .975 }, - { "DejaVu Sans", 13, "Regular Class", 'l', .95 }, - { "DejaVu Sans", 13, "Regular Class", 'i', .95 }, - { "DejaVu Sans", 13, "Regular Class", 'j', .95 }, - { "DejaVu Sans", 10, "Regular Class", 0, 1.1 }, - { "DejaVu Sans", 12, "Regular Class", 0, 1.05 }, - { "Georgia", 10, "", 0, 1.05 }, - { "Georgia", 11, "", 0, 1.1 }, - { "Georgia", 12, "", 0, 1.025 }, - { "Georgia", 13, "", 0, 1.05 }, - { "Georgia", 16, "", 0, 1.05 }, - { "Georgia", 17, "", 0, 1.03 }, - { "Liberation Sans", 12, "Regular Class", 'm', 1.1 }, - { "Lucida Grande", 11, "Regular Class", 'm', 1.1 }, - { "Microsoft Sans Serif", 11, "Regular Class", 'm', .95 }, - { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1.05 }, - { "Segoe UI", 12, "Regular Class", 'H', 1.05 }, - { "Segoe UI", 12, "Regular Class", 'm', 1.05 }, - { "Segoe UI", 14, "Regular Class", 'm', 1.05 }, - { "Tahoma", 11, "Regular Class", 'm', .975 }, - { "Verdana", 10, "Regular Class", 0, 1.1 }, - { "Verdana", 12, "Regular Class", 'm', .975 }, - { "Verdana", 12, "Regular Class", 0, 1.05 }, - { "Verdana", 16, "Regular Class", 0, 1.05 }, - { "Verdana", 9, "Regular Class", 0, 1.05 }, - { "Times New Roman", 16, "Regular Class", 'm', .95 }, - { "Trebuchet MS", 12, "Regular Class", 'm', .95 }, - }; -#else -#define COMPATIBLE_WIDTHS_RULES_SIZE 1 - SPH_TweakRule COMPATIBLE_WIDTHS_Rules - [COMPATIBLE_WIDTHS_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - -#define X_SCALING_RULES_SIZE 1 - SPH_ScaleRule X_SCALING_Rules - [X_SCALING_RULES_SIZE] = - { - { "-", 0, "", 0, 1.0 }, - }; -#endif /* FORCE_NATURAL_WIDTHS */ - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - -#endif /* __TTSUBPIX_H__ */ - -/* END */ |