From d1245c0dd28f3604e266b44e7b3ff0108ae0c806 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 27 Aug 2002 22:34:20 +0000 Subject: [PATCH] updating sources to support the new FT_LOAD_TARGET_ constants to support target-specific hinting --- include/freetype/internal/autohint.h | 2 +- include/freetype/internal/psaux.h | 2 + include/freetype/internal/pshints.h | 16 +- src/autohint/ahhint.c | 215 +++++++++++++-------------- src/autohint/ahhint.h | 6 +- src/autohint/ahmodule.c | 2 +- src/autohint/ahtypes.h | 5 + src/cff/cffgload.c | 20 ++- src/cff/cffgload.h | 15 +- src/cid/cidgload.c | 3 +- src/cid/cidgload.h | 2 +- src/psaux/t1decode.c | 6 +- src/psaux/t1decode.h | 1 + src/pshinter/pshalgo1.c | 10 +- src/pshinter/pshalgo1.h | 8 +- src/pshinter/pshalgo2.c | 10 +- src/pshinter/pshalgo2.h | 8 +- src/pshinter/pshalgo3.c | 41 +++-- src/pshinter/pshalgo3.h | 13 +- src/type1/t1gload.c | 4 +- src/type1/t1gload.h | 2 +- 21 files changed, 213 insertions(+), 178 deletions(-) diff --git a/include/freetype/internal/autohint.h b/include/freetype/internal/autohint.h index cf1568e45..22340afc3 100644 --- a/include/freetype/internal/autohint.h +++ b/include/freetype/internal/autohint.h @@ -176,7 +176,7 @@ FT_BEGIN_HEADER FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, - FT_ULong load_flags ); + FT_Int32 load_flags ); /*************************************************************************/ diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h index fbb743496..e79f83aa4 100644 --- a/include/freetype/internal/psaux.h +++ b/include/freetype/internal/psaux.h @@ -610,6 +610,7 @@ FT_BEGIN_HEADER FT_Byte** glyph_names, PS_Blend blend, FT_Bool hinting, + FT_Render_Mode hint_mode, T1_Decoder_Callback callback ); void @@ -652,6 +653,7 @@ FT_BEGIN_HEADER PS_Blend blend; /* for multiple master support */ FT_UInt32 hint_flags; + FT_Render_Mode hint_mode; T1_Decoder_Callback parse_callback; T1_Decoder_FuncsRec funcs; diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h index 5af27b133..15571d9bc 100644 --- a/include/freetype/internal/pshints.h +++ b/include/freetype/internal/pshints.h @@ -280,10 +280,10 @@ FT_BEGIN_HEADER /* which must correspond to the same font as the glyph. */ /* */ typedef FT_Error - (*T1_Hints_ApplyFunc)( T1_Hints hints, - FT_Outline* outline, - PSH_Globals globals, - FT_UInt32 hint_flags ); + (*T1_Hints_ApplyFunc)( T1_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); /*************************************************************************/ @@ -561,10 +561,10 @@ FT_BEGIN_HEADER /* which must correspond to the same font than the glyph. */ /* */ typedef FT_Error - (*T2_Hints_ApplyFunc)( T2_Hints hints, - FT_Outline* outline, - PSH_Globals globals, - FT_UInt32 hint_flags ); + (*T2_Hints_ApplyFunc)( T2_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); /*************************************************************************/ diff --git a/src/autohint/ahhint.c b/src/autohint/ahhint.c index e9fcedb42..33d65c6b0 100644 --- a/src/autohint/ahhint.c +++ b/src/autohint/ahhint.c @@ -40,7 +40,6 @@ /*************************************************************************/ /*************************************************************************/ -#if 0 /* snap a given width in scaled coordinates to one of the */ /* current standard widths */ static FT_Pos @@ -86,11 +85,11 @@ return width; } -#endif + /* compute the snapped width of a given stem */ static FT_Pos - ah_compute_stem_width( AH_Hinter hinter, + ah_compute_stem_width( AH_Hinter hinter, int vertical, FT_Pos width ) { @@ -105,85 +104,93 @@ sign = 1; } -#if 1 - if ( dist < 64 ) - dist = 64; - + if ( ( vertical && hinter->no_vert_snapping ) || + ( !vertical && hinter->no_horz_snapping ) ) { - FT_Pos delta = dist - globals->stds[vertical]; - - - if ( delta < 0 ) - delta = -delta; - - if ( delta < 40 ) - { - dist = globals->stds[vertical]; - if ( dist < 32 ) - dist = 32; - } - - if ( dist < 3 * 64 ) - { - delta = ( dist & 63 ); - dist &= -64; - - if ( delta < 10 ) - dist += delta; - - else if ( delta < 32 ) - dist += 10; - - else if ( delta < 54 ) - dist += 54; - - else - dist += delta; - } - else - dist = ( dist + 32 ) & -64; - } -#else - if ( vertical ) - { - dist = ah_snap_width( globals->heights, globals->num_heights, dist ); - - /* in the case of vertical hinting, always round */ - /* the stem heights to integer pixels */ - if ( dist >= 64 ) - dist = ( dist + 16 ) & -64; - else + /* smooth hinting process, very lightly quantize the stem width */ + /* */ + if ( dist < 64 ) dist = 64; + + { + FT_Pos delta = dist - globals->stds[vertical]; + + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = globals->stds[vertical]; + if ( dist < 32 ) + dist = 32; + } + + if ( dist < 3 * 64 ) + { + delta = ( dist & 63 ); + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & -64; + } } else { - dist = ah_snap_width( globals->widths, globals->num_widths, dist ); - - if ( hinter->flags & AH_HINTER_MONOCHROME ) + /* strong hinting process, snap the stem width to integer pixels */ + /* */ + if ( vertical ) { - /* monochrome horizontal hinting: snap widths to integer pixels */ - /* with a different threshold */ - if ( dist < 64 ) - dist = 64; + dist = ah_snap_width( globals->heights, globals->num_heights, dist ); + + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + if ( dist >= 64 ) + dist = ( dist + 16 ) & -64; else - dist = ( dist + 32 ) & -64; + dist = 64; } else { - /* for horizontal anti-aliased hinting, we adopt a more subtle */ - /* approach: we strengthen small stems, round stems whose size */ - /* is between 1 and 2 pixels to an integer, otherwise nothing */ - if ( dist < 48 ) - dist = ( dist + 64 ) >> 1; - - else if ( dist < 128 ) - dist = ( dist + 22 ) & -64; + dist = ah_snap_width( globals->widths, globals->num_widths, dist ); + + if ( hinter->flags & AH_HINTER_MONOCHROME ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & -64; + } else - /* XXX: round otherwise, prevent color fringes in LCD mode */ - dist = ( dist + 32 ) & -64; + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + dist = ( dist + 22 ) & -64; + else + /* XXX: round otherwise, prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & -64; + } } } -#endif if ( sign ) dist = -dist; @@ -278,10 +285,10 @@ int has_serifs = 0; - if ( ah_debug_disable_vert && !dimension ) + if ( hinter->no_horz_hints && !dimension ) goto Next_Dimension; - if ( ah_debug_disable_horz && dimension ) + if ( hinter->no_vert_hints && dimension ) goto Next_Dimension; /* we begin by aligning all stems relative to the blue zone */ @@ -467,38 +474,13 @@ FT_LOCAL_DEF( void ) - ah_hinter_hint_edges( AH_Hinter hinter, - FT_Bool no_horz_edges, - FT_Bool no_vert_edges ) + ah_hinter_hint_edges( AH_Hinter hinter ) { -#if 0 - ah_debug_disable_horz = no_horz_edges; - ah_debug_disable_vert = no_vert_edges; -#else - FT_UNUSED( no_horz_edges ); - FT_UNUSED( no_vert_edges ); -#endif /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */ /* reduce the problem of the disappearing eye in the `e' of Times... */ /* also, creates some artifacts near the blue zones? */ { ah_hint_edges_3( hinter ); - -#if 0 - /* outline optimizer removed temporarily */ - if ( hinter->flags & AH_HINTER_OPTIMIZE ) - { - AH_Optimizer opt; - - - if ( !AH_Optimizer_Init( &opt, hinter->glyph, hinter->memory ) ) - { - AH_Optimizer_Compute( &opt ); - AH_Optimizer_Done( &opt ); - } - } -#endif - } } @@ -1048,7 +1030,7 @@ /* create a face's autohint globals */ FT_LOCAL_DEF( FT_Error ) - ah_hinter_new_face_globals( AH_Hinter hinter, + ah_hinter_new_face_globals( AH_Hinter hinter, FT_Face face, AH_Globals globals ) { @@ -1091,9 +1073,9 @@ static FT_Error - ah_hinter_load( AH_Hinter hinter, + ah_hinter_load( AH_Hinter hinter, FT_UInt glyph_index, - FT_UInt load_flags, + FT_Int32 load_flags, FT_UInt depth ) { FT_Face face = hinter->face; @@ -1104,11 +1086,6 @@ FT_Error error; AH_Outline outline = hinter->glyph; AH_Loader gloader = hinter->loader; - FT_Bool no_horz_hints = FT_BOOL( - ( load_flags & AH_HINT_NO_HORZ_EDGES ) != 0 ); - FT_Bool no_vert_hints = FT_BOOL( - ( load_flags & AH_HINT_NO_VERT_EDGES ) != 0 ); - /* load the glyph */ error = FT_Load_Glyph( face, glyph_index, load_flags ); @@ -1191,14 +1168,14 @@ /* perform feature detection */ ah_outline_detect_features( outline ); - if ( !no_horz_hints ) + if ( !hinter->no_vert_hints ) { ah_outline_compute_blue_edges( outline, hinter->globals ); ah_outline_scale_blue_edges( outline, hinter->globals ); } /* perform alignment control */ - ah_hinter_hint_edges( hinter, no_horz_hints, no_vert_hints ); + ah_hinter_hint_edges( hinter ); ah_hinter_align( hinter ); /* now save the current outline into the loader's current table */ @@ -1421,17 +1398,18 @@ /* load and hint a given glyph */ FT_LOCAL_DEF( FT_Error ) - ah_hinter_load_glyph( AH_Hinter hinter, + ah_hinter_load_glyph( AH_Hinter hinter, FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, - FT_Int load_flags ) + FT_Int32 load_flags ) { FT_Face face = slot->face; FT_Error error; FT_Fixed x_scale = size->metrics.x_scale; FT_Fixed y_scale = size->metrics.y_scale; AH_Face_Globals face_globals = FACE_GLOBALS( face ); + FT_Render_Mode hint_mode = FT_LOAD_TARGET_MODE(load_flags); /* first of all, we need to check that we're using the correct face and */ @@ -1459,6 +1437,25 @@ ah_loader_rewind( hinter->loader ); + /* reset hinting flags according to load flags and current render target */ + hinter->no_horz_hints = FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT ); + hinter->no_vert_hints = FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT ); + +#ifdef DEBUG_HINTER + hinter->no_horz_hints = ah_debug_disable_vert; /* not a bug, the meaning */ + hinter->no_vert_hints = ah_debug_disable_horz; /* of h/v is inverted !! */ +#endif + + /* we snap the width of vertical stems for the monochrome and horizontal */ + /* LCD rendering targets only. Corresponds to X snapping */ + hinter->no_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL || + hint_mode == FT_RENDER_MODE_LCD_V ); + + /* we snap the width of horizontal stems for the monochrome and vertical */ + /* LCD rendering targets only. Corresponds to Y snapping */ + hinter->no_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL || + hint_mode == FT_RENDER_MODE_LCD ); + #if 1 load_flags = FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM ; diff --git a/src/autohint/ahhint.h b/src/autohint/ahhint.h index 88b950fc2..d190eb43a 100644 --- a/src/autohint/ahhint.h +++ b/src/autohint/ahhint.h @@ -32,8 +32,8 @@ FT_BEGIN_HEADER #define AH_HINT_DEFAULT 0 #define AH_HINT_NO_ALIGNMENT 1 -#define AH_HINT_NO_HORZ_EDGES 0x20000L -#define AH_HINT_NO_VERT_EDGES 0x40000L +#define AH_HINT_NO_HORZ_EDGES 0x200000L /* temporary hack */ +#define AH_HINT_NO_VERT_EDGES 0x400000L /* temporary hack */ /* create a new empty hinter object */ @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, - FT_Int load_flags ); + FT_Int32 load_flags ); /* finalize a hinter object */ FT_LOCAL( void ) diff --git a/src/autohint/ahmodule.c b/src/autohint/ahmodule.c index c44e3965f..eb4ab1cff 100644 --- a/src/autohint/ahmodule.c +++ b/src/autohint/ahmodule.c @@ -69,7 +69,7 @@ FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, - FT_ULong load_flags ) + FT_Int32 load_flags ) { return ah_hinter_load_glyph( module->hinter, slot, size, glyph_index, load_flags ); diff --git a/src/autohint/ahtypes.h b/src/autohint/ahtypes.h index de053e90e..04f9b292b 100644 --- a/src/autohint/ahtypes.h +++ b/src/autohint/ahtypes.h @@ -491,6 +491,11 @@ FT_BEGIN_HEADER FT_Vector trans_delta; FT_Matrix trans_matrix; + FT_Bool no_horz_hints; /* disable X hinting */ + FT_Bool no_vert_hints; /* disable Y hinting */ + FT_Bool no_horz_snapping; /* disable X stem size snapping */ + FT_Bool no_vert_snapping; /* disable Y stem size snapping */ + } AH_HinterRec, *AH_Hinter; diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c index c9098fc66..f24da51a7 100644 --- a/src/cff/cffgload.c +++ b/src/cff/cffgload.c @@ -347,11 +347,12 @@ /* slot :: The current glyph object. */ /* */ FT_LOCAL_DEF( void ) - cff_decoder_init( CFF_Decoder* decoder, - TT_Face face, - CFF_Size size, - CFF_GlyphSlot slot, - FT_Bool hinting ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode ) { CFF_Font cff = (CFF_Font)face->extra.data; @@ -366,6 +367,8 @@ decoder->num_globals = cff->num_global_subrs; decoder->globals = cff->global_subrs; decoder->globals_bias = cff_compute_bias( decoder->num_globals ); + + decoder->hint_mode = hint_mode; } @@ -2203,7 +2206,7 @@ *max_advance = 0; /* Initialize load decoder */ - cff_decoder_init( &decoder, face, 0, 0, 0 ); + cff_decoder_init( &decoder, face, 0, 0, 0, 0 ); decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; @@ -2262,7 +2265,7 @@ cff_slot_load( CFF_GlyphSlot glyph, CFF_Size size, FT_Int glyph_index, - FT_Int load_flags ) + FT_Int32 load_flags ) { FT_Error error; CFF_Decoder decoder; @@ -2298,7 +2301,8 @@ FT_ULong charstring_len; - cff_decoder_init( &decoder, face, size, glyph, hinting ); + cff_decoder_init( &decoder, face, size, glyph, hinting, + FT_LOAD_TARGET_MODE(load_flags) ); decoder.builder.no_recurse = (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h index c9748379e..146cfddb7 100644 --- a/src/cff/cffgload.h +++ b/src/cff/cffgload.h @@ -168,15 +168,18 @@ FT_BEGIN_HEADER FT_Byte** glyph_names; /* for pure CFF fonts only */ FT_UInt num_glyphs; /* number of glyphs in font */ + FT_Render_Mode hint_mode; + } CFF_Decoder; FT_LOCAL( void ) - cff_decoder_init( CFF_Decoder* decoder, - TT_Face face, - CFF_Size size, - CFF_GlyphSlot slot, - FT_Bool hinting ); + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode ); FT_LOCAL( void ) cff_decoder_prepare( CFF_Decoder* decoder, @@ -200,7 +203,7 @@ FT_BEGIN_HEADER cff_slot_load( CFF_GlyphSlot glyph, CFF_Size size, FT_Int glyph_index, - FT_Int load_flags ); + FT_Int32 load_flags ); FT_END_HEADER diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c index b5b58f123..c5b2ecf2c 100644 --- a/src/cid/cidgload.c +++ b/src/cid/cidgload.c @@ -272,7 +272,7 @@ cid_slot_load_glyph( CID_GlyphSlot glyph, CID_Size size, FT_Int glyph_index, - FT_Int load_flags ) + FT_Int32 load_flags ) { FT_Error error; T1_DecoderRec decoder; @@ -306,6 +306,7 @@ 0, /* glyph names -- XXX */ 0, /* blend == 0 */ hinting, + FT_LOAD_TARGET_MODE(load_flags), cid_load_glyph ); /* set up the decoder */ diff --git a/src/cid/cidgload.h b/src/cid/cidgload.h index 578b7c40e..93858e865 100644 --- a/src/cid/cidgload.h +++ b/src/cid/cidgload.h @@ -40,7 +40,7 @@ FT_BEGIN_HEADER cid_slot_load_glyph( CID_GlyphSlot glyph, CID_Size size, FT_Int glyph_index, - FT_Int load_flags ); + FT_Int32 load_flags ); FT_END_HEADER diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c index 5abc8cf9d..05193057f 100644 --- a/src/psaux/t1decode.c +++ b/src/psaux/t1decode.c @@ -752,8 +752,8 @@ /* apply hints to the loaded glyph outline now */ hinter->apply( hinter->hints, builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_flags ); + (PSH_Globals) builder->hints_globals, + decoder->hint_mode ); } /* add current outline to the glyph slot */ @@ -1122,6 +1122,7 @@ FT_Byte** glyph_names, PS_Blend blend, FT_Bool hinting, + FT_Render_Mode hint_mode, T1_Decoder_Callback parse_callback ) { FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); @@ -1148,6 +1149,7 @@ decoder->num_glyphs = face->num_glyphs; decoder->glyph_names = glyph_names; decoder->hint_flags = face->internal->hint_flags; + decoder->hint_mode = hint_mode; decoder->blend = blend; decoder->parse_callback = parse_callback; diff --git a/src/psaux/t1decode.h b/src/psaux/t1decode.h index 4540d4add..fcb853ce8 100644 --- a/src/psaux/t1decode.h +++ b/src/psaux/t1decode.h @@ -50,6 +50,7 @@ FT_BEGIN_HEADER FT_Byte** glyph_names, PS_Blend blend, FT_Bool hinting, + FT_Render_Mode hint_mode, T1_Decoder_Callback parse_glyph ); FT_LOCAL( void ) diff --git a/src/pshinter/pshalgo1.c b/src/pshinter/pshalgo1.c index 7f4d7e8ad..06da5977d 100644 --- a/src/pshinter/pshalgo1.c +++ b/src/pshinter/pshalgo1.c @@ -742,17 +742,17 @@ /*************************************************************************/ FT_Error - ps1_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_UInt32 hint_flags ) + ps1_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) { PSH1_Hint_TableRec hints; FT_Error error = 0; FT_Int dimension; - FT_UNUSED( hint_flags ); + FT_UNUSED( hint_mode ); for ( dimension = 1; dimension >= 0; dimension-- ) { diff --git a/src/pshinter/pshalgo1.h b/src/pshinter/pshalgo1.h index 1eae160b7..2f795a6a5 100644 --- a/src/pshinter/pshalgo1.h +++ b/src/pshinter/pshalgo1.h @@ -86,10 +86,10 @@ FT_BEGIN_HEADER extern FT_Error - ps1_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_UInt32 hint_flags ); + ps1_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); #ifdef DEBUG_HINTER diff --git a/src/pshinter/pshalgo2.c b/src/pshinter/pshalgo2.c index 65ff454e8..372ff287e 100644 --- a/src/pshinter/pshalgo2.c +++ b/src/pshinter/pshalgo2.c @@ -1492,10 +1492,10 @@ /*************************************************************************/ FT_Error - ps2_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_UInt32 hint_flags ) + ps2_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) { PSH2_GlyphRec glyphrec; PSH2_Glyph glyph = &glyphrec; @@ -1505,7 +1505,7 @@ #endif FT_Int dimension; - FT_UNUSED( hint_flags ); + FT_UNUSED( hint_mode ); #ifdef DEBUG_HINTER memory = globals->memory; diff --git a/src/pshinter/pshalgo2.h b/src/pshinter/pshalgo2.h index 408cd951a..405d34b56 100644 --- a/src/pshinter/pshalgo2.h +++ b/src/pshinter/pshalgo2.h @@ -188,10 +188,10 @@ FT_BEGIN_HEADER extern FT_Error - ps2_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_UInt32 hint_flags ); + ps2_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); FT_END_HEADER diff --git a/src/pshinter/pshalgo3.c b/src/pshinter/pshalgo3.c index 90009a556..0a178e04a 100644 --- a/src/pshinter/pshalgo3.c +++ b/src/pshinter/pshalgo3.c @@ -380,7 +380,7 @@ psh3_hint_align( PSH3_Hint hint, PSH_Globals globals, FT_Int dimension, - FT_UInt32 hint_flags ) + PSH3_Glyph glyph ) { PSH_Dimension dim = &globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; @@ -392,14 +392,15 @@ FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; FT_Pos len = FT_MulFix( hint->org_len, scale ); + FT_Int no_snapping; FT_Pos fit_center; FT_Pos fit_len; PSH_AlignmentRec align; /* 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 ) ) + if ( ( dimension == 0 && glyph->no_horz_hints ) || + ( dimension == 1 && glyph->no_vert_hints ) ) { hint->cur_pos = pos; hint->cur_len = len; @@ -409,7 +410,10 @@ } /* perform stem snapping when requested */ - if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 ) + no_snapping = ( dimension == 0 && !glyph->no_horz_snapping ) || + ( dimension == 1 && !glyph->no_vert_snapping ); + + if ( !no_snapping ) { /* compute fitted width/height */ fit_len = 0; @@ -468,7 +472,7 @@ /* ensure that parent is already fitted */ if ( !psh3_hint_is_fitted( parent ) ) - psh3_hint_align( parent, globals, dimension, hint_flags ); + psh3_hint_align( parent, globals, dimension, glyph ); par_org_center = parent->org_pos + ( parent->org_len >> 1 ); par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 ); @@ -478,7 +482,7 @@ pos = par_cur_center + cur_delta - ( len >> 1 ); } - if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 ) + if ( !no_snapping ) { /* normal processing */ if ( fit_len & 64 ) @@ -537,7 +541,7 @@ FT_Fixed delta_a, delta_b; - if ( ( len / 64 ) & 1 ) + if ( len & 64 ) { delta_a = ( center & -64 ) + 32 - center; delta_b = ( ( center + 32 ) & - 64 ) - center; @@ -587,7 +591,7 @@ psh3_hint_table_align_hints( PSH3_Hint_Table table, PSH_Globals globals, FT_Int dimension, - FT_UInt32 hint_flags ) + PSH3_Glyph glyph ) { PSH3_Hint hint; FT_UInt count; @@ -617,7 +621,7 @@ count = table->max_hints; for ( ; count > 0; count--, hint++ ) - psh3_hint_align( hint, globals, dimension, hint_flags ); + psh3_hint_align( hint, globals, dimension, glyph ); } @@ -1675,10 +1679,10 @@ /*************************************************************************/ FT_Error - ps3_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_UInt32 hint_flags ) + ps3_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) { PSH3_GlyphRec glyphrec; PSH3_Glyph glyph = &glyphrec; @@ -1706,6 +1710,15 @@ #endif /* DEBUG_HINTER */ + glyph->no_horz_hints = 0; + glyph->no_vert_hints = 0; + + glyph->no_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL || + hint_mode == FT_RENDER_MODE_LCD_V ); + + glyph->no_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL || + hint_mode == FT_RENDER_MODE_LCD ); + error = psh3_glyph_init( glyph, outline, ps_hints, globals ); if ( error ) goto Exit; @@ -1722,7 +1735,7 @@ psh3_hint_table_align_hints( &glyph->hint_tables[dimension], glyph->globals, dimension, - hint_flags ); + glyph ); /* 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 5813dc27c..a1a01db3d 100644 --- a/src/pshinter/pshalgo3.h +++ b/src/pshinter/pshalgo3.h @@ -217,6 +217,11 @@ FT_BEGIN_HEADER FT_Int major_dir; FT_Int minor_dir; + FT_Bool no_horz_hints; + FT_Bool no_vert_hints; + FT_Bool no_horz_snapping; + FT_Bool no_vert_snapping; + } PSH3_GlyphRec, *PSH3_Glyph; @@ -234,10 +239,10 @@ FT_BEGIN_HEADER extern FT_Error - ps3_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_UInt32 hint_flags ); + ps3_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); FT_END_HEADER diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index ecf85f6bc..91979040f 100644 --- a/src/type1/t1gload.c +++ b/src/type1/t1gload.c @@ -164,6 +164,7 @@ (FT_Byte**)type1->glyph_names, face->blend, 0, + 0, T1_Parse_Glyph ); if ( error ) return error; @@ -214,7 +215,7 @@ T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, FT_UInt glyph_index, - FT_Int load_flags ) + FT_Int32 load_flags ) { FT_Error error; T1_DecoderRec decoder; @@ -251,6 +252,7 @@ (FT_Byte**)type1->glyph_names, face->blend, FT_BOOL( hinting ), + FT_LOAD_TARGET_MODE(load_flags), T1_Parse_Glyph ); if ( error ) goto Exit; diff --git a/src/type1/t1gload.h b/src/type1/t1gload.h index 4b7ba5d62..0324a0d15 100644 --- a/src/type1/t1gload.h +++ b/src/type1/t1gload.h @@ -35,7 +35,7 @@ FT_BEGIN_HEADER T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, FT_UInt glyph_index, - FT_Int load_flags ); + FT_Int32 load_flags ); FT_END_HEADER