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