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