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