📄 ttsbit.c
字号:
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> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF FT_Error TT_Load_SBit_Strikes( TT_Face face, FT_Stream stream ) { FT_Error error = 0; FT_Memory memory = stream->memory; FT_Fixed version; FT_ULong num_strikes; FT_ULong table_base; const FT_Frame_Field sbit_line_metrics_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_SBit_Line_Metrics /* no FT_FRAME_START */ FT_FRAME_CHAR( ascender ), FT_FRAME_CHAR( descender ), FT_FRAME_BYTE( max_width ), FT_FRAME_CHAR( caret_slope_numerator ), FT_FRAME_CHAR( caret_slope_denominator ), FT_FRAME_CHAR( caret_offset ), FT_FRAME_CHAR( min_origin_SB ), FT_FRAME_CHAR( min_advance_SB ), FT_FRAME_CHAR( max_before_BL ), FT_FRAME_CHAR( min_after_BL ), FT_FRAME_CHAR( pads[0] ), FT_FRAME_CHAR( pads[1] ), FT_FRAME_END }; const FT_Frame_Field strike_start_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_SBit_Strike /* no FT_FRAME_START */ FT_FRAME_ULONG( ranges_offset ), FT_FRAME_SKIP_LONG, FT_FRAME_ULONG( num_ranges ), FT_FRAME_ULONG( color_ref ), FT_FRAME_END }; const FT_Frame_Field strike_end_fields[] = { /* no FT_FRAME_START */ FT_FRAME_USHORT( start_glyph ), FT_FRAME_USHORT( end_glyph ), FT_FRAME_BYTE ( x_ppem ), FT_FRAME_BYTE ( y_ppem ), FT_FRAME_BYTE ( bit_depth ), FT_FRAME_CHAR ( flags ), FT_FRAME_END }; face->num_sbit_strikes = 0; /* this table is optional */ error = face->goto_table( face, TTAG_EBLC, stream, 0 ); if ( error ) error = face->goto_table( face, TTAG_bloc, stream, 0 ); if ( error ) 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 != 0x00020000L || num_strikes >= 0x10000L ) { 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; FT_ULong count = num_strikes; if ( ACCESS_Frame( 48L * num_strikes ) ) goto Exit; while ( count > 0 ) { if ( READ_Fields( strike_start_fields, strike ) || READ_Fields( sbit_line_metrics_fields, &strike->hori ) || READ_Fields( sbit_line_metrics_fields, &strike->vert ) || READ_Fields( strike_end_fields, strike ) ) break; count--; strike++; } FORGET_Frame(); } /* allocate the index ranges for each strike table */ { TT_SBit_Strike* strike = face->sbit_strikes; FT_ULong count = num_strikes; while ( count > 0 ) { TT_SBit_Range* range; FT_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. */ /* */ FT_LOCAL_DEF 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; } FT_LOCAL_DEF FT_Error TT_Set_SBit_Strike( TT_Face face, FT_Int x_ppem, FT_Int y_ppem, FT_ULong *astrike_index ) { FT_Int i; if ( x_ppem < 0 || x_ppem > 255 || y_ppem < 1 || y_ppem > 255 ) return TT_Err_Invalid_PPem; for ( i = 0; i < face->num_sbit_strikes; i++ ) { if ( ( face->sbit_strikes[i].y_ppem == y_ppem ) && ( ( x_ppem == 0 ) || ( face->sbit_strikes[i].x_ppem == x_ppem ) ) ) { *astrike_index = i; return TT_Err_Ok; } } return TT_Err_Invalid_PPem; } /*************************************************************************/ /* */ /* <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> */ /* FreeType error code. 0 means the glyph index was found. */ /* */ static FT_Error Find_SBit_Range( FT_UInt glyph_index, TT_SBit_Strike* strike, TT_SBit_Range** arange, FT_ULong* aglyph_offset ) { TT_SBit_Range *range, *range_limit; /* check whether the glyph index is within this strike's */ /* glyph range */ if ( glyph_index < (FT_UInt)strike->start_glyph || glyph_index > (FT_UInt)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 >= (FT_UInt)range->first_glyph && glyph_index <= (FT_UInt)range->last_glyph ) { FT_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: { FT_ULong n; for ( n = 0; n < range->num_glyphs; n++ ) { if ( (FT_UInt)range->glyph_codes[n] == glyph_index ) { if ( range->index_format == 4 ) *aglyph_offset = range->glyph_offsets[n]; else *aglyph_offset = range->image_offset + n * range->image_size; goto Found; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -