📄 ftxsbit.c
字号:
metrics->height = GET_Byte(); metrics->width = GET_Byte(); metrics->horiBearingX = GET_Char(); metrics->horiBearingY = GET_Char(); metrics->horiAdvance = GET_Byte(); metrics->vertBearingX = GET_Char(); metrics->vertBearingY = GET_Char(); metrics->vertAdvance = GET_Byte(); FORGET_Frame(); } if ( format != 2 ) /* load range codes, formats 4 and 5 */ error = Load_Range_Codes( range, face, (format == 4) ); } break; default: error = TT_Err_Invalid_File_Format; } PTRACE3(( "Embedded Bitmap Location Tables loaded.\n" )); return error; }/******************************************************************* * * Function : Load_TrueType_Eblc * * Description : Loads the Eblc table directory into face table. * * Input : face face record to look for * * Output : Error code. * ******************************************************************/ static TT_Error Load_TrueType_Eblc( PFace face, TT_EBLC* eblc ) { DEFINE_LOCALS; ULong eblc_offset; UShort i; Long table; TT_SBit_Strike* strike; PTRACE2(( "Load_EBLC_Table( %08lx )\n", (long)face )); eblc->version = 0; /* Try to find the `EBLC' or `bloc' table in the font files. */ /* Both tags describe the same table; `EBLC' is for OpenType */ /* fonts while `bloc' is for TrueType GX fonts. Many fonts */ /* contain both tags pointing to the same table. */ table = TT_LookUp_Table( face, TTAG_EBLC ); if ( table < 0 ) table = TT_LookUp_Table( face, TTAG_bloc ); if ( table < 0 ) /* This table is optional */ return TT_Err_Ok; eblc_offset = face->dirTables[table].Offset; if ( FILE_Seek( eblc_offset ) || ACCESS_Frame( 8L ) ) return error; eblc->version = GET_ULong(); eblc->num_strikes = GET_ULong(); FORGET_Frame(); PTRACE2(( "-- Tables count: %12u\n", eblc->num_strikes )); PTRACE2(( "-- Format version: %08lx\n", eblc->version )); if ( eblc->version != 0x00020000 ) { PERROR(( "Invalid file format!\n" )); return TT_Err_Invalid_File_Format; } if ( ALLOC_ARRAY( eblc->strikes, eblc->num_strikes, TT_SBit_Strike ) || ACCESS_Frame( 48L * eblc->num_strikes ) ) return error; strike = eblc->strikes; for ( i = 0; i < eblc->num_strikes; i++, strike++ ) { /* loop through the tables and get all entries */ ULong indexTablesSize; TT_SBit_Line_Metrics* metrics; Int count; strike->ranges_offset = GET_ULong(); indexTablesSize = GET_ULong(); /* dont' save */ strike->num_ranges = GET_ULong(); strike->color_ref = GET_ULong(); /* load horizontal and vertical metrics */ metrics = &strike->hori; for ( count = 2; count > 0; count-- ) { metrics->ascender = GET_Char(); metrics->descender = GET_Char(); metrics->max_width = GET_Byte(); metrics->caret_slope_numerator = GET_Char(); metrics->caret_slope_denominator = GET_Char(); metrics->caret_offset = GET_Char(); metrics->min_origin_SB = GET_Char(); metrics->min_advance_SB = GET_Char(); metrics->max_before_BL = GET_Char(); metrics->min_after_BL = GET_Char(); metrics->pads[0] = GET_Char(); metrics->pads[1] = GET_Char(); metrics = &strike->vert; } 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(); PTRACE4(( " start - end - ppemX - ppemY\n" )); PTRACE4(( " %04d - %04d - %3u - %3u\n", strike->start_glyph, strike->end_glyph, strike->x_ppem, strike->y_ppem )); } FORGET_Frame(); /* Load EBLC index ranges */ strike = eblc->strikes; for ( i = 0; i < eblc->num_strikes; i++, strike++ ) { TT_SBit_Range* range; UShort count = strike->num_ranges; /* loop through the tables and get all entries */ if ( ALLOC_ARRAY( strike->sbit_ranges, strike->num_ranges, TT_SBit_Range ) || FILE_Seek( eblc_offset + strike->ranges_offset ) || ACCESS_Frame( strike->num_ranges * 8L ) ) return error; for ( range = strike->sbit_ranges; count > 0; count--, range++ ) { range->first_glyph = GET_UShort(); range->last_glyph = GET_UShort(); range->table_offset = eblc_offset + strike->ranges_offset + GET_ULong(); } FORGET_Frame(); /* Now, read each index table */ range = strike->sbit_ranges; for ( count = strike->num_ranges; count > 0; count--, range++ ) { /* Read the header */ if ( FILE_Seek( range->table_offset ) || ACCESS_Frame( 8L ) ) return error;; range->index_format = GET_UShort(); range->image_format = GET_UShort(); range->image_offset = GET_ULong(); FORGET_Frame(); error = Load_SBit_Range( strike, range, face ); if (error) return error; } } return TT_Err_Ok; } static void Free_TrueType_Eblc( TT_EBLC* eblc ) { if ( eblc ) { ULong i; TT_SBit_Strike* strike = eblc->strikes; strike = eblc->strikes; for ( i = eblc->num_strikes; i > 0; i--, strike++ ) { /* for each strike, release all glyph ranges */ TT_SBit_Range* range = strike->sbit_ranges; Int n; for ( n = strike->num_ranges; n > 0; n--, range++ ) { /* release a range */ FREE( range->glyph_offsets ); FREE( range->glyph_codes ); } FREE( strike->sbit_ranges ); strike->num_ranges = 0; } FREE( eblc->strikes ); eblc->num_strikes = 0; eblc->version = 0; } } static TT_Error Load_SBit_Metrics( TT_Big_Glyph_Metrics* metrics, TT_SBit_Range* range, ULong ebdt_offset ) { TT_Error error; Byte height, width; /* copy bitmap metrics for formats 2 and 5 */ if ( ( ( range->index_format == 2 ) || ( range->index_format == 5 ) ) && ( range->image_format == 5 ) ) /* metrics are taken from current image bitmap */ /* i.e. from `image.metrics' */ { TT_SBit_Metrics* rmetrics = &range->metrics; metrics->bbox.xMin = rmetrics->horiBearingX; metrics->bbox.xMax = metrics->bbox.xMin + rmetrics->width; metrics->bbox.yMax = rmetrics->horiBearingY; metrics->bbox.yMin = metrics->bbox.yMax - rmetrics->height; metrics->horiBearingX = rmetrics->horiBearingX; metrics->horiBearingY = metrics->bbox.yMax; metrics->horiAdvance = rmetrics->horiAdvance; metrics->vertBearingX = rmetrics->vertBearingX; metrics->vertBearingY = rmetrics->vertBearingY; metrics->vertAdvance = rmetrics->vertAdvance; return TT_Err_Ok; } switch ( range->image_format ) { case 1: case 2: case 6: case 7: case 8: case 9: { Long length = 5L; if ( range->image_format == 8 ) length++; /* read the small metrics */ if ( ACCESS_Frame( length ) ) return error; height = GET_Byte(); width = GET_Byte(); metrics->horiBearingX = GET_Char(); metrics->horiBearingY = GET_Char(); metrics->horiAdvance = GET_Byte(); FORGET_Frame(); metrics->bbox.xMin = metrics->horiBearingX; metrics->bbox.yMax = metrics->horiBearingY; metrics->bbox.xMax = metrics->bbox.xMin + width; metrics->bbox.yMin = metrics->bbox.yMax - height; /* read the rest of the big metrics for the formats */ /* that support it. */ if ( ( range->image_format >= 6 ) && ( range->image_format != 8 ) ) { if ( ACCESS_Frame( 3L ) ) return error; metrics->vertBearingX = (Int)GET_Char(); metrics->vertBearingY = (Int)GET_Char(); metrics->vertAdvance = (Int)GET_Char(); FORGET_Frame(); } else { /* XXX: How can we fill these when the information isn't */ /* available? */ metrics->vertBearingX = 0; metrics->vertBearingY = 0; metrics->vertAdvance = 0; } } break; case 5: /* metrics are taken from current image bitmap */ /* i.e. from 'image.metrics' */ break; default: PERROR(( "Unsupported embedded bitmap format!\n" )); return TT_Err_Invalid_File_Format; } return TT_Err_Ok; } static TT_Error Load_SBit_Image( TT_SBit_Strike strike, UShort glyph_index, Byte x_offset, Byte y_offset, ULong ebdt_offset, TT_SBit_Image* image, UShort component_depth ) { TT_Error error; Byte height, width; ULong bitmap_offset; TT_SBit_Range* range = 0; TT_Big_Glyph_Metrics metrics; /********************************************************************/ /* */ /* Scan the strike's range for the position/metrics of the source */ /* glyph. */ { UShort count = strike.num_ranges; TT_SBit_Range* cur = strike.sbit_ranges; for ( ; count > 0; count--, cur++ ) { /* look for the glyph in the current range */ switch ( cur->index_format ) { case 1: case 2: case 3: if ( glyph_index >= cur->first_glyph && glyph_index <= cur->last_glyph ) { UShort delta = glyph_index - cur->first_glyph; range = cur; bitmap_offset = cur->index_format == 2 ? cur->image_offset + cur->image_size * delta : cur->glyph_offsets[delta]; goto Found; } break; case 4: case 5: { UShort n; for ( n = 0; n < cur->num_glyphs; n++ ) if ( cur->glyph_codes[n] == glyph_index ) { range = cur; bitmap_offset = cur->index_format == 4 ? cur->glyph_offsets[n] : cur->image_offset + cur->image_size * n; goto Found; } } break; default: return TT_Err_Invalid_Glyph_Index; } } /* Not found */ return TT_Err_Invalid_Glyph_Index; } Found: if ( FILE_Seek( ebdt_offset + bitmap_offset ) ) return error; /* First of all, load the metrics if needed */ error = Load_SBit_Metrics( &metrics, range, ebdt_offset ); if ( error ) return error; width = metrics.bbox.xMax - metrics.bbox.xMin; height = metrics.bbox.yMax - metrics.bbox.yMin; if ( !component_depth ) { image->metrics = metrics; image->map.width = width; image->map.rows = height; image->map.cols = (width + 7) >> 3; image->map.size = height * image->map.cols; if ( REALLOC( image->map.bitmap, image->map.size ) ) return error; MEM_Set( image->map.bitmap, 0, image->map.size ); } /* Now, load the data as needed */ switch ( range->image_format ) { case 1: case 6: /* byte-aligned data */ error = Load_BitmapData( image, height * (( width + 7 ) >> 3), x_offset, y_offset, width, height, 1 ); if ( error ) return error; break; case 2: case 5: case 7: error = Load_BitmapData( image, (width * height + 7) >> 3, x_offset, y_offset, width, height, 0 ); if ( error ) return error; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -