📄 ttsbit.c
字号:
default: error = SFNT_Err_Invalid_File_Format; } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_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_face_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_LineMetricsRec /* 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_StrikeRec /* 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 = FT_STREAM_POS(); if ( FT_FRAME_ENTER( 8L ) ) goto Exit; version = FT_GET_LONG(); num_strikes = FT_GET_ULONG(); FT_FRAME_EXIT(); /* check version number and strike count */ if ( version != 0x00020000L || num_strikes >= 0x10000L ) { FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" )); error = SFNT_Err_Invalid_File_Format; goto Exit; } /* allocate the strikes table */ if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) ) 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 ( FT_FRAME_ENTER( 48L * num_strikes ) ) goto Exit; while ( count > 0 ) { if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike ) || FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) || FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) || FT_STREAM_READ_FIELDS( strike_end_fields, strike ) ) break; count--; strike++; } FT_FRAME_EXIT(); } /* 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 ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) ) goto Exit; /* read each range */ if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) || FT_FRAME_ENTER( strike->num_ranges * 8L ) ) goto Exit; range = strike->sbit_ranges; while ( count2 > 0 ) { range->first_glyph = FT_GET_USHORT(); range->last_glyph = FT_GET_USHORT(); range->table_offset = table_base + strike->ranges_offset + FT_GET_ULONG(); count2--; range++; } FT_FRAME_EXIT(); /* Now, read each index table */ count2 = strike->num_ranges; range = strike->sbit_ranges; while ( count2 > 0 ) { /* Read the header */ if ( FT_STREAM_SEEK( range->table_offset ) || FT_FRAME_ENTER( 8L ) ) goto Exit; range->index_format = FT_GET_USHORT(); range->image_format = FT_GET_USHORT(); range->image_offset = FT_GET_ULONG(); FT_FRAME_EXIT(); error = Load_SBit_Range( range, stream ); if ( error ) goto Exit; count2--; range++; } count--; strike++; } } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_free_sbit_strikes */ /* */ /* <Description> */ /* Releases the embedded bitmap tables. */ /* */ /* <Input> */ /* face :: The target face object. */ /* */ FT_LOCAL_DEF( void ) tt_face_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 */ FT_FREE( range->glyph_offsets ); FT_FREE( range->glyph_codes ); } } FT_FREE( strike->sbit_ranges ); strike->num_ranges = 0; } FT_FREE( face->sbit_strikes ); } face->num_sbit_strikes = 0; } FT_LOCAL_DEF( FT_Error ) tt_face_set_sbit_strike( TT_Face face, FT_Int x_ppem, FT_Int y_ppem, FT_ULong *astrike_index ) { FT_ULong i; if ( x_ppem < 0 || x_ppem > 255 || y_ppem < 1 || y_ppem > 255 ) return SFNT_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 SFNT_Err_Ok; } } return SFNT_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_RangeRec *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 = (FT_UShort)( 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; } } } /* fall-through */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -