ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pfrload.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.