summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Turner <david@freetype.org>2002-07-08 22:26:11 +0000
committerDavid Turner <david@freetype.org>2002-07-08 22:26:11 +0000
commit27c322e9835b8fec7e5f65a012f56e1c64fc9879 (patch)
tree0be3fe96e6871546fc50f5a76ca50d25169567b6
parentdcb61e478566a67134a16195ca462730c1bb1030 (diff)
downloadfreetype2-27c322e9835b8fec7e5f65a012f56e1c64fc9879.tar.gz
* include/freetype/freetype.h, src/base/ftobjs.h,
freetype/internal/ftobjs.h, freetype/internal/psaux.h, freetype/internal/pshints.h, src/psaux/t1decode.c, src/cff/cffgload.h, src/cff/cffgload.c, src/pshinter/pshalgo1.h, src/pshinter/pshalgo1.c, src/pshinter/pshalgo2.h, src/pshinter/pshalgo2.c, src/pshinter/pshalgo3.h, src/pshinter/pshalgo3.c: Adding support for hinter-specific bit flags, and the new FT_Set_Hint_Flags high-level API
-rw-r--r--ChangeLog12
-rw-r--r--include/freetype/freetype.h59
-rw-r--r--include/freetype/internal/ftobjs.h5
-rw-r--r--include/freetype/internal/psaux.h18
-rw-r--r--include/freetype/internal/pshints.h10
-rw-r--r--src/base/ftobjs.c17
-rw-r--r--src/cff/cffgload.c4
-rw-r--r--src/cff/cffgload.h2
-rw-r--r--src/psaux/t1decode.c4
-rw-r--r--src/pshinter/pshalgo1.c5
-rw-r--r--src/pshinter/pshalgo1.h3
-rw-r--r--src/pshinter/pshalgo2.c4
-rw-r--r--src/pshinter/pshalgo2.h3
-rw-r--r--src/pshinter/pshalgo3.c531
-rw-r--r--src/pshinter/pshalgo3.h3
15 files changed, 260 insertions, 420 deletions
diff --git a/ChangeLog b/ChangeLog
index cefe6429a..0be5f229f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2002-07-07 Owen Taylor <owen@redhat.com>
+
+ * include/freetype/freetype.h, src/base/ftobjs.h,
+ freetype/internal/ftobjs.h, freetype/internal/psaux.h,
+ freetype/internal/pshints.h, src/psaux/t1decode.c, src/cff/cffgload.h,
+ src/cff/cffgload.c, src/pshinter/pshalgo1.h, src/pshinter/pshalgo1.c,
+ src/pshinter/pshalgo2.h, src/pshinter/pshalgo2.c, src/pshinter/pshalgo3.h,
+ src/pshinter/pshalgo3.c: Adding support for hinter-specific bit flags,
+ and the new FT_Set_Hint_Flags high-level API
+
2002-07-04 David Turner <david@freetype.org>
* src/pfr/pfrobjs.c (pfr_slot_load): fixed a small bug that returned
@@ -5,7 +15,7 @@
metrics resolution
* src/autohint/ahhint.c: removing compiler warnings
-
+
* src/autohint/ahglyph.c: slight improvements to the serif detection
code. More work is needed though..
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 57c0fcbee..18659dbc6 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -2775,6 +2775,65 @@ FT_BEGIN_HEADER
FT_Matrix* matrix );
+
+ /*@***********************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Set_Hint_Flags */
+ /* */
+ /* <Description> */
+ /* A function used to set a number of flags that are used to control */
+ /* the hinting process when glyphs are loaded. */
+ /* */
+ /* <InOut> */
+ /* face :: A handle to the source face object. */
+ /* */
+ /* <Input> */
+ /* flags :: A set of bit flags that control the hinting process */
+ /* see the FT_HINT_XXX constants for details. */
+ /* */
+ /* <Note> */
+ /* The interpretation of the flags depends on the hinter module in */
+ /* use. Not all modules will support all flags */
+ /* */
+ FT_EXPORT( void )
+ FT_Set_Hint_Flags( FT_Face face,
+ FT_ULong hint_flags );
+
+
+ /*@***********************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_HINT_NO_INTEGER_STEM */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Set_Hint_Flags() to to suppress */
+ /* snapping of stem widths to integer values */
+ /* */
+#define FT_HINT_NO_INTEGER_STEM 1
+
+ /*@***********************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_HINT_NO_HSTEM_ALIGN */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Set_Hint_Flags() to to suppress */
+ /* alignment of horizontal stems with the pixel grid. */
+ /* */
+#define FT_HINT_NO_HSTEM_ALIGN 2
+
+ /*@***********************************************************************/
+ /* */
+ /* <Constant> */
+ /* FT_HINT_NO_VSTEM_ALIGN */
+ /* */
+ /* <Description> */
+ /* A bit-field constant, used with FT_Set_Hint_Flags() to to suppress */
+ /* alignment of vertical stems with the pixel grid */
+ /* */
+#define FT_HINT_NO_VSTEM_ALIGN 4
+
/* */
FT_END_HEADER
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index f92115c6a..015349ab0 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -291,6 +291,9 @@ FT_BEGIN_HEADER
/* transform_flags :: Some flags used to classify the transform. */
/* Only used by the convenience functions. */
/* */
+ /* hint_flags :: Some flags used to change the hinters' */
+ /* behaviour. Only used for debugging for now */
+ /* */
/* postscript_name :: Postscript font name for this face. */
/* */
typedef struct FT_Face_InternalRec_
@@ -302,6 +305,8 @@ FT_BEGIN_HEADER
FT_Vector transform_delta;
FT_Int transform_flags;
+ FT_UInt32 hint_flags;
+
const char* postscript_name;
} FT_Face_InternalRec;
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index a2cf527a8..2f1557d6b 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -142,10 +142,10 @@ FT_BEGIN_HEADER
typedef struct PS_ParserRec_* PS_Parser;
typedef struct T1_TokenRec_* T1_Token;
-
+
typedef struct T1_FieldRec_* T1_Field;
-
+
/* simple enumeration type used to identify token types */
typedef enum T1_TokenType_
{
@@ -388,7 +388,7 @@ FT_BEGIN_HEADER
FT_Memory memory;
PS_Parser_FuncsRec funcs;
-
+
} PS_ParserRec;
@@ -544,7 +544,7 @@ FT_BEGIN_HEADER
void* hints_globals; /* hinter-specific */
T1_Builder_FuncsRec funcs;
-
+
} T1_BuilderRec;
@@ -613,7 +613,7 @@ FT_BEGIN_HEADER
(*parse_charstrings)( T1_Decoder decoder,
FT_Byte* base,
FT_UInt len );
-
+
} T1_Decoder_FuncsRec;
@@ -645,9 +645,11 @@ FT_BEGIN_HEADER
PS_Blend blend; /* for multiple master support */
+ FT_UInt32 hint_flags;
+
T1_Decoder_Callback parse_callback;
T1_Decoder_FuncsRec funcs;
-
+
} T1_DecoderRec;
@@ -667,9 +669,9 @@ FT_BEGIN_HEADER
FT_CMap_Class expert;
FT_CMap_Class custom;
FT_CMap_Class unicode;
-
+
} T1_CMap_ClassesRec;
-
+
/*************************************************************************/
/*************************************************************************/
diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h
index 9b85065b9..e7fd76faa 100644
--- a/include/freetype/internal/pshints.h
+++ b/include/freetype/internal/pshints.h
@@ -267,6 +267,8 @@ FT_BEGIN_HEADER
/* */
/* globals :: The hinter globals for this font. */
/* */
+ /* hint_flags :: hinter bit flags */
+ /* */
/* @return: */
/* FreeType error code. 0 means success. */
/* */
@@ -280,7 +282,8 @@ FT_BEGIN_HEADER
typedef FT_Error
(*T1_Hints_ApplyFunc)( T1_Hints hints,
FT_Outline* outline,
- PSH_Globals globals );
+ PSH_Globals globals,
+ FT_UInt32 hint_flags );
/*************************************************************************/
@@ -545,6 +548,8 @@ FT_BEGIN_HEADER
/* */
/* globals :: The hinter globals for this font. */
/* */
+ /* hint_flags :: hinter bit flags */
+ /* */
/* @return: */
/* FreeType error code. 0 means success. */
/* */
@@ -558,7 +563,8 @@ FT_BEGIN_HEADER
typedef FT_Error
(*T2_Hints_ApplyFunc)( T2_Hints hints,
FT_Outline* outline,
- PSH_Globals globals );
+ PSH_Globals globals,
+ FT_UInt32 hint_flags );
/*************************************************************************/
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 0fce50cd7..c37072db3 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -380,6 +380,23 @@
}
+ /* documentation is in freetype.h */
+
+ FT_EXPORT_DEF( void )
+ FT_Set_Hint_Flags( FT_Face face,
+ FT_ULong flags )
+ {
+ FT_Face_Internal internal;
+
+ if ( !face )
+ return;
+
+ internal = face->internal;
+
+ internal->hint_flags = (FT_UInt)flags;
+ }
+
+
static FT_Renderer
ft_lookup_glyph_renderer( FT_GlyphSlot slot );
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 07a137c44..519346d76 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -246,6 +246,7 @@
builder->current = &loader->current.outline;
FT_GlyphLoader_Rewind( loader );
+ builder->hint_flags = FT_FACE(face)->internal->hint_flags;
builder->hints_globals = 0;
builder->hints_funcs = 0;
@@ -1676,7 +1677,8 @@
/* apply hints to the loaded glyph outline now */
hinter->apply( hinter->hints,
builder->current,
- (PSH_Globals)builder->hints_globals );
+ (PSH_Globals)builder->hints_globals,
+ builder->hint_flags );
}
/* add current outline to the glyph slot */
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index b749d1d97..15182fe01 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -114,6 +114,8 @@ FT_BEGIN_HEADER
FT_Error error; /* only used for memory errors */
FT_Bool metrics_only;
+ FT_UInt32 hint_flags;
+
void* hints_funcs; /* hinter-specific */
void* hints_globals; /* hinter-specific */
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index 4544ad1fb..91220fc33 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -752,7 +752,8 @@
/* apply hints to the loaded glyph outline now */
hinter->apply( hinter->hints,
builder->current,
- (PSH_Globals)builder->hints_globals );
+ (PSH_Globals)builder->hints_globals,
+ decoder->hint_flags );
}
/* add current outline to the glyph slot */
@@ -1146,6 +1147,7 @@
decoder->num_glyphs = face->num_glyphs;
decoder->glyph_names = glyph_names;
+ decoder->hint_flags = face->internal->hint_flags;
decoder->blend = blend;
decoder->parse_callback = parse_callback;
diff --git a/src/pshinter/pshalgo1.c b/src/pshinter/pshalgo1.c
index 8fa03256e..25e343317 100644
--- a/src/pshinter/pshalgo1.c
+++ b/src/pshinter/pshalgo1.c
@@ -744,13 +744,16 @@
FT_Error
ps1_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
- PSH_Globals globals )
+ PSH_Globals globals,
+ FT_UInt32 hint_flags )
{
PSH1_Hint_TableRec hints;
FT_Error error = 0;
FT_Int dimension;
+ FT_UNUSED( hint_flags );
+
for ( dimension = 1; dimension >= 0; dimension-- )
{
PS_Dimension dim = &ps_hints->dimension[dimension];
diff --git a/src/pshinter/pshalgo1.h b/src/pshinter/pshalgo1.h
index ed1031fd6..1eae160b7 100644
--- a/src/pshinter/pshalgo1.h
+++ b/src/pshinter/pshalgo1.h
@@ -88,7 +88,8 @@ FT_BEGIN_HEADER
extern FT_Error
ps1_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
- PSH_Globals globals );
+ PSH_Globals globals,
+ FT_UInt32 hint_flags );
#ifdef DEBUG_HINTER
diff --git a/src/pshinter/pshalgo2.c b/src/pshinter/pshalgo2.c
index 2eb8b8caf..b8ece3cf2 100644
--- a/src/pshinter/pshalgo2.c
+++ b/src/pshinter/pshalgo2.c
@@ -1494,7 +1494,8 @@
FT_Error
ps2_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
- PSH_Globals globals )
+ PSH_Globals globals,
+ FT_UInt32 hint_flags )
{
PSH2_GlyphRec glyphrec;
PSH2_Glyph glyph = &glyphrec;
@@ -1504,6 +1505,7 @@
#endif
FT_Int dimension;
+ FT_UNUSED( hint_flags );
#ifdef DEBUG_HINTER
memory = globals->memory;
diff --git a/src/pshinter/pshalgo2.h b/src/pshinter/pshalgo2.h
index 5d6a61ee7..408cd951a 100644
--- a/src/pshinter/pshalgo2.h
+++ b/src/pshinter/pshalgo2.h
@@ -190,7 +190,8 @@ FT_BEGIN_HEADER
extern FT_Error
ps2_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
- PSH_Globals globals );
+ PSH_Globals globals,
+ FT_UInt32 hint_flags );
FT_END_HEADER
diff --git a/src/pshinter/pshalgo3.c b/src/pshinter/pshalgo3.c
index afc357ecf..35b8ad05e 100644
--- a/src/pshinter/pshalgo3.c
+++ b/src/pshinter/pshalgo3.c
@@ -34,7 +34,7 @@
#undef SNAP_STEMS
#undef ONLY_ALIGN_Y
-
+
/*************************************************************************/
@@ -359,11 +359,11 @@
static FT_Fixed
psh3_hint_snap_stem_side_delta ( FT_Fixed pos,
- FT_Fixed len )
+ FT_Fixed len )
{
FT_Fixed delta1 = ( ( pos + 32 ) & -64 ) - pos;
FT_Fixed delta2 = ( ( pos + len + 32 ) & -64 ) - pos - len;
-
+
if ( ABS( delta1 ) <= ABS( delta2 ) )
{
return delta1;
@@ -378,7 +378,8 @@
static void
psh3_hint_align( PSH3_Hint hint,
PSH_Globals globals,
- FT_Int dimension )
+ FT_Int dimension,
+ FT_UInt32 hint_flags )
{
PSH_Dimension dim = &globals->dimension[dimension];
FT_Fixed scale = dim->scale_mult;
@@ -390,22 +391,38 @@
FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta;
FT_Pos len = FT_MulFix( hint->org_len, scale );
-#ifdef SNAP_STEMS
- FT_Pos fit_center;
- FT_Pos fit_len;
-
+ FT_Pos fit_center;
+ FT_Pos fit_len;
PSH_AlignmentRec align;
- /* compute fitted width/height */
- fit_len = 0;
- if ( hint->org_len )
+
+ /* ignore stem alignments when requested through the hint flags */
+ if ( ( dimension == 0 && ( hint_flags & FT_HINT_NO_VSTEM_ALIGN ) != 0 ) ||
+ ( dimension == 1 && ( hint_flags & FT_HINT_NO_HSTEM_ALIGN ) != 0 ) )
{
- fit_len = psh_dimension_snap_width( dim, hint->org_len );
- if ( fit_len < 64 )
- fit_len = 64;
- else
- fit_len = ( fit_len + 32 ) & -64;
+ hint->cur_pos = pos;
+ hint->cur_len = len;
+
+ psh3_hint_set_fitted( hint );
+ return;
+ }
+
+ /* perform stem snapping when requested */
+ if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 )
+ {
+ /* compute fitted width/height */
+ fit_len = 0;
+ if ( hint->org_len )
+ {
+ fit_len = psh_dimension_snap_width( dim, hint->org_len );
+ if ( fit_len < 64 )
+ fit_len = 64;
+ else
+ fit_len = ( fit_len + 32 ) & -64;
+ }
}
+ else
+ fit_len = len;
hint->cur_len = fit_len;
@@ -450,182 +467,113 @@
/* ensure that parent is already fitted */
if ( !psh3_hint_is_fitted( parent ) )
- psh3_hint_align( parent, globals, dimension );
+ psh3_hint_align( parent, globals, dimension, hint_flags );
par_org_center = parent->org_pos + ( parent->org_len / 2);
par_cur_center = parent->cur_pos + ( parent->cur_len / 2);
cur_org_center = hint->org_pos + ( hint->org_len / 2);
cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
-#if 0
- if ( cur_delta >= 0 )
- cur_delta = ( cur_delta + 16 ) & -64;
- else
- cur_delta = -( (-cur_delta + 16 ) & -64 );
-#endif
- pos = par_cur_center + cur_delta - ( len >> 1 );
+ pos = par_cur_center + cur_delta - ( len >> 1 );
}
- /* normal processing */
- if ( ( fit_len / 64 ) & 1 )
+ if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 )
{
- /* odd number of pixels */
- fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32;
+ /* normal processing */
+ if ( ( fit_len / 64 ) & 1 )
+ {
+ /* odd number of pixels */
+ fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32;
+ }
+ else
+ {
+ /* even number of pixels */
+ fit_center = ( pos + ( len >> 1 ) + 32 ) & -64;
+ }
+ hint->cur_pos = fit_center - ( fit_len >> 1 );
}
else
{
- /* even number of pixels */
- fit_center = ( pos + ( len >> 1 ) + 32 ) & -64;
- }
-
- hint->cur_pos = fit_center - ( fit_len >> 1 );
- }
- }
-#else
- PSH_AlignmentRec align;
-
- hint->cur_len = len;
-
- /* check blue zones for horizontal stems */
- align.align = PSH_BLUE_ALIGN_NONE;
- align.align_bot = align.align_top = 0;
-
- if ( dimension == 1 )
- psh_blues_snap_stem( &globals->blues,
- hint->org_pos + hint->org_len,
- hint->org_pos,
- &align );
-#ifdef ONLY_ALIGN_Y
- else
- {
- hint->cur_pos = pos;
- return;
- }
-#endif
-
- switch ( align.align )
- {
- case PSH_BLUE_ALIGN_TOP:
- /* the top of the stem is aligned against a blue zone */
- hint->cur_pos = align.align_top - len;
- break;
-
- case PSH_BLUE_ALIGN_BOT:
- /* the bottom of the stem is aligned against a blue zone */
- hint->cur_pos = align.align_bot;
- break;
-
- case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
- /* both edges of the stem are aligned against blue zones */
- hint->cur_pos = align.align_bot;
- hint->cur_len = align.align_top - align.align_bot;
- break;
-
- default:
- {
- PSH3_Hint parent = hint->parent;
-
- if ( parent )
- {
- FT_Pos par_org_center, par_cur_center;
- FT_Pos cur_org_center, cur_delta;
+ /* Stems less than one pixel wide are easy - we want to
+ * make them as dark as possible, so they must fall within
+ * one pixel. If the stem is split between two pixels
+ * then snap the edge that is nearer to the pixel boundary
+ * to the pixel boundary
+ */
+ if (len <= 64)
+ {
+ if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 )
+ pos += psh3_hint_snap_stem_side_delta ( pos, len );
+ }
+ /* Position stems other to minimize the amount of mid-grays.
+ * There are, in general, two positions that do this,
+ * illustrated as A) and B) below.
+ *
+ * + + + +
+ *
+ * A) |--------------------------------|
+ * B) |--------------------------------|
+ * C) |--------------------------------|
+ *
+ * Position A) (split the excess stem equally) should be better
+ * for stems of width N + f where f < 0.5
+ *
+ * Position B) (split the deficiency equally) should be better
+ * for stems of width N + f where f > 0.5
+ *
+ * It turns out though that minimizing the total number of touched
+ * pixels is also important, so position C), with one edge
+ * aligned with a pixel boundary is actually preferable
+ * to A). There are also more possible positions for C) than
+ * for A) or B), so there will be less distortion of the overall
+ * character shape.
+ */
+ else
+ {
+ FT_Fixed frac_len = len & 63;
+ FT_Fixed center = pos + ( len >> 1 );
+ FT_Fixed delta_a, delta_b;
- /* ensure that parent is already fitted */
- if ( !psh3_hint_is_fitted( parent ) )
- psh3_hint_align( parent, globals, dimension );
+ if ( ( len / 64 ) & 1 )
+ {
+ delta_a = ( center & -64 ) + 32 - center;
+ delta_b = ( ( center + 32 ) & - 64 ) - center;
+ }
+ else
+ {
+ delta_a = ( ( center + 32 ) & - 64 ) - center;
+ delta_b = ( center & -64 ) + 32 - center;
+ }
- par_org_center = parent->org_pos + ( parent->org_len / 2);
- par_cur_center = parent->cur_pos + ( parent->cur_len / 2);
- cur_org_center = hint->org_pos + ( hint->org_len / 2);
+ /* We choose between B) and C) above based on the amount
+ * of fractional stem width: for small amounts, choose
+ * C) always; for large amounts, B) always; inbetween,
+ * pick whichever one involves less stem movement.
+ */
+ if (frac_len < 32)
+ {
+ pos += psh3_hint_snap_stem_side_delta ( pos, len );
+ }
+ else if (frac_len < 48)
+ {
+ FT_Fixed side_delta = psh3_hint_snap_stem_side_delta ( pos, len );
- cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
- pos = par_cur_center + cur_delta - ( len >> 1 );
+ if ( ABS( side_delta ) < ABS( delta_b ) )
+ pos += side_delta;
+ else
+ pos += delta_b;
+ }
+ else
+ {
+ pos += delta_b;
+ }
+ }
+ hint->cur_pos = pos;
}
-
- {
- /* Stems less than one pixel wide are easy - we want to
- * make them as dark as possible, so they must fall within
- * one pixel. If the stem is split between two pixels
- * then snap the edge that is nearer to the pixel boundary
- * to the pixel boundary
- */
- if (len <= 64)
- {
- if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 )
- pos += psh3_hint_snap_stem_side_delta ( pos, len );
- }
- /* Position stems other to minimize the amount of mid-grays.
- * There are, in general, two positions that do this,
- * illustrated as A) and B) below.
- *
- * + + + +
- *
- * A) |--------------------------------|
- * B) |--------------------------------|
- * C) |--------------------------------|
- *
- * Position A) (split the excess stem equally) should be better
- * for stems of width N + f where f < 0.5
- *
- * Position B) (split the deficiency equally) should be better
- * for stems of width N + f where f > 0.5
- *
- * It turns out though that minimizing the total number of lit
- * pixels is also important, so position C), with one edge
- * aligned with a pixel boundary is actually preferable
- * to A). There are also more possibile positions for C) than
- * for A) or B), so it involves less distortion of the overall
- * character shape.
- */
- else
- {
- FT_Fixed frac_len = len & 63;
- FT_Fixed center = pos + ( len >> 1 );
-
- FT_Fixed delta_a, delta_b;
-
- if ( ( len / 64 ) & 1 )
- {
- delta_a = ( center & -64 ) + 32 - center;
- delta_b = ( ( center + 32 ) & - 64 ) - center;
- }
- else
- {
- delta_a = ( ( center + 32 ) & - 64 ) - center;
- delta_b = ( center & -64 ) + 32 - center;
- }
-
- /* We choose between B) and C) above based on the amount
- * of fractinal stem width; for small amounts, choose
- * C) always, for large amounts, B) always, and inbetween,
- * pick whichever one involves less stem movement.
- */
- if (frac_len < 32)
- {
- pos += psh3_hint_snap_stem_side_delta ( pos, len );
- }
- else if (frac_len < 48)
- {
- FT_Fixed side_delta = psh3_hint_snap_stem_side_delta ( pos, len );
-
- if ( ABS( side_delta ) < ABS( delta_b ) )
- pos += side_delta;
- else
- pos += delta_b;
- }
- else
- {
- pos += delta_b;
- }
- }
- }
-
- hint->cur_pos = pos;
- }
+ }
}
-#endif
-
+
psh3_hint_set_fitted( hint );
#ifdef DEBUG_HINTER
@@ -639,7 +587,8 @@
static void
psh3_hint_table_align_hints( PSH3_Hint_Table table,
PSH_Globals globals,
- FT_Int dimension )
+ FT_Int dimension,
+ FT_UInt32 hint_flags )
{
PSH3_Hint hint;
FT_UInt count;
@@ -667,7 +616,7 @@
count = table->max_hints;
for ( ; count > 0; count--, hint++ )
- psh3_hint_align( hint, globals, dimension );
+ psh3_hint_align( hint, globals, dimension, hint_flags );
}
@@ -705,230 +654,6 @@
#endif
-#if 0
- /* setup interpolation zones once the hints have been grid-fitted */
- /* by the optimizer */
- static void
- psh3_hint_table_setup_zones( PSH3_Hint_Table table,
- FT_Fixed scale,
- FT_Fixed delta )
- {
- FT_UInt count;
- PSH3_Zone zone;
- PSH3_Hint *sort, hint, hint2;
-
-
- zone = table->zones;
-
- /* special case, no hints defined */
- if ( table->num_hints == 0 )
- {
- zone->scale = scale;
- zone->delta = delta;
- zone->min = PSH3_ZONE_MIN;
- zone->max = PSH3_ZONE_MAX;
-
- table->num_zones = 1;
- table->zone = zone;
- return;
- }
-
- /* the first zone is before the first hint */
- /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */
- sort = table->sort;
- hint = sort[0];
-
- zone->scale = scale;
- zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale );
- zone->min = PSH3_ZONE_MIN;
- zone->max = hint->org_pos;
-
- psh3_print_zone( zone );
-
- zone++;
-
- for ( count = table->num_hints; count > 0; count-- )
- {
- FT_Fixed scale2;
-
-
- if ( hint->org_len > 0 )
- {
- /* setup a zone for inner-stem interpolation */
- /* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0) */
- /* x' = x*s2 + x0' - x0*s2 */
-
- scale2 = FT_DivFix( hint->cur_len, hint->org_len );
- zone->scale = scale2;
- zone->min = hint->org_pos;
- zone->max = hint->org_pos + hint->org_len;
- zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 );
-
- psh3_print_zone( zone );
-
- zone++;
- }
-
- if ( count == 1 )
- break;
-
- sort++;
- hint2 = sort[0];
-
- /* setup zone for inter-stem interpolation */
- /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */
- /* x' = x*s3 + x1' - x1*s3 */
-
- scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len),
- hint2->org_pos - (hint->org_pos + hint->org_len) );
- zone->scale = scale2;
- zone->min = hint->org_pos + hint->org_len;
- zone->max = hint2->org_pos;
- zone->delta = hint->cur_pos + hint->cur_len -
- FT_MulFix( zone->min, scale2 );
-
- psh3_print_zone( zone );
-
- zone++;
-
- hint = hint2;
- }
-
- /* the last zone */
- zone->scale = scale;
- zone->min = hint->org_pos + hint->org_len;
- zone->max = PSH3_ZONE_MAX;
- zone->delta = hint->cur_pos + hint->cur_len -
- FT_MulFix( zone->min, scale );
-
- psh3_print_zone( zone );
-
- zone++;
-
- table->num_zones = zone - table->zones;
- table->zone = table->zones;
- }
-#endif
-
-#if 0
- /* tune a single coordinate with the current interpolation zones */
- static FT_Pos
- psh3_hint_table_tune_coord( PSH3_Hint_Table table,
- FT_Int coord )
- {
- PSH3_Zone zone;
-
-
- zone = table->zone;
-
- if ( coord < zone->min )
- {
- do
- {
- if ( zone == table->zones )
- break;
-
- zone--;
-
- } while ( coord < zone->min );
- table->zone = zone;
- }
- else if ( coord > zone->max )
- {
- do
- {
- if ( zone == table->zones + table->num_zones - 1 )
- break;
-
- zone++;
-
- } while ( coord > zone->max );
- table->zone = zone;
- }
-
- return FT_MulFix( coord, zone->scale ) + zone->delta;
- }
-#endif
-
-#if 0
- /* tune a given outline with current interpolation zones */
- /* the function only works in a single dimension.. */
- static void
- psh3_hint_table_tune_outline( PSH3_Hint_Table table,
- FT_Outline* outline,
- PSH_Globals globals,
- FT_Int dimension )
-
- {
- FT_UInt count, first, last;
- PS_Mask_Table hint_masks = table->hint_masks;
- PS_Mask mask;
- PSH_Dimension dim = &globals->dimension[dimension];
- FT_Fixed scale = dim->scale_mult;
- FT_Fixed delta = dim->scale_delta;
-
-
- if ( hint_masks && hint_masks->num_masks > 0 )
- {
- first = 0;
- mask = hint_masks->masks;
- count = hint_masks->num_masks;
-
- for ( ; count > 0; count--, mask++ )
- {
- last = mask->end_point;
-
- if ( last > first )
- {
- FT_Vector* vec;
- FT_Int count2;
-
-
- psh3_hint_table_activate_mask( table, mask );
- psh3_hint_table_optimize( table, globals, outline, dimension );
- psh3_hint_table_setup_zones( table, scale, delta );
- last = mask->end_point;
-
- vec = outline->points + first;
- count2 = last - first;
-
- for ( ; count2 > 0; count2--, vec++ )
- {
- FT_Pos x, *px;
-
-
- px = dimension ? &vec->y : &vec->x;
- x = *px;
-
- *px = psh3_hint_table_tune_coord( table, (FT_Int)x );
- }
- }
-
- first = last;
- }
- }
- else /* no hints in this glyph, simply scale the outline */
- {
- FT_Vector* vec;
-
-
- vec = outline->points;
- count = outline->n_points;
-
- if ( dimension == 0 )
- {
- for ( ; count > 0; count--, vec++ )
- vec->x = FT_MulFix( vec->x, scale ) + delta;
- }
- else
- {
- for ( ; count > 0; count--, vec++ )
- vec->y = FT_MulFix( vec->y, scale ) + delta;
- }
- }
- }
-#endif
-
/*************************************************************************/
/*************************************************************************/
@@ -1661,7 +1386,8 @@
FT_Error
ps3_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
- PSH_Globals globals )
+ PSH_Globals globals,
+ FT_UInt32 hint_flags )
{
PSH3_GlyphRec glyphrec;
PSH3_Glyph glyph = &glyphrec;
@@ -1699,7 +1425,8 @@
/* compute aligned stem/hints positions */
psh3_hint_table_align_hints( &glyph->hint_tables[dimension],
glyph->globals,
- dimension );
+ dimension,
+ hint_flags );
/* find strong points, align them, then interpolate others */
psh3_glyph_find_strong_points( glyph, dimension );
diff --git a/src/pshinter/pshalgo3.h b/src/pshinter/pshalgo3.h
index 4d4abb733..6ad637185 100644
--- a/src/pshinter/pshalgo3.h
+++ b/src/pshinter/pshalgo3.h
@@ -190,7 +190,8 @@ FT_BEGIN_HEADER
extern FT_Error
ps3_hints_apply( PS_Hints ps_hints,
FT_Outline* outline,
- PSH_Globals globals );
+ PSH_Globals globals,
+ FT_UInt32 hint_flags );
FT_END_HEADER