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