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