1 /***************************************************************************/ 2 /* */ 3 /* pfrload.c */ 4 /* */ 5 /* FreeType PFR loader (body). */ 6 /* */ 7 /* Copyright 2002-2005, 2007, 2009, 2010, 2013, 2014 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* This file is part of the FreeType project, and may only be used, */ 11 /* modified, and distributed under the terms of the FreeType project */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* this file you indicate that you have read the license and */ 14 /* understand and accept it fully. */ 15 /* */ 16 /***************************************************************************/ 17 18 19 #include "pfrload.h" 20 #include FT_INTERNAL_DEBUG_H 21 #include FT_INTERNAL_STREAM_H 22 23 #include "pfrerror.h" 24 25 #undef FT_COMPONENT 26 #define FT_COMPONENT trace_pfr 27 28 29 /*************************************************************************/ 30 /*************************************************************************/ 31 /***** *****/ 32 /***** EXTRA ITEMS *****/ 33 /***** *****/ 34 /*************************************************************************/ 35 /*************************************************************************/ 36 37 38 FT_LOCAL_DEF( FT_Error ) 39 pfr_extra_items_skip( FT_Byte* *pp, 40 FT_Byte* limit ) 41 { 42 return pfr_extra_items_parse( pp, limit, NULL, NULL ); 43 } 44 45 46 FT_LOCAL_DEF( FT_Error ) 47 pfr_extra_items_parse( FT_Byte* *pp, 48 FT_Byte* limit, 49 PFR_ExtraItem item_list, 50 FT_Pointer item_data ) 51 { 52 FT_Error error = FT_Err_Ok; 53 FT_Byte* p = *pp; 54 FT_UInt num_items, item_type, item_size; 55 56 57 PFR_CHECK( 1 ); 58 num_items = PFR_NEXT_BYTE( p ); 59 60 for ( ; num_items > 0; num_items-- ) 61 { 62 PFR_CHECK( 2 ); 63 item_size = PFR_NEXT_BYTE( p ); 64 item_type = PFR_NEXT_BYTE( p ); 65 66 PFR_CHECK( item_size ); 67 68 if ( item_list ) 69 { 70 PFR_ExtraItem extra = item_list; 71 72 73 for ( extra = item_list; extra->parser != NULL; extra++ ) 74 { 75 if ( extra->type == item_type ) 76 { 77 error = extra->parser( p, p + item_size, item_data ); 78 if ( error ) goto Exit; 79 80 break; 81 } 82 } 83 } 84 85 p += item_size; 86 } 87 88 Exit: 89 *pp = p; 90 return error; 91 92 Too_Short: 93 FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" )); 94 error = FT_THROW( Invalid_Table ); 95 goto Exit; 96 } 97 98 99 /*************************************************************************/ 100 /*************************************************************************/ 101 /***** *****/ 102 /***** PFR HEADER *****/ 103 /***** *****/ 104 /*************************************************************************/ 105 /*************************************************************************/ 106 107 static const FT_Frame_Field pfr_header_fields[] = 108 { 109 #undef FT_STRUCTURE 110 #define FT_STRUCTURE PFR_HeaderRec 111 112 FT_FRAME_START( 58 ), 113 FT_FRAME_ULONG ( signature ), 114 FT_FRAME_USHORT( version ), 115 FT_FRAME_USHORT( signature2 ), 116 FT_FRAME_USHORT( header_size ), 117 118 FT_FRAME_USHORT( log_dir_size ), 119 FT_FRAME_USHORT( log_dir_offset ), 120 121 FT_FRAME_USHORT( log_font_max_size ), 122 FT_FRAME_UOFF3 ( log_font_section_size ), 123 FT_FRAME_UOFF3 ( log_font_section_offset ), 124 125 FT_FRAME_USHORT( phy_font_max_size ), 126 FT_FRAME_UOFF3 ( phy_font_section_size ), 127 FT_FRAME_UOFF3 ( phy_font_section_offset ), 128 129 FT_FRAME_USHORT( gps_max_size ), 130 FT_FRAME_UOFF3 ( gps_section_size ), 131 FT_FRAME_UOFF3 ( gps_section_offset ), 132 133 FT_FRAME_BYTE ( max_blue_values ), 134 FT_FRAME_BYTE ( max_x_orus ), 135 FT_FRAME_BYTE ( max_y_orus ), 136 137 FT_FRAME_BYTE ( phy_font_max_size_high ), 138 FT_FRAME_BYTE ( color_flags ), 139 140 FT_FRAME_UOFF3 ( bct_max_size ), 141 FT_FRAME_UOFF3 ( bct_set_max_size ), 142 FT_FRAME_UOFF3 ( phy_bct_set_max_size ), 143 144 FT_FRAME_USHORT( num_phy_fonts ), 145 FT_FRAME_BYTE ( max_vert_stem_snap ), 146 FT_FRAME_BYTE ( max_horz_stem_snap ), 147 FT_FRAME_USHORT( max_chars ), 148 FT_FRAME_END 149 }; 150 151 152 FT_LOCAL_DEF( FT_Error ) 153 pfr_header_load( PFR_Header header, 154 FT_Stream stream ) 155 { 156 FT_Error error; 157 158 159 /* read header directly */ 160 if ( !FT_STREAM_SEEK( 0 ) && 161 !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) ) 162 { 163 /* make a few adjustments to the header */ 164 header->phy_font_max_size += 165 (FT_UInt32)header->phy_font_max_size_high << 16; 166 } 167 168 return error; 169 } 170 171 172 FT_LOCAL_DEF( FT_Bool ) 173 pfr_header_check( PFR_Header header ) 174 { 175 FT_Bool result = 1; 176 177 178 /* check signature and header size */ 179 if ( header->signature != 0x50465230L || /* "PFR0" */ 180 header->version > 4 || 181 header->header_size < 58 || 182 header->signature2 != 0x0d0a ) /* CR/LF */ 183 { 184 result = 0; 185 } 186 return result; 187 } 188 189 190 /***********************************************************************/ 191 /***********************************************************************/ 192 /***** *****/ 193 /***** PFR LOGICAL FONTS *****/ 194 /***** *****/ 195 /***********************************************************************/ 196 /***********************************************************************/ 197 198 199 FT_LOCAL_DEF( FT_Error ) 200 pfr_log_font_count( FT_Stream stream, 201 FT_UInt32 section_offset, 202 FT_UInt *acount ) 203 { 204 FT_Error error; 205 FT_UInt count; 206 FT_UInt result = 0; 207 208 209 if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) 210 goto Exit; 211 212 result = count; 213 214 Exit: 215 *acount = result; 216 return error; 217 } 218 219 220 FT_LOCAL_DEF( FT_Error ) 221 pfr_log_font_load( PFR_LogFont log_font, 222 FT_Stream stream, 223 FT_UInt idx, 224 FT_UInt32 section_offset, 225 FT_Bool size_increment ) 226 { 227 FT_UInt num_log_fonts; 228 FT_UInt flags; 229 FT_UInt32 offset; 230 FT_UInt32 size; 231 FT_Error error; 232 233 234 if ( FT_STREAM_SEEK( section_offset ) || 235 FT_READ_USHORT( num_log_fonts ) ) 236 goto Exit; 237 238 if ( idx >= num_log_fonts ) 239 return FT_THROW( Invalid_Argument ); 240 241 if ( FT_STREAM_SKIP( idx * 5 ) || 242 FT_READ_USHORT( size ) || 243 FT_READ_UOFF3 ( offset ) ) 244 goto Exit; 245 246 /* save logical font size and offset */ 247 log_font->size = size; 248 log_font->offset = offset; 249 250 /* now, check the rest of the table before loading it */ 251 { 252 FT_Byte* p; 253 FT_Byte* limit; 254 FT_UInt local; 255 256 257 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) 258 goto Exit; 259 260 p = stream->cursor; 261 limit = p + size; 262 263 PFR_CHECK(13); 264 265 log_font->matrix[0] = PFR_NEXT_LONG( p ); 266 log_font->matrix[1] = PFR_NEXT_LONG( p ); 267 log_font->matrix[2] = PFR_NEXT_LONG( p ); 268 log_font->matrix[3] = PFR_NEXT_LONG( p ); 269 270 flags = PFR_NEXT_BYTE( p ); 271 272 local = 0; 273 if ( flags & PFR_LOG_STROKE ) 274 { 275 local++; 276 if ( flags & PFR_LOG_2BYTE_STROKE ) 277 local++; 278 279 if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) 280 local += 3; 281 } 282 if ( flags & PFR_LOG_BOLD ) 283 { 284 local++; 285 if ( flags & PFR_LOG_2BYTE_BOLD ) 286 local++; 287 } 288 289 PFR_CHECK( local ); 290 291 if ( flags & PFR_LOG_STROKE ) 292 { 293 log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE ) 294 ? PFR_NEXT_SHORT( p ) 295 : PFR_NEXT_BYTE( p ); 296 297 if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) 298 log_font->miter_limit = PFR_NEXT_LONG( p ); 299 } 300 301 if ( flags & PFR_LOG_BOLD ) 302 { 303 log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD ) 304 ? PFR_NEXT_SHORT( p ) 305 : PFR_NEXT_BYTE( p ); 306 } 307 308 if ( flags & PFR_LOG_EXTRA_ITEMS ) 309 { 310 error = pfr_extra_items_skip( &p, limit ); 311 if (error) goto Fail; 312 } 313 314 PFR_CHECK(5); 315 log_font->phys_size = PFR_NEXT_USHORT( p ); 316 log_font->phys_offset = PFR_NEXT_ULONG( p ); 317 if ( size_increment ) 318 { 319 PFR_CHECK( 1 ); 320 log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16; 321 } 322 } 323 324 Fail: 325 FT_FRAME_EXIT(); 326 327 Exit: 328 return error; 329 330 Too_Short: 331 FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" )); 332 error = FT_THROW( Invalid_Table ); 333 goto Fail; 334 } 335 336 337 /***********************************************************************/ 338 /***********************************************************************/ 339 /***** *****/ 340 /***** PFR PHYSICAL FONTS *****/ 341 /***** *****/ 342 /***********************************************************************/ 343 /***********************************************************************/ 344 345 346 /* load bitmap strikes lists */ 347 FT_CALLBACK_DEF( FT_Error ) 348 pfr_extra_item_load_bitmap_info( FT_Byte* p, 349 FT_Byte* limit, 350 PFR_PhyFont phy_font ) 351 { 352 FT_Memory memory = phy_font->memory; 353 PFR_Strike strike; 354 FT_UInt flags0; 355 FT_UInt n, count, size1; 356 FT_Error error = FT_Err_Ok; 357 358 359 PFR_CHECK( 5 ); 360 361 p += 3; /* skip bctSize */ 362 flags0 = PFR_NEXT_BYTE( p ); 363 count = PFR_NEXT_BYTE( p ); 364 365 /* re-allocate when needed */ 366 if ( phy_font->num_strikes + count > phy_font->max_strikes ) 367 { 368 FT_UInt new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 ); 369 370 371 if ( FT_RENEW_ARRAY( phy_font->strikes, 372 phy_font->num_strikes, 373 new_max ) ) 374 goto Exit; 375 376 phy_font->max_strikes = new_max; 377 } 378 379 size1 = 1 + 1 + 1 + 2 + 2 + 1; 380 if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) 381 size1++; 382 383 if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) 384 size1++; 385 386 if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) 387 size1++; 388 389 if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) 390 size1++; 391 392 if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) 393 size1++; 394 395 strike = phy_font->strikes + phy_font->num_strikes; 396 397 PFR_CHECK( count * size1 ); 398 399 for ( n = 0; n < count; n++, strike++ ) 400 { 401 strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) 402 ? PFR_NEXT_USHORT( p ) 403 : PFR_NEXT_BYTE( p ); 404 405 strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) 406 ? PFR_NEXT_USHORT( p ) 407 : PFR_NEXT_BYTE( p ); 408 409 strike->flags = PFR_NEXT_BYTE( p ); 410 411 strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) 412 ? PFR_NEXT_ULONG( p ) 413 : PFR_NEXT_USHORT( p ); 414 415 strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) 416 ? PFR_NEXT_ULONG( p ) 417 : PFR_NEXT_USHORT( p ); 418 419 strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) 420 ? PFR_NEXT_USHORT( p ) 421 : PFR_NEXT_BYTE( p ); 422 } 423 424 phy_font->num_strikes += count; 425 426 Exit: 427 return error; 428 429 Too_Short: 430 error = FT_THROW( Invalid_Table ); 431 FT_ERROR(( "pfr_extra_item_load_bitmap_info:" 432 " invalid bitmap info table\n" )); 433 goto Exit; 434 } 435 436 437 /* Load font ID. This is a so-called "unique" name that is rather 438 * long and descriptive (like "Tiresias ScreenFont v7.51"). 439 * 440 * Note that a PFR font's family name is contained in an *undocumented* 441 * string of the "auxiliary data" portion of a physical font record. This 442 * may also contain the "real" style name! 443 * 444 * If no family name is present, the font ID is used instead for the 445 * family. 446 */ 447 FT_CALLBACK_DEF( FT_Error ) 448 pfr_extra_item_load_font_id( FT_Byte* p, 449 FT_Byte* limit, 450 PFR_PhyFont phy_font ) 451 { 452 FT_Error error = FT_Err_Ok; 453 FT_Memory memory = phy_font->memory; 454 FT_PtrDist len = limit - p; 455 456 457 if ( phy_font->font_id != NULL ) 458 goto Exit; 459 460 if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) 461 goto Exit; 462 463 /* copy font ID name, and terminate it for safety */ 464 FT_MEM_COPY( phy_font->font_id, p, len ); 465 phy_font->font_id[len] = 0; 466 467 Exit: 468 return error; 469 } 470 471 472 /* load stem snap tables */ 473 FT_CALLBACK_DEF( FT_Error ) 474 pfr_extra_item_load_stem_snaps( FT_Byte* p, 475 FT_Byte* limit, 476 PFR_PhyFont phy_font ) 477 { 478 FT_UInt count, num_vert, num_horz; 479 FT_Int* snaps = NULL; 480 FT_Error error = FT_Err_Ok; 481 FT_Memory memory = phy_font->memory; 482 483 484 if ( phy_font->vertical.stem_snaps != NULL ) 485 goto Exit; 486 487 PFR_CHECK( 1 ); 488 count = PFR_NEXT_BYTE( p ); 489 490 num_vert = count & 15; 491 num_horz = count >> 4; 492 count = num_vert + num_horz; 493 494 PFR_CHECK( count * 2 ); 495 496 if ( FT_NEW_ARRAY( snaps, count ) ) 497 goto Exit; 498 499 phy_font->vertical.stem_snaps = snaps; 500 phy_font->horizontal.stem_snaps = snaps + num_vert; 501 502 for ( ; count > 0; count--, snaps++ ) 503 *snaps = FT_NEXT_SHORT( p ); 504 505 Exit: 506 return error; 507 508 Too_Short: 509 error = FT_THROW( Invalid_Table ); 510 FT_ERROR(( "pfr_exta_item_load_stem_snaps:" 511 " invalid stem snaps table\n" )); 512 goto Exit; 513 } 514 515 516 517 /* load kerning pair data */ 518 FT_CALLBACK_DEF( FT_Error ) 519 pfr_extra_item_load_kerning_pairs( FT_Byte* p, 520 FT_Byte* limit, 521 PFR_PhyFont phy_font ) 522 { 523 PFR_KernItem item = NULL; 524 FT_Error error = FT_Err_Ok; 525 FT_Memory memory = phy_font->memory; 526 527 528 FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); 529 530 if ( FT_NEW( item ) ) 531 goto Exit; 532 533 PFR_CHECK( 4 ); 534 535 item->pair_count = PFR_NEXT_BYTE( p ); 536 item->base_adj = PFR_NEXT_SHORT( p ); 537 item->flags = PFR_NEXT_BYTE( p ); 538 item->offset = phy_font->offset + ( p - phy_font->cursor ); 539 540 #ifndef PFR_CONFIG_NO_CHECKS 541 item->pair_size = 3; 542 543 if ( item->flags & PFR_KERN_2BYTE_CHAR ) 544 item->pair_size += 2; 545 546 if ( item->flags & PFR_KERN_2BYTE_ADJ ) 547 item->pair_size += 1; 548 549 PFR_CHECK( item->pair_count * item->pair_size ); 550 #endif 551 552 /* load first and last pairs into the item to speed up */ 553 /* lookup later... */ 554 if ( item->pair_count > 0 ) 555 { 556 FT_UInt char1, char2; 557 FT_Byte* q; 558 559 560 if ( item->flags & PFR_KERN_2BYTE_CHAR ) 561 { 562 q = p; 563 char1 = PFR_NEXT_USHORT( q ); 564 char2 = PFR_NEXT_USHORT( q ); 565 566 item->pair1 = PFR_KERN_INDEX( char1, char2 ); 567 568 q = p + item->pair_size * ( item->pair_count - 1 ); 569 char1 = PFR_NEXT_USHORT( q ); 570 char2 = PFR_NEXT_USHORT( q ); 571 572 item->pair2 = PFR_KERN_INDEX( char1, char2 ); 573 } 574 else 575 { 576 q = p; 577 char1 = PFR_NEXT_BYTE( q ); 578 char2 = PFR_NEXT_BYTE( q ); 579 580 item->pair1 = PFR_KERN_INDEX( char1, char2 ); 581 582 q = p + item->pair_size * ( item->pair_count - 1 ); 583 char1 = PFR_NEXT_BYTE( q ); 584 char2 = PFR_NEXT_BYTE( q ); 585 586 item->pair2 = PFR_KERN_INDEX( char1, char2 ); 587 } 588 589 /* add new item to the current list */ 590 item->next = NULL; 591 *phy_font->kern_items_tail = item; 592 phy_font->kern_items_tail = &item->next; 593 phy_font->num_kern_pairs += item->pair_count; 594 } 595 else 596 { 597 /* empty item! */ 598 FT_FREE( item ); 599 } 600 601 Exit: 602 return error; 603 604 Too_Short: 605 FT_FREE( item ); 606 607 error = FT_THROW( Invalid_Table ); 608 FT_ERROR(( "pfr_extra_item_load_kerning_pairs:" 609 " invalid kerning pairs table\n" )); 610 goto Exit; 611 } 612 613 614 615 static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = 616 { 617 { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, 618 { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id }, 619 { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps }, 620 { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs }, 621 { 0, NULL } 622 }; 623 624 625 /* Loads a name from the auxiliary data. Since this extracts undocumented 626 * strings from the font file, we need to be careful here. 627 */ 628 static FT_Error 629 pfr_aux_name_load( FT_Byte* p, 630 FT_UInt len, 631 FT_Memory memory, 632 FT_String* *astring ) 633 { 634 FT_Error error = FT_Err_Ok; 635 FT_String* result = NULL; 636 FT_UInt n, ok; 637 638 639 if ( len > 0 && p[len - 1] == 0 ) 640 len--; 641 642 /* check that each character is ASCII for making sure not to 643 load garbage 644 */ 645 ok = ( len > 0 ); 646 for ( n = 0; n < len; n++ ) 647 if ( p[n] < 32 || p[n] > 127 ) 648 { 649 ok = 0; 650 break; 651 } 652 653 if ( ok ) 654 { 655 if ( FT_ALLOC( result, len + 1 ) ) 656 goto Exit; 657 658 FT_MEM_COPY( result, p, len ); 659 result[len] = 0; 660 } 661 Exit: 662 *astring = result; 663 return error; 664 } 665 666 667 FT_LOCAL_DEF( void ) 668 pfr_phy_font_done( PFR_PhyFont phy_font, 669 FT_Memory memory ) 670 { 671 FT_FREE( phy_font->font_id ); 672 FT_FREE( phy_font->family_name ); 673 FT_FREE( phy_font->style_name ); 674 675 FT_FREE( phy_font->vertical.stem_snaps ); 676 phy_font->vertical.num_stem_snaps = 0; 677 678 phy_font->horizontal.stem_snaps = NULL; 679 phy_font->horizontal.num_stem_snaps = 0; 680 681 FT_FREE( phy_font->strikes ); 682 phy_font->num_strikes = 0; 683 phy_font->max_strikes = 0; 684 685 FT_FREE( phy_font->chars ); 686 phy_font->num_chars = 0; 687 phy_font->chars_offset = 0; 688 689 FT_FREE( phy_font->blue_values ); 690 phy_font->num_blue_values = 0; 691 692 { 693 PFR_KernItem item, next; 694 695 696 item = phy_font->kern_items; 697 while ( item ) 698 { 699 next = item->next; 700 FT_FREE( item ); 701 item = next; 702 } 703 phy_font->kern_items = NULL; 704 phy_font->kern_items_tail = NULL; 705 } 706 707 phy_font->num_kern_pairs = 0; 708 } 709 710 711 FT_LOCAL_DEF( FT_Error ) 712 pfr_phy_font_load( PFR_PhyFont phy_font, 713 FT_Stream stream, 714 FT_UInt32 offset, 715 FT_UInt32 size ) 716 { 717 FT_Error error; 718 FT_Memory memory = stream->memory; 719 FT_UInt flags; 720 FT_ULong num_aux; 721 FT_Byte* p; 722 FT_Byte* limit; 723 724 725 phy_font->memory = memory; 726 phy_font->offset = offset; 727 728 phy_font->kern_items = NULL; 729 phy_font->kern_items_tail = &phy_font->kern_items; 730 731 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) 732 goto Exit; 733 734 phy_font->cursor = stream->cursor; 735 736 p = stream->cursor; 737 limit = p + size; 738 739 PFR_CHECK( 15 ); 740 phy_font->font_ref_number = PFR_NEXT_USHORT( p ); 741 phy_font->outline_resolution = PFR_NEXT_USHORT( p ); 742 phy_font->metrics_resolution = PFR_NEXT_USHORT( p ); 743 phy_font->bbox.xMin = PFR_NEXT_SHORT( p ); 744 phy_font->bbox.yMin = PFR_NEXT_SHORT( p ); 745 phy_font->bbox.xMax = PFR_NEXT_SHORT( p ); 746 phy_font->bbox.yMax = PFR_NEXT_SHORT( p ); 747 phy_font->flags = flags = PFR_NEXT_BYTE( p ); 748 749 /* get the standard advance for non-proportional fonts */ 750 if ( !(flags & PFR_PHY_PROPORTIONAL) ) 751 { 752 PFR_CHECK( 2 ); 753 phy_font->standard_advance = PFR_NEXT_SHORT( p ); 754 } 755 756 /* load the extra items when present */ 757 if ( flags & PFR_PHY_EXTRA_ITEMS ) 758 { 759 error = pfr_extra_items_parse( &p, limit, 760 pfr_phy_font_extra_items, phy_font ); 761 762 if ( error ) 763 goto Fail; 764 } 765 766 /* In certain fonts, the auxiliary bytes contain interesting */ 767 /* information. These are not in the specification but can be */ 768 /* guessed by looking at the content of a few PFR0 fonts. */ 769 PFR_CHECK( 3 ); 770 num_aux = PFR_NEXT_ULONG( p ); 771 772 if ( num_aux > 0 ) 773 { 774 FT_Byte* q = p; 775 FT_Byte* q2; 776 777 778 PFR_CHECK( num_aux ); 779 p += num_aux; 780 781 while ( num_aux > 0 ) 782 { 783 FT_UInt length, type; 784 785 786 if ( q + 4 > p ) 787 break; 788 789 length = PFR_NEXT_USHORT( q ); 790 if ( length < 4 || length > num_aux ) 791 break; 792 793 q2 = q + length - 2; 794 type = PFR_NEXT_USHORT( q ); 795 796 switch ( type ) 797 { 798 case 1: 799 /* this seems to correspond to the font's family name, 800 * padded to 16-bits with one zero when necessary 801 */ 802 error = pfr_aux_name_load( q, length - 4U, memory, 803 &phy_font->family_name ); 804 if ( error ) 805 goto Exit; 806 break; 807 808 case 2: 809 if ( q + 32 > q2 ) 810 break; 811 812 q += 10; 813 phy_font->ascent = PFR_NEXT_SHORT( q ); 814 phy_font->descent = PFR_NEXT_SHORT( q ); 815 phy_font->leading = PFR_NEXT_SHORT( q ); 816 break; 817 818 case 3: 819 /* this seems to correspond to the font's style name, 820 * padded to 16-bits with one zero when necessary 821 */ 822 error = pfr_aux_name_load( q, length - 4U, memory, 823 &phy_font->style_name ); 824 if ( error ) 825 goto Exit; 826 break; 827 828 default: 829 ; 830 } 831 832 q = q2; 833 num_aux -= length; 834 } 835 } 836 837 /* read the blue values */ 838 { 839 FT_UInt n, count; 840 841 842 PFR_CHECK( 1 ); 843 phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); 844 845 PFR_CHECK( count * 2 ); 846 847 if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) 848 goto Fail; 849 850 for ( n = 0; n < count; n++ ) 851 phy_font->blue_values[n] = PFR_NEXT_SHORT( p ); 852 } 853 854 PFR_CHECK( 8 ); 855 phy_font->blue_fuzz = PFR_NEXT_BYTE( p ); 856 phy_font->blue_scale = PFR_NEXT_BYTE( p ); 857 858 phy_font->vertical.standard = PFR_NEXT_USHORT( p ); 859 phy_font->horizontal.standard = PFR_NEXT_USHORT( p ); 860 861 /* read the character descriptors */ 862 { 863 FT_UInt n, count, Size; 864 865 866 phy_font->num_chars = count = PFR_NEXT_USHORT( p ); 867 phy_font->chars_offset = offset + ( p - stream->cursor ); 868 869 if ( FT_NEW_ARRAY( phy_font->chars, count ) ) 870 goto Fail; 871 872 Size = 1 + 1 + 2; 873 if ( flags & PFR_PHY_2BYTE_CHARCODE ) 874 Size += 1; 875 876 if ( flags & PFR_PHY_PROPORTIONAL ) 877 Size += 2; 878 879 if ( flags & PFR_PHY_ASCII_CODE ) 880 Size += 1; 881 882 if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) 883 Size += 1; 884 885 if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) 886 Size += 1; 887 888 PFR_CHECK( count * Size ); 889 890 for ( n = 0; n < count; n++ ) 891 { 892 PFR_Char cur = &phy_font->chars[n]; 893 894 895 cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) 896 ? PFR_NEXT_USHORT( p ) 897 : PFR_NEXT_BYTE( p ); 898 899 cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) 900 ? PFR_NEXT_SHORT( p ) 901 : (FT_Int) phy_font->standard_advance; 902 903 #if 0 904 cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) 905 ? PFR_NEXT_BYTE( p ) 906 : 0; 907 #else 908 if ( flags & PFR_PHY_ASCII_CODE ) 909 p += 1; 910 #endif 911 cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) 912 ? PFR_NEXT_USHORT( p ) 913 : PFR_NEXT_BYTE( p ); 914 915 cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) 916 ? PFR_NEXT_ULONG( p ) 917 : PFR_NEXT_USHORT( p ); 918 } 919 } 920 921 /* that's it! */ 922 923 Fail: 924 FT_FRAME_EXIT(); 925 926 /* save position of bitmap info */ 927 phy_font->bct_offset = FT_STREAM_POS(); 928 phy_font->cursor = NULL; 929 930 Exit: 931 return error; 932 933 Too_Short: 934 error = FT_THROW( Invalid_Table ); 935 FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); 936 goto Fail; 937 } 938 939 940 /* END */ 941