diff options
Diffstat (limited to 'src/pshinter/pshalgo2.c')
-rw-r--r-- | src/pshinter/pshalgo2.c | 555 |
1 files changed, 312 insertions, 243 deletions
diff --git a/src/pshinter/pshalgo2.c b/src/pshinter/pshalgo2.c index 86ede1d3c..4bfd3553c 100644 --- a/src/pshinter/pshalgo2.c +++ b/src/pshinter/pshalgo2.c @@ -1,3 +1,21 @@ +/***************************************************************************/ +/* */ +/* pshalgo2.c */ +/* */ +/* PostScript hinting algorithm 2 (body). */ +/* */ +/* Copyright 2001 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_OBJECTS_H #include FT_INTERNAL_DEBUG_H @@ -5,20 +23,21 @@ #ifdef DEBUG_HINTER - extern PSH2_Hint_Table ps2_debug_hint_table = 0; - extern PSH2_HintFunc ps2_debug_hint_func = 0; - extern PSH2_Glyph ps2_debug_glyph = 0; + extern PSH2_Hint_Table ps2_debug_hint_table = 0; + extern PSH2_HintFunc ps2_debug_hint_func = 0; + extern PSH2_Glyph ps2_debug_glyph = 0; #endif - /************************************************************************/ - /************************************************************************/ - /***** *****/ - /***** BASIC HINTS RECORDINGS *****/ - /***** *****/ - /************************************************************************/ - /************************************************************************/ - /* return true iff two stem hints overlap */ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC HINTS RECORDINGS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* return true iff two stem hints overlap */ static FT_Int psh2_hint_overlap( PSH2_Hint hint1, PSH2_Hint hint2 ) @@ -28,7 +47,7 @@ } - /* destroy hints table */ + /* destroy hints table */ static void psh2_hint_table_done( PSH2_Hint_Table table, FT_Memory memory ) @@ -45,28 +64,30 @@ } - /* deactivate all hints in a table */ + /* deactivate all hints in a table */ static void psh2_hint_table_deactivate( PSH2_Hint_Table table ) { FT_UInt count = table->max_hints; PSH2_Hint hint = table->hints; + for ( ; count > 0; count--, hint++ ) { - psh2_hint_deactivate(hint); + psh2_hint_deactivate( hint ); hint->order = -1; } } - /* internal function used to record a new hint */ + /* internal function used to record a new hint */ static void psh2_hint_table_record( PSH2_Hint_Table table, FT_UInt index ) { PSH2_Hint hint = table->hints + index; + if ( index >= table->max_hints ) { FT_ERROR(( "%s.activate: invalid hint index %d\n", index )); @@ -74,18 +95,19 @@ } /* ignore active hints */ - if ( psh2_hint_is_active(hint) ) + if ( psh2_hint_is_active( hint ) ) return; - psh2_hint_activate(hint); + psh2_hint_activate( hint ); /* now scan the current active hint set in order to determine */ - /* if we're overlapping with another segment.. */ + /* if we are overlapping with another segment */ { PSH2_Hint* sorted = table->sort_global; FT_UInt count = table->num_hints; PSH2_Hint hint2; + hint->parent = 0; for ( ; count > 0; count--, sorted++ ) { @@ -100,12 +122,10 @@ } if ( table->num_hints < table->max_hints ) - table->sort_global[ table->num_hints++ ] = hint; + table->sort_global[table->num_hints++] = hint; else - { - FT_ERROR(( "%s.activate: too many sorted hints !! BUG !!\n", + FT_ERROR(( "%s.activate: too many sorted hints! BUG!\n", "ps.fitter" )); - } } @@ -117,6 +137,7 @@ FT_Byte* cursor = hint_mask->bytes; FT_UInt index, limit; + limit = hint_mask->num_bits; for ( index = 0; index < limit; index++ ) @@ -135,7 +156,7 @@ } - /* create hints table */ + /* create hints table */ static FT_Error psh2_hint_table_init( PSH2_Hint_Table table, PS_Hint_Table hints, @@ -146,12 +167,13 @@ FT_UInt count = hints->num_hints; FT_Error error; - FT_UNUSED(counter_masks); + FT_UNUSED( counter_masks ); + /* allocate our tables */ - if ( ALLOC_ARRAY( table->sort, 2*count, PSH2_Hint ) || - ALLOC_ARRAY( table->hints, count, PSH2_HintRec ) || - ALLOC_ARRAY( table->zones, 2*count+1, PSH2_ZoneRec ) ) + if ( ALLOC_ARRAY( table->sort, 2 * count, PSH2_Hint ) || + ALLOC_ARRAY( table->hints, count, PSH2_HintRec ) || + ALLOC_ARRAY( table->zones, 2 * count + 1, PSH2_ZoneRec ) ) goto Exit; table->max_hints = count; @@ -160,10 +182,11 @@ table->num_zones = 0; table->zone = 0; - /* now, initialise the "hints" array */ + /* now, initialize the "hints" array */ { PSH2_Hint write = table->hints; - PS_Hint read = hints->hints; + PS_Hint read = hints->hints; + for ( ; count > 0; count--, write++, read++ ) { @@ -173,28 +196,30 @@ } } - /* we now need to determine the initial "parent" stems, first */ + /* we now need to determine the initial "parent" stems; first */ /* activate the hints that are given by the initial hint masks */ if ( hint_masks ) { - FT_UInt count = hint_masks->num_masks; - PS_Mask mask = hint_masks->masks; + FT_UInt Count = hint_masks->num_masks; + PS_Mask Mask = hint_masks->masks; + table->hint_masks = hint_masks; - for ( ; count > 0; count--, mask++ ) - psh2_hint_table_record_mask( table, mask ); + for ( ; Count > 0; Count--, Mask++ ) + psh2_hint_table_record_mask( table, Mask ); } /* now, do a linear parse in case some hints were left alone */ if ( table->num_hints != table->max_hints ) { - FT_UInt index, count; + FT_UInt Index, Count; - FT_ERROR(( "%s.init: missing/incorrect hint masks !!\n" )); + + FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" )); count = table->max_hints; - for ( index = 0; index < count; index++ ) - psh2_hint_table_record( table, index ); + for ( Index = 0; Index < Count; Index++ ) + psh2_hint_table_record( table, Index ); } Exit: @@ -202,7 +227,6 @@ } - static void psh2_hint_table_activate_mask( PSH2_Hint_Table table, PS_Mask hint_mask ) @@ -211,6 +235,7 @@ FT_Byte* cursor = hint_mask->bytes; FT_UInt index, limit, count; + limit = hint_mask->num_bits; count = 0; @@ -228,7 +253,8 @@ { PSH2_Hint hint = &table->hints[index]; - if ( !psh2_hint_is_active(hint) ) + + if ( !psh2_hint_is_active( hint ) ) { FT_UInt count2; @@ -240,10 +266,8 @@ { hint2 = sort[0]; if ( psh2_hint_overlap( hint, hint2 ) ) - { FT_ERROR(( "%s.activate_mask: found overlapping hints\n", "psf.hint" )); - } } #else count2 = 0; @@ -255,10 +279,8 @@ if ( count < table->max_hints ) table->sort[count++] = hint; else - { FT_ERROR(( "%s.activate_mask: too many active hints\n", "psf.hint" )); - } } } } @@ -267,56 +289,53 @@ } table->num_hints = count; - /* now, sort the hints, they're guaranteed to not overlap */ - /* so we can compare their "org_pos" field directly.. */ + /* now, sort the hints; they are guaranteed to not overlap */ + /* so we can compare their "org_pos" field directly */ { - FT_Int i1, i2; + FT_Int i1, i2; PSH2_Hint hint1, hint2; PSH2_Hint* sort = table->sort; + /* a simple bubble sort will do, since in 99% of cases, the hints */ - /* will be already sorted.. and the sort will be linear */ + /* will be already sorted -- and the sort will be linear */ for ( i1 = 1; i1 < (FT_Int)count; i1++ ) { hint1 = sort[i1]; - for ( i2 = i1-1; i2 >= 0; i2-- ) + for ( i2 = i1 - 1; i2 >= 0; i2-- ) { hint2 = sort[i2]; if ( hint2->org_pos < hint1->org_pos ) break; - sort[i2+1] = hint2; - sort[i2] = hint1; + sort[i2 + 1] = hint2; + sort[i2] = hint1; } } } } - - - - - - /************************************************************************/ - /************************************************************************/ - /***** *****/ - /***** HINTS GRID-FITTING AND OPTIMISATION *****/ - /***** *****/ - /************************************************************************/ - /************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ #ifdef DEBUG_HINTER static void ps2_simple_scale( PSH2_Hint_Table table, - FT_Fixed scale, - FT_Fixed delta, - FT_Int vertical ) + FT_Fixed scale, + FT_Fixed delta, + FT_Int vertical ) { PSH2_Hint hint; FT_UInt count; + for ( count = 0; count < table->max_hints; count++ ) { hint = table->hints + count; @@ -324,7 +343,7 @@ hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; hint->cur_len = FT_MulFix( hint->org_len, scale ); - if (ps2_debug_hint_func) + if ( ps2_debug_hint_func ) ps2_debug_hint_func( hint, vertical ); } } @@ -340,16 +359,18 @@ FT_Fixed scale = dim->scale_mult; FT_Fixed delta = dim->scale_delta; + if ( !psh2_hint_is_fitted(hint) ) { - FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; - FT_Pos len = FT_MulFix( hint->org_len, scale ); + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); - 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 ) @@ -358,7 +379,7 @@ if ( fit_len < 64 ) fit_len = 64; else - fit_len = (fit_len + 32 ) & -64; + fit_len = ( fit_len + 32 ) & -64; } hint->cur_len = fit_len; @@ -367,85 +388,79 @@ align.align = 0; align.align_bot = align.align_top = 0; - if (!vertical) - { + if ( !vertical ) psh_blues_snap_stem( &globals->blues, - hint->org_pos + hint->org_len, - hint->org_pos, - &align ); - } + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); - switch (align.align) + 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 - fit_len; - break; - } + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_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_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: + { + PSH2_Hint parent = hint->parent; - 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: + if ( parent ) { - PSH2_Hint parent = hint->parent; + FT_Pos par_org_center, par_cur_center; + FT_Pos cur_org_center, cur_delta; - if ( parent ) - { - FT_Pos par_org_center, par_cur_center; - FT_Pos cur_org_center, cur_delta; - /* ensure that parent is already fitted */ - if ( !psh2_hint_is_fitted(parent) ) - psh2_hint_align( parent, globals, vertical ); + /* ensure that parent is already fitted */ + if ( !psh2_hint_is_fitted( parent ) ) + psh2_hint_align( parent, globals, vertical ); - 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); + 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 ); + 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); - } - - /* normal processing */ - if ( (fit_len/64) & 1 ) - { - /* odd number of pixels */ - fit_center = ((pos + (len >> 1)) & -64) + 32; - } + if ( cur_delta >= 0 ) + cur_delta = ( cur_delta + 16 ) & -64; else - { - /* even number of pixels */ - fit_center = (pos + (len >> 1) + 32) & -64; - } + cur_delta = -( (-cur_delta + 16 ) & -64 ); +#endif + pos = par_cur_center + cur_delta - ( len >> 1 ); + } - hint->cur_pos = fit_center - (fit_len >> 1); + /* 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 ); + } } - psh2_hint_set_fitted(hint); + psh2_hint_set_fitted( hint ); #ifdef DEBUG_HINTER - if (ps2_debug_hint_func) + if ( ps2_debug_hint_func ) ps2_debug_hint_func( hint, vertical ); #endif } @@ -465,6 +480,7 @@ FT_Fixed scale = dim->scale_mult; FT_Fixed delta = dim->scale_delta; + if ( ps_debug_no_vert_hints && vertical ) { ps2_simple_scale( table, scale, delta, vertical ); @@ -480,25 +496,26 @@ hint = table->hints; count = table->max_hints; + for ( ; count > 0; count--, hint++ ) psh2_hint_align( hint, globals, vertical ); } - /************************************************************************/ - /************************************************************************/ - /***** *****/ - /***** POINTS INTERPOLATION ROUTINES *****/ - /***** *****/ - /************************************************************************/ - /************************************************************************/ - -#define PSH2_ZONE_MIN -3200000 -#define PSH2_ZONE_MAX +3200000 + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** POINTS INTERPOLATION ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ +#define PSH2_ZONE_MIN -3200000 +#define PSH2_ZONE_MAX +3200000 #define xxDEBUG_ZONES + #ifdef DEBUG_ZONES #include <stdio.h> @@ -514,22 +531,25 @@ } #else -# define print_zone(x) do { } while (0) + +#define print_zone( x ) do { } while ( 0 ) + #endif #if 0 - /* setup interpolation zones once the hints have been grid-fitted */ - /* by the optimizer.. */ + /* setup interpolation zones once the hints have been grid-fitted */ + /* by the optimizer */ static void psh2_hint_table_setup_zones( PSH2_Hint_Table table, FT_Fixed scale, FT_Fixed delta ) { - FT_UInt count; - PSH2_Zone zone; - PSH2_Hint *sort, hint, hint2; + FT_UInt count; + PSH2_Zone zone; + PSH2_Hint *sort, hint, hint2; - zone = table->zones; + + zone = table->zones; /* special case, no hints defined */ if ( table->num_hints == 0 ) @@ -546,8 +566,8 @@ /* the first zone is before the first hint */ /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */ - sort = table->sort; - hint = sort[0]; + sort = table->sort; + hint = sort[0]; zone->scale = scale; zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale ); @@ -562,6 +582,7 @@ { FT_Fixed scale2; + if ( hint->org_len > 0 ) { /* setup a zone for inner-stem interpolation */ @@ -588,25 +609,28 @@ /* 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 ); + zone->delta = hint->cur_pos + hint->cur_len - + FT_MulFix( zone->min, scale2 ); print_zone( zone ); zone++; - hint = hint2; + hint = hint2; } /* the last zone */ zone->scale = scale; zone->min = hint->org_pos + hint->org_len; zone->max = PSH2_ZONE_MAX; - zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale ); + zone->delta = hint->cur_pos + hint->cur_len - + FT_MulFix( zone->min, scale ); print_zone( zone ); @@ -618,13 +642,14 @@ #endif #if 0 - /* tune a single coordinate with the current interpolation zones */ + /* tune a single coordinate with the current interpolation zones */ static FT_Pos psh2_hint_table_tune_coord( PSH2_Hint_Table table, FT_Int coord ) { PSH2_Zone zone; + zone = table->zone; if ( coord < zone->min ) @@ -635,8 +660,8 @@ break; zone--; - } - while ( coord < zone->min ); + + } while ( coord < zone->min ); table->zone = zone; } else if ( coord > zone->max ) @@ -647,8 +672,8 @@ break; zone++; - } - while ( coord > zone->max ); + + } while ( coord > zone->max ); table->zone = zone; } @@ -673,11 +698,13 @@ 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; @@ -687,6 +714,7 @@ FT_Vector* vec; FT_Int count2; + psh2_hint_table_activate_mask( table, mask ); psh2_hint_table_optimize( table, globals, outline, vertical ); psh2_hint_table_setup_zones( table, scale, delta ); @@ -694,10 +722,12 @@ vec = outline->points + first; count2 = last - first; + for ( ; count2 > 0; count2--, vec++ ) { FT_Pos x, *px; + px = vertical ? &vec->x : &vec->y; x = *px; @@ -712,6 +742,7 @@ { FT_Vector* vec; + vec = outline->points; count = outline->n_points; @@ -729,13 +760,14 @@ } #endif - /************************************************************************/ - /************************************************************************/ - /***** *****/ - /***** HINTER GLYPH MANAGEMENT *****/ - /***** *****/ - /************************************************************************/ - /************************************************************************/ + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTER GLYPH MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ static int psh2_point_is_extremum( PSH2_Point point ) @@ -745,6 +777,7 @@ FT_Pos d_before; FT_Pos d_after; + do { before = before->prev; @@ -752,8 +785,8 @@ return 0; d_before = before->org_u - point->org_u; - } - while ( d_before == 0 ); + + } while ( d_before == 0 ); do { @@ -762,20 +795,20 @@ return 0; d_after = after->org_u - point->org_u; - } - while ( d_after == 0 ); + + } while ( d_after == 0 ); return ( ( d_before > 0 && d_after > 0 ) || ( d_before < 0 && d_after < 0 ) ); } - static void psh2_glyph_done( PSH2_Glyph glyph ) { FT_Memory memory = glyph->memory; + psh2_hint_table_done( &glyph->hint_tables[1], memory ); psh2_hint_table_done( &glyph->hint_tables[0], memory ); @@ -790,24 +823,27 @@ static int - psh2_compute_dir( FT_Pos dx, FT_Pos dy ) + psh2_compute_dir( FT_Pos dx, + FT_Pos dy ) { FT_Pos ax, ay; int result = PSH2_DIR_NONE; + ax = ( dx >= 0 ) ? dx : -dx; ay = ( dy >= 0 ) ? dy : -dy; - if ( ay*12 < ax ) + if ( ay * 12 < ax ) { /* |dy| <<< |dx| means a near-horizontal segment */ result = ( dx >= 0 ) ? PSH2_DIR_RIGHT : PSH2_DIR_LEFT; } - else if ( ax*12 < ay ) + else if ( ax * 12 < ay ) { /* |dx| <<< |dy| means a near-vertical segment */ result = ( dy >= 0 ) ? PSH2_DIR_UP : PSH2_DIR_DOWN; } + return result; } @@ -821,14 +857,17 @@ FT_Error error; FT_Memory memory; + /* clear all fields */ - memset( glyph, 0, sizeof(*glyph) ); + memset( glyph, 0, sizeof ( *glyph ) ); memory = globals->memory; /* allocate and setup points + contours arrays */ - if ( ALLOC_ARRAY( glyph->points, outline->n_points, PSH2_PointRec ) || - ALLOC_ARRAY( glyph->contours, outline->n_contours, PSH2_ContourRec ) ) + if ( ALLOC_ARRAY( glyph->points, outline->n_points, + PSH2_PointRec ) || + ALLOC_ARRAY( glyph->contours, outline->n_contours, + PSH2_ContourRec ) ) goto Exit; glyph->num_points = outline->n_points; @@ -839,11 +878,13 @@ PSH2_Point points = glyph->points; PSH2_Contour contour = glyph->contours; + for ( n = 0; n < glyph->num_contours; n++ ) { FT_Int count; PSH2_Point point; + next = outline->contours[n] + 1; count = next - first; @@ -856,6 +897,7 @@ point->prev = points + next - 1; point->contour = contour; + for ( ; count > 1; count-- ) { point[0].next = point + 1; @@ -877,30 +919,30 @@ FT_Vector* vec = outline->points; FT_UInt n; + for ( n = 0; n < glyph->num_points; n++, point++ ) { - FT_Int n_prev = point->prev - points; - FT_Int n_next = point->next - points; - FT_Pos dxi, dyi, dxo, dyo; + FT_Int n_prev = point->prev - points; + FT_Int n_next = point->next - points; + FT_Pos dxi, dyi, dxo, dyo; + - if ( !(outline->tags[n] & FT_Curve_Tag_On) ) + if ( !( outline->tags[n] & FT_Curve_Tag_On ) ) point->flags = PSH2_POINT_OFF; dxi = vec[n].x - vec[n_prev].x; dyi = vec[n].y - vec[n_prev].y; - point->dir_in = (FT_Char) psh2_compute_dir( dxi, dyi ); + point->dir_in = (FT_Char)psh2_compute_dir( dxi, dyi ); dxo = vec[n_next].x - vec[n].x; dyo = vec[n_next].y - vec[n].y; - point->dir_out = (FT_Char) psh2_compute_dir( dxo, dyo ); + point->dir_out = (FT_Char)psh2_compute_dir( dxo, dyo ); /* detect smooth points */ if ( point->flags & PSH2_POINT_OFF ) - { point->flags |= PSH2_POINT_SMOOTH; - } else if ( point->dir_in != PSH2_DIR_NONE || point->dir_out != PSH2_DIR_NONE ) { @@ -911,6 +953,7 @@ { FT_Angle angle_in, angle_out, diff; + angle_in = FT_Atan2( dxi, dyi ); angle_out = FT_Atan2( dxo, dyo ); @@ -921,7 +964,7 @@ if ( diff > FT_ANGLE_PI ) diff = FT_ANGLE_2PI - diff; - if ( (diff < FT_ANGLE_PI/16) ) + if ( diff < FT_ANGLE_PI / 16 ) point->flags |= PSH2_POINT_SMOOTH; } } @@ -937,21 +980,23 @@ &ps_hints->dimension[0].masks, &ps_hints->dimension[0].counters, memory ); - if (error) goto Exit; + if ( error ) + goto Exit; error = psh2_hint_table_init( &glyph->hint_tables [1], &ps_hints->dimension[1].hints, &ps_hints->dimension[1].masks, &ps_hints->dimension[1].counters, memory ); - if (error) goto Exit; + if ( error ) + goto Exit; Exit: return error; } - /* load outline point coordinates into hinter glyph */ + /* load outline point coordinates into hinter glyph */ static void psh2_glyph_load_points( PSH2_Glyph glyph, FT_Int vertical ) @@ -960,24 +1005,25 @@ PSH2_Point point = glyph->points; FT_UInt count = glyph->num_points; + for ( ; count > 0; count--, point++, vec++ ) { point->flags &= PSH2_POINT_OFF | PSH2_POINT_SMOOTH; point->hint = 0; - if (vertical) + if ( vertical ) point->org_u = vec->x; else point->org_u = vec->y; #ifdef DEBUG_HINTER - point->org_x = vec->x; - point->org_y = vec->y; + point->org_x = vec->x; + point->org_y = vec->y; #endif } } - /* save hinted point coordinates back to outline */ + /* save hinted point coordinates back to outline */ static void psh2_glyph_save_points( PSH2_Glyph glyph, FT_Int vertical ) @@ -987,18 +1033,19 @@ FT_Vector* vec = glyph->outline->points; char* tags = glyph->outline->tags; + for ( n = 0; n < glyph->num_points; n++ ) { - if (vertical) + if ( vertical ) vec[n].x = point->cur_u; else vec[n].y = point->cur_u; - if ( psh2_point_is_strong(point) ) + if ( psh2_point_is_strong( point ) ) tags[n] |= vertical ? 32 : 64; #ifdef DEBUG_HINTER - if (vertical) + if ( vertical ) { point->cur_x = point->cur_u; point->flags_x = point->flags; @@ -1014,7 +1061,8 @@ } -#define PSH2_STRONG_THRESHOLD 10 +#define PSH2_STRONG_THRESHOLD 10 + static void psh2_hint_table_find_strong_point( PSH2_Hint_Table table, @@ -1024,26 +1072,29 @@ PSH2_Hint* sort = table->sort; FT_UInt num_hints = table->num_hints; + for ( ; num_hints > 0; num_hints--, sort++ ) { PSH2_Hint hint = sort[0]; - if ( ABS(point->dir_in) == major_dir || - ABS(point->dir_out) == major_dir ) + + if ( ABS( point->dir_in ) == major_dir || + ABS( point->dir_out ) == major_dir ) { FT_Pos d; + d = point->org_u - hint->org_pos; - if ( ABS(d) < PSH2_STRONG_THRESHOLD ) + if ( ABS( d ) < PSH2_STRONG_THRESHOLD ) { Is_Strong: - psh2_point_set_strong(point); + psh2_point_set_strong( point ); point->hint = hint; break; } d -= hint->org_len; - if ( ABS(d) < PSH2_STRONG_THRESHOLD ) + if ( ABS( d ) < PSH2_STRONG_THRESHOLD ) goto Is_Strong; } @@ -1061,8 +1112,7 @@ } - - /* find strong points in a glyph */ + /* find strong points in a glyph */ static void psh2_glyph_find_strong_points( PSH2_Glyph glyph, FT_Int vertical ) @@ -1076,6 +1126,7 @@ FT_UInt first = 0; FT_Int major_dir = vertical ? PSH2_DIR_UP : PSH2_DIR_RIGHT; + /* process secondary hints to "selected" points */ if ( num_masks > 1 ) { @@ -1085,12 +1136,14 @@ FT_UInt next; FT_Int count; + next = mask->end_point; count = next - first; if ( count > 0 ) { PSH2_Point point = glyph->points + first; + psh2_hint_table_activate_mask( table, mask ); for ( ; count > 0; count--, point++ ) @@ -1106,30 +1159,31 @@ FT_UInt count = glyph->num_points; PSH2_Point point = glyph->points; + psh2_hint_table_activate_mask( table, table->hint_masks->masks ); for ( ; count > 0; count--, point++ ) { - if ( !psh2_point_is_strong(point) ) + if ( !psh2_point_is_strong( point ) ) psh2_hint_table_find_strong_point( table, point, major_dir ); } } /* now, certain points may have been attached to hint and */ - /* not marked as strong, update their flags then.. */ + /* not marked as strong; update their flags then */ { FT_UInt count = glyph->num_points; PSH2_Point point = glyph->points; + for ( ; count > 0; count--, point++ ) - if ( point->hint && !psh2_point_is_strong(point) ) - psh2_point_set_strong(point); + if ( point->hint && !psh2_point_is_strong( point ) ) + psh2_point_set_strong( point ); } } } - - /* interpolate strong points with the help of hinted coordinates */ + /* interpolate strong points with the help of hinted coordinates */ static void psh2_glyph_interpolate_strong_points( PSH2_Glyph glyph, FT_Int vertical ) @@ -1137,18 +1191,22 @@ PSH_Dimension dim = &glyph->globals->dimension[vertical]; FT_Fixed scale = dim->scale_mult; + { FT_UInt count = glyph->num_points; PSH2_Point point = glyph->points; + for ( ; count > 0; count--, point++ ) { PSH2_Hint hint = point->hint; + if ( hint ) { FT_Pos delta; + delta = point->org_u - hint->org_pos; if ( delta <= 0 ) @@ -1164,7 +1222,7 @@ else point->cur_u = hint->cur_pos; - psh2_point_set_fitted(point); + psh2_point_set_fitted( point ); } } } @@ -1179,18 +1237,20 @@ PSH_Dimension dim = &glyph->globals->dimension[vertical]; FT_Fixed scale = dim->scale_mult; + /* first technique: a point is strong if it is a local extrema */ { FT_UInt count = glyph->num_points; PSH2_Point point = glyph->points; + for ( ; count > 0; count--, point++ ) { - if ( psh2_point_is_strong(point) ) + if ( psh2_point_is_strong( point ) ) continue; /* sometimes, some local extremas are smooth points */ - if ( psh2_point_is_smooth(point) ) + if ( psh2_point_is_smooth( point ) ) { if ( point->dir_in == PSH2_DIR_NONE || point->dir_in != point->dir_out ) @@ -1214,12 +1274,14 @@ FT_Int count2 = glyph->num_points; PSH2_Point cur = glyph->points; + for ( ; count2 > 0; count2--, cur++ ) { - if ( psh2_point_is_strong(cur) ) + if ( psh2_point_is_strong( cur ) ) { FT_Pos diff = cur->org_u - u;; + if ( diff <= 0 ) { if ( diff > diff_before ) @@ -1244,15 +1306,15 @@ if ( !after ) continue; - /* we're before the first strong point coordinate */ - /* simply translate the point.. */ + /* we are before the first strong point coordinate; */ + /* simply translate the point */ point->cur_u = after->cur_u + FT_MulFix( point->org_u - after->org_u, scale ); } else if ( !after ) { - /* we're after the last strong point coordinate */ - /* simply translate the point.. */ + /* we are after the last strong point coordinate; */ + /* simply translate the point */ point->cur_u = before->cur_u + FT_MulFix( point->org_u - before->org_u, scale ); } @@ -1271,7 +1333,7 @@ after->org_u - before->org_u ); } - psh2_point_set_fitted(point); + psh2_point_set_fitted( point ); } } } @@ -1279,8 +1341,7 @@ } - - /* interpolate other points */ + /* interpolate other points */ static void psh2_glyph_interpolate_other_points( PSH2_Glyph glyph, FT_Int vertical ) @@ -1291,19 +1352,21 @@ PSH2_Contour contour = glyph->contours; FT_UInt num_contours = glyph->num_contours; + for ( ; num_contours > 0; num_contours--, contour++ ) { PSH2_Point start = contour->start; PSH2_Point first, next, point; FT_UInt fit_count; + /* count the number of strong points in this contour */ next = start + contour->count; fit_count = 0; first = 0; for ( point = start; point < next; point++ ) - if ( psh2_point_is_fitted(point) ) + if ( psh2_point_is_fitted( point ) ) { if ( !first ) first = point; @@ -1311,8 +1374,8 @@ fit_count++; } - /* if there is less than 2 fitted points in the contour, we'll */ - /* simply scale and eventually translate the contour points */ + /* if there are less than 2 fitted points in the contour, we */ + /* simply scale and eventually translate the contour points */ if ( fit_count < 2 ) { if ( fit_count == 1 ) @@ -1325,8 +1388,8 @@ goto Next_Contour; } - /* there are more than 2 strong points in this contour, we'll */ - /* need to interpolate weak points between them.. */ + /* there are more than 2 strong points in this contour; we */ + /* need to interpolate weak points between them */ start = first; do { @@ -1339,7 +1402,7 @@ if ( next == start ) goto Next_Contour; - if ( !psh2_point_is_fitted(next) ) + if ( !psh2_point_is_fitted( next ) ) break; first = next; @@ -1349,7 +1412,7 @@ for (;;) { next = next->next; - if ( psh2_point_is_fitted(next) ) + if ( psh2_point_is_fitted( next ) ) break; } @@ -1359,6 +1422,7 @@ FT_Pos org_c, org_ac, cur_c; FT_Fixed scale_ab; + if ( first->org_u <= next->org_u ) { org_a = first->org_u; @@ -1403,27 +1467,28 @@ point->cur_u = cur_c; point = point->next; - } - while ( point != next ); + + } while ( point != next ); } /* keep going until all points in the contours have been processed */ first = next; - } - while ( first != start ); + + } while ( first != start ); Next_Contour: ; } } - /************************************************************************/ - /************************************************************************/ - /***** *****/ - /***** HIGH-LEVEL INTERFACE *****/ - /***** *****/ - /************************************************************************/ - /************************************************************************/ + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HIGH-LEVEL INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ FT_Error ps2_hints_apply( PS_Hints ps_hints, @@ -1436,11 +1501,11 @@ FT_Memory memory; FT_Int dimension; - memory = globals->memory; - FT_UNUSED(glyphrec); + memory = globals->memory; + #ifdef DEBUG_HINTER if ( ps2_debug_glyph ) { @@ -1448,7 +1513,7 @@ FREE( ps2_debug_glyph ); } - if ( ALLOC( glyph, sizeof(*glyph) ) ) + if ( ALLOC( glyph, sizeof ( *glyph ) ) ) return error; ps2_debug_glyph = glyph; @@ -1457,7 +1522,8 @@ #endif error = psh2_glyph_init( glyph, outline, ps_hints, globals ); - if (error) goto Exit; + if ( error ) + goto Exit; for ( dimension = 1; dimension >= 0; dimension-- ) { @@ -1485,3 +1551,6 @@ #endif return error; } + + +/* END */ |