Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpfrload.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* pfrload.c */ 00004 /* */ 00005 /* FreeType PFR loader (body). */ 00006 /* */ 00007 /* Copyright 2002, 2003, 2004, 2005, 2007, 2009, 2010 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 00019 #include "pfrload.h" 00020 #include FT_INTERNAL_DEBUG_H 00021 #include FT_INTERNAL_STREAM_H 00022 00023 #include "pfrerror.h" 00024 00025 #undef FT_COMPONENT 00026 #define FT_COMPONENT trace_pfr 00027 00028 00029 /*************************************************************************/ 00030 /*************************************************************************/ 00031 /***** *****/ 00032 /***** EXTRA ITEMS *****/ 00033 /***** *****/ 00034 /*************************************************************************/ 00035 /*************************************************************************/ 00036 00037 00038 FT_LOCAL_DEF( FT_Error ) 00039 pfr_extra_items_skip( FT_Byte* *pp, 00040 FT_Byte* limit ) 00041 { 00042 return pfr_extra_items_parse( pp, limit, NULL, NULL ); 00043 } 00044 00045 00046 FT_LOCAL_DEF( FT_Error ) 00047 pfr_extra_items_parse( FT_Byte* *pp, 00048 FT_Byte* limit, 00049 PFR_ExtraItem item_list, 00050 FT_Pointer item_data ) 00051 { 00052 FT_Error error = PFR_Err_Ok; 00053 FT_Byte* p = *pp; 00054 FT_UInt num_items, item_type, item_size; 00055 00056 00057 PFR_CHECK( 1 ); 00058 num_items = PFR_NEXT_BYTE( p ); 00059 00060 for ( ; num_items > 0; num_items-- ) 00061 { 00062 PFR_CHECK( 2 ); 00063 item_size = PFR_NEXT_BYTE( p ); 00064 item_type = PFR_NEXT_BYTE( p ); 00065 00066 PFR_CHECK( item_size ); 00067 00068 if ( item_list ) 00069 { 00070 PFR_ExtraItem extra = item_list; 00071 00072 00073 for ( extra = item_list; extra->parser != NULL; extra++ ) 00074 { 00075 if ( extra->type == item_type ) 00076 { 00077 error = extra->parser( p, p + item_size, item_data ); 00078 if ( error ) goto Exit; 00079 00080 break; 00081 } 00082 } 00083 } 00084 00085 p += item_size; 00086 } 00087 00088 Exit: 00089 *pp = p; 00090 return error; 00091 00092 Too_Short: 00093 FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" )); 00094 error = PFR_Err_Invalid_Table; 00095 goto Exit; 00096 } 00097 00098 00099 /*************************************************************************/ 00100 /*************************************************************************/ 00101 /***** *****/ 00102 /***** PFR HEADER *****/ 00103 /***** *****/ 00104 /*************************************************************************/ 00105 /*************************************************************************/ 00106 00107 static const FT_Frame_Field pfr_header_fields[] = 00108 { 00109 #undef FT_STRUCTURE 00110 #define FT_STRUCTURE PFR_HeaderRec 00111 00112 FT_FRAME_START( 58 ), 00113 FT_FRAME_ULONG ( signature ), 00114 FT_FRAME_USHORT( version ), 00115 FT_FRAME_USHORT( signature2 ), 00116 FT_FRAME_USHORT( header_size ), 00117 00118 FT_FRAME_USHORT( log_dir_size ), 00119 FT_FRAME_USHORT( log_dir_offset ), 00120 00121 FT_FRAME_USHORT( log_font_max_size ), 00122 FT_FRAME_UOFF3 ( log_font_section_size ), 00123 FT_FRAME_UOFF3 ( log_font_section_offset ), 00124 00125 FT_FRAME_USHORT( phy_font_max_size ), 00126 FT_FRAME_UOFF3 ( phy_font_section_size ), 00127 FT_FRAME_UOFF3 ( phy_font_section_offset ), 00128 00129 FT_FRAME_USHORT( gps_max_size ), 00130 FT_FRAME_UOFF3 ( gps_section_size ), 00131 FT_FRAME_UOFF3 ( gps_section_offset ), 00132 00133 FT_FRAME_BYTE ( max_blue_values ), 00134 FT_FRAME_BYTE ( max_x_orus ), 00135 FT_FRAME_BYTE ( max_y_orus ), 00136 00137 FT_FRAME_BYTE ( phy_font_max_size_high ), 00138 FT_FRAME_BYTE ( color_flags ), 00139 00140 FT_FRAME_UOFF3 ( bct_max_size ), 00141 FT_FRAME_UOFF3 ( bct_set_max_size ), 00142 FT_FRAME_UOFF3 ( phy_bct_set_max_size ), 00143 00144 FT_FRAME_USHORT( num_phy_fonts ), 00145 FT_FRAME_BYTE ( max_vert_stem_snap ), 00146 FT_FRAME_BYTE ( max_horz_stem_snap ), 00147 FT_FRAME_USHORT( max_chars ), 00148 FT_FRAME_END 00149 }; 00150 00151 00152 FT_LOCAL_DEF( FT_Error ) 00153 pfr_header_load( PFR_Header header, 00154 FT_Stream stream ) 00155 { 00156 FT_Error error; 00157 00158 00159 /* read header directly */ 00160 if ( !FT_STREAM_SEEK( 0 ) && 00161 !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) ) 00162 { 00163 /* make a few adjustments to the header */ 00164 header->phy_font_max_size += 00165 (FT_UInt32)header->phy_font_max_size_high << 16; 00166 } 00167 00168 return error; 00169 } 00170 00171 00172 FT_LOCAL_DEF( FT_Bool ) 00173 pfr_header_check( PFR_Header header ) 00174 { 00175 FT_Bool result = 1; 00176 00177 00178 /* check signature and header size */ 00179 if ( header->signature != 0x50465230L || /* "PFR0" */ 00180 header->version > 4 || 00181 header->header_size < 58 || 00182 header->signature2 != 0x0d0a ) /* CR/LF */ 00183 { 00184 result = 0; 00185 } 00186 return result; 00187 } 00188 00189 00190 /***********************************************************************/ 00191 /***********************************************************************/ 00192 /***** *****/ 00193 /***** PFR LOGICAL FONTS *****/ 00194 /***** *****/ 00195 /***********************************************************************/ 00196 /***********************************************************************/ 00197 00198 00199 FT_LOCAL_DEF( FT_Error ) 00200 pfr_log_font_count( FT_Stream stream, 00201 FT_UInt32 section_offset, 00202 FT_UInt *acount ) 00203 { 00204 FT_Error error; 00205 FT_UInt count; 00206 FT_UInt result = 0; 00207 00208 00209 if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) 00210 goto Exit; 00211 00212 result = count; 00213 00214 Exit: 00215 *acount = result; 00216 return error; 00217 } 00218 00219 00220 FT_LOCAL_DEF( FT_Error ) 00221 pfr_log_font_load( PFR_LogFont log_font, 00222 FT_Stream stream, 00223 FT_UInt idx, 00224 FT_UInt32 section_offset, 00225 FT_Bool size_increment ) 00226 { 00227 FT_UInt num_log_fonts; 00228 FT_UInt flags; 00229 FT_UInt32 offset; 00230 FT_UInt32 size; 00231 FT_Error error; 00232 00233 00234 if ( FT_STREAM_SEEK( section_offset ) || 00235 FT_READ_USHORT( num_log_fonts ) ) 00236 goto Exit; 00237 00238 if ( idx >= num_log_fonts ) 00239 return PFR_Err_Invalid_Argument; 00240 00241 if ( FT_STREAM_SKIP( idx * 5 ) || 00242 FT_READ_USHORT( size ) || 00243 FT_READ_UOFF3 ( offset ) ) 00244 goto Exit; 00245 00246 /* save logical font size and offset */ 00247 log_font->size = size; 00248 log_font->offset = offset; 00249 00250 /* now, check the rest of the table before loading it */ 00251 { 00252 FT_Byte* p; 00253 FT_Byte* limit; 00254 FT_UInt local; 00255 00256 00257 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) 00258 goto Exit; 00259 00260 p = stream->cursor; 00261 limit = p + size; 00262 00263 PFR_CHECK(13); 00264 00265 log_font->matrix[0] = PFR_NEXT_LONG( p ); 00266 log_font->matrix[1] = PFR_NEXT_LONG( p ); 00267 log_font->matrix[2] = PFR_NEXT_LONG( p ); 00268 log_font->matrix[3] = PFR_NEXT_LONG( p ); 00269 00270 flags = PFR_NEXT_BYTE( p ); 00271 00272 local = 0; 00273 if ( flags & PFR_LOG_STROKE ) 00274 { 00275 local++; 00276 if ( flags & PFR_LOG_2BYTE_STROKE ) 00277 local++; 00278 00279 if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) 00280 local += 3; 00281 } 00282 if ( flags & PFR_LOG_BOLD ) 00283 { 00284 local++; 00285 if ( flags & PFR_LOG_2BYTE_BOLD ) 00286 local++; 00287 } 00288 00289 PFR_CHECK( local ); 00290 00291 if ( flags & PFR_LOG_STROKE ) 00292 { 00293 log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE ) 00294 ? PFR_NEXT_SHORT( p ) 00295 : PFR_NEXT_BYTE( p ); 00296 00297 if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) 00298 log_font->miter_limit = PFR_NEXT_LONG( p ); 00299 } 00300 00301 if ( flags & PFR_LOG_BOLD ) 00302 { 00303 log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD ) 00304 ? PFR_NEXT_SHORT( p ) 00305 : PFR_NEXT_BYTE( p ); 00306 } 00307 00308 if ( flags & PFR_LOG_EXTRA_ITEMS ) 00309 { 00310 error = pfr_extra_items_skip( &p, limit ); 00311 if (error) goto Fail; 00312 } 00313 00314 PFR_CHECK(5); 00315 log_font->phys_size = PFR_NEXT_USHORT( p ); 00316 log_font->phys_offset = PFR_NEXT_ULONG( p ); 00317 if ( size_increment ) 00318 { 00319 PFR_CHECK( 1 ); 00320 log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16; 00321 } 00322 } 00323 00324 Fail: 00325 FT_FRAME_EXIT(); 00326 00327 Exit: 00328 return error; 00329 00330 Too_Short: 00331 FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" )); 00332 error = PFR_Err_Invalid_Table; 00333 goto Fail; 00334 } 00335 00336 00337 /***********************************************************************/ 00338 /***********************************************************************/ 00339 /***** *****/ 00340 /***** PFR PHYSICAL FONTS *****/ 00341 /***** *****/ 00342 /***********************************************************************/ 00343 /***********************************************************************/ 00344 00345 00346 /* load bitmap strikes lists */ 00347 FT_CALLBACK_DEF( FT_Error ) 00348 pfr_extra_item_load_bitmap_info( FT_Byte* p, 00349 FT_Byte* limit, 00350 PFR_PhyFont phy_font ) 00351 { 00352 FT_Memory memory = phy_font->memory; 00353 PFR_Strike strike; 00354 FT_UInt flags0; 00355 FT_UInt n, count, size1; 00356 FT_Error error = PFR_Err_Ok; 00357 00358 00359 PFR_CHECK( 5 ); 00360 00361 p += 3; /* skip bctSize */ 00362 flags0 = PFR_NEXT_BYTE( p ); 00363 count = PFR_NEXT_BYTE( p ); 00364 00365 /* re-allocate when needed */ 00366 if ( phy_font->num_strikes + count > phy_font->max_strikes ) 00367 { 00368 FT_UInt new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 ); 00369 00370 00371 if ( FT_RENEW_ARRAY( phy_font->strikes, 00372 phy_font->num_strikes, 00373 new_max ) ) 00374 goto Exit; 00375 00376 phy_font->max_strikes = new_max; 00377 } 00378 00379 size1 = 1 + 1 + 1 + 2 + 2 + 1; 00380 if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) 00381 size1++; 00382 00383 if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) 00384 size1++; 00385 00386 if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) 00387 size1++; 00388 00389 if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) 00390 size1++; 00391 00392 if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) 00393 size1++; 00394 00395 strike = phy_font->strikes + phy_font->num_strikes; 00396 00397 PFR_CHECK( count * size1 ); 00398 00399 for ( n = 0; n < count; n++, strike++ ) 00400 { 00401 strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) 00402 ? PFR_NEXT_USHORT( p ) 00403 : PFR_NEXT_BYTE( p ); 00404 00405 strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) 00406 ? PFR_NEXT_USHORT( p ) 00407 : PFR_NEXT_BYTE( p ); 00408 00409 strike->flags = PFR_NEXT_BYTE( p ); 00410 00411 strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) 00412 ? PFR_NEXT_ULONG( p ) 00413 : PFR_NEXT_USHORT( p ); 00414 00415 strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) 00416 ? PFR_NEXT_ULONG( p ) 00417 : PFR_NEXT_USHORT( p ); 00418 00419 strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) 00420 ? PFR_NEXT_USHORT( p ) 00421 : PFR_NEXT_BYTE( p ); 00422 } 00423 00424 phy_font->num_strikes += count; 00425 00426 Exit: 00427 return error; 00428 00429 Too_Short: 00430 error = PFR_Err_Invalid_Table; 00431 FT_ERROR(( "pfr_extra_item_load_bitmap_info:" 00432 " invalid bitmap info table\n" )); 00433 goto Exit; 00434 } 00435 00436 00437 /* Load font ID. This is a so-called "unique" name that is rather 00438 * long and descriptive (like "Tiresias ScreenFont v7.51"). 00439 * 00440 * Note that a PFR font's family name is contained in an *undocumented* 00441 * string of the "auxiliary data" portion of a physical font record. This 00442 * may also contain the "real" style name! 00443 * 00444 * If no family name is present, the font ID is used instead for the 00445 * family. 00446 */ 00447 FT_CALLBACK_DEF( FT_Error ) 00448 pfr_extra_item_load_font_id( FT_Byte* p, 00449 FT_Byte* limit, 00450 PFR_PhyFont phy_font ) 00451 { 00452 FT_Error error = PFR_Err_Ok; 00453 FT_Memory memory = phy_font->memory; 00454 FT_PtrDist len = limit - p; 00455 00456 00457 if ( phy_font->font_id != NULL ) 00458 goto Exit; 00459 00460 if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) 00461 goto Exit; 00462 00463 /* copy font ID name, and terminate it for safety */ 00464 FT_MEM_COPY( phy_font->font_id, p, len ); 00465 phy_font->font_id[len] = 0; 00466 00467 Exit: 00468 return error; 00469 } 00470 00471 00472 /* load stem snap tables */ 00473 FT_CALLBACK_DEF( FT_Error ) 00474 pfr_extra_item_load_stem_snaps( FT_Byte* p, 00475 FT_Byte* limit, 00476 PFR_PhyFont phy_font ) 00477 { 00478 FT_UInt count, num_vert, num_horz; 00479 FT_Int* snaps; 00480 FT_Error error = PFR_Err_Ok; 00481 FT_Memory memory = phy_font->memory; 00482 00483 00484 if ( phy_font->vertical.stem_snaps != NULL ) 00485 goto Exit; 00486 00487 PFR_CHECK( 1 ); 00488 count = PFR_NEXT_BYTE( p ); 00489 00490 num_vert = count & 15; 00491 num_horz = count >> 4; 00492 count = num_vert + num_horz; 00493 00494 PFR_CHECK( count * 2 ); 00495 00496 if ( FT_NEW_ARRAY( snaps, count ) ) 00497 goto Exit; 00498 00499 phy_font->vertical.stem_snaps = snaps; 00500 phy_font->horizontal.stem_snaps = snaps + num_vert; 00501 00502 for ( ; count > 0; count--, snaps++ ) 00503 *snaps = FT_NEXT_SHORT( p ); 00504 00505 Exit: 00506 return error; 00507 00508 Too_Short: 00509 error = PFR_Err_Invalid_Table; 00510 FT_ERROR(( "pfr_exta_item_load_stem_snaps:" 00511 " invalid stem snaps table\n" )); 00512 goto Exit; 00513 } 00514 00515 00516 00517 /* load kerning pair data */ 00518 FT_CALLBACK_DEF( FT_Error ) 00519 pfr_extra_item_load_kerning_pairs( FT_Byte* p, 00520 FT_Byte* limit, 00521 PFR_PhyFont phy_font ) 00522 { 00523 PFR_KernItem item = NULL; 00524 FT_Error error = PFR_Err_Ok; 00525 FT_Memory memory = phy_font->memory; 00526 00527 00528 FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); 00529 00530 if ( FT_NEW( item ) ) 00531 goto Exit; 00532 00533 PFR_CHECK( 4 ); 00534 00535 item->pair_count = PFR_NEXT_BYTE( p ); 00536 item->base_adj = PFR_NEXT_SHORT( p ); 00537 item->flags = PFR_NEXT_BYTE( p ); 00538 item->offset = phy_font->offset + ( p - phy_font->cursor ); 00539 00540 #ifndef PFR_CONFIG_NO_CHECKS 00541 item->pair_size = 3; 00542 00543 if ( item->flags & PFR_KERN_2BYTE_CHAR ) 00544 item->pair_size += 2; 00545 00546 if ( item->flags & PFR_KERN_2BYTE_ADJ ) 00547 item->pair_size += 1; 00548 00549 PFR_CHECK( item->pair_count * item->pair_size ); 00550 #endif 00551 00552 /* load first and last pairs into the item to speed up */ 00553 /* lookup later... */ 00554 if ( item->pair_count > 0 ) 00555 { 00556 FT_UInt char1, char2; 00557 FT_Byte* q; 00558 00559 00560 if ( item->flags & PFR_KERN_2BYTE_CHAR ) 00561 { 00562 q = p; 00563 char1 = PFR_NEXT_USHORT( q ); 00564 char2 = PFR_NEXT_USHORT( q ); 00565 00566 item->pair1 = PFR_KERN_INDEX( char1, char2 ); 00567 00568 q = p + item->pair_size * ( item->pair_count - 1 ); 00569 char1 = PFR_NEXT_USHORT( q ); 00570 char2 = PFR_NEXT_USHORT( q ); 00571 00572 item->pair2 = PFR_KERN_INDEX( char1, char2 ); 00573 } 00574 else 00575 { 00576 q = p; 00577 char1 = PFR_NEXT_BYTE( q ); 00578 char2 = PFR_NEXT_BYTE( q ); 00579 00580 item->pair1 = PFR_KERN_INDEX( char1, char2 ); 00581 00582 q = p + item->pair_size * ( item->pair_count - 1 ); 00583 char1 = PFR_NEXT_BYTE( q ); 00584 char2 = PFR_NEXT_BYTE( q ); 00585 00586 item->pair2 = PFR_KERN_INDEX( char1, char2 ); 00587 } 00588 00589 /* add new item to the current list */ 00590 item->next = NULL; 00591 *phy_font->kern_items_tail = item; 00592 phy_font->kern_items_tail = &item->next; 00593 phy_font->num_kern_pairs += item->pair_count; 00594 } 00595 else 00596 { 00597 /* empty item! */ 00598 FT_FREE( item ); 00599 } 00600 00601 Exit: 00602 return error; 00603 00604 Too_Short: 00605 FT_FREE( item ); 00606 00607 error = PFR_Err_Invalid_Table; 00608 FT_ERROR(( "pfr_extra_item_load_kerning_pairs:" 00609 " invalid kerning pairs table\n" )); 00610 goto Exit; 00611 } 00612 00613 00614 00615 static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = 00616 { 00617 { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, 00618 { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id }, 00619 { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps }, 00620 { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs }, 00621 { 0, NULL } 00622 }; 00623 00624 00625 /* Loads a name from the auxiliary data. Since this extracts undocumented 00626 * strings from the font file, we need to be careful here. 00627 */ 00628 static FT_Error 00629 pfr_aux_name_load( FT_Byte* p, 00630 FT_UInt len, 00631 FT_Memory memory, 00632 FT_String* *astring ) 00633 { 00634 FT_Error error = PFR_Err_Ok; 00635 FT_String* result = NULL; 00636 FT_UInt n, ok; 00637 00638 00639 if ( len > 0 && p[len - 1] == 0 ) 00640 len--; 00641 00642 /* check that each character is ASCII for making sure not to 00643 load garbage 00644 */ 00645 ok = ( len > 0 ); 00646 for ( n = 0; n < len; n++ ) 00647 if ( p[n] < 32 || p[n] > 127 ) 00648 { 00649 ok = 0; 00650 break; 00651 } 00652 00653 if ( ok ) 00654 { 00655 if ( FT_ALLOC( result, len + 1 ) ) 00656 goto Exit; 00657 00658 FT_MEM_COPY( result, p, len ); 00659 result[len] = 0; 00660 } 00661 Exit: 00662 *astring = result; 00663 return error; 00664 } 00665 00666 00667 FT_LOCAL_DEF( void ) 00668 pfr_phy_font_done( PFR_PhyFont phy_font, 00669 FT_Memory memory ) 00670 { 00671 FT_FREE( phy_font->font_id ); 00672 FT_FREE( phy_font->family_name ); 00673 FT_FREE( phy_font->style_name ); 00674 00675 FT_FREE( phy_font->vertical.stem_snaps ); 00676 phy_font->vertical.num_stem_snaps = 0; 00677 00678 phy_font->horizontal.stem_snaps = NULL; 00679 phy_font->horizontal.num_stem_snaps = 0; 00680 00681 FT_FREE( phy_font->strikes ); 00682 phy_font->num_strikes = 0; 00683 phy_font->max_strikes = 0; 00684 00685 FT_FREE( phy_font->chars ); 00686 phy_font->num_chars = 0; 00687 phy_font->chars_offset = 0; 00688 00689 FT_FREE( phy_font->blue_values ); 00690 phy_font->num_blue_values = 0; 00691 00692 { 00693 PFR_KernItem item, next; 00694 00695 00696 item = phy_font->kern_items; 00697 while ( item ) 00698 { 00699 next = item->next; 00700 FT_FREE( item ); 00701 item = next; 00702 } 00703 phy_font->kern_items = NULL; 00704 phy_font->kern_items_tail = NULL; 00705 } 00706 00707 phy_font->num_kern_pairs = 0; 00708 } 00709 00710 00711 FT_LOCAL_DEF( FT_Error ) 00712 pfr_phy_font_load( PFR_PhyFont phy_font, 00713 FT_Stream stream, 00714 FT_UInt32 offset, 00715 FT_UInt32 size ) 00716 { 00717 FT_Error error; 00718 FT_Memory memory = stream->memory; 00719 FT_UInt flags; 00720 FT_ULong num_aux; 00721 FT_Byte* p; 00722 FT_Byte* limit; 00723 00724 00725 phy_font->memory = memory; 00726 phy_font->offset = offset; 00727 00728 phy_font->kern_items = NULL; 00729 phy_font->kern_items_tail = &phy_font->kern_items; 00730 00731 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) 00732 goto Exit; 00733 00734 phy_font->cursor = stream->cursor; 00735 00736 p = stream->cursor; 00737 limit = p + size; 00738 00739 PFR_CHECK( 15 ); 00740 phy_font->font_ref_number = PFR_NEXT_USHORT( p ); 00741 phy_font->outline_resolution = PFR_NEXT_USHORT( p ); 00742 phy_font->metrics_resolution = PFR_NEXT_USHORT( p ); 00743 phy_font->bbox.xMin = PFR_NEXT_SHORT( p ); 00744 phy_font->bbox.yMin = PFR_NEXT_SHORT( p ); 00745 phy_font->bbox.xMax = PFR_NEXT_SHORT( p ); 00746 phy_font->bbox.yMax = PFR_NEXT_SHORT( p ); 00747 phy_font->flags = flags = PFR_NEXT_BYTE( p ); 00748 00749 /* get the standard advance for non-proportional fonts */ 00750 if ( !(flags & PFR_PHY_PROPORTIONAL) ) 00751 { 00752 PFR_CHECK( 2 ); 00753 phy_font->standard_advance = PFR_NEXT_SHORT( p ); 00754 } 00755 00756 /* load the extra items when present */ 00757 if ( flags & PFR_PHY_EXTRA_ITEMS ) 00758 { 00759 error = pfr_extra_items_parse( &p, limit, 00760 pfr_phy_font_extra_items, phy_font ); 00761 00762 if ( error ) 00763 goto Fail; 00764 } 00765 00766 /* In certain fonts, the auxiliary bytes contain interesting */ 00767 /* information. These are not in the specification but can be */ 00768 /* guessed by looking at the content of a few PFR0 fonts. */ 00769 PFR_CHECK( 3 ); 00770 num_aux = PFR_NEXT_ULONG( p ); 00771 00772 if ( num_aux > 0 ) 00773 { 00774 FT_Byte* q = p; 00775 FT_Byte* q2; 00776 00777 00778 PFR_CHECK( num_aux ); 00779 p += num_aux; 00780 00781 while ( num_aux > 0 ) 00782 { 00783 FT_UInt length, type; 00784 00785 00786 if ( q + 4 > p ) 00787 break; 00788 00789 length = PFR_NEXT_USHORT( q ); 00790 if ( length < 4 || length > num_aux ) 00791 break; 00792 00793 q2 = q + length - 2; 00794 type = PFR_NEXT_USHORT( q ); 00795 00796 switch ( type ) 00797 { 00798 case 1: 00799 /* this seems to correspond to the font's family name, 00800 * padded to 16-bits with one zero when necessary 00801 */ 00802 error = pfr_aux_name_load( q, length - 4U, memory, 00803 &phy_font->family_name ); 00804 if ( error ) 00805 goto Exit; 00806 break; 00807 00808 case 2: 00809 if ( q + 32 > q2 ) 00810 break; 00811 00812 q += 10; 00813 phy_font->ascent = PFR_NEXT_SHORT( q ); 00814 phy_font->descent = PFR_NEXT_SHORT( q ); 00815 phy_font->leading = PFR_NEXT_SHORT( q ); 00816 q += 16; 00817 break; 00818 00819 case 3: 00820 /* this seems to correspond to the font's style name, 00821 * padded to 16-bits with one zero when necessary 00822 */ 00823 error = pfr_aux_name_load( q, length - 4U, memory, 00824 &phy_font->style_name ); 00825 if ( error ) 00826 goto Exit; 00827 break; 00828 00829 default: 00830 ; 00831 } 00832 00833 q = q2; 00834 num_aux -= length; 00835 } 00836 } 00837 00838 /* read the blue values */ 00839 { 00840 FT_UInt n, count; 00841 00842 00843 PFR_CHECK( 1 ); 00844 phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); 00845 00846 PFR_CHECK( count * 2 ); 00847 00848 if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) 00849 goto Fail; 00850 00851 for ( n = 0; n < count; n++ ) 00852 phy_font->blue_values[n] = PFR_NEXT_SHORT( p ); 00853 } 00854 00855 PFR_CHECK( 8 ); 00856 phy_font->blue_fuzz = PFR_NEXT_BYTE( p ); 00857 phy_font->blue_scale = PFR_NEXT_BYTE( p ); 00858 00859 phy_font->vertical.standard = PFR_NEXT_USHORT( p ); 00860 phy_font->horizontal.standard = PFR_NEXT_USHORT( p ); 00861 00862 /* read the character descriptors */ 00863 { 00864 FT_UInt n, count, Size; 00865 00866 00867 phy_font->num_chars = count = PFR_NEXT_USHORT( p ); 00868 phy_font->chars_offset = offset + ( p - stream->cursor ); 00869 00870 if ( FT_NEW_ARRAY( phy_font->chars, count ) ) 00871 goto Fail; 00872 00873 Size = 1 + 1 + 2; 00874 if ( flags & PFR_PHY_2BYTE_CHARCODE ) 00875 Size += 1; 00876 00877 if ( flags & PFR_PHY_PROPORTIONAL ) 00878 Size += 2; 00879 00880 if ( flags & PFR_PHY_ASCII_CODE ) 00881 Size += 1; 00882 00883 if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) 00884 Size += 1; 00885 00886 if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) 00887 Size += 1; 00888 00889 PFR_CHECK( count * Size ); 00890 00891 for ( n = 0; n < count; n++ ) 00892 { 00893 PFR_Char cur = &phy_font->chars[n]; 00894 00895 00896 cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) 00897 ? PFR_NEXT_USHORT( p ) 00898 : PFR_NEXT_BYTE( p ); 00899 00900 cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) 00901 ? PFR_NEXT_SHORT( p ) 00902 : (FT_Int) phy_font->standard_advance; 00903 00904 #if 0 00905 cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) 00906 ? PFR_NEXT_BYTE( p ) 00907 : 0; 00908 #else 00909 if ( flags & PFR_PHY_ASCII_CODE ) 00910 p += 1; 00911 #endif 00912 cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) 00913 ? PFR_NEXT_USHORT( p ) 00914 : PFR_NEXT_BYTE( p ); 00915 00916 cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) 00917 ? PFR_NEXT_ULONG( p ) 00918 : PFR_NEXT_USHORT( p ); 00919 } 00920 } 00921 00922 /* that's it! */ 00923 00924 Fail: 00925 FT_FRAME_EXIT(); 00926 00927 /* save position of bitmap info */ 00928 phy_font->bct_offset = FT_STREAM_POS(); 00929 phy_font->cursor = NULL; 00930 00931 Exit: 00932 return error; 00933 00934 Too_Short: 00935 error = PFR_Err_Invalid_Table; 00936 FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); 00937 goto Fail; 00938 } 00939 00940 00941 /* END */ Generated on Sun May 27 2012 04:33:53 for ReactOS by
1.7.6.1
|