📄 pshrec.c
字号:
FT_Memory memory ) { FT_UInt temp; FT_Error error = 0; /* swap index1 and index2 so that index1 < index2 */ if ( index1 > index2 ) { temp = index1; index1 = index2; index2 = temp; } if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks ) { /* we need to merge the bitsets of index1 and index2 with a */ /* simple union */ PS_Mask mask1 = table->masks + index1; PS_Mask mask2 = table->masks + index2; FT_UInt count1 = mask1->num_bits; FT_UInt count2 = mask2->num_bits; FT_Int delta; if ( count2 > 0 ) { FT_UInt pos; FT_Byte* read; FT_Byte* write; /* if "count2" is greater than "count1", we need to grow the */ /* first bitset, and clear the highest bits */ if ( count2 > count1 ) { error = ps_mask_ensure( mask1, count2, memory ); if ( error ) goto Exit; for ( pos = count1; pos < count2; pos++ ) ps_mask_clear_bit( mask1, pos ); } /* merge (unite) the bitsets */ read = mask2->bytes; write = mask1->bytes; pos = (FT_UInt)( ( count2 + 7 ) >> 3 ); for ( ; pos > 0; pos-- ) { write[0] = (FT_Byte)( write[0] | read[0] ); write++; read++; } } /* Now, remove "mask2" from the list. We need to keep the masks */ /* sorted in order of importance, so move table elements. */ mask2->num_bits = 0; mask2->end_point = 0; delta = table->num_masks - 1 - index2; /* number of masks to move */ if ( delta > 0 ) { /* move to end of table for reuse */ PS_MaskRec dummy = *mask2; ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) ); mask2[delta] = dummy; } table->num_masks--; } else FT_ERROR(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", index1, index2 )); Exit: return error; } /* Try to merge all masks in a given table. This is used to merge */ /* all counter masks into independent counter "paths". */ /* */ static FT_Error ps_mask_table_merge_all( PS_Mask_Table table, FT_Memory memory ) { FT_Int index1, index2; FT_Error error = 0; for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) { for ( index2 = index1 - 1; index2 >= 0; index2-- ) { if ( ps_mask_table_test_intersect( table, index1, index2 ) ) { error = ps_mask_table_merge( table, index2, index1, memory ); if ( error ) goto Exit; break; } } } Exit: return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** PS_DIMENSION MANAGEMENT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* finalize a given dimension */ static void ps_dimension_done( PS_Dimension dimension, FT_Memory memory ) { ps_mask_table_done( &dimension->counters, memory ); ps_mask_table_done( &dimension->masks, memory ); ps_hint_table_done( &dimension->hints, memory ); } /* initialize a given dimension */ static void ps_dimension_init( PS_Dimension dimension ) { dimension->hints.num_hints = 0; dimension->masks.num_masks = 0; dimension->counters.num_masks = 0; }#if 0 /* set a bit at a given index in the current hint mask */ static FT_Error ps_dimension_set_mask_bit( PS_Dimension dim, FT_UInt idx, FT_Memory memory ) { PS_Mask mask; FT_Error error = 0; /* get last hint mask */ error = ps_mask_table_last( &dim->masks, memory, &mask ); if ( error ) goto Exit; error = ps_mask_set_bit( mask, idx, memory ); Exit: return error; }#endif /* set the end point in a mask, called from "End" & "Reset" methods */ static void ps_dimension_end_mask( PS_Dimension dim, FT_UInt end_point ) { FT_UInt count = dim->masks.num_masks; PS_Mask mask; if ( count > 0 ) { mask = dim->masks.masks + count - 1; mask->end_point = end_point; } } /* set the end point in the current mask, then create a new empty one */ /* (called by "Reset" method) */ static FT_Error ps_dimension_reset_mask( PS_Dimension dim, FT_UInt end_point, FT_Memory memory ) { PS_Mask mask; /* end current mask */ ps_dimension_end_mask( dim, end_point ); /* allocate new one */ return ps_mask_table_alloc( &dim->masks, memory, &mask ); } /* set a new mask, called from the "T2Stem" method */ static FT_Error ps_dimension_set_mask_bits( PS_Dimension dim, const FT_Byte* source, FT_UInt source_pos, FT_UInt source_bits, FT_UInt end_point, FT_Memory memory ) { FT_Error error = 0; /* reset current mask, if any */ error = ps_dimension_reset_mask( dim, end_point, memory ); if ( error ) goto Exit; /* set bits in new mask */ error = ps_mask_table_set_bits( &dim->masks, (FT_Byte*)source, source_pos, source_bits, memory ); Exit: return error; } /* add a new single stem (called from "T1Stem" method) */ static FT_Error ps_dimension_add_t1stem( PS_Dimension dim, FT_Int pos, FT_Int len, FT_Memory memory, FT_Int *aindex ) { FT_Error error = 0; FT_UInt flags = 0; /* detect ghost stem */ if ( len < 0 ) { flags |= PS_HINT_FLAG_GHOST; if ( len == -21 ) { flags |= PS_HINT_FLAG_BOTTOM; pos += len; } len = 0; } if ( aindex ) *aindex = -1; /* now, lookup stem in the current hints table */ { PS_Mask mask; FT_UInt idx; FT_UInt max = dim->hints.num_hints; PS_Hint hint = dim->hints.hints; for ( idx = 0; idx < max; idx++, hint++ ) { if ( hint->pos == pos && hint->len == len ) break; } /* we need to create a new hint in the table */ if ( idx >= max ) { error = ps_hint_table_alloc( &dim->hints, memory, &hint ); if ( error ) goto Exit; hint->pos = pos; hint->len = len; hint->flags = flags; } /* now, store the hint in the current mask */ error = ps_mask_table_last( &dim->masks, memory, &mask ); if ( error ) goto Exit; error = ps_mask_set_bit( mask, idx, memory ); if ( error ) goto Exit; if ( aindex ) *aindex = (FT_Int)idx; } Exit: return error; } /* add a "hstem3/vstem3" counter to our dimension table */ static FT_Error ps_dimension_add_counter( PS_Dimension dim, FT_Int hint1, FT_Int hint2, FT_Int hint3, FT_Memory memory ) { FT_Error error = 0; FT_UInt count = dim->counters.num_masks; PS_Mask counter = dim->counters.masks; /* try to find an existing counter mask that already uses */ /* one of these stems here */ for ( ; count > 0; count--, counter++ ) { if ( ps_mask_test_bit( counter, hint1 ) || ps_mask_test_bit( counter, hint2 ) || ps_mask_test_bit( counter, hint3 ) ) break; } /* create a new counter when needed */ if ( count == 0 ) { error = ps_mask_table_alloc( &dim->counters, memory, &counter ); if ( error ) goto Exit; } /* now, set the bits for our hints in the counter mask */ error = ps_mask_set_bit( counter, hint1, memory ); if ( error ) goto Exit; error = ps_mask_set_bit( counter, hint2, memory ); if ( error ) goto Exit; error = ps_mask_set_bit( counter, hint3, memory ); if ( error ) goto Exit; Exit: return error; } /* end of recording session for a given dimension */ static FT_Error ps_dimension_end( PS_Dimension dim, FT_UInt end_point, FT_Memory memory ) { /* end hint mask table */ ps_dimension_end_mask( dim, end_point ); /* merge all counter masks into independent "paths" */ return ps_mask_table_merge_all( &dim->counters, memory ); } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** PS_RECORDER MANAGEMENT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* destroy hints */ FT_LOCAL( void ) ps_hints_done( PS_Hints hints ) { FT_Memory memory = hints->memory; ps_dimension_done( &hints->dimension[0], memory ); ps_dimension_done( &hints->dimension[1], memory ); hints->error = 0; hints->memory = 0; } FT_LOCAL( FT_Error ) ps_hints_init( PS_Hints hints, FT_Memory memory ) { FT_MEM_ZERO( hints, sizeof ( *hints ) ); hints->memory = memory; return 0; } /* initialize a hints for a new session */ static void ps_hints_open( PS_Hints hints, PS_Hint_Type hint_type ) { switch ( hint_type )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -