1 /***************************************************************************/ 2 /* */ 3 /* pfrload.c */ 4 /* */ 5 /* FreeType PFR loader (body). */ 6 /* */ 7 /* Copyright 2002 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 ) pfr_extra_items_skip(FT_Byte ** pp,FT_Byte * limit)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 ) pfr_extra_items_parse(FT_Byte ** pp,FT_Byte * limit,PFR_ExtraItem item_list,FT_Pointer item_data)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 = 0; 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 = PFR_Err_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 ) pfr_header_load(PFR_Header header,FT_Stream stream)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 ) pfr_header_check(PFR_Header header)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 ) pfr_log_font_count(FT_Stream stream,FT_UInt32 section_offset,FT_UInt * acount)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 ) pfr_log_font_load(PFR_LogFont log_font,FT_Stream stream,FT_UInt idx,FT_UInt32 section_offset,FT_Bool size_increment)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 PFR_Err_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 = PFR_Err_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 ) pfr_extra_item_load_bitmap_info(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)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 = 0; 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 = (phy_font->num_strikes + count + 3) & -4; 369 370 if ( FT_RENEW_ARRAY( phy_font->strikes, 371 phy_font->num_strikes, 372 new_max ) ) 373 goto Exit; 374 375 phy_font->max_strikes = new_max; 376 } 377 378 size1 = 1 + 1 + 1 + 2 + 2 + 1; 379 if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) 380 size1++; 381 382 if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) 383 size1++; 384 385 if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) 386 size1++; 387 388 if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) 389 size1++; 390 391 if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) 392 size1++; 393 394 strike = phy_font->strikes + phy_font->num_strikes; 395 396 PFR_CHECK( count * size1 ); 397 398 for ( n = 0; n < count; n++, strike++ ) 399 { 400 strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) 401 ? PFR_NEXT_USHORT( p ) 402 : PFR_NEXT_BYTE( p ); 403 404 strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) 405 ? PFR_NEXT_USHORT( p ) 406 : PFR_NEXT_BYTE( p ); 407 408 strike->flags = PFR_NEXT_BYTE( p ); 409 410 strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) 411 ? PFR_NEXT_ULONG( p ) 412 : PFR_NEXT_USHORT( p ); 413 414 strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) 415 ? PFR_NEXT_ULONG( p ) 416 : PFR_NEXT_USHORT( p ); 417 418 strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) 419 ? PFR_NEXT_USHORT( p ) 420 : PFR_NEXT_BYTE( p ); 421 } 422 423 phy_font->num_strikes += count; 424 425 Exit: 426 return error; 427 428 Too_Short: 429 error = PFR_Err_Invalid_Table; 430 FT_ERROR(( "pfr_extra_item_load_bitmap_info: invalid bitmap info table\n" )); 431 goto Exit; 432 } 433 434 435 /* load font ID, i.e. name */ 436 FT_CALLBACK_DEF( FT_Error ) pfr_extra_item_load_font_id(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)437 pfr_extra_item_load_font_id( FT_Byte* p, 438 FT_Byte* limit, 439 PFR_PhyFont phy_font ) 440 { 441 FT_Error error = 0; 442 FT_Memory memory = phy_font->memory; 443 FT_UInt len = (FT_UInt)( limit - p ); 444 445 446 if ( phy_font->font_id != NULL ) 447 goto Exit; 448 449 if ( FT_ALLOC( phy_font->font_id, len+1 ) ) 450 goto Exit; 451 452 /* copy font ID name, and terminate it for safety */ 453 FT_MEM_COPY( phy_font->font_id, p, len ); 454 phy_font->font_id[len] = 0; 455 456 Exit: 457 return error; 458 } 459 460 461 /* load stem snap tables */ 462 FT_CALLBACK_DEF( FT_Error ) pfr_extra_item_load_stem_snaps(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)463 pfr_extra_item_load_stem_snaps( FT_Byte* p, 464 FT_Byte* limit, 465 PFR_PhyFont phy_font ) 466 { 467 FT_UInt count, num_vert, num_horz; 468 FT_Int* snaps; 469 FT_Error error = 0; 470 FT_Memory memory = phy_font->memory; 471 472 473 if ( phy_font->vertical.stem_snaps != NULL ) 474 goto Exit; 475 476 PFR_CHECK( 1 ); 477 count = PFR_NEXT_BYTE( p ); 478 479 num_vert = count & 15; 480 num_horz = count >> 4; 481 count = num_vert + num_horz; 482 483 PFR_CHECK( count * 2 ); 484 485 if ( FT_NEW_ARRAY( snaps, count ) ) 486 goto Exit; 487 488 phy_font->vertical.stem_snaps = snaps; 489 phy_font->horizontal.stem_snaps = snaps + num_vert; 490 491 for ( ; count > 0; count--, snaps++ ) 492 *snaps = FT_NEXT_SHORT( p ); 493 494 Exit: 495 return error; 496 497 Too_Short: 498 error = PFR_Err_Invalid_Table; 499 FT_ERROR(( "pfr_exta_item_load_stem_snaps: invalid stem snaps table\n" )); 500 goto Exit; 501 } 502 503 504 #if 0 505 506 /* load kerning pair data */ 507 FT_CALLBACK_DEF( FT_Error ) 508 pfr_extra_item_load_kerning_pairs( FT_Byte* p, 509 FT_Byte* limit, 510 PFR_PhyFont phy_font ) 511 { 512 FT_Int count; 513 FT_UShort base_adj; 514 FT_UInt flags; 515 FT_UInt num_pairs; 516 PFR_KernPair pairs; 517 FT_Error error = 0; 518 FT_Memory memory = phy_font->memory; 519 520 521 /* allocate a new kerning item */ 522 /* XXX: there may be multiple extra items for kerning */ 523 if ( phy_font->kern_pairs != NULL ) 524 goto Exit; 525 526 FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); 527 528 PFR_CHECK( 4 ); 529 530 num_pairs = PFR_NEXT_BYTE( p ); 531 base_adj = PFR_NEXT_SHORT( p ); 532 flags = PFR_NEXT_BYTE( p ); 533 534 #ifndef PFR_CONFIG_NO_CHECKS 535 count = 3; 536 537 if ( flags & PFR_KERN_2BYTE_CHAR ) 538 count += 2; 539 540 if ( flags & PFR_KERN_2BYTE_ADJ ) 541 count += 1; 542 543 PFR_CHECK( num_pairs * count ); 544 #endif 545 546 if ( FT_NEW_ARRAY( pairs, num_pairs ) ) 547 goto Exit; 548 549 phy_font->num_kern_pairs = num_pairs; 550 phy_font->kern_pairs = pairs; 551 552 for (count = num_pairs ; count > 0; count--, pairs++ ) 553 { 554 if ( flags & PFR_KERN_2BYTE_CHAR ) 555 { 556 pairs->glyph1 = PFR_NEXT_USHORT( p ); 557 pairs->glyph2 = PFR_NEXT_USHORT( p ); 558 } 559 else 560 { 561 pairs->glyph1 = PFR_NEXT_BYTE( p ); 562 pairs->glyph2 = PFR_NEXT_BYTE( p ); 563 } 564 565 if ( flags & PFR_KERN_2BYTE_ADJ ) 566 pairs->kerning.x = base_adj + PFR_NEXT_SHORT( p ); 567 else 568 pairs->kerning.x = base_adj + PFR_NEXT_INT8( p ); 569 570 pairs->kerning.y = 0; 571 572 FT_TRACE2(( "kerning %d <-> %d : %ld\n", 573 pairs->glyph1, pairs->glyph2, pairs->kerning.x )); 574 } 575 576 Exit: 577 return error; 578 579 Too_Short: 580 error = PFR_Err_Invalid_Table; 581 FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " 582 "invalid kerning pairs table\n" )); 583 goto Exit; 584 } 585 586 #else /* 0 */ 587 588 /* load kerning pair data */ 589 FT_CALLBACK_DEF( FT_Error ) pfr_extra_item_load_kerning_pairs(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)590 pfr_extra_item_load_kerning_pairs( FT_Byte* p, 591 FT_Byte* limit, 592 PFR_PhyFont phy_font ) 593 { 594 PFR_KernItem item; 595 FT_Error error = 0; 596 FT_Memory memory = phy_font->memory; 597 598 599 FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); 600 601 if ( FT_NEW( item ) ) 602 goto Exit; 603 604 PFR_CHECK( 4 ); 605 606 item->pair_count = PFR_NEXT_BYTE( p ); 607 item->base_adj = PFR_NEXT_SHORT( p ); 608 item->flags = PFR_NEXT_BYTE( p ); 609 item->offset = phy_font->offset + ( p - phy_font->cursor ); 610 611 #ifndef PFR_CONFIG_NO_CHECKS 612 item->pair_size = 3; 613 614 if ( item->flags & PFR_KERN_2BYTE_CHAR ) 615 item->pair_size += 2; 616 617 if ( item->flags & PFR_KERN_2BYTE_ADJ ) 618 item->pair_size += 1; 619 620 PFR_CHECK( item->pair_count * item->pair_size ); 621 #endif 622 623 /* load first and last pairs into the item to speed up */ 624 /* lookup later... */ 625 if ( item->pair_count > 0 ) 626 { 627 FT_UInt char1, char2; 628 FT_Byte* q; 629 630 631 if ( item->flags & PFR_KERN_2BYTE_CHAR ) 632 { 633 q = p; 634 char1 = PFR_NEXT_USHORT( q ); 635 char2 = PFR_NEXT_USHORT( q ); 636 637 item->pair1 = PFR_KERN_INDEX( char1, char2 ); 638 639 q = p + item->pair_size * ( item->pair_count - 1 ); 640 char1 = PFR_NEXT_USHORT( q ); 641 char2 = PFR_NEXT_USHORT( q ); 642 643 item->pair2 = PFR_KERN_INDEX( char1, char2 ); 644 } 645 else 646 { 647 q = p; 648 char1 = PFR_NEXT_BYTE( q ); 649 char2 = PFR_NEXT_BYTE( q ); 650 651 item->pair1 = PFR_KERN_INDEX( char1, char2 ); 652 653 q = p + item->pair_size * ( item->pair_count - 1 ); 654 char1 = PFR_NEXT_BYTE( q ); 655 char2 = PFR_NEXT_BYTE( q ); 656 657 item->pair2 = PFR_KERN_INDEX( char1, char2 ); 658 } 659 660 /* add new item to the current list */ 661 item->next = NULL; 662 *phy_font->kern_items_tail = item; 663 phy_font->kern_items_tail = &item->next; 664 phy_font->num_kern_pairs += item->pair_count; 665 } 666 else 667 { 668 /* empty item! */ 669 FT_FREE( item ); 670 } 671 672 Exit: 673 return error; 674 675 Too_Short: 676 FT_FREE( item ); 677 678 error = PFR_Err_Invalid_Table; 679 FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " 680 "invalid kerning pairs table\n" )); 681 goto Exit; 682 } 683 #endif /* 0 */ 684 685 686 static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = 687 { 688 { 1, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_bitmap_info }, 689 { 2, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_font_id }, 690 { 3, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_stem_snaps }, 691 { 4, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_kerning_pairs }, 692 { 0, NULL } 693 }; 694 695 696 FT_LOCAL_DEF( void ) pfr_phy_font_done(PFR_PhyFont phy_font,FT_Memory memory)697 pfr_phy_font_done( PFR_PhyFont phy_font, 698 FT_Memory memory ) 699 { 700 if ( phy_font->font_id ) 701 FT_FREE( phy_font->font_id ); 702 703 FT_FREE( phy_font->vertical.stem_snaps ); 704 phy_font->vertical.num_stem_snaps = 0; 705 706 phy_font->horizontal.stem_snaps = NULL; 707 phy_font->horizontal.num_stem_snaps = 0; 708 709 FT_FREE( phy_font->strikes ); 710 phy_font->num_strikes = 0; 711 phy_font->max_strikes = 0; 712 713 FT_FREE( phy_font->chars ); 714 phy_font->num_chars = 0; 715 phy_font->chars_offset = 0; 716 717 FT_FREE( phy_font->blue_values ); 718 phy_font->num_blue_values = 0; 719 720 { 721 PFR_KernItem item, next; 722 723 724 item = phy_font->kern_items; 725 while ( item ) 726 { 727 next = item->next; 728 FT_FREE( item ); 729 item = next; 730 } 731 phy_font->kern_items = NULL; 732 phy_font->kern_items_tail = NULL; 733 } 734 735 phy_font->num_kern_pairs = 0; 736 } 737 738 739 FT_LOCAL_DEF( FT_Error ) pfr_phy_font_load(PFR_PhyFont phy_font,FT_Stream stream,FT_UInt32 offset,FT_UInt32 size)740 pfr_phy_font_load( PFR_PhyFont phy_font, 741 FT_Stream stream, 742 FT_UInt32 offset, 743 FT_UInt32 size ) 744 { 745 FT_Error error; 746 FT_Memory memory = stream->memory; 747 FT_UInt flags, num_aux; 748 FT_Byte* p; 749 FT_Byte* limit; 750 751 752 phy_font->memory = memory; 753 phy_font->offset = offset; 754 755 phy_font->kern_items = NULL; 756 phy_font->kern_items_tail = &phy_font->kern_items; 757 758 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) 759 goto Exit; 760 761 phy_font->cursor = stream->cursor; 762 763 p = stream->cursor; 764 limit = p + size; 765 766 PFR_CHECK( 15 ); 767 phy_font->font_ref_number = PFR_NEXT_USHORT( p ); 768 phy_font->outline_resolution = PFR_NEXT_USHORT( p ); 769 phy_font->metrics_resolution = PFR_NEXT_USHORT( p ); 770 phy_font->bbox.xMin = PFR_NEXT_SHORT( p ); 771 phy_font->bbox.yMin = PFR_NEXT_SHORT( p ); 772 phy_font->bbox.xMax = PFR_NEXT_SHORT( p ); 773 phy_font->bbox.yMax = PFR_NEXT_SHORT( p ); 774 phy_font->flags = flags = PFR_NEXT_BYTE( p ); 775 776 /* get the standard advance for non-proprotional fonts */ 777 if ( !(flags & PFR_PHY_PROPORTIONAL) ) 778 { 779 PFR_CHECK( 2 ); 780 phy_font->standard_advance = PFR_NEXT_SHORT( p ); 781 } 782 783 /* load the extra items when present */ 784 if ( flags & PFR_PHY_EXTRA_ITEMS ) 785 { 786 error = pfr_extra_items_parse( &p, limit, 787 pfr_phy_font_extra_items, phy_font ); 788 789 if ( error ) 790 goto Fail; 791 } 792 793 /* skip the aux bytes */ 794 PFR_CHECK( 3 ); 795 num_aux = PFR_NEXT_ULONG( p ); 796 797 PFR_CHECK( num_aux ); 798 p += num_aux; 799 800 /* read the blue values */ 801 { 802 FT_UInt n, count; 803 804 PFR_CHECK( 1 ); 805 phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); 806 807 PFR_CHECK( count * 2 ); 808 809 if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) 810 goto Fail; 811 812 for ( n = 0; n < count; n++ ) 813 phy_font->blue_values[n] = PFR_NEXT_SHORT( p ); 814 } 815 816 PFR_CHECK( 8 ); 817 phy_font->blue_fuzz = PFR_NEXT_BYTE( p ); 818 phy_font->blue_scale = PFR_NEXT_BYTE( p ); 819 820 phy_font->vertical.standard = PFR_NEXT_USHORT( p ); 821 phy_font->horizontal.standard = PFR_NEXT_USHORT( p ); 822 823 /* read the character descriptors */ 824 { 825 FT_UInt n, count, Size; 826 827 828 phy_font->num_chars = count = PFR_NEXT_USHORT( p ); 829 phy_font->chars_offset = offset + ( p - stream->cursor ); 830 831 if ( FT_NEW_ARRAY( phy_font->chars, count ) ) 832 goto Fail; 833 834 Size = 1 + 1 + 2; 835 if ( flags & PFR_PHY_2BYTE_CHARCODE ) 836 Size += 1; 837 838 if ( flags & PFR_PHY_PROPORTIONAL ) 839 Size += 2; 840 841 if ( flags & PFR_PHY_ASCII_CODE ) 842 Size += 1; 843 844 if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) 845 Size += 1; 846 847 if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) 848 Size += 1; 849 850 PFR_CHECK( count * Size ); 851 852 for ( n = 0; n < count; n++ ) 853 { 854 PFR_Char cur = &phy_font->chars[n]; 855 856 857 cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) 858 ? PFR_NEXT_USHORT( p ) 859 : PFR_NEXT_BYTE( p ); 860 861 cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) 862 ? PFR_NEXT_SHORT( p ) 863 : (FT_Int) phy_font->standard_advance; 864 865 #if 0 866 cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) 867 ? PFR_NEXT_BYTE( p ) 868 : 0; 869 #else 870 if ( flags & PFR_PHY_ASCII_CODE ) 871 p += 1; 872 #endif 873 cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) 874 ? PFR_NEXT_USHORT( p ) 875 : PFR_NEXT_BYTE( p ); 876 877 cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) 878 ? PFR_NEXT_ULONG( p ) 879 : PFR_NEXT_USHORT( p ); 880 } 881 } 882 883 /* that's it !! */ 884 Fail: 885 FT_FRAME_EXIT(); 886 887 /* save position of bitmap info */ 888 phy_font->bct_offset = FT_STREAM_POS(); 889 phy_font->cursor = NULL; 890 891 Exit: 892 return error; 893 894 Too_Short: 895 error = PFR_Err_Invalid_Table; 896 FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); 897 goto Fail; 898 } 899 900 901 /* END */ 902