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