📄 ttsbit.c
字号:
FORGET_Frame(); Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_SBit_Range */ /* */ /* <Description> */ /* Loads a given `EBLC' index/range table. */ /* */ /* <Input> */ /* range :: The target range. */ /* stream :: The input stream. */ /* */ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ static TT_Error Load_SBit_Range( TT_SBit_Range* range, FT_Stream stream ) { TT_Error error; FT_Memory memory = stream->memory; switch( range->index_format ) { case 1: /* variable metrics with 4-byte offsets */ case 3: /* variable metrics with 2-byte offsets */ { TT_ULong num_glyphs, n; TT_Int size_elem; TT_Bool large = (range->index_format == 1); num_glyphs = range->last_glyph - range->first_glyph + 1L; range->num_glyphs = num_glyphs; num_glyphs++; /* XXX : BEWARE - see spec */ size_elem = ( large ? 4 : 2 ); if ( ALLOC_ARRAY( range->glyph_offsets, num_glyphs, TT_ULong ) || ACCESS_Frame( num_glyphs * size_elem ) ) goto Exit; for ( n = 0; n < num_glyphs; n++ ) range->glyph_offsets[n] = (TT_ULong)( range->image_offset + (large ? GET_ULong() : GET_UShort()) ); FORGET_Frame(); } break; case 2: /* all glyphs have identical metrics */ error = Load_SBit_Const_Metrics( range, stream ); break; case 4: error = Load_SBit_Range_Codes( range, stream, 1 ); break; case 5: error = Load_SBit_Const_Metrics( range, stream ) || Load_SBit_Range_Codes( range, stream, 0 ); break; default: error = TT_Err_Invalid_File_Format; } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_SBit_Strikes */ /* */ /* <Description> */ /* Loads the table of embedded bitmap sizes for this face. */ /* */ /* <Input> */ /* face :: The target face object. */ /* stream :: The input stream. */ /* */ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC TT_Error TT_Load_SBit_Strikes( TT_Face face, FT_Stream stream ) { TT_Error error = 0; FT_Memory memory = stream->memory; TT_Fixed version; TT_ULong num_strikes; TT_ULong table_base; /* this table is optional */ error = face->goto_table( face, TTAG_EBLC, stream, 0 ); { error = 0; goto Exit; } table_base = FILE_Pos(); if ( ACCESS_Frame( 8L ) ) goto Exit; version = GET_Long(); num_strikes = GET_ULong(); FORGET_Frame(); /* check version number and strike count */ if ( version != 0x00020000 || num_strikes >= 0x10000 ) { FT_ERROR(( "TT_Load_SBit_Strikes: invalid table version!\n" )); error = TT_Err_Invalid_File_Format; goto Exit; } /* allocate the strikes table */ if ( ALLOC_ARRAY( face->sbit_strikes, num_strikes, TT_SBit_Strike ) ) goto Exit; face->num_sbit_strikes = num_strikes; /* now read each strike table separately */ { TT_SBit_Strike* strike = face->sbit_strikes; TT_ULong count = num_strikes; if ( ACCESS_Frame( 48L * num_strikes ) ) goto Exit; while ( count > 0 ) { TT_ULong indexTablesSize; strike->ranges_offset = GET_ULong(); indexTablesSize = GET_ULong(); /* don't save */ strike->num_ranges = GET_ULong(); strike->color_ref = GET_ULong(); TT_Load_SBit_Line_Metrics( &strike->hori, stream ); TT_Load_SBit_Line_Metrics( &strike->vert, stream ); strike->start_glyph = GET_UShort(); strike->end_glyph = GET_UShort(); strike->x_ppem = GET_Byte(); strike->y_ppem = GET_Byte(); strike->bit_depth = GET_Byte(); strike->flags = GET_Char(); count--; strike++; } FORGET_Frame(); } /* allocate the index ranges for each strike table */ { TT_SBit_Strike* strike = face->sbit_strikes; TT_ULong count = num_strikes; while ( count > 0 ) { TT_SBit_Range* range; TT_ULong count2 = strike->num_ranges; if ( ALLOC_ARRAY( strike->sbit_ranges, strike->num_ranges, TT_SBit_Range ) ) goto Exit; /* read each range */ if ( FILE_Seek( table_base + strike->ranges_offset ) || ACCESS_Frame( strike->num_ranges * 8L ) ) goto Exit; range = strike->sbit_ranges; while ( count2 > 0 ) { range->first_glyph = GET_UShort(); range->last_glyph = GET_UShort(); range->table_offset = table_base + strike->ranges_offset + GET_ULong(); count2--; range++; } FORGET_Frame(); /* Now, read each index table */ count2 = strike->num_ranges; range = strike->sbit_ranges; while ( count2 > 0 ) { /* Read the header */ if ( FILE_Seek( range->table_offset ) || ACCESS_Frame( 8L ) ) goto Exit; range->index_format = GET_UShort(); range->image_format = GET_UShort(); range->image_offset = GET_ULong(); FORGET_Frame(); error = Load_SBit_Range( range, stream ); if ( error ) goto Exit; count2--; range++; } count--; strike++; } } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Free_SBit_Strikes */ /* */ /* <Description> */ /* Releases the embedded bitmap tables. */ /* */ /* <Input> */ /* face :: The target face object. */ /* */ LOCAL_FUNC void TT_Free_SBit_Strikes( TT_Face face ) { FT_Memory memory = face->root.memory; TT_SBit_Strike* strike = face->sbit_strikes; TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes; if ( strike ) { for ( ; strike < strike_limit; strike++ ) { TT_SBit_Range* range = strike->sbit_ranges; TT_SBit_Range* range_limit = range + strike->num_ranges; if ( range ) { for ( ; range < range_limit; range++ ) { /* release the glyph offsets and codes tables */ /* where appropriate */ FREE( range->glyph_offsets ); FREE( range->glyph_codes ); } } FREE( strike->sbit_ranges ); strike->num_ranges = 0; } FREE( face->sbit_strikes ); } face->num_sbit_strikes = 0; } /*************************************************************************/ /* */ /* <Function> */ /* Find_SBit_Range */ /* */ /* <Description> */ /* Scans a given strike's ranges and return, for a given glyph */ /* index, the corresponding sbit range, and `EBDT' offset. */ /* */ /* <Input> */ /* glyph_index :: The glyph index. */ /* strike :: The source/current sbit strike. */ /* */ /* <Output> */ /* arange :: The sbit range containing the glyph index. */ /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ /* */ /* <Return> */ /* TrueType error code. 0 means the glyph index was found. */ /* */ static TT_Error Find_SBit_Range( TT_UInt glyph_index, TT_SBit_Strike* strike, TT_SBit_Range** arange, TT_ULong* aglyph_offset ) { TT_SBit_Range *range, *range_limit; /* check whether the glyph index is within this strike's */ /* glyph range */ if ( glyph_index < strike->start_glyph || glyph_index > strike->end_glyph ) goto Fail; /* scan all ranges in strike */ range = strike->sbit_ranges; range_limit = range + strike->num_ranges; if ( !range ) goto Fail; for ( ; range < range_limit; range++ ) { if ( glyph_index >= range->first_glyph && glyph_index <= range->last_glyph ) { TT_UShort delta = glyph_index - range->first_glyph; switch ( range->index_format ) { case 1: case 3: *aglyph_offset = range->glyph_offsets[delta]; break; case 2: *aglyph_offset = range->image_offset + range->image_size * delta; break; case 4: case 5: { TT_ULong n; for ( n = 0; n < range->num_glyphs; n++ ) { if ( range->glyph_codes[n] == glyph_index ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -