summaryrefslogtreecommitdiffstats
path: root/src/autofit/aflatin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/autofit/aflatin.c')
-rw-r--r--src/autofit/aflatin.c233
1 files changed, 221 insertions, 12 deletions
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 0fd3045..fdf2dd2 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -22,6 +22,7 @@
#include "aflatin.h"
#include "aferrors.h"
+#include "strings.h"
#ifdef AF_CONFIG_OPTION_USE_WARPER
@@ -528,7 +529,30 @@
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 )
{
@@ -556,7 +580,7 @@
{
AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT];
AF_LatinBlue blue = NULL;
-
+ int threshold = 40;
for ( nn = 0; nn < Axis->blue_count; nn++ )
{
@@ -566,12 +590,16 @@
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 + 40 ) & ~63;
-
+ FT_Pos fitted = ( scaled + threshold ) & ~63;
if ( scaled != fitted )
{
@@ -626,7 +654,6 @@
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;
@@ -635,7 +662,12 @@
/* 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;
@@ -686,7 +718,12 @@
delta2 = -delta2;
blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
+ /* Round to prevent fringes */
+ blue->shoot.fit = FT_PIX_ROUND( blue->ref.fit - delta2 );
+#else
blue->shoot.fit = blue->ref.fit - delta2;
+#endif
#endif
@@ -1433,6 +1470,8 @@
if ( dist < 0 )
dist = -dist;
+ /* round down to pixels */
+ /*dist = FT_MulFix( dist, scale ) & ~63;*/
dist = FT_MulFix( dist, scale );
if ( dist < best_dist )
{
@@ -1595,20 +1634,95 @@
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;
- if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||
- axis->extra_light )
- return width;
+
+ 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 ( 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 ) ) )
+ if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||
+ ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )
+#endif
{
/* smooth hinting process: very lightly quantize the stem width */
@@ -1667,7 +1781,10 @@
dist = ( dist + 32 ) & ~63;
}
}
- else
+ else
+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
+ if ( autohint_snap_stem_height < 100 )
+#endif
{
/* strong hinting process: snap the stem width to integer pixels */
@@ -1675,7 +1792,9 @@
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 */
@@ -1738,6 +1857,23 @@
}
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;
@@ -1760,6 +1896,8 @@
(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;
@@ -2234,8 +2372,32 @@
{
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;
@@ -2292,7 +2454,54 @@
}
}
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;
}