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