ttsbit0.c revision a38fc482eeeb2c1929803c233835369dcf1b8781
1/***************************************************************************/ 2/* */ 3/* ttsbit0.c */ 4/* */ 5/* TrueType and OpenType embedded bitmap support (body). */ 6/* This is a heap-optimized version. */ 7/* */ 8/* Copyright 2005, 2006, 2007, 2008 by */ 9/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 10/* */ 11/* This file is part of the FreeType project, and may only be used, */ 12/* modified, and distributed under the terms of the FreeType project */ 13/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 14/* this file you indicate that you have read the license and */ 15/* understand and accept it fully. */ 16/* */ 17/***************************************************************************/ 18 19 20/* This file is included by ttsbit.c */ 21 22 23#include <ft2build.h> 24#include FT_INTERNAL_DEBUG_H 25#include FT_INTERNAL_STREAM_H 26#include FT_TRUETYPE_TAGS_H 27#include "ttsbit.h" 28 29#include "sferrors.h" 30 31 32 /*************************************************************************/ 33 /* */ 34 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 35 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 36 /* messages during execution. */ 37 /* */ 38#undef FT_COMPONENT 39#define FT_COMPONENT trace_ttsbit 40 41 42 static const FT_Frame_Field tt_sbit_line_metrics_fields[] = 43 { 44#undef FT_STRUCTURE 45#define FT_STRUCTURE TT_SBit_LineMetricsRec 46 47 /* no FT_FRAME_START */ 48 FT_FRAME_CHAR( ascender ), 49 FT_FRAME_CHAR( descender ), 50 FT_FRAME_BYTE( max_width ), 51 52 FT_FRAME_CHAR( caret_slope_numerator ), 53 FT_FRAME_CHAR( caret_slope_denominator ), 54 FT_FRAME_CHAR( caret_offset ), 55 56 FT_FRAME_CHAR( min_origin_SB ), 57 FT_FRAME_CHAR( min_advance_SB ), 58 FT_FRAME_CHAR( max_before_BL ), 59 FT_FRAME_CHAR( min_after_BL ), 60 FT_FRAME_CHAR( pads[0] ), 61 FT_FRAME_CHAR( pads[1] ), 62 FT_FRAME_END 63 }; 64 65 static const FT_Frame_Field tt_strike_start_fields[] = 66 { 67#undef FT_STRUCTURE 68#define FT_STRUCTURE TT_SBit_StrikeRec 69 70 /* no FT_FRAME_START */ 71 FT_FRAME_ULONG( ranges_offset ), 72 FT_FRAME_SKIP_LONG, 73 FT_FRAME_ULONG( num_ranges ), 74 FT_FRAME_ULONG( color_ref ), 75 FT_FRAME_END 76 }; 77 78 static const FT_Frame_Field tt_strike_end_fields[] = 79 { 80 /* no FT_FRAME_START */ 81 FT_FRAME_USHORT( start_glyph ), 82 FT_FRAME_USHORT( end_glyph ), 83 FT_FRAME_BYTE ( x_ppem ), 84 FT_FRAME_BYTE ( y_ppem ), 85 FT_FRAME_BYTE ( bit_depth ), 86 FT_FRAME_CHAR ( flags ), 87 FT_FRAME_END 88 }; 89 90 91 FT_LOCAL_DEF( FT_Error ) 92 tt_face_load_eblc( TT_Face face, 93 FT_Stream stream ) 94 { 95 FT_Error error = SFNT_Err_Ok; 96 FT_Fixed version; 97 FT_ULong num_strikes, table_size; 98 FT_Byte* p; 99 FT_Byte* p_limit; 100 FT_UInt count; 101 102 103 face->sbit_num_strikes = 0; 104 105 /* this table is optional */ 106 error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); 107 if ( error ) 108 error = face->goto_table( face, TTAG_bloc, stream, &table_size ); 109 if ( error ) 110 goto Exit; 111 112 if ( table_size < 8 ) 113 { 114 FT_ERROR(( "%s: table too short!\n", "tt_face_load_sbit_strikes" )); 115 error = SFNT_Err_Invalid_File_Format; 116 goto Exit; 117 } 118 119 if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) 120 goto Exit; 121 122 face->sbit_table_size = table_size; 123 124 p = face->sbit_table; 125 p_limit = p + table_size; 126 127 version = FT_NEXT_ULONG( p ); 128 num_strikes = FT_NEXT_ULONG( p ); 129 130 if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) 131 { 132 FT_ERROR(( "%s: invalid table version!\n", 133 "tt_face_load_sbit_strikes" )); 134 error = SFNT_Err_Invalid_File_Format; 135 goto Fail; 136 } 137 138 /* 139 * Count the number of strikes available in the table. We are a bit 140 * paranoid there and don't trust the data. 141 */ 142 count = (FT_UInt)num_strikes; 143 if ( 8 + 48UL * count > table_size ) 144 count = (FT_UInt)( ( p_limit - p ) / 48 ); 145 146 face->sbit_num_strikes = count; 147 148 FT_TRACE3(( "sbit_num_strikes: %u\n", count )); 149 Exit: 150 return error; 151 152 Fail: 153 FT_FRAME_RELEASE( face->sbit_table ); 154 face->sbit_table_size = 0; 155 goto Exit; 156 } 157 158 159 FT_LOCAL_DEF( void ) 160 tt_face_free_eblc( TT_Face face ) 161 { 162 FT_Stream stream = face->root.stream; 163 164 165 FT_FRAME_RELEASE( face->sbit_table ); 166 face->sbit_table_size = 0; 167 face->sbit_num_strikes = 0; 168 } 169 170 171 FT_LOCAL_DEF( FT_Error ) 172 tt_face_set_sbit_strike( TT_Face face, 173 FT_Size_Request req, 174 FT_ULong* astrike_index ) 175 { 176 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); 177 } 178 179 180 FT_LOCAL_DEF( FT_Error ) 181 tt_face_load_strike_metrics( TT_Face face, 182 FT_ULong strike_index, 183 FT_Size_Metrics* metrics ) 184 { 185 FT_Byte* strike; 186 187 188 if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) 189 return SFNT_Err_Invalid_Argument; 190 191 strike = face->sbit_table + 8 + strike_index * 48; 192 193 metrics->x_ppem = (FT_UShort)strike[44]; 194 metrics->y_ppem = (FT_UShort)strike[45]; 195 196 metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ 197 metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ 198 metrics->height = metrics->ascender - metrics->descender; 199 200 /* XXX: Is this correct? */ 201 metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ 202 strike[18] + /* max_width */ 203 (FT_Char)strike[23] /* min_advance_SB */ 204 ) << 6; 205 206 return SFNT_Err_Ok; 207 } 208 209 210 typedef struct TT_SBitDecoderRec_ 211 { 212 TT_Face face; 213 FT_Stream stream; 214 FT_Bitmap* bitmap; 215 TT_SBit_Metrics metrics; 216 FT_Bool metrics_loaded; 217 FT_Bool bitmap_allocated; 218 FT_Byte bit_depth; 219 220 FT_ULong ebdt_start; 221 FT_ULong ebdt_size; 222 223 FT_ULong strike_index_array; 224 FT_ULong strike_index_count; 225 FT_Byte* eblc_base; 226 FT_Byte* eblc_limit; 227 228 } TT_SBitDecoderRec, *TT_SBitDecoder; 229 230 231 static FT_Error 232 tt_sbit_decoder_init( TT_SBitDecoder decoder, 233 TT_Face face, 234 FT_ULong strike_index, 235 TT_SBit_MetricsRec* metrics ) 236 { 237 FT_Error error; 238 FT_Stream stream = face->root.stream; 239 FT_ULong ebdt_size; 240 241 242 error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); 243 if ( error ) 244 error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); 245 if ( error ) 246 goto Exit; 247 248 decoder->face = face; 249 decoder->stream = stream; 250 decoder->bitmap = &face->root.glyph->bitmap; 251 decoder->metrics = metrics; 252 253 decoder->metrics_loaded = 0; 254 decoder->bitmap_allocated = 0; 255 256 decoder->ebdt_start = FT_STREAM_POS(); 257 decoder->ebdt_size = ebdt_size; 258 259 decoder->eblc_base = face->sbit_table; 260 decoder->eblc_limit = face->sbit_table + face->sbit_table_size; 261 262 /* now find the strike corresponding to the index */ 263 { 264 FT_Byte* p; 265 266 267 if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size ) 268 { 269 error = SFNT_Err_Invalid_File_Format; 270 goto Exit; 271 } 272 273 p = decoder->eblc_base + 8 + 48 * strike_index; 274 275 decoder->strike_index_array = FT_NEXT_ULONG( p ); 276 p += 4; 277 decoder->strike_index_count = FT_NEXT_ULONG( p ); 278 p += 34; 279 decoder->bit_depth = *p; 280 281 if ( decoder->strike_index_array > face->sbit_table_size || 282 decoder->strike_index_array + 8 * decoder->strike_index_count > 283 face->sbit_table_size ) 284 error = SFNT_Err_Invalid_File_Format; 285 } 286 287 Exit: 288 return error; 289 } 290 291 292 static void 293 tt_sbit_decoder_done( TT_SBitDecoder decoder ) 294 { 295 FT_UNUSED( decoder ); 296 } 297 298 299 static FT_Error 300 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) 301 { 302 FT_Error error = SFNT_Err_Ok; 303 FT_UInt width, height; 304 FT_Bitmap* map = decoder->bitmap; 305 FT_Long size; 306 307 308 if ( !decoder->metrics_loaded ) 309 { 310 error = SFNT_Err_Invalid_Argument; 311 goto Exit; 312 } 313 314 width = decoder->metrics->width; 315 height = decoder->metrics->height; 316 317 map->width = (int)width; 318 map->rows = (int)height; 319 320 switch ( decoder->bit_depth ) 321 { 322 case 1: 323 map->pixel_mode = FT_PIXEL_MODE_MONO; 324 map->pitch = ( map->width + 7 ) >> 3; 325 break; 326 327 case 2: 328 map->pixel_mode = FT_PIXEL_MODE_GRAY2; 329 map->pitch = ( map->width + 3 ) >> 2; 330 break; 331 332 case 4: 333 map->pixel_mode = FT_PIXEL_MODE_GRAY4; 334 map->pitch = ( map->width + 1 ) >> 1; 335 break; 336 337 case 8: 338 map->pixel_mode = FT_PIXEL_MODE_GRAY; 339 map->pitch = map->width; 340 break; 341 342 default: 343 error = SFNT_Err_Invalid_File_Format; 344 goto Exit; 345 } 346 347 size = map->rows * map->pitch; 348 349 /* check that there is no empty image */ 350 if ( size == 0 ) 351 goto Exit; /* exit successfully! */ 352 353 error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); 354 if ( error ) 355 goto Exit; 356 357 decoder->bitmap_allocated = 1; 358 359 Exit: 360 return error; 361 } 362 363 364 static FT_Error 365 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder, 366 FT_Byte* *pp, 367 FT_Byte* limit, 368 FT_Bool big ) 369 { 370 FT_Byte* p = *pp; 371 TT_SBit_Metrics metrics = decoder->metrics; 372 373 374 if ( p + 5 > limit ) 375 goto Fail; 376 377 if ( !decoder->metrics_loaded ) 378 { 379 metrics->height = p[0]; 380 metrics->width = p[1]; 381 metrics->horiBearingX = (FT_Char)p[2]; 382 metrics->horiBearingY = (FT_Char)p[3]; 383 metrics->horiAdvance = p[4]; 384 } 385 386 p += 5; 387 if ( big ) 388 { 389 if ( p + 3 > limit ) 390 goto Fail; 391 392 if ( !decoder->metrics_loaded ) 393 { 394 metrics->vertBearingX = (FT_Char)p[0]; 395 metrics->vertBearingY = (FT_Char)p[1]; 396 metrics->vertAdvance = p[2]; 397 } 398 399 p += 3; 400 } 401 402 decoder->metrics_loaded = 1; 403 *pp = p; 404 return 0; 405 406 Fail: 407 return SFNT_Err_Invalid_Argument; 408 } 409 410 411 /* forward declaration */ 412 static FT_Error 413 tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 414 FT_UInt glyph_index, 415 FT_Int x_pos, 416 FT_Int y_pos ); 417 418 typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, 419 FT_Byte* p, 420 FT_Byte* plimit, 421 FT_Int x_pos, 422 FT_Int y_pos ); 423 424 425 static FT_Error 426 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, 427 FT_Byte* p, 428 FT_Byte* limit, 429 FT_Int x_pos, 430 FT_Int y_pos ) 431 { 432 FT_Error error = SFNT_Err_Ok; 433 FT_Byte* line; 434 FT_Int bit_height, bit_width, pitch, width, height, h; 435 FT_Bitmap* bitmap; 436 437 438 if ( !decoder->bitmap_allocated ) 439 { 440 error = tt_sbit_decoder_alloc_bitmap( decoder ); 441 if ( error ) 442 goto Exit; 443 } 444 445 /* check that we can write the glyph into the bitmap */ 446 bitmap = decoder->bitmap; 447 bit_width = bitmap->width; 448 bit_height = bitmap->rows; 449 pitch = bitmap->pitch; 450 line = bitmap->buffer; 451 452 width = decoder->metrics->width; 453 height = decoder->metrics->height; 454 455 if ( x_pos < 0 || x_pos + width > bit_width || 456 y_pos < 0 || y_pos + height > bit_height ) 457 { 458 error = SFNT_Err_Invalid_File_Format; 459 goto Exit; 460 } 461 462 if ( p + ( ( width + 7 ) >> 3 ) * height > limit ) 463 { 464 error = SFNT_Err_Invalid_File_Format; 465 goto Exit; 466 } 467 468 /* now do the blit */ 469 line += y_pos * pitch + ( x_pos >> 3 ); 470 x_pos &= 7; 471 472 if ( x_pos == 0 ) /* the easy one */ 473 { 474 for ( h = height; h > 0; h--, line += pitch ) 475 { 476 FT_Byte* write = line; 477 FT_Int w; 478 479 480 for ( w = width; w >= 8; w -= 8 ) 481 { 482 write[0] = (FT_Byte)( write[0] | *p++ ); 483 write += 1; 484 } 485 486 if ( w > 0 ) 487 write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) ); 488 } 489 } 490 else /* x_pos > 0 */ 491 { 492 for ( h = height; h > 0; h--, line += pitch ) 493 { 494 FT_Byte* write = line; 495 FT_Int w; 496 FT_UInt wval = 0; 497 498 499 for ( w = width; w >= 8; w -= 8 ) 500 { 501 wval = (FT_UInt)( wval | *p++ ); 502 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); 503 write += 1; 504 wval <<= 8; 505 } 506 507 if ( w > 0 ) 508 wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); 509 510 /* all bits read and there are ( x_pos + w ) bits to be written */ 511 512 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); 513 514 if ( x_pos + w > 8 ) 515 { 516 write++; 517 wval <<= 8; 518 write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) ); 519 } 520 } 521 } 522 523 Exit: 524 return error; 525 } 526 527 528 static FT_Error 529 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, 530 FT_Byte* p, 531 FT_Byte* limit, 532 FT_Int x_pos, 533 FT_Int y_pos ) 534 { 535 FT_Error error = SFNT_Err_Ok; 536 FT_Byte* line; 537 FT_Int bit_height, bit_width, pitch, width, height, h, nbits; 538 FT_Bitmap* bitmap; 539 FT_UShort rval; 540 541 542 if ( !decoder->bitmap_allocated ) 543 { 544 error = tt_sbit_decoder_alloc_bitmap( decoder ); 545 if ( error ) 546 goto Exit; 547 } 548 549 /* check that we can write the glyph into the bitmap */ 550 bitmap = decoder->bitmap; 551 bit_width = bitmap->width; 552 bit_height = bitmap->rows; 553 pitch = bitmap->pitch; 554 line = bitmap->buffer; 555 556 width = decoder->metrics->width; 557 height = decoder->metrics->height; 558 559 if ( x_pos < 0 || x_pos + width > bit_width || 560 y_pos < 0 || y_pos + height > bit_height ) 561 { 562 error = SFNT_Err_Invalid_File_Format; 563 goto Exit; 564 } 565 566 if ( p + ( ( width * height + 7 ) >> 3 ) > limit ) 567 { 568 error = SFNT_Err_Invalid_File_Format; 569 goto Exit; 570 } 571 572 /* now do the blit */ 573 line += y_pos * pitch + ( x_pos >> 3 ); 574 x_pos &= 7; 575 576 /* the higher byte of `rval' is used as a buffer */ 577 rval = 0; 578 nbits = 0; 579 580 for ( h = height; h > 0; h--, line += pitch ) 581 { 582 FT_Byte* write = line; 583 FT_Int w = width; 584 585 586 if ( x_pos ) 587 { 588 w = ( width < 8 - x_pos ) ? width : 8 - x_pos; 589 590 if ( nbits < w ) 591 { 592 rval |= *p++; 593 nbits += 8 - w; 594 } 595 else 596 { 597 rval >>= 8; 598 nbits -= w; 599 } 600 601 *write++ |= ( ( rval >> nbits ) & 0xFF ) & ~( 0xFF << w ); 602 rval <<= 8; 603 604 w = width - w; 605 } 606 607 for ( ; w >= 8; w -= 8 ) 608 { 609 rval |= *p++; 610 *write++ |= ( rval >> nbits ) & 0xFF; 611 612 rval <<= 8; 613 } 614 615 if ( w > 0 ) 616 { 617 if ( nbits < w ) 618 { 619 rval |= *p++; 620 *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 621 nbits += 8 - w; 622 623 rval <<= 8; 624 } 625 else 626 { 627 *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 628 nbits -= w; 629 } 630 } 631 } 632 633 Exit: 634 return error; 635 } 636 637 638 static FT_Error 639 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, 640 FT_Byte* p, 641 FT_Byte* limit, 642 FT_Int x_pos, 643 FT_Int y_pos ) 644 { 645 FT_Error error = SFNT_Err_Ok; 646 FT_UInt num_components, nn; 647 648 649 if ( p + 2 > limit ) 650 goto Fail; 651 652 num_components = FT_NEXT_USHORT( p ); 653 if ( p + 4 * num_components > limit ) 654 goto Fail; 655 656 for ( nn = 0; nn < num_components; nn++ ) 657 { 658 FT_UInt gindex = FT_NEXT_USHORT( p ); 659 FT_Byte dx = FT_NEXT_BYTE( p ); 660 FT_Byte dy = FT_NEXT_BYTE( p ); 661 662 663 /* NB: a recursive call */ 664 error = tt_sbit_decoder_load_image( decoder, gindex, 665 x_pos + dx, y_pos + dy ); 666 if ( error ) 667 break; 668 } 669 670 Exit: 671 return error; 672 673 Fail: 674 error = SFNT_Err_Invalid_File_Format; 675 goto Exit; 676 } 677 678 679 static FT_Error 680 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, 681 FT_UInt glyph_format, 682 FT_ULong glyph_start, 683 FT_ULong glyph_size, 684 FT_Int x_pos, 685 FT_Int y_pos ) 686 { 687 FT_Error error; 688 FT_Stream stream = decoder->stream; 689 FT_Byte* p; 690 FT_Byte* p_limit; 691 FT_Byte* data; 692 693 694 /* seek into the EBDT table now */ 695 if ( glyph_start + glyph_size > decoder->ebdt_size ) 696 { 697 error = SFNT_Err_Invalid_Argument; 698 goto Exit; 699 } 700 701 if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || 702 FT_FRAME_EXTRACT( glyph_size, data ) ) 703 goto Exit; 704 705 p = data; 706 p_limit = p + glyph_size; 707 708 /* read the data, depending on the glyph format */ 709 switch ( glyph_format ) 710 { 711 case 1: 712 case 2: 713 case 8: 714 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); 715 break; 716 717 case 6: 718 case 7: 719 case 9: 720 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); 721 break; 722 723 default: 724 error = SFNT_Err_Ok; 725 } 726 727 if ( error ) 728 goto Fail; 729 730 { 731 TT_SBitDecoder_LoadFunc loader; 732 733 734 switch ( glyph_format ) 735 { 736 case 1: 737 case 6: 738 loader = tt_sbit_decoder_load_byte_aligned; 739 break; 740 741 case 2: 742 case 5: 743 case 7: 744 loader = tt_sbit_decoder_load_bit_aligned; 745 break; 746 747 case 8: 748 if ( p + 1 > p_limit ) 749 goto Fail; 750 751 p += 1; /* skip padding */ 752 /* fall-through */ 753 754 case 9: 755 loader = tt_sbit_decoder_load_compound; 756 break; 757 758 default: 759 goto Fail; 760 } 761 762 error = loader( decoder, p, p_limit, x_pos, y_pos ); 763 } 764 765 Fail: 766 FT_FRAME_RELEASE( data ); 767 768 Exit: 769 return error; 770 } 771 772 773 static FT_Error 774 tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 775 FT_UInt glyph_index, 776 FT_Int x_pos, 777 FT_Int y_pos ) 778 { 779 /* 780 * First, we find the correct strike range that applies to this 781 * glyph index. 782 */ 783 784 FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; 785 FT_Byte* p_limit = decoder->eblc_limit; 786 FT_ULong num_ranges = decoder->strike_index_count; 787 FT_UInt start, end, index_format, image_format; 788 FT_ULong image_start = 0, image_end = 0, image_offset; 789 790 791 for ( ; num_ranges > 0; num_ranges-- ) 792 { 793 start = FT_NEXT_USHORT( p ); 794 end = FT_NEXT_USHORT( p ); 795 796 if ( glyph_index >= start && glyph_index <= end ) 797 goto FoundRange; 798 799 p += 4; /* ignore index offset */ 800 } 801 goto NoBitmap; 802 803 FoundRange: 804 image_offset = FT_NEXT_ULONG( p ); 805 806 /* overflow check */ 807 if ( decoder->eblc_base + decoder->strike_index_array + image_offset < 808 decoder->eblc_base ) 809 goto Failure; 810 811 p = decoder->eblc_base + decoder->strike_index_array + image_offset; 812 if ( p + 8 > p_limit ) 813 goto NoBitmap; 814 815 /* now find the glyph's location and extend within the ebdt table */ 816 index_format = FT_NEXT_USHORT( p ); 817 image_format = FT_NEXT_USHORT( p ); 818 image_offset = FT_NEXT_ULONG ( p ); 819 820 switch ( index_format ) 821 { 822 case 1: /* 4-byte offsets relative to `image_offset' */ 823 { 824 p += 4 * ( glyph_index - start ); 825 if ( p + 8 > p_limit ) 826 goto NoBitmap; 827 828 image_start = FT_NEXT_ULONG( p ); 829 image_end = FT_NEXT_ULONG( p ); 830 831 if ( image_start == image_end ) /* missing glyph */ 832 goto NoBitmap; 833 } 834 break; 835 836 case 2: /* big metrics, constant image size */ 837 { 838 FT_ULong image_size; 839 840 841 if ( p + 12 > p_limit ) 842 goto NoBitmap; 843 844 image_size = FT_NEXT_ULONG( p ); 845 846 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 847 goto NoBitmap; 848 849 image_start = image_size * ( glyph_index - start ); 850 image_end = image_start + image_size; 851 } 852 break; 853 854 case 3: /* 2-byte offsets relative to 'image_offset' */ 855 { 856 p += 2 * ( glyph_index - start ); 857 if ( p + 4 > p_limit ) 858 goto NoBitmap; 859 860 image_start = FT_NEXT_USHORT( p ); 861 image_end = FT_NEXT_USHORT( p ); 862 863 if ( image_start == image_end ) /* missing glyph */ 864 goto NoBitmap; 865 } 866 break; 867 868 case 4: /* sparse glyph array with (glyph,offset) pairs */ 869 { 870 FT_ULong mm, num_glyphs; 871 872 873 if ( p + 4 > p_limit ) 874 goto NoBitmap; 875 876 num_glyphs = FT_NEXT_ULONG( p ); 877 878 /* overflow check */ 879 if ( p + ( num_glyphs + 1 ) * 4 < p ) 880 goto Failure; 881 882 if ( p + ( num_glyphs + 1 ) * 4 > p_limit ) 883 goto NoBitmap; 884 885 for ( mm = 0; mm < num_glyphs; mm++ ) 886 { 887 FT_UInt gindex = FT_NEXT_USHORT( p ); 888 889 890 if ( gindex == glyph_index ) 891 { 892 image_start = FT_NEXT_USHORT( p ); 893 p += 2; 894 image_end = FT_PEEK_USHORT( p ); 895 break; 896 } 897 p += 2; 898 } 899 900 if ( mm >= num_glyphs ) 901 goto NoBitmap; 902 } 903 break; 904 905 case 5: /* constant metrics with sparse glyph codes */ 906 { 907 FT_ULong image_size, mm, num_glyphs; 908 909 910 if ( p + 16 > p_limit ) 911 goto NoBitmap; 912 913 image_size = FT_NEXT_ULONG( p ); 914 915 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 916 goto NoBitmap; 917 918 num_glyphs = FT_NEXT_ULONG( p ); 919 920 /* overflow check */ 921 if ( p + 2 * num_glyphs < p ) 922 goto Failure; 923 924 if ( p + 2 * num_glyphs > p_limit ) 925 goto NoBitmap; 926 927 for ( mm = 0; mm < num_glyphs; mm++ ) 928 { 929 FT_UInt gindex = FT_NEXT_USHORT( p ); 930 931 932 if ( gindex == glyph_index ) 933 break; 934 } 935 936 if ( mm >= num_glyphs ) 937 goto NoBitmap; 938 939 image_start = image_size * mm; 940 image_end = image_start + image_size; 941 } 942 break; 943 944 default: 945 goto NoBitmap; 946 } 947 948 if ( image_start > image_end ) 949 goto NoBitmap; 950 951 image_end -= image_start; 952 image_start = image_offset + image_start; 953 954 return tt_sbit_decoder_load_bitmap( decoder, 955 image_format, 956 image_start, 957 image_end, 958 x_pos, 959 y_pos ); 960 961 Failure: 962 return SFNT_Err_Invalid_Table; 963 964 NoBitmap: 965 return SFNT_Err_Invalid_Argument; 966 } 967 968 969 FT_LOCAL( FT_Error ) 970 tt_face_load_sbit_image( TT_Face face, 971 FT_ULong strike_index, 972 FT_UInt glyph_index, 973 FT_UInt load_flags, 974 FT_Stream stream, 975 FT_Bitmap *map, 976 TT_SBit_MetricsRec *metrics ) 977 { 978 TT_SBitDecoderRec decoder[1]; 979 FT_Error error; 980 981 FT_UNUSED( load_flags ); 982 FT_UNUSED( stream ); 983 FT_UNUSED( map ); 984 985 986 error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); 987 if ( !error ) 988 { 989 error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 ); 990 tt_sbit_decoder_done( decoder ); 991 } 992 993 return error; 994 } 995 996/* EOF */ 997