00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <ft2build.h>
00024 #include FT_INTERNAL_DEBUG_H
00025 #include FT_INTERNAL_STREAM_H
00026 #include FT_TRUETYPE_TAGS_H
00027 #include "ttsbit.h"
00028
00029 #include "sferrors.h"
00030
00031
00032
00033
00034
00035
00036
00037
00038 #undef FT_COMPONENT
00039 #define FT_COMPONENT trace_ttsbit
00040
00041
00042 FT_LOCAL_DEF( FT_Error )
00043 tt_face_load_eblc( TT_Face face,
00044 FT_Stream stream )
00045 {
00046 FT_Error error = SFNT_Err_Ok;
00047 FT_Fixed version;
00048 FT_ULong num_strikes, table_size;
00049 FT_Byte* p;
00050 FT_Byte* p_limit;
00051 FT_UInt count;
00052
00053
00054 face->sbit_num_strikes = 0;
00055
00056
00057 error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
00058 if ( error )
00059 error = face->goto_table( face, TTAG_bloc, stream, &table_size );
00060 if ( error )
00061 goto Exit;
00062
00063 if ( table_size < 8 )
00064 {
00065 FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
00066 error = SFNT_Err_Invalid_File_Format;
00067 goto Exit;
00068 }
00069
00070 if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
00071 goto Exit;
00072
00073 face->sbit_table_size = table_size;
00074
00075 p = face->sbit_table;
00076 p_limit = p + table_size;
00077
00078 version = FT_NEXT_ULONG( p );
00079 num_strikes = FT_NEXT_ULONG( p );
00080
00081 if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
00082 {
00083 FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
00084 error = SFNT_Err_Invalid_File_Format;
00085 goto Fail;
00086 }
00087
00088
00089
00090
00091
00092 count = (FT_UInt)num_strikes;
00093 if ( 8 + 48UL * count > table_size )
00094 count = (FT_UInt)( ( p_limit - p ) / 48 );
00095
00096 face->sbit_num_strikes = count;
00097
00098 FT_TRACE3(( "sbit_num_strikes: %u\n", count ));
00099 Exit:
00100 return error;
00101
00102 Fail:
00103 FT_FRAME_RELEASE( face->sbit_table );
00104 face->sbit_table_size = 0;
00105 goto Exit;
00106 }
00107
00108
00109 FT_LOCAL_DEF( void )
00110 tt_face_free_eblc( TT_Face face )
00111 {
00112 FT_Stream stream = face->root.stream;
00113
00114
00115 FT_FRAME_RELEASE( face->sbit_table );
00116 face->sbit_table_size = 0;
00117 face->sbit_num_strikes = 0;
00118 }
00119
00120
00121 FT_LOCAL_DEF( FT_Error )
00122 tt_face_set_sbit_strike( TT_Face face,
00123 FT_Size_Request req,
00124 FT_ULong* astrike_index )
00125 {
00126 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
00127 }
00128
00129
00130 FT_LOCAL_DEF( FT_Error )
00131 tt_face_load_strike_metrics( TT_Face face,
00132 FT_ULong strike_index,
00133 FT_Size_Metrics* metrics )
00134 {
00135 FT_Byte* strike;
00136
00137
00138 if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
00139 return SFNT_Err_Invalid_Argument;
00140
00141 strike = face->sbit_table + 8 + strike_index * 48;
00142
00143 metrics->x_ppem = (FT_UShort)strike[44];
00144 metrics->y_ppem = (FT_UShort)strike[45];
00145
00146 metrics->ascender = (FT_Char)strike[16] << 6;
00147 metrics->descender = (FT_Char)strike[17] << 6;
00148 metrics->height = metrics->ascender - metrics->descender;
00149
00150
00151 metrics->max_advance = ( (FT_Char)strike[22] +
00152 strike[18] +
00153 (FT_Char)strike[23]
00154 ) << 6;
00155
00156 return SFNT_Err_Ok;
00157 }
00158
00159
00160 typedef struct TT_SBitDecoderRec_
00161 {
00162 TT_Face face;
00163 FT_Stream stream;
00164 FT_Bitmap* bitmap;
00165 TT_SBit_Metrics metrics;
00166 FT_Bool metrics_loaded;
00167 FT_Bool bitmap_allocated;
00168 FT_Byte bit_depth;
00169
00170 FT_ULong ebdt_start;
00171 FT_ULong ebdt_size;
00172
00173 FT_ULong strike_index_array;
00174 FT_ULong strike_index_count;
00175 FT_Byte* eblc_base;
00176 FT_Byte* eblc_limit;
00177
00178 } TT_SBitDecoderRec, *TT_SBitDecoder;
00179
00180
00181 static FT_Error
00182 tt_sbit_decoder_init( TT_SBitDecoder decoder,
00183 TT_Face face,
00184 FT_ULong strike_index,
00185 TT_SBit_MetricsRec* metrics )
00186 {
00187 FT_Error error;
00188 FT_Stream stream = face->root.stream;
00189 FT_ULong ebdt_size;
00190
00191
00192 error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
00193 if ( error )
00194 error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
00195 if ( error )
00196 goto Exit;
00197
00198 decoder->face = face;
00199 decoder->stream = stream;
00200 decoder->bitmap = &face->root.glyph->bitmap;
00201 decoder->metrics = metrics;
00202
00203 decoder->metrics_loaded = 0;
00204 decoder->bitmap_allocated = 0;
00205
00206 decoder->ebdt_start = FT_STREAM_POS();
00207 decoder->ebdt_size = ebdt_size;
00208
00209 decoder->eblc_base = face->sbit_table;
00210 decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
00211
00212
00213 {
00214 FT_Byte* p;
00215
00216
00217 if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
00218 {
00219 error = SFNT_Err_Invalid_File_Format;
00220 goto Exit;
00221 }
00222
00223 p = decoder->eblc_base + 8 + 48 * strike_index;
00224
00225 decoder->strike_index_array = FT_NEXT_ULONG( p );
00226 p += 4;
00227 decoder->strike_index_count = FT_NEXT_ULONG( p );
00228 p += 34;
00229 decoder->bit_depth = *p;
00230
00231 if ( decoder->strike_index_array > face->sbit_table_size ||
00232 decoder->strike_index_array + 8 * decoder->strike_index_count >
00233 face->sbit_table_size )
00234 error = SFNT_Err_Invalid_File_Format;
00235 }
00236
00237 Exit:
00238 return error;
00239 }
00240
00241
00242 static void
00243 tt_sbit_decoder_done( TT_SBitDecoder decoder )
00244 {
00245 FT_UNUSED( decoder );
00246 }
00247
00248
00249 static FT_Error
00250 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder )
00251 {
00252 FT_Error error = SFNT_Err_Ok;
00253 FT_UInt width, height;
00254 FT_Bitmap* map = decoder->bitmap;
00255 FT_Long size;
00256
00257
00258 if ( !decoder->metrics_loaded )
00259 {
00260 error = SFNT_Err_Invalid_Argument;
00261 goto Exit;
00262 }
00263
00264 width = decoder->metrics->width;
00265 height = decoder->metrics->height;
00266
00267 map->width = (int)width;
00268 map->rows = (int)height;
00269
00270 switch ( decoder->bit_depth )
00271 {
00272 case 1:
00273 map->pixel_mode = FT_PIXEL_MODE_MONO;
00274 map->pitch = ( map->width + 7 ) >> 3;
00275 break;
00276
00277 case 2:
00278 map->pixel_mode = FT_PIXEL_MODE_GRAY2;
00279 map->pitch = ( map->width + 3 ) >> 2;
00280 break;
00281
00282 case 4:
00283 map->pixel_mode = FT_PIXEL_MODE_GRAY4;
00284 map->pitch = ( map->width + 1 ) >> 1;
00285 break;
00286
00287 case 8:
00288 map->pixel_mode = FT_PIXEL_MODE_GRAY;
00289 map->pitch = map->width;
00290 break;
00291
00292 default:
00293 error = SFNT_Err_Invalid_File_Format;
00294 goto Exit;
00295 }
00296
00297 size = map->rows * map->pitch;
00298
00299
00300 if ( size == 0 )
00301 goto Exit;
00302
00303 error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
00304 if ( error )
00305 goto Exit;
00306
00307 decoder->bitmap_allocated = 1;
00308
00309 Exit:
00310 return error;
00311 }
00312
00313
00314 static FT_Error
00315 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder,
00316 FT_Byte* *pp,
00317 FT_Byte* limit,
00318 FT_Bool big )
00319 {
00320 FT_Byte* p = *pp;
00321 TT_SBit_Metrics metrics = decoder->metrics;
00322
00323
00324 if ( p + 5 > limit )
00325 goto Fail;
00326
00327 metrics->height = p[0];
00328 metrics->width = p[1];
00329 metrics->horiBearingX = (FT_Char)p[2];
00330 metrics->horiBearingY = (FT_Char)p[3];
00331 metrics->horiAdvance = p[4];
00332
00333 p += 5;
00334 if ( big )
00335 {
00336 if ( p + 3 > limit )
00337 goto Fail;
00338
00339 metrics->vertBearingX = (FT_Char)p[0];
00340 metrics->vertBearingY = (FT_Char)p[1];
00341 metrics->vertAdvance = p[2];
00342
00343 p += 3;
00344 }
00345
00346 decoder->metrics_loaded = 1;
00347 *pp = p;
00348 return SFNT_Err_Ok;
00349
00350 Fail:
00351 return SFNT_Err_Invalid_Argument;
00352 }
00353
00354
00355
00356 static FT_Error
00357 tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
00358 FT_UInt glyph_index,
00359 FT_Int x_pos,
00360 FT_Int y_pos );
00361
00362 typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder,
00363 FT_Byte* p,
00364 FT_Byte* plimit,
00365 FT_Int x_pos,
00366 FT_Int y_pos );
00367
00368
00369 static FT_Error
00370 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder,
00371 FT_Byte* p,
00372 FT_Byte* limit,
00373 FT_Int x_pos,
00374 FT_Int y_pos )
00375 {
00376 FT_Error error = SFNT_Err_Ok;
00377 FT_Byte* line;
00378 FT_Int bit_height, bit_width, pitch, width, height, h;
00379 FT_Bitmap* bitmap;
00380
00381
00382 if ( !decoder->bitmap_allocated )
00383 {
00384 error = tt_sbit_decoder_alloc_bitmap( decoder );
00385 if ( error )
00386 goto Exit;
00387 }
00388
00389
00390 bitmap = decoder->bitmap;
00391 bit_width = bitmap->width;
00392 bit_height = bitmap->rows;
00393 pitch = bitmap->pitch;
00394 line = bitmap->buffer;
00395
00396 width = decoder->metrics->width;
00397 height = decoder->metrics->height;
00398
00399 if ( x_pos < 0 || x_pos + width > bit_width ||
00400 y_pos < 0 || y_pos + height > bit_height )
00401 {
00402 error = SFNT_Err_Invalid_File_Format;
00403 goto Exit;
00404 }
00405
00406 if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
00407 {
00408 error = SFNT_Err_Invalid_File_Format;
00409 goto Exit;
00410 }
00411
00412
00413 line += y_pos * pitch + ( x_pos >> 3 );
00414 x_pos &= 7;
00415
00416 if ( x_pos == 0 )
00417 {
00418 for ( h = height; h > 0; h--, line += pitch )
00419 {
00420 FT_Byte* write = line;
00421 FT_Int w;
00422
00423
00424 for ( w = width; w >= 8; w -= 8 )
00425 {
00426 write[0] = (FT_Byte)( write[0] | *p++ );
00427 write += 1;
00428 }
00429
00430 if ( w > 0 )
00431 write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
00432 }
00433 }
00434 else
00435 {
00436 for ( h = height; h > 0; h--, line += pitch )
00437 {
00438 FT_Byte* write = line;
00439 FT_Int w;
00440 FT_UInt wval = 0;
00441
00442
00443 for ( w = width; w >= 8; w -= 8 )
00444 {
00445 wval = (FT_UInt)( wval | *p++ );
00446 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
00447 write += 1;
00448 wval <<= 8;
00449 }
00450
00451 if ( w > 0 )
00452 wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
00453
00454
00455
00456 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
00457
00458 if ( x_pos + w > 8 )
00459 {
00460 write++;
00461 wval <<= 8;
00462 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
00463 }
00464 }
00465 }
00466
00467 Exit:
00468 return error;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 static FT_Error
00508 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder,
00509 FT_Byte* p,
00510 FT_Byte* limit,
00511 FT_Int x_pos,
00512 FT_Int y_pos )
00513 {
00514 FT_Error error = SFNT_Err_Ok;
00515 FT_Byte* line;
00516 FT_Int bit_height, bit_width, pitch, width, height, h, nbits;
00517 FT_Bitmap* bitmap;
00518 FT_UShort rval;
00519
00520
00521 if ( !decoder->bitmap_allocated )
00522 {
00523 error = tt_sbit_decoder_alloc_bitmap( decoder );
00524 if ( error )
00525 goto Exit;
00526 }
00527
00528
00529 bitmap = decoder->bitmap;
00530 bit_width = bitmap->width;
00531 bit_height = bitmap->rows;
00532 pitch = bitmap->pitch;
00533 line = bitmap->buffer;
00534
00535 width = decoder->metrics->width;
00536 height = decoder->metrics->height;
00537
00538 if ( x_pos < 0 || x_pos + width > bit_width ||
00539 y_pos < 0 || y_pos + height > bit_height )
00540 {
00541 error = SFNT_Err_Invalid_File_Format;
00542 goto Exit;
00543 }
00544
00545 if ( p + ( ( width * height + 7 ) >> 3 ) > limit )
00546 {
00547 error = SFNT_Err_Invalid_File_Format;
00548 goto Exit;
00549 }
00550
00551
00552
00553
00554 line += y_pos * pitch + ( x_pos >> 3 );
00555 x_pos &= 7;
00556
00557
00558 rval = 0;
00559 nbits = 0;
00560
00561 for ( h = height; h > 0; h--, line += pitch )
00562 {
00563 FT_Byte* write = line;
00564 FT_Int w = width;
00565
00566
00567
00568 if ( x_pos )
00569 {
00570 w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
00571
00572 if ( h == height )
00573 {
00574 rval = *p++;
00575 nbits = x_pos;
00576 }
00577 else if ( nbits < w )
00578 {
00579 if ( p < limit )
00580 rval |= *p++;
00581 nbits += 8 - w;
00582 }
00583 else
00584 {
00585 rval >>= 8;
00586 nbits -= w;
00587 }
00588
00589 *write++ |= ( ( rval >> nbits ) & 0xFF ) &
00590 ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
00591 rval <<= 8;
00592
00593 w = width - w;
00594 }
00595
00596
00597 for ( ; w >= 8; w -= 8 )
00598 {
00599 rval |= *p++;
00600 *write++ |= ( rval >> nbits ) & 0xFF;
00601
00602 rval <<= 8;
00603 }
00604
00605
00606 if ( w > 0 )
00607 {
00608 if ( nbits < w )
00609 {
00610 if ( p < limit )
00611 rval |= *p++;
00612 *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
00613 nbits += 8 - w;
00614
00615 rval <<= 8;
00616 }
00617 else
00618 {
00619 *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
00620 nbits -= w;
00621 }
00622 }
00623 }
00624
00625 Exit:
00626 return error;
00627 }
00628
00629
00630 static FT_Error
00631 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder,
00632 FT_Byte* p,
00633 FT_Byte* limit,
00634 FT_Int x_pos,
00635 FT_Int y_pos )
00636 {
00637 FT_Error error = SFNT_Err_Ok;
00638 FT_UInt num_components, nn;
00639
00640 FT_Char horiBearingX = decoder->metrics->horiBearingX;
00641 FT_Char horiBearingY = decoder->metrics->horiBearingY;
00642 FT_Byte horiAdvance = decoder->metrics->horiAdvance;
00643 FT_Char vertBearingX = decoder->metrics->vertBearingX;
00644 FT_Char vertBearingY = decoder->metrics->vertBearingY;
00645 FT_Byte vertAdvance = decoder->metrics->vertAdvance;
00646
00647
00648 if ( p + 2 > limit )
00649 goto Fail;
00650
00651 num_components = FT_NEXT_USHORT( p );
00652 if ( p + 4 * num_components > limit )
00653 goto Fail;
00654
00655 if ( !decoder->bitmap_allocated )
00656 {
00657 error = tt_sbit_decoder_alloc_bitmap( decoder );
00658 if ( error )
00659 goto Exit;
00660 }
00661
00662 for ( nn = 0; nn < num_components; nn++ )
00663 {
00664 FT_UInt gindex = FT_NEXT_USHORT( p );
00665 FT_Byte dx = FT_NEXT_BYTE( p );
00666 FT_Byte dy = FT_NEXT_BYTE( p );
00667
00668
00669
00670 error = tt_sbit_decoder_load_image( decoder, gindex,
00671 x_pos + dx, y_pos + dy );
00672 if ( error )
00673 break;
00674 }
00675
00676 decoder->metrics->horiBearingX = horiBearingX;
00677 decoder->metrics->horiBearingY = horiBearingY;
00678 decoder->metrics->horiAdvance = horiAdvance;
00679 decoder->metrics->vertBearingX = vertBearingX;
00680 decoder->metrics->vertBearingY = vertBearingY;
00681 decoder->metrics->vertAdvance = vertAdvance;
00682 decoder->metrics->width = (FT_UInt)decoder->bitmap->width;
00683 decoder->metrics->height = (FT_UInt)decoder->bitmap->rows;
00684
00685 Exit:
00686 return error;
00687
00688 Fail:
00689 error = SFNT_Err_Invalid_File_Format;
00690 goto Exit;
00691 }
00692
00693
00694 static FT_Error
00695 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder,
00696 FT_UInt glyph_format,
00697 FT_ULong glyph_start,
00698 FT_ULong glyph_size,
00699 FT_Int x_pos,
00700 FT_Int y_pos )
00701 {
00702 FT_Error error;
00703 FT_Stream stream = decoder->stream;
00704 FT_Byte* p;
00705 FT_Byte* p_limit;
00706 FT_Byte* data;
00707
00708
00709
00710 if ( glyph_start + glyph_size > decoder->ebdt_size )
00711 {
00712 error = SFNT_Err_Invalid_Argument;
00713 goto Exit;
00714 }
00715
00716 if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
00717 FT_FRAME_EXTRACT( glyph_size, data ) )
00718 goto Exit;
00719
00720 p = data;
00721 p_limit = p + glyph_size;
00722
00723
00724 switch ( glyph_format )
00725 {
00726 case 1:
00727 case 2:
00728 case 8:
00729 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
00730 break;
00731
00732 case 6:
00733 case 7:
00734 case 9:
00735 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
00736 break;
00737
00738 default:
00739 error = SFNT_Err_Ok;
00740 }
00741
00742 if ( error )
00743 goto Fail;
00744
00745 {
00746 TT_SBitDecoder_LoadFunc loader;
00747
00748
00749 switch ( glyph_format )
00750 {
00751 case 1:
00752 case 6:
00753 loader = tt_sbit_decoder_load_byte_aligned;
00754 break;
00755
00756 case 2:
00757 case 5:
00758 case 7:
00759 loader = tt_sbit_decoder_load_bit_aligned;
00760 break;
00761
00762 case 8:
00763 if ( p + 1 > p_limit )
00764 goto Fail;
00765
00766 p += 1;
00767
00768
00769 case 9:
00770 loader = tt_sbit_decoder_load_compound;
00771 break;
00772
00773 default:
00774 goto Fail;
00775 }
00776
00777 error = loader( decoder, p, p_limit, x_pos, y_pos );
00778 }
00779
00780 Fail:
00781 FT_FRAME_RELEASE( data );
00782
00783 Exit:
00784 return error;
00785 }
00786
00787
00788 static FT_Error
00789 tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
00790 FT_UInt glyph_index,
00791 FT_Int x_pos,
00792 FT_Int y_pos )
00793 {
00794
00795
00796
00797
00798
00799 FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
00800 FT_Byte* p_limit = decoder->eblc_limit;
00801 FT_ULong num_ranges = decoder->strike_index_count;
00802 FT_UInt start, end, index_format, image_format;
00803 FT_ULong image_start = 0, image_end = 0, image_offset;
00804
00805
00806 for ( ; num_ranges > 0; num_ranges-- )
00807 {
00808 start = FT_NEXT_USHORT( p );
00809 end = FT_NEXT_USHORT( p );
00810
00811 if ( glyph_index >= start && glyph_index <= end )
00812 goto FoundRange;
00813
00814 p += 4;
00815 }
00816 goto NoBitmap;
00817
00818 FoundRange:
00819 image_offset = FT_NEXT_ULONG( p );
00820
00821
00822 if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
00823 decoder->eblc_base )
00824 goto Failure;
00825
00826 p = decoder->eblc_base + decoder->strike_index_array + image_offset;
00827 if ( p + 8 > p_limit )
00828 goto NoBitmap;
00829
00830
00831 index_format = FT_NEXT_USHORT( p );
00832 image_format = FT_NEXT_USHORT( p );
00833 image_offset = FT_NEXT_ULONG ( p );
00834
00835 switch ( index_format )
00836 {
00837 case 1:
00838 {
00839 p += 4 * ( glyph_index - start );
00840 if ( p + 8 > p_limit )
00841 goto NoBitmap;
00842
00843 image_start = FT_NEXT_ULONG( p );
00844 image_end = FT_NEXT_ULONG( p );
00845
00846 if ( image_start == image_end )
00847 goto NoBitmap;
00848 }
00849 break;
00850
00851 case 2:
00852 {
00853 FT_ULong image_size;
00854
00855
00856 if ( p + 12 > p_limit )
00857 goto NoBitmap;
00858
00859 image_size = FT_NEXT_ULONG( p );
00860
00861 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
00862 goto NoBitmap;
00863
00864 image_start = image_size * ( glyph_index - start );
00865 image_end = image_start + image_size;
00866 }
00867 break;
00868
00869 case 3:
00870 {
00871 p += 2 * ( glyph_index - start );
00872 if ( p + 4 > p_limit )
00873 goto NoBitmap;
00874
00875 image_start = FT_NEXT_USHORT( p );
00876 image_end = FT_NEXT_USHORT( p );
00877
00878 if ( image_start == image_end )
00879 goto NoBitmap;
00880 }
00881 break;
00882
00883 case 4:
00884 {
00885 FT_ULong mm, num_glyphs;
00886
00887
00888 if ( p + 4 > p_limit )
00889 goto NoBitmap;
00890
00891 num_glyphs = FT_NEXT_ULONG( p );
00892
00893
00894 if ( p + ( num_glyphs + 1 ) * 4 < p )
00895 goto Failure;
00896
00897 if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
00898 goto NoBitmap;
00899
00900 for ( mm = 0; mm < num_glyphs; mm++ )
00901 {
00902 FT_UInt gindex = FT_NEXT_USHORT( p );
00903
00904
00905 if ( gindex == glyph_index )
00906 {
00907 image_start = FT_NEXT_USHORT( p );
00908 p += 2;
00909 image_end = FT_PEEK_USHORT( p );
00910 break;
00911 }
00912 p += 2;
00913 }
00914
00915 if ( mm >= num_glyphs )
00916 goto NoBitmap;
00917 }
00918 break;
00919
00920 case 5:
00921 {
00922 FT_ULong image_size, mm, num_glyphs;
00923
00924
00925 if ( p + 16 > p_limit )
00926 goto NoBitmap;
00927
00928 image_size = FT_NEXT_ULONG( p );
00929
00930 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
00931 goto NoBitmap;
00932
00933 num_glyphs = FT_NEXT_ULONG( p );
00934
00935
00936 if ( p + 2 * num_glyphs < p )
00937 goto Failure;
00938
00939 if ( p + 2 * num_glyphs > p_limit )
00940 goto NoBitmap;
00941
00942 for ( mm = 0; mm < num_glyphs; mm++ )
00943 {
00944 FT_UInt gindex = FT_NEXT_USHORT( p );
00945
00946
00947 if ( gindex == glyph_index )
00948 break;
00949 }
00950
00951 if ( mm >= num_glyphs )
00952 goto NoBitmap;
00953
00954 image_start = image_size * mm;
00955 image_end = image_start + image_size;
00956 }
00957 break;
00958
00959 default:
00960 goto NoBitmap;
00961 }
00962
00963 if ( image_start > image_end )
00964 goto NoBitmap;
00965
00966 image_end -= image_start;
00967 image_start = image_offset + image_start;
00968
00969 return tt_sbit_decoder_load_bitmap( decoder,
00970 image_format,
00971 image_start,
00972 image_end,
00973 x_pos,
00974 y_pos );
00975
00976 Failure:
00977 return SFNT_Err_Invalid_Table;
00978
00979 NoBitmap:
00980 return SFNT_Err_Invalid_Argument;
00981 }
00982
00983
00984 FT_LOCAL( FT_Error )
00985 tt_face_load_sbit_image( TT_Face face,
00986 FT_ULong strike_index,
00987 FT_UInt glyph_index,
00988 FT_UInt load_flags,
00989 FT_Stream stream,
00990 FT_Bitmap *map,
00991 TT_SBit_MetricsRec *metrics )
00992 {
00993 TT_SBitDecoderRec decoder[1];
00994 FT_Error error;
00995
00996 FT_UNUSED( load_flags );
00997 FT_UNUSED( stream );
00998 FT_UNUSED( map );
00999
01000
01001 error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
01002 if ( !error )
01003 {
01004 error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );
01005 tt_sbit_decoder_done( decoder );
01006 }
01007
01008 return error;
01009 }
01010
01011