📄 ttsbit.c
字号:
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 = SFNT_Err_Invalid_File_Format; } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_load_eblc */ /* */ /* <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_eblc( 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; static 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 }; static 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 }; static 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; /* read each range */ if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) || FT_FRAME_ENTER( strike->num_ranges * 8L ) ) goto Exit; if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) ) 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_eblc */ /* */ /* <Description> */ /* Releases the embedded bitmap tables. */ /* */ /* <Input> */ /* face :: The target face object. */ /* */ FT_LOCAL_DEF( void ) tt_face_free_eblc( 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_Size_Request req, FT_ULong* astrike_index ) { return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); } FT_LOCAL_DEF( FT_Error ) tt_face_load_strike_metrics( TT_Face face, FT_ULong strike_index, FT_Size_Metrics* metrics ) { TT_SBit_Strike strike; if ( strike_index >= face->num_sbit_strikes ) return SFNT_Err_Invalid_Argument; strike = face->sbit_strikes + strike_index; metrics->x_ppem = strike->x_ppem; metrics->y_ppem = strike->y_ppem; metrics->ascender = strike->hori.ascender << 6; metrics->descender = strike->hori.descender << 6; /* XXX: Is this correct? */ metrics->max_advance = ( strike->hori.min_origin_SB + strike->hori.max_width + strike->hori.min_advance_SB ) << 6; metrics->height = metrics->ascender - metrics->descender; return SFNT_Err_Ok; } /*************************************************************************/ /* */ /* <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++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -