1 /***************************************************************************/ 2 /* */ 3 /* ttsbit.c */ 4 /* */ 5 /* TrueType and OpenType embedded bitmap support (body). */ 6 /* */ 7 /* Copyright 2005-2015 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* Copyright 2013 by Google, Inc. */ 11 /* Google Author(s): Behdad Esfahbod. */ 12 /* */ 13 /* This file is part of the FreeType project, and may only be used, */ 14 /* modified, and distributed under the terms of the FreeType project */ 15 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 16 /* this file you indicate that you have read the license and */ 17 /* understand and accept it fully. */ 18 /* */ 19 /***************************************************************************/ 20 21 22 #include <ft2build.h> 23 #include FT_INTERNAL_DEBUG_H 24 #include FT_INTERNAL_STREAM_H 25 #include FT_TRUETYPE_TAGS_H 26 #include FT_BITMAP_H 27 #include "ttsbit.h" 28 29 #include "sferrors.h" 30 31 #include "ttmtx.h" 32 #include "pngshim.h" 33 34 35 /*************************************************************************/ 36 /* */ 37 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 38 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 39 /* messages during execution. */ 40 /* */ 41 #undef FT_COMPONENT 42 #define FT_COMPONENT trace_ttsbit 43 44 45 FT_LOCAL_DEF( FT_Error ) 46 tt_face_load_sbit( TT_Face face, 47 FT_Stream stream ) 48 { 49 FT_Error error; 50 FT_ULong table_size; 51 52 53 face->sbit_table = NULL; 54 face->sbit_table_size = 0; 55 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; 56 face->sbit_num_strikes = 0; 57 58 error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); 59 if ( !error ) 60 face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC; 61 else 62 { 63 error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); 64 if ( error ) 65 error = face->goto_table( face, TTAG_bloc, stream, &table_size ); 66 if ( !error ) 67 face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC; 68 } 69 70 if ( error ) 71 { 72 error = face->goto_table( face, TTAG_sbix, stream, &table_size ); 73 if ( !error ) 74 face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX; 75 } 76 if ( error ) 77 goto Exit; 78 79 if ( table_size < 8 ) 80 { 81 FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); 82 error = FT_THROW( Invalid_File_Format ); 83 goto Exit; 84 } 85 86 switch ( (FT_UInt)face->sbit_table_type ) 87 { 88 case TT_SBIT_TABLE_TYPE_EBLC: 89 case TT_SBIT_TABLE_TYPE_CBLC: 90 { 91 FT_Byte* p; 92 FT_Fixed version; 93 FT_ULong num_strikes; 94 FT_UInt count; 95 96 97 if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) 98 goto Exit; 99 100 face->sbit_table_size = table_size; 101 102 p = face->sbit_table; 103 104 version = FT_NEXT_LONG( p ); 105 num_strikes = FT_NEXT_ULONG( p ); 106 107 if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL && 108 ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL ) 109 { 110 error = FT_THROW( Unknown_File_Format ); 111 goto Exit; 112 } 113 114 if ( num_strikes >= 0x10000UL ) 115 { 116 error = FT_THROW( Invalid_File_Format ); 117 goto Exit; 118 } 119 120 /* 121 * Count the number of strikes available in the table. We are a bit 122 * paranoid there and don't trust the data. 123 */ 124 count = (FT_UInt)num_strikes; 125 if ( 8 + 48UL * count > table_size ) 126 count = (FT_UInt)( ( table_size - 8 ) / 48 ); 127 128 face->sbit_num_strikes = count; 129 } 130 break; 131 132 case TT_SBIT_TABLE_TYPE_SBIX: 133 { 134 FT_UShort version; 135 FT_UShort flags; 136 FT_ULong num_strikes; 137 FT_UInt count; 138 139 140 if ( FT_FRAME_ENTER( 8 ) ) 141 goto Exit; 142 143 version = FT_GET_USHORT(); 144 flags = FT_GET_USHORT(); 145 num_strikes = FT_GET_ULONG(); 146 147 FT_FRAME_EXIT(); 148 149 if ( version < 1 ) 150 { 151 error = FT_THROW( Unknown_File_Format ); 152 goto Exit; 153 } 154 155 /* Bit 0 must always be `1'. */ 156 /* Bit 1 controls the overlay of bitmaps with outlines. */ 157 /* All other bits should be zero. */ 158 if ( !( flags == 1 || flags == 3 ) || 159 num_strikes >= 0x10000UL ) 160 { 161 error = FT_THROW( Invalid_File_Format ); 162 goto Exit; 163 } 164 165 /* we currently don't support bit 1; however, it is better to */ 166 /* draw at least something... */ 167 if ( flags == 3 ) 168 FT_TRACE1(( "tt_face_load_sbit_strikes:" 169 " sbix overlay not supported yet\n" 170 " " 171 " expect bad rendering results\n" )); 172 173 /* 174 * Count the number of strikes available in the table. We are a bit 175 * paranoid there and don't trust the data. 176 */ 177 count = (FT_UInt)num_strikes; 178 if ( 8 + 4UL * count > table_size ) 179 count = (FT_UInt)( ( table_size - 8 ) / 4 ); 180 181 if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) ) 182 goto Exit; 183 184 face->sbit_table_size = 8 + count * 4; 185 if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) ) 186 goto Exit; 187 188 face->sbit_num_strikes = count; 189 } 190 break; 191 192 default: 193 error = FT_THROW( Unknown_File_Format ); 194 break; 195 } 196 197 if ( !error ) 198 FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes )); 199 200 return FT_Err_Ok; 201 202 Exit: 203 if ( error ) 204 { 205 if ( face->sbit_table ) 206 FT_FRAME_RELEASE( face->sbit_table ); 207 face->sbit_table_size = 0; 208 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; 209 } 210 211 return error; 212 } 213 214 215 FT_LOCAL_DEF( void ) 216 tt_face_free_sbit( TT_Face face ) 217 { 218 FT_Stream stream = face->root.stream; 219 220 221 FT_FRAME_RELEASE( face->sbit_table ); 222 face->sbit_table_size = 0; 223 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; 224 face->sbit_num_strikes = 0; 225 } 226 227 228 FT_LOCAL_DEF( FT_Error ) 229 tt_face_set_sbit_strike( TT_Face face, 230 FT_Size_Request req, 231 FT_ULong* astrike_index ) 232 { 233 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); 234 } 235 236 237 FT_LOCAL_DEF( FT_Error ) 238 tt_face_load_strike_metrics( TT_Face face, 239 FT_ULong strike_index, 240 FT_Size_Metrics* metrics ) 241 { 242 if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) 243 return FT_THROW( Invalid_Argument ); 244 245 switch ( (FT_UInt)face->sbit_table_type ) 246 { 247 case TT_SBIT_TABLE_TYPE_EBLC: 248 case TT_SBIT_TABLE_TYPE_CBLC: 249 { 250 FT_Byte* strike; 251 FT_Char max_before_bl; 252 FT_Char min_after_bl; 253 254 255 strike = face->sbit_table + 8 + strike_index * 48; 256 257 metrics->x_ppem = (FT_UShort)strike[44]; 258 metrics->y_ppem = (FT_UShort)strike[45]; 259 260 metrics->ascender = (FT_Char)strike[16] * 64; /* hori.ascender */ 261 metrics->descender = (FT_Char)strike[17] * 64; /* hori.descender */ 262 263 /* Due to fuzzy wording in the EBLC documentation, we find both */ 264 /* positive and negative values for `descender'. Additionally, */ 265 /* many fonts have both `ascender' and `descender' set to zero */ 266 /* (which is definitely wrong). MS Windows simply ignores all */ 267 /* those values... For these reasons we apply some heuristics */ 268 /* to get a reasonable, non-zero value for the height. */ 269 270 max_before_bl = (FT_Char)strike[24]; 271 min_after_bl = (FT_Char)strike[25]; 272 273 if ( metrics->descender > 0 ) 274 { 275 /* compare sign of descender with `min_after_bl' */ 276 if ( min_after_bl < 0 ) 277 metrics->descender = -metrics->descender; 278 } 279 280 else if ( metrics->descender == 0 ) 281 { 282 if ( metrics->ascender == 0 ) 283 { 284 FT_TRACE2(( "tt_face_load_strike_metrics:" 285 " sanitizing invalid ascender and descender\n" 286 " " 287 " values for strike (%d, %d)\n", 288 metrics->x_ppem, metrics->y_ppem )); 289 290 /* sanitize buggy ascender and descender values */ 291 if ( max_before_bl || min_after_bl ) 292 { 293 metrics->ascender = max_before_bl * 64; 294 metrics->descender = min_after_bl * 64; 295 } 296 else 297 { 298 metrics->ascender = metrics->y_ppem * 64; 299 metrics->descender = 0; 300 } 301 } 302 } 303 304 #if 0 305 else 306 ; /* if we have a negative descender, simply use it */ 307 #endif 308 309 metrics->height = metrics->ascender - metrics->descender; 310 if ( metrics->height == 0 ) 311 { 312 FT_TRACE2(( "tt_face_load_strike_metrics:" 313 " sanitizing invalid height value\n" 314 " " 315 " for strike (%d, %d)\n", 316 metrics->x_ppem, metrics->y_ppem )); 317 metrics->height = metrics->y_ppem * 64; 318 metrics->descender = metrics->ascender - metrics->height; 319 } 320 321 /* Is this correct? */ 322 metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ 323 strike[18] + /* max_width */ 324 (FT_Char)strike[23] /* min_advance_SB */ 325 ) * 64; 326 return FT_Err_Ok; 327 } 328 329 case TT_SBIT_TABLE_TYPE_SBIX: 330 { 331 FT_Stream stream = face->root.stream; 332 FT_UInt offset; 333 FT_UShort upem, ppem, resolution; 334 TT_HoriHeader *hori; 335 FT_ULong table_size; 336 FT_Pos ppem_; /* to reduce casts */ 337 338 FT_Error error; 339 FT_Byte* p; 340 341 342 p = face->sbit_table + 8 + 4 * strike_index; 343 offset = FT_NEXT_ULONG( p ); 344 345 error = face->goto_table( face, TTAG_sbix, stream, &table_size ); 346 if ( error ) 347 return error; 348 349 if ( offset + 4 > table_size ) 350 return FT_THROW( Invalid_File_Format ); 351 352 if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) || 353 FT_FRAME_ENTER( 4 ) ) 354 return error; 355 356 ppem = FT_GET_USHORT(); 357 resolution = FT_GET_USHORT(); 358 359 FT_UNUSED( resolution ); /* What to do with this? */ 360 361 FT_FRAME_EXIT(); 362 363 upem = face->header.Units_Per_EM; 364 hori = &face->horizontal; 365 366 metrics->x_ppem = ppem; 367 metrics->y_ppem = ppem; 368 369 ppem_ = (FT_Pos)ppem; 370 371 metrics->ascender = 372 FT_MulDiv( hori->Ascender, ppem_ * 64, upem ); 373 metrics->descender = 374 FT_MulDiv( hori->Descender, ppem_ * 64, upem ); 375 metrics->height = 376 FT_MulDiv( hori->Ascender - hori->Descender + hori->Line_Gap, 377 ppem_ * 64, upem ); 378 metrics->max_advance = 379 FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem ); 380 381 return error; 382 } 383 384 default: 385 return FT_THROW( Unknown_File_Format ); 386 } 387 } 388 389 390 typedef struct TT_SBitDecoderRec_ 391 { 392 TT_Face face; 393 FT_Stream stream; 394 FT_Bitmap* bitmap; 395 TT_SBit_Metrics metrics; 396 FT_Bool metrics_loaded; 397 FT_Bool bitmap_allocated; 398 FT_Byte bit_depth; 399 400 FT_ULong ebdt_start; 401 FT_ULong ebdt_size; 402 403 FT_ULong strike_index_array; 404 FT_ULong strike_index_count; 405 FT_Byte* eblc_base; 406 FT_Byte* eblc_limit; 407 408 } TT_SBitDecoderRec, *TT_SBitDecoder; 409 410 411 static FT_Error 412 tt_sbit_decoder_init( TT_SBitDecoder decoder, 413 TT_Face face, 414 FT_ULong strike_index, 415 TT_SBit_MetricsRec* metrics ) 416 { 417 FT_Error error; 418 FT_Stream stream = face->root.stream; 419 FT_ULong ebdt_size; 420 421 422 error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size ); 423 if ( error ) 424 error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); 425 if ( error ) 426 error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); 427 if ( error ) 428 goto Exit; 429 430 decoder->face = face; 431 decoder->stream = stream; 432 decoder->bitmap = &face->root.glyph->bitmap; 433 decoder->metrics = metrics; 434 435 decoder->metrics_loaded = 0; 436 decoder->bitmap_allocated = 0; 437 438 decoder->ebdt_start = FT_STREAM_POS(); 439 decoder->ebdt_size = ebdt_size; 440 441 decoder->eblc_base = face->sbit_table; 442 decoder->eblc_limit = face->sbit_table + face->sbit_table_size; 443 444 /* now find the strike corresponding to the index */ 445 { 446 FT_Byte* p; 447 448 449 if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size ) 450 { 451 error = FT_THROW( Invalid_File_Format ); 452 goto Exit; 453 } 454 455 p = decoder->eblc_base + 8 + 48 * strike_index; 456 457 decoder->strike_index_array = FT_NEXT_ULONG( p ); 458 p += 4; 459 decoder->strike_index_count = FT_NEXT_ULONG( p ); 460 p += 34; 461 decoder->bit_depth = *p; 462 463 /* decoder->strike_index_array + */ 464 /* 8 * decoder->strike_index_count > face->sbit_table_size ? */ 465 if ( decoder->strike_index_array > face->sbit_table_size || 466 decoder->strike_index_count > 467 ( face->sbit_table_size - decoder->strike_index_array ) / 8 ) 468 error = FT_THROW( Invalid_File_Format ); 469 } 470 471 Exit: 472 return error; 473 } 474 475 476 static void 477 tt_sbit_decoder_done( TT_SBitDecoder decoder ) 478 { 479 FT_UNUSED( decoder ); 480 } 481 482 483 static FT_Error 484 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) 485 { 486 FT_Error error = FT_Err_Ok; 487 FT_UInt width, height; 488 FT_Bitmap* map = decoder->bitmap; 489 FT_ULong size; 490 491 492 if ( !decoder->metrics_loaded ) 493 { 494 error = FT_THROW( Invalid_Argument ); 495 goto Exit; 496 } 497 498 width = decoder->metrics->width; 499 height = decoder->metrics->height; 500 501 map->width = width; 502 map->rows = height; 503 504 switch ( decoder->bit_depth ) 505 { 506 case 1: 507 map->pixel_mode = FT_PIXEL_MODE_MONO; 508 map->pitch = (int)( ( map->width + 7 ) >> 3 ); 509 map->num_grays = 2; 510 break; 511 512 case 2: 513 map->pixel_mode = FT_PIXEL_MODE_GRAY2; 514 map->pitch = (int)( ( map->width + 3 ) >> 2 ); 515 map->num_grays = 4; 516 break; 517 518 case 4: 519 map->pixel_mode = FT_PIXEL_MODE_GRAY4; 520 map->pitch = (int)( ( map->width + 1 ) >> 1 ); 521 map->num_grays = 16; 522 break; 523 524 case 8: 525 map->pixel_mode = FT_PIXEL_MODE_GRAY; 526 map->pitch = (int)( map->width ); 527 map->num_grays = 256; 528 break; 529 530 case 32: 531 map->pixel_mode = FT_PIXEL_MODE_BGRA; 532 map->pitch = (int)( map->width * 4 ); 533 map->num_grays = 256; 534 break; 535 536 default: 537 error = FT_THROW( Invalid_File_Format ); 538 goto Exit; 539 } 540 541 size = map->rows * (FT_ULong)map->pitch; 542 543 /* check that there is no empty image */ 544 if ( size == 0 ) 545 goto Exit; /* exit successfully! */ 546 547 error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); 548 if ( error ) 549 goto Exit; 550 551 decoder->bitmap_allocated = 1; 552 553 Exit: 554 return error; 555 } 556 557 558 static FT_Error 559 tt_sbit_decoder_load_metrics( TT_SBitDecoder decoder, 560 FT_Byte* *pp, 561 FT_Byte* limit, 562 FT_Bool big ) 563 { 564 FT_Byte* p = *pp; 565 TT_SBit_Metrics metrics = decoder->metrics; 566 567 568 if ( p + 5 > limit ) 569 goto Fail; 570 571 metrics->height = p[0]; 572 metrics->width = p[1]; 573 metrics->horiBearingX = (FT_Char)p[2]; 574 metrics->horiBearingY = (FT_Char)p[3]; 575 metrics->horiAdvance = p[4]; 576 577 p += 5; 578 if ( big ) 579 { 580 if ( p + 3 > limit ) 581 goto Fail; 582 583 metrics->vertBearingX = (FT_Char)p[0]; 584 metrics->vertBearingY = (FT_Char)p[1]; 585 metrics->vertAdvance = p[2]; 586 587 p += 3; 588 } 589 else 590 { 591 /* avoid uninitialized data in case there is no vertical info -- */ 592 metrics->vertBearingX = 0; 593 metrics->vertBearingY = 0; 594 metrics->vertAdvance = 0; 595 } 596 597 decoder->metrics_loaded = 1; 598 *pp = p; 599 return FT_Err_Ok; 600 601 Fail: 602 FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table\n" )); 603 return FT_THROW( Invalid_Argument ); 604 } 605 606 607 /* forward declaration */ 608 static FT_Error 609 tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 610 FT_UInt glyph_index, 611 FT_Int x_pos, 612 FT_Int y_pos, 613 FT_UInt recurse_count ); 614 615 typedef FT_Error (*TT_SBitDecoder_LoadFunc)( 616 TT_SBitDecoder decoder, 617 FT_Byte* p, 618 FT_Byte* plimit, 619 FT_Int x_pos, 620 FT_Int y_pos, 621 FT_UInt recurse_count ); 622 623 624 static FT_Error 625 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, 626 FT_Byte* p, 627 FT_Byte* limit, 628 FT_Int x_pos, 629 FT_Int y_pos, 630 FT_UInt recurse_count ) 631 { 632 FT_Error error = FT_Err_Ok; 633 FT_Byte* line; 634 FT_Int pitch, width, height, line_bits, h; 635 FT_UInt bit_height, bit_width; 636 FT_Bitmap* bitmap; 637 638 FT_UNUSED( recurse_count ); 639 640 641 /* check that we can write the glyph into the bitmap */ 642 bitmap = decoder->bitmap; 643 bit_width = bitmap->width; 644 bit_height = bitmap->rows; 645 pitch = bitmap->pitch; 646 line = bitmap->buffer; 647 648 width = decoder->metrics->width; 649 height = decoder->metrics->height; 650 651 line_bits = width * decoder->bit_depth; 652 653 if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width || 654 y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height ) 655 { 656 FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:" 657 " invalid bitmap dimensions\n" )); 658 error = FT_THROW( Invalid_File_Format ); 659 goto Exit; 660 } 661 662 if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit ) 663 { 664 FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" )); 665 error = FT_THROW( Invalid_File_Format ); 666 goto Exit; 667 } 668 669 /* now do the blit */ 670 line += y_pos * pitch + ( x_pos >> 3 ); 671 x_pos &= 7; 672 673 if ( x_pos == 0 ) /* the easy one */ 674 { 675 for ( h = height; h > 0; h--, line += pitch ) 676 { 677 FT_Byte* pwrite = line; 678 FT_Int w; 679 680 681 for ( w = line_bits; w >= 8; w -= 8 ) 682 { 683 pwrite[0] = (FT_Byte)( pwrite[0] | *p++ ); 684 pwrite += 1; 685 } 686 687 if ( w > 0 ) 688 pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) ); 689 } 690 } 691 else /* x_pos > 0 */ 692 { 693 for ( h = height; h > 0; h--, line += pitch ) 694 { 695 FT_Byte* pwrite = line; 696 FT_Int w; 697 FT_UInt wval = 0; 698 699 700 for ( w = line_bits; w >= 8; w -= 8 ) 701 { 702 wval = (FT_UInt)( wval | *p++ ); 703 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 704 pwrite += 1; 705 wval <<= 8; 706 } 707 708 if ( w > 0 ) 709 wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) ); 710 711 /* all bits read and there are `x_pos + w' bits to be written */ 712 713 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 714 715 if ( x_pos + w > 8 ) 716 { 717 pwrite++; 718 wval <<= 8; 719 pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) ); 720 } 721 } 722 } 723 724 Exit: 725 if ( !error ) 726 FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" )); 727 return error; 728 } 729 730 731 /* 732 * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap 733 * (with pointer `pwrite'). In the example below, the width is 3 pixel, 734 * and `x_pos' is 1 pixel. 735 * 736 * p p+1 737 * | | | 738 * | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |... 739 * | | | 740 * +-------+ +-------+ +-------+ ... 741 * . . . 742 * . . . 743 * v . . 744 * +-------+ . . 745 * | | . 746 * | 7 6 5 4 3 2 1 0 | . 747 * | | . 748 * pwrite . . 749 * . . 750 * v . 751 * +-------+ . 752 * | | 753 * | 7 6 5 4 3 2 1 0 | 754 * | | 755 * pwrite+1 . 756 * . 757 * v 758 * +-------+ 759 * | | 760 * | 7 6 5 4 3 2 1 0 | 761 * | | 762 * pwrite+2 763 * 764 */ 765 766 static FT_Error 767 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, 768 FT_Byte* p, 769 FT_Byte* limit, 770 FT_Int x_pos, 771 FT_Int y_pos, 772 FT_UInt recurse_count ) 773 { 774 FT_Error error = FT_Err_Ok; 775 FT_Byte* line; 776 FT_Int pitch, width, height, line_bits, h, nbits; 777 FT_UInt bit_height, bit_width; 778 FT_Bitmap* bitmap; 779 FT_UShort rval; 780 781 FT_UNUSED( recurse_count ); 782 783 784 /* check that we can write the glyph into the bitmap */ 785 bitmap = decoder->bitmap; 786 bit_width = bitmap->width; 787 bit_height = bitmap->rows; 788 pitch = bitmap->pitch; 789 line = bitmap->buffer; 790 791 width = decoder->metrics->width; 792 height = decoder->metrics->height; 793 794 line_bits = width * decoder->bit_depth; 795 796 if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width || 797 y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height ) 798 { 799 FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:" 800 " invalid bitmap dimensions\n" )); 801 error = FT_THROW( Invalid_File_Format ); 802 goto Exit; 803 } 804 805 if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit ) 806 { 807 FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" )); 808 error = FT_THROW( Invalid_File_Format ); 809 goto Exit; 810 } 811 812 if ( !line_bits || !height ) 813 { 814 /* nothing to do */ 815 goto Exit; 816 } 817 818 /* now do the blit */ 819 820 /* adjust `line' to point to the first byte of the bitmap */ 821 line += y_pos * pitch + ( x_pos >> 3 ); 822 x_pos &= 7; 823 824 /* the higher byte of `rval' is used as a buffer */ 825 rval = 0; 826 nbits = 0; 827 828 for ( h = height; h > 0; h--, line += pitch ) 829 { 830 FT_Byte* pwrite = line; 831 FT_Int w = line_bits; 832 833 834 /* handle initial byte (in target bitmap) specially if necessary */ 835 if ( x_pos ) 836 { 837 w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos; 838 839 if ( h == height ) 840 { 841 rval = *p++; 842 nbits = x_pos; 843 } 844 else if ( nbits < w ) 845 { 846 if ( p < limit ) 847 rval |= *p++; 848 nbits += 8 - w; 849 } 850 else 851 { 852 rval >>= 8; 853 nbits -= w; 854 } 855 856 *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) & 857 ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); 858 rval <<= 8; 859 860 w = line_bits - w; 861 } 862 863 /* handle medial bytes */ 864 for ( ; w >= 8; w -= 8 ) 865 { 866 rval |= *p++; 867 *pwrite++ |= ( rval >> nbits ) & 0xFF; 868 869 rval <<= 8; 870 } 871 872 /* handle final byte if necessary */ 873 if ( w > 0 ) 874 { 875 if ( nbits < w ) 876 { 877 if ( p < limit ) 878 rval |= *p++; 879 *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 880 nbits += 8 - w; 881 882 rval <<= 8; 883 } 884 else 885 { 886 *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w ); 887 nbits -= w; 888 } 889 } 890 } 891 892 Exit: 893 if ( !error ) 894 FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" )); 895 return error; 896 } 897 898 899 static FT_Error 900 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, 901 FT_Byte* p, 902 FT_Byte* limit, 903 FT_Int x_pos, 904 FT_Int y_pos, 905 FT_UInt recurse_count ) 906 { 907 FT_Error error = FT_Err_Ok; 908 FT_UInt num_components, nn; 909 910 FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX; 911 FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY; 912 FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance; 913 FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX; 914 FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY; 915 FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance; 916 917 918 if ( p + 2 > limit ) 919 goto Fail; 920 921 num_components = FT_NEXT_USHORT( p ); 922 if ( p + 4 * num_components > limit ) 923 { 924 FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" )); 925 goto Fail; 926 } 927 928 FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n", 929 num_components )); 930 931 for ( nn = 0; nn < num_components; nn++ ) 932 { 933 FT_UInt gindex = FT_NEXT_USHORT( p ); 934 FT_Byte dx = FT_NEXT_BYTE( p ); 935 FT_Byte dy = FT_NEXT_BYTE( p ); 936 937 938 /* NB: a recursive call */ 939 error = tt_sbit_decoder_load_image( decoder, 940 gindex, 941 x_pos + dx, 942 y_pos + dy, 943 recurse_count + 1 ); 944 if ( error ) 945 break; 946 } 947 948 FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" )); 949 950 decoder->metrics->horiBearingX = horiBearingX; 951 decoder->metrics->horiBearingY = horiBearingY; 952 decoder->metrics->horiAdvance = horiAdvance; 953 decoder->metrics->vertBearingX = vertBearingX; 954 decoder->metrics->vertBearingY = vertBearingY; 955 decoder->metrics->vertAdvance = vertAdvance; 956 decoder->metrics->width = (FT_Byte)decoder->bitmap->width; 957 decoder->metrics->height = (FT_Byte)decoder->bitmap->rows; 958 959 Exit: 960 return error; 961 962 Fail: 963 error = FT_THROW( Invalid_File_Format ); 964 goto Exit; 965 } 966 967 968 #ifdef FT_CONFIG_OPTION_USE_PNG 969 970 static FT_Error 971 tt_sbit_decoder_load_png( TT_SBitDecoder decoder, 972 FT_Byte* p, 973 FT_Byte* limit, 974 FT_Int x_pos, 975 FT_Int y_pos, 976 FT_UInt recurse_count ) 977 { 978 FT_Error error = FT_Err_Ok; 979 FT_ULong png_len; 980 981 FT_UNUSED( recurse_count ); 982 983 984 if ( limit - p < 4 ) 985 { 986 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); 987 error = FT_THROW( Invalid_File_Format ); 988 goto Exit; 989 } 990 991 png_len = FT_NEXT_ULONG( p ); 992 if ( (FT_ULong)( limit - p ) < png_len ) 993 { 994 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); 995 error = FT_THROW( Invalid_File_Format ); 996 goto Exit; 997 } 998 999 error = Load_SBit_Png( decoder->face->root.glyph, 1000 x_pos, 1001 y_pos, 1002 decoder->bit_depth, 1003 decoder->metrics, 1004 decoder->stream->memory, 1005 p, 1006 png_len, 1007 FALSE ); 1008 1009 Exit: 1010 if ( !error ) 1011 FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" )); 1012 return error; 1013 } 1014 1015 #endif /* FT_CONFIG_OPTION_USE_PNG */ 1016 1017 1018 static FT_Error 1019 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, 1020 FT_UInt glyph_format, 1021 FT_ULong glyph_start, 1022 FT_ULong glyph_size, 1023 FT_Int x_pos, 1024 FT_Int y_pos, 1025 FT_UInt recurse_count ) 1026 { 1027 FT_Error error; 1028 FT_Stream stream = decoder->stream; 1029 FT_Byte* p; 1030 FT_Byte* p_limit; 1031 FT_Byte* data; 1032 1033 1034 /* seek into the EBDT table now */ 1035 if ( !glyph_size || 1036 glyph_start + glyph_size > decoder->ebdt_size ) 1037 { 1038 error = FT_THROW( Invalid_Argument ); 1039 goto Exit; 1040 } 1041 1042 if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) || 1043 FT_FRAME_EXTRACT( glyph_size, data ) ) 1044 goto Exit; 1045 1046 p = data; 1047 p_limit = p + glyph_size; 1048 1049 /* read the data, depending on the glyph format */ 1050 switch ( glyph_format ) 1051 { 1052 case 1: 1053 case 2: 1054 case 8: 1055 case 17: 1056 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 ); 1057 break; 1058 1059 case 6: 1060 case 7: 1061 case 9: 1062 case 18: 1063 error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ); 1064 break; 1065 1066 default: 1067 error = FT_Err_Ok; 1068 } 1069 1070 if ( error ) 1071 goto Fail; 1072 1073 { 1074 TT_SBitDecoder_LoadFunc loader; 1075 1076 1077 switch ( glyph_format ) 1078 { 1079 case 1: 1080 case 6: 1081 loader = tt_sbit_decoder_load_byte_aligned; 1082 break; 1083 1084 case 2: 1085 case 7: 1086 { 1087 /* Don't trust `glyph_format'. For example, Apple's main Korean */ 1088 /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */ 1089 /* format 7, but the data is format 6. We check whether we have */ 1090 /* an excessive number of bytes in the image: If it is equal to */ 1091 /* the value for a byte-aligned glyph, use the other loading */ 1092 /* routine. */ 1093 /* */ 1094 /* Note that for some (width,height) combinations, where the */ 1095 /* width is not a multiple of 8, the sizes for bit- and */ 1096 /* byte-aligned data are equal, for example (7,7) or (15,6). We */ 1097 /* then prefer what `glyph_format' specifies. */ 1098 1099 FT_UInt width = decoder->metrics->width; 1100 FT_UInt height = decoder->metrics->height; 1101 1102 FT_UInt bit_size = ( width * height + 7 ) >> 3; 1103 FT_UInt byte_size = height * ( ( width + 7 ) >> 3 ); 1104 1105 1106 if ( bit_size < byte_size && 1107 byte_size == (FT_UInt)( p_limit - p ) ) 1108 loader = tt_sbit_decoder_load_byte_aligned; 1109 else 1110 loader = tt_sbit_decoder_load_bit_aligned; 1111 } 1112 break; 1113 1114 case 5: 1115 loader = tt_sbit_decoder_load_bit_aligned; 1116 break; 1117 1118 case 8: 1119 if ( p + 1 > p_limit ) 1120 goto Fail; 1121 1122 p += 1; /* skip padding */ 1123 /* fall-through */ 1124 1125 case 9: 1126 loader = tt_sbit_decoder_load_compound; 1127 break; 1128 1129 case 17: /* small metrics, PNG image data */ 1130 case 18: /* big metrics, PNG image data */ 1131 case 19: /* metrics in EBLC, PNG image data */ 1132 #ifdef FT_CONFIG_OPTION_USE_PNG 1133 loader = tt_sbit_decoder_load_png; 1134 break; 1135 #else 1136 error = FT_THROW( Unimplemented_Feature ); 1137 goto Fail; 1138 #endif /* FT_CONFIG_OPTION_USE_PNG */ 1139 1140 default: 1141 error = FT_THROW( Invalid_Table ); 1142 goto Fail; 1143 } 1144 1145 if ( !decoder->bitmap_allocated ) 1146 { 1147 error = tt_sbit_decoder_alloc_bitmap( decoder ); 1148 if ( error ) 1149 goto Fail; 1150 } 1151 1152 error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count ); 1153 } 1154 1155 Fail: 1156 FT_FRAME_RELEASE( data ); 1157 1158 Exit: 1159 return error; 1160 } 1161 1162 1163 static FT_Error 1164 tt_sbit_decoder_load_image( TT_SBitDecoder decoder, 1165 FT_UInt glyph_index, 1166 FT_Int x_pos, 1167 FT_Int y_pos, 1168 FT_UInt recurse_count ) 1169 { 1170 FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; 1171 FT_Byte* p_limit = decoder->eblc_limit; 1172 FT_ULong num_ranges = decoder->strike_index_count; 1173 FT_UInt start, end, index_format, image_format; 1174 FT_ULong image_start = 0, image_end = 0, image_offset; 1175 1176 1177 /* arbitrary recursion limit */ 1178 if ( recurse_count > 100 ) 1179 { 1180 FT_TRACE4(( "tt_sbit_decoder_load_image:" 1181 " recursion depth exceeded\n" )); 1182 goto Failure; 1183 } 1184 1185 1186 /* First, we find the correct strike range that applies to this */ 1187 /* glyph index. */ 1188 for ( ; num_ranges > 0; num_ranges-- ) 1189 { 1190 start = FT_NEXT_USHORT( p ); 1191 end = FT_NEXT_USHORT( p ); 1192 1193 if ( glyph_index >= start && glyph_index <= end ) 1194 goto FoundRange; 1195 1196 p += 4; /* ignore index offset */ 1197 } 1198 goto NoBitmap; 1199 1200 FoundRange: 1201 image_offset = FT_NEXT_ULONG( p ); 1202 1203 /* overflow check */ 1204 p = decoder->eblc_base + decoder->strike_index_array; 1205 if ( image_offset > (FT_ULong)( p_limit - p ) ) 1206 goto Failure; 1207 1208 p += image_offset; 1209 if ( p + 8 > p_limit ) 1210 goto NoBitmap; 1211 1212 /* now find the glyph's location and extend within the ebdt table */ 1213 index_format = FT_NEXT_USHORT( p ); 1214 image_format = FT_NEXT_USHORT( p ); 1215 image_offset = FT_NEXT_ULONG ( p ); 1216 1217 switch ( index_format ) 1218 { 1219 case 1: /* 4-byte offsets relative to `image_offset' */ 1220 p += 4 * ( glyph_index - start ); 1221 if ( p + 8 > p_limit ) 1222 goto NoBitmap; 1223 1224 image_start = FT_NEXT_ULONG( p ); 1225 image_end = FT_NEXT_ULONG( p ); 1226 1227 if ( image_start == image_end ) /* missing glyph */ 1228 goto NoBitmap; 1229 break; 1230 1231 case 2: /* big metrics, constant image size */ 1232 { 1233 FT_ULong image_size; 1234 1235 1236 if ( p + 12 > p_limit ) 1237 goto NoBitmap; 1238 1239 image_size = FT_NEXT_ULONG( p ); 1240 1241 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 1242 goto NoBitmap; 1243 1244 image_start = image_size * ( glyph_index - start ); 1245 image_end = image_start + image_size; 1246 } 1247 break; 1248 1249 case 3: /* 2-byte offsets relative to 'image_offset' */ 1250 p += 2 * ( glyph_index - start ); 1251 if ( p + 4 > p_limit ) 1252 goto NoBitmap; 1253 1254 image_start = FT_NEXT_USHORT( p ); 1255 image_end = FT_NEXT_USHORT( p ); 1256 1257 if ( image_start == image_end ) /* missing glyph */ 1258 goto NoBitmap; 1259 break; 1260 1261 case 4: /* sparse glyph array with (glyph,offset) pairs */ 1262 { 1263 FT_ULong mm, num_glyphs; 1264 1265 1266 if ( p + 4 > p_limit ) 1267 goto NoBitmap; 1268 1269 num_glyphs = FT_NEXT_ULONG( p ); 1270 1271 /* overflow check for p + ( num_glyphs + 1 ) * 4 */ 1272 if ( p + 4 > p_limit || 1273 num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) 1274 goto NoBitmap; 1275 1276 for ( mm = 0; mm < num_glyphs; mm++ ) 1277 { 1278 FT_UInt gindex = FT_NEXT_USHORT( p ); 1279 1280 1281 if ( gindex == glyph_index ) 1282 { 1283 image_start = FT_NEXT_USHORT( p ); 1284 p += 2; 1285 image_end = FT_PEEK_USHORT( p ); 1286 break; 1287 } 1288 p += 2; 1289 } 1290 1291 if ( mm >= num_glyphs ) 1292 goto NoBitmap; 1293 } 1294 break; 1295 1296 case 5: /* constant metrics with sparse glyph codes */ 1297 case 19: 1298 { 1299 FT_ULong image_size, mm, num_glyphs; 1300 1301 1302 if ( p + 16 > p_limit ) 1303 goto NoBitmap; 1304 1305 image_size = FT_NEXT_ULONG( p ); 1306 1307 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) 1308 goto NoBitmap; 1309 1310 num_glyphs = FT_NEXT_ULONG( p ); 1311 1312 /* overflow check for p + 2 * num_glyphs */ 1313 if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) ) 1314 goto NoBitmap; 1315 1316 for ( mm = 0; mm < num_glyphs; mm++ ) 1317 { 1318 FT_UInt gindex = FT_NEXT_USHORT( p ); 1319 1320 1321 if ( gindex == glyph_index ) 1322 break; 1323 } 1324 1325 if ( mm >= num_glyphs ) 1326 goto NoBitmap; 1327 1328 image_start = image_size * mm; 1329 image_end = image_start + image_size; 1330 } 1331 break; 1332 1333 default: 1334 goto NoBitmap; 1335 } 1336 1337 if ( image_start > image_end ) 1338 goto NoBitmap; 1339 1340 image_end -= image_start; 1341 image_start = image_offset + image_start; 1342 1343 FT_TRACE3(( "tt_sbit_decoder_load_image:" 1344 " found sbit (format %d) for glyph index %d\n", 1345 image_format, glyph_index )); 1346 1347 return tt_sbit_decoder_load_bitmap( decoder, 1348 image_format, 1349 image_start, 1350 image_end, 1351 x_pos, 1352 y_pos, 1353 recurse_count ); 1354 1355 Failure: 1356 return FT_THROW( Invalid_Table ); 1357 1358 NoBitmap: 1359 FT_TRACE4(( "tt_sbit_decoder_load_image:" 1360 " no sbit found for glyph index %d\n", glyph_index )); 1361 1362 return FT_THROW( Invalid_Argument ); 1363 } 1364 1365 1366 static FT_Error 1367 tt_face_load_sbix_image( TT_Face face, 1368 FT_ULong strike_index, 1369 FT_UInt glyph_index, 1370 FT_Stream stream, 1371 FT_Bitmap *map, 1372 TT_SBit_MetricsRec *metrics ) 1373 { 1374 FT_UInt sbix_pos, strike_offset, glyph_start, glyph_end; 1375 FT_ULong table_size; 1376 FT_Int originOffsetX, originOffsetY; 1377 FT_Tag graphicType; 1378 FT_Int recurse_depth = 0; 1379 1380 FT_Error error; 1381 FT_Byte* p; 1382 1383 FT_UNUSED( map ); 1384 1385 1386 metrics->width = 0; 1387 metrics->height = 0; 1388 1389 p = face->sbit_table + 8 + 4 * strike_index; 1390 strike_offset = FT_NEXT_ULONG( p ); 1391 1392 error = face->goto_table( face, TTAG_sbix, stream, &table_size ); 1393 if ( error ) 1394 return error; 1395 sbix_pos = FT_STREAM_POS(); 1396 1397 retry: 1398 if ( glyph_index > (FT_UInt)face->root.num_glyphs ) 1399 return FT_THROW( Invalid_Argument ); 1400 1401 if ( strike_offset >= table_size || 1402 table_size - strike_offset < 4 + glyph_index * 4 + 8 ) 1403 return FT_THROW( Invalid_File_Format ); 1404 1405 if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) || 1406 FT_FRAME_ENTER( 8 ) ) 1407 return error; 1408 1409 glyph_start = FT_GET_ULONG(); 1410 glyph_end = FT_GET_ULONG(); 1411 1412 FT_FRAME_EXIT(); 1413 1414 if ( glyph_start == glyph_end ) 1415 return FT_THROW( Invalid_Argument ); 1416 if ( glyph_start > glyph_end || 1417 glyph_end - glyph_start < 8 || 1418 table_size - strike_offset < glyph_end ) 1419 return FT_THROW( Invalid_File_Format ); 1420 1421 if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) || 1422 FT_FRAME_ENTER( glyph_end - glyph_start ) ) 1423 return error; 1424 1425 originOffsetX = FT_GET_SHORT(); 1426 originOffsetY = FT_GET_SHORT(); 1427 1428 graphicType = FT_GET_TAG4(); 1429 1430 switch ( graphicType ) 1431 { 1432 case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ): 1433 if ( recurse_depth < 4 ) 1434 { 1435 glyph_index = FT_GET_USHORT(); 1436 FT_FRAME_EXIT(); 1437 recurse_depth++; 1438 goto retry; 1439 } 1440 error = FT_THROW( Invalid_File_Format ); 1441 break; 1442 1443 case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ): 1444 #ifdef FT_CONFIG_OPTION_USE_PNG 1445 error = Load_SBit_Png( face->root.glyph, 1446 0, 1447 0, 1448 32, 1449 metrics, 1450 stream->memory, 1451 stream->cursor, 1452 glyph_end - glyph_start - 8, 1453 TRUE ); 1454 #else 1455 error = FT_THROW( Unimplemented_Feature ); 1456 #endif 1457 break; 1458 1459 case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ): 1460 case FT_MAKE_TAG( 't', 'i', 'f', 'f' ): 1461 case FT_MAKE_TAG( 'r', 'g', 'b', 'l' ): /* used on iOS 7.1 */ 1462 error = FT_THROW( Unknown_File_Format ); 1463 break; 1464 1465 default: 1466 error = FT_THROW( Unimplemented_Feature ); 1467 break; 1468 } 1469 1470 FT_FRAME_EXIT(); 1471 1472 if ( !error ) 1473 { 1474 FT_Short abearing; 1475 FT_UShort aadvance; 1476 1477 1478 tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance ); 1479 1480 metrics->horiBearingX = (FT_Short)originOffsetX; 1481 metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height ); 1482 metrics->horiAdvance = (FT_UShort)( aadvance * 1483 face->root.size->metrics.x_ppem / 1484 face->header.Units_Per_EM ); 1485 } 1486 1487 return error; 1488 } 1489 1490 FT_LOCAL( FT_Error ) 1491 tt_face_load_sbit_image( TT_Face face, 1492 FT_ULong strike_index, 1493 FT_UInt glyph_index, 1494 FT_UInt load_flags, 1495 FT_Stream stream, 1496 FT_Bitmap *map, 1497 TT_SBit_MetricsRec *metrics ) 1498 { 1499 FT_Error error = FT_Err_Ok; 1500 1501 1502 switch ( (FT_UInt)face->sbit_table_type ) 1503 { 1504 case TT_SBIT_TABLE_TYPE_EBLC: 1505 case TT_SBIT_TABLE_TYPE_CBLC: 1506 { 1507 TT_SBitDecoderRec decoder[1]; 1508 1509 1510 error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); 1511 if ( !error ) 1512 { 1513 error = tt_sbit_decoder_load_image( decoder, 1514 glyph_index, 1515 0, 1516 0, 1517 0 ); 1518 tt_sbit_decoder_done( decoder ); 1519 } 1520 } 1521 break; 1522 1523 case TT_SBIT_TABLE_TYPE_SBIX: 1524 error = tt_face_load_sbix_image( face, 1525 strike_index, 1526 glyph_index, 1527 stream, 1528 map, 1529 metrics ); 1530 break; 1531 1532 default: 1533 error = FT_THROW( Unknown_File_Format ); 1534 break; 1535 } 1536 1537 /* Flatten color bitmaps if color was not requested. */ 1538 if ( !error && 1539 !( load_flags & FT_LOAD_COLOR ) && 1540 map->pixel_mode == FT_PIXEL_MODE_BGRA ) 1541 { 1542 FT_Bitmap new_map; 1543 FT_Library library = face->root.glyph->library; 1544 1545 1546 FT_Bitmap_Init( &new_map ); 1547 1548 /* Convert to 8bit grayscale. */ 1549 error = FT_Bitmap_Convert( library, map, &new_map, 1 ); 1550 if ( error ) 1551 FT_Bitmap_Done( library, &new_map ); 1552 else 1553 { 1554 map->pixel_mode = new_map.pixel_mode; 1555 map->pitch = new_map.pitch; 1556 map->num_grays = new_map.num_grays; 1557 1558 ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer ); 1559 face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP; 1560 } 1561 } 1562 1563 return error; 1564 } 1565 1566 1567 /* EOF */ 1568