📄 pshrec.c
字号:
/***************************************************************************//* *//* pshrec.c *//* *//* FreeType PostScript hints recorder (body). *//* *//* Copyright 2001, 2002, 2003, 2004, 2007 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_FREETYPE_H#include FT_INTERNAL_OBJECTS_H#include FT_INTERNAL_DEBUG_H#include "pshrec.h"#include "pshalgo.h"#include "pshnterr.h"#undef FT_COMPONENT#define FT_COMPONENT trace_pshrec#ifdef DEBUG_HINTER PS_Hints ps_debug_hints = 0; int ps_debug_no_horz_hints = 0; int ps_debug_no_vert_hints = 0;#endif /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** PS_HINT MANAGEMENT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* destroy hints table */ static void ps_hint_table_done( PS_Hint_Table table, FT_Memory memory ) { FT_FREE( table->hints ); table->num_hints = 0; table->max_hints = 0; } /* ensure that a table can contain "count" elements */ static FT_Error ps_hint_table_ensure( PS_Hint_Table table, FT_UInt count, FT_Memory memory ) { FT_UInt old_max = table->max_hints; FT_UInt new_max = count; FT_Error error = 0; if ( new_max > old_max ) { /* try to grow the table */ new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) ) table->max_hints = new_max; } return error; } static FT_Error ps_hint_table_alloc( PS_Hint_Table table, FT_Memory memory, PS_Hint *ahint ) { FT_Error error = 0; FT_UInt count; PS_Hint hint = 0; count = table->num_hints; count++; if ( count >= table->max_hints ) { error = ps_hint_table_ensure( table, count, memory ); if ( error ) goto Exit; } hint = table->hints + count - 1; hint->pos = 0; hint->len = 0; hint->flags = 0; table->num_hints = count; Exit: *ahint = hint; return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** PS_MASK MANAGEMENT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* destroy mask */ static void ps_mask_done( PS_Mask mask, FT_Memory memory ) { FT_FREE( mask->bytes ); mask->num_bits = 0; mask->max_bits = 0; mask->end_point = 0; } /* ensure that a mask can contain "count" bits */ static FT_Error ps_mask_ensure( PS_Mask mask, FT_UInt count, FT_Memory memory ) { FT_UInt old_max = ( mask->max_bits + 7 ) >> 3; FT_UInt new_max = ( count + 7 ) >> 3; FT_Error error = 0; if ( new_max > old_max ) { new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) ) mask->max_bits = new_max * 8; } return error; } /* test a bit value in a given mask */ static FT_Int ps_mask_test_bit( PS_Mask mask, FT_Int idx ) { if ( (FT_UInt)idx >= mask->num_bits ) return 0; return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) ); } /* clear a given bit */ static void ps_mask_clear_bit( PS_Mask mask, FT_Int idx ) { FT_Byte* p; if ( (FT_UInt)idx >= mask->num_bits ) return; p = mask->bytes + ( idx >> 3 ); p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) ); } /* set a given bit, possibly grow the mask */ static FT_Error ps_mask_set_bit( PS_Mask mask, FT_Int idx, FT_Memory memory ) { FT_Error error = 0; FT_Byte* p; if ( idx < 0 ) goto Exit; if ( (FT_UInt)idx >= mask->num_bits ) { error = ps_mask_ensure( mask, idx + 1, memory ); if ( error ) goto Exit; mask->num_bits = idx + 1; } p = mask->bytes + ( idx >> 3 ); p[0] = (FT_Byte)( p[0] | ( 0x80 >> ( idx & 7 ) ) ); Exit: return error; } /* destroy mask table */ static void ps_mask_table_done( PS_Mask_Table table, FT_Memory memory ) { FT_UInt count = table->max_masks; PS_Mask mask = table->masks; for ( ; count > 0; count--, mask++ ) ps_mask_done( mask, memory ); FT_FREE( table->masks ); table->num_masks = 0; table->max_masks = 0; } /* ensure that a mask table can contain "count" masks */ static FT_Error ps_mask_table_ensure( PS_Mask_Table table, FT_UInt count, FT_Memory memory ) { FT_UInt old_max = table->max_masks; FT_UInt new_max = count; FT_Error error = 0; if ( new_max > old_max ) { new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) ) table->max_masks = new_max; } return error; } /* allocate a new mask in a table */ static FT_Error ps_mask_table_alloc( PS_Mask_Table table, FT_Memory memory, PS_Mask *amask ) { FT_UInt count; FT_Error error = 0; PS_Mask mask = 0; count = table->num_masks; count++; if ( count > table->max_masks ) { error = ps_mask_table_ensure( table, count, memory ); if ( error ) goto Exit; } mask = table->masks + count - 1; mask->num_bits = 0; mask->end_point = 0; table->num_masks = count; Exit: *amask = mask; return error; } /* return last hint mask in a table, create one if the table is empty */ static FT_Error ps_mask_table_last( PS_Mask_Table table, FT_Memory memory, PS_Mask *amask ) { FT_Error error = 0; FT_UInt count; PS_Mask mask; count = table->num_masks; if ( count == 0 ) { error = ps_mask_table_alloc( table, memory, &mask ); if ( error ) goto Exit; } else mask = table->masks + count - 1; Exit: *amask = mask; return error; } /* set a new mask to a given bit range */ static FT_Error ps_mask_table_set_bits( PS_Mask_Table table, FT_Byte* source, FT_UInt bit_pos, FT_UInt bit_count, FT_Memory memory ) { FT_Error error = 0; PS_Mask mask; error = ps_mask_table_last( table, memory, &mask ); if ( error ) goto Exit; error = ps_mask_ensure( mask, bit_count, memory ); if ( error ) goto Exit; mask->num_bits = bit_count; /* now, copy bits */ { FT_Byte* read = source + ( bit_pos >> 3 ); FT_Int rmask = 0x80 >> ( bit_pos & 7 ); FT_Byte* write = mask->bytes; FT_Int wmask = 0x80; FT_Int val; for ( ; bit_count > 0; bit_count-- ) { val = write[0] & ~wmask; if ( read[0] & rmask ) val |= wmask; write[0] = (FT_Byte)val; rmask >>= 1; if ( rmask == 0 ) { read++; rmask = 0x80; } wmask >>= 1; if ( wmask == 0 ) { write++; wmask = 0x80; } } } Exit: return error; } /* test whether two masks in a table intersect */ static FT_Int ps_mask_table_test_intersect( PS_Mask_Table table, FT_Int index1, FT_Int index2 ) { PS_Mask mask1 = table->masks + index1; PS_Mask mask2 = table->masks + index2; FT_Byte* p1 = mask1->bytes; FT_Byte* p2 = mask2->bytes; FT_UInt count1 = mask1->num_bits; FT_UInt count2 = mask2->num_bits; FT_UInt count; count = ( count1 <= count2 ) ? count1 : count2; for ( ; count >= 8; count -= 8 ) { if ( p1[0] & p2[0] ) return 1; p1++; p2++; } if ( count == 0 ) return 0; return ( p1[0] & p2[0] ) & ~( 0xFF >> count ); } /* merge two masks, used by ps_mask_table_merge_all */ static FT_Error ps_mask_table_merge( PS_Mask_Table table, FT_Int index1, FT_Int index2,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -