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

ttload.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ttload.c                                                               */
00004 /*                                                                         */
00005 /*    Load the basic TrueType tables, i.e., tables that can be either in   */
00006 /*    TTF or OTF fonts (body).                                             */
00007 /*                                                                         */
00008 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
00009 /*            2010 by                                                      */
00010 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00011 /*                                                                         */
00012 /*  This file is part of the FreeType project, and may only be used,       */
00013 /*  modified, and distributed under the terms of the FreeType project      */
00014 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00015 /*  this file you indicate that you have read the license and              */
00016 /*  understand and accept it fully.                                        */
00017 /*                                                                         */
00018 /***************************************************************************/
00019 
00020 
00021 #include <ft2build.h>
00022 #include FT_INTERNAL_DEBUG_H
00023 #include FT_INTERNAL_STREAM_H
00024 #include FT_TRUETYPE_TAGS_H
00025 #include "ttload.h"
00026 
00027 #include "sferrors.h"
00028 
00029 
00030   /*************************************************************************/
00031   /*                                                                       */
00032   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00033   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00034   /* messages during execution.                                            */
00035   /*                                                                       */
00036 #undef  FT_COMPONENT
00037 #define FT_COMPONENT  trace_ttload
00038 
00039 
00040   /*************************************************************************/
00041   /*                                                                       */
00042   /* <Function>                                                            */
00043   /*    tt_face_lookup_table                                               */
00044   /*                                                                       */
00045   /* <Description>                                                         */
00046   /*    Looks for a TrueType table by name.                                */
00047   /*                                                                       */
00048   /* <Input>                                                               */
00049   /*    face :: A face object handle.                                      */
00050   /*                                                                       */
00051   /*    tag  :: The searched tag.                                          */
00052   /*                                                                       */
00053   /* <Return>                                                              */
00054   /*    A pointer to the table directory entry.  0 if not found.           */
00055   /*                                                                       */
00056   FT_LOCAL_DEF( TT_Table  )
00057   tt_face_lookup_table( TT_Face   face,
00058                         FT_ULong  tag  )
00059   {
00060     TT_Table  entry;
00061     TT_Table  limit;
00062 #ifdef FT_DEBUG_LEVEL_TRACE
00063     FT_Bool   zero_length = FALSE;
00064 #endif
00065 
00066 
00067     FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
00068                 face,
00069                 (FT_Char)( tag >> 24 ),
00070                 (FT_Char)( tag >> 16 ),
00071                 (FT_Char)( tag >> 8  ),
00072                 (FT_Char)( tag       ) ));
00073 
00074     entry = face->dir_tables;
00075     limit = entry + face->num_tables;
00076 
00077     for ( ; entry < limit; entry++ )
00078     {
00079       /* For compatibility with Windows, we consider    */
00080       /* zero-length tables the same as missing tables. */
00081       if ( entry->Tag == tag )
00082       {
00083         if ( entry->Length != 0 )
00084         {
00085           FT_TRACE4(( "found table.\n" ));
00086           return entry;
00087         }
00088 #ifdef FT_DEBUG_LEVEL_TRACE
00089         zero_length = TRUE;
00090 #endif
00091       }
00092     }
00093 
00094 #ifdef FT_DEBUG_LEVEL_TRACE
00095     if ( zero_length )
00096       FT_TRACE4(( "ignoring empty table\n" ));
00097     else
00098       FT_TRACE4(( "could not find table\n" ));
00099 #endif
00100 
00101     return NULL;
00102   }
00103 
00104 
00105   /*************************************************************************/
00106   /*                                                                       */
00107   /* <Function>                                                            */
00108   /*    tt_face_goto_table                                                 */
00109   /*                                                                       */
00110   /* <Description>                                                         */
00111   /*    Looks for a TrueType table by name, then seek a stream to it.      */
00112   /*                                                                       */
00113   /* <Input>                                                               */
00114   /*    face   :: A face object handle.                                    */
00115   /*                                                                       */
00116   /*    tag    :: The searched tag.                                        */
00117   /*                                                                       */
00118   /*    stream :: The stream to seek when the table is found.              */
00119   /*                                                                       */
00120   /* <Output>                                                              */
00121   /*    length :: The length of the table if found, undefined otherwise.   */
00122   /*                                                                       */
00123   /* <Return>                                                              */
00124   /*    FreeType error code.  0 means success.                             */
00125   /*                                                                       */
00126   FT_LOCAL_DEF( FT_Error )
00127   tt_face_goto_table( TT_Face    face,
00128                       FT_ULong   tag,
00129                       FT_Stream  stream,
00130                       FT_ULong*  length )
00131   {
00132     TT_Table  table;
00133     FT_Error  error;
00134 
00135 
00136     table = tt_face_lookup_table( face, tag );
00137     if ( table )
00138     {
00139       if ( length )
00140         *length = table->Length;
00141 
00142       if ( FT_STREAM_SEEK( table->Offset ) )
00143         goto Exit;
00144     }
00145     else
00146       error = SFNT_Err_Table_Missing;
00147 
00148   Exit:
00149     return error;
00150   }
00151 
00152 
00153   /* Here, we                                                         */
00154   /*                                                                  */
00155   /* - check that `num_tables' is valid (and adjust it if necessary)  */
00156   /*                                                                  */
00157   /* - look for a `head' table, check its size, and parse it to check */
00158   /*   whether its `magic' field is correctly set                     */
00159   /*                                                                  */
00160   /* - errors (except errors returned by stream handling)             */
00161   /*                                                                  */
00162   /*     SFNT_Err_Unknown_File_Format:                                */
00163   /*       no table is defined in directory, it is not sfnt-wrapped   */
00164   /*       data                                                       */
00165   /*     SFNT_Err_Table_Missing:                                      */
00166   /*       table directory is valid, but essential tables             */
00167   /*       (head/bhed/SING) are missing                               */
00168   /*                                                                  */
00169   static FT_Error
00170   check_table_dir( SFNT_Header  sfnt,
00171                    FT_Stream    stream )
00172   {
00173     FT_Error   error;
00174     FT_UShort  nn, valid_entries = 0;
00175     FT_UInt    has_head = 0, has_sing = 0, has_meta = 0;
00176     FT_ULong   offset = sfnt->offset + 12;
00177 
00178     static const FT_Frame_Field  table_dir_entry_fields[] =
00179     {
00180 #undef  FT_STRUCTURE
00181 #define FT_STRUCTURE  TT_TableRec
00182 
00183       FT_FRAME_START( 16 ),
00184         FT_FRAME_ULONG( Tag ),
00185         FT_FRAME_ULONG( CheckSum ),
00186         FT_FRAME_ULONG( Offset ),
00187         FT_FRAME_ULONG( Length ),
00188       FT_FRAME_END
00189     };
00190 
00191 
00192     if ( FT_STREAM_SEEK( offset ) )
00193       goto Exit;
00194 
00195     for ( nn = 0; nn < sfnt->num_tables; nn++ )
00196     {
00197       TT_TableRec  table;
00198 
00199 
00200       if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
00201       {
00202         nn--;
00203         FT_TRACE2(( "check_table_dir:"
00204                     " can read only %d table%s in font (instead of %d)\n",
00205                     nn, nn == 1 ? "" : "s", sfnt->num_tables ));
00206         sfnt->num_tables = nn;
00207         break;
00208       }
00209 
00210       /* we ignore invalid tables */
00211       if ( table.Offset + table.Length > stream->size )
00212       {
00213         FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
00214         continue;
00215       }
00216       else
00217         valid_entries++;
00218 
00219       if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )
00220       {
00221         FT_UInt32  magic;
00222 
00223 
00224 #ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00225         if ( table.Tag == TTAG_head )
00226 #endif
00227           has_head = 1;
00228 
00229         /*
00230          * The table length should be 0x36, but certain font tools make it
00231          * 0x38, so we will just check that it is greater.
00232          *
00233          * Note that according to the specification, the table must be
00234          * padded to 32-bit lengths, but this doesn't apply to the value of
00235          * its `Length' field!
00236          *
00237          */
00238         if ( table.Length < 0x36 )
00239         {
00240           FT_TRACE2(( "check_table_dir: `head' table too small\n" ));
00241           error = SFNT_Err_Table_Missing;
00242           goto Exit;
00243         }
00244 
00245         if ( FT_STREAM_SEEK( table.Offset + 12 ) ||
00246              FT_READ_ULONG( magic )              )
00247           goto Exit;
00248 
00249         if ( magic != 0x5F0F3CF5UL )
00250         {
00251           FT_TRACE2(( "check_table_dir:"
00252                       " no magic number found in `head' table\n"));
00253           error = SFNT_Err_Table_Missing;
00254           goto Exit;
00255         }
00256 
00257         if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )
00258           goto Exit;
00259       }
00260       else if ( table.Tag == TTAG_SING )
00261         has_sing = 1;
00262       else if ( table.Tag == TTAG_META )
00263         has_meta = 1;
00264     }
00265 
00266     sfnt->num_tables = valid_entries;
00267 
00268     if ( sfnt->num_tables == 0 )
00269     {
00270       FT_TRACE2(( "check_table_dir: no tables found\n" ));
00271       error = SFNT_Err_Unknown_File_Format;
00272       goto Exit;
00273     }
00274 
00275     /* if `sing' and `meta' tables are present, there is no `head' table */
00276     if ( has_head || ( has_sing && has_meta ) )
00277     {
00278       error = SFNT_Err_Ok;
00279       goto Exit;
00280     }
00281     else
00282     {
00283       FT_TRACE2(( "check_table_dir:" ));
00284 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00285       FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" ));
00286 #else
00287       FT_TRACE2(( " neither `head' nor `sing' table found\n" ));
00288 #endif
00289       error = SFNT_Err_Table_Missing;
00290     }
00291 
00292   Exit:
00293     return error;
00294   }
00295 
00296 
00297   /*************************************************************************/
00298   /*                                                                       */
00299   /* <Function>                                                            */
00300   /*    tt_face_load_font_dir                                              */
00301   /*                                                                       */
00302   /* <Description>                                                         */
00303   /*    Loads the header of a SFNT font file.                              */
00304   /*                                                                       */
00305   /* <Input>                                                               */
00306   /*    face       :: A handle to the target face object.                  */
00307   /*                                                                       */
00308   /*    stream     :: The input stream.                                    */
00309   /*                                                                       */
00310   /* <Output>                                                              */
00311   /*    sfnt       :: The SFNT header.                                     */
00312   /*                                                                       */
00313   /* <Return>                                                              */
00314   /*    FreeType error code.  0 means success.                             */
00315   /*                                                                       */
00316   /* <Note>                                                                */
00317   /*    The stream cursor must be at the beginning of the font directory.  */
00318   /*                                                                       */
00319   FT_LOCAL_DEF( FT_Error )
00320   tt_face_load_font_dir( TT_Face    face,
00321                          FT_Stream  stream )
00322   {
00323     SFNT_HeaderRec  sfnt;
00324     FT_Error        error;
00325     FT_Memory       memory = stream->memory;
00326     TT_TableRec*    entry;
00327     FT_Int          nn;
00328 
00329     static const FT_Frame_Field  offset_table_fields[] =
00330     {
00331 #undef  FT_STRUCTURE
00332 #define FT_STRUCTURE  SFNT_HeaderRec
00333 
00334       FT_FRAME_START( 8 ),
00335         FT_FRAME_USHORT( num_tables ),
00336         FT_FRAME_USHORT( search_range ),
00337         FT_FRAME_USHORT( entry_selector ),
00338         FT_FRAME_USHORT( range_shift ),
00339       FT_FRAME_END
00340     };
00341 
00342 
00343     FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));
00344 
00345     /* read the offset table */
00346 
00347     sfnt.offset = FT_STREAM_POS();
00348 
00349     if ( FT_READ_ULONG( sfnt.format_tag )                    ||
00350          FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )
00351       goto Exit;
00352 
00353     /* many fonts don't have these fields set correctly */
00354 #if 0
00355     if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 )        ||
00356          sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
00357       return SFNT_Err_Unknown_File_Format;
00358 #endif
00359 
00360     /* load the table directory */
00361 
00362     FT_TRACE2(( "-- Number of tables: %10u\n",    sfnt.num_tables ));
00363     FT_TRACE2(( "-- Format version:   0x%08lx\n", sfnt.format_tag ));
00364 
00365     /* check first */
00366     error = check_table_dir( &sfnt, stream );
00367     if ( error )
00368     {
00369       FT_TRACE2(( "tt_face_load_font_dir:"
00370                   " invalid table directory for TrueType\n" ));
00371 
00372       goto Exit;
00373     }
00374 
00375     face->num_tables = sfnt.num_tables;
00376     face->format_tag = sfnt.format_tag;
00377 
00378     if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
00379       goto Exit;
00380 
00381     if ( FT_STREAM_SEEK( sfnt.offset + 12 )       ||
00382          FT_FRAME_ENTER( face->num_tables * 16L ) )
00383       goto Exit;
00384 
00385     entry = face->dir_tables;
00386 
00387     FT_TRACE2(( "\n"
00388                 "  tag    offset    length   checksum\n"
00389                 "  ----------------------------------\n" ));
00390 
00391     for ( nn = 0; nn < sfnt.num_tables; nn++ )
00392     {
00393       entry->Tag      = FT_GET_TAG4();
00394       entry->CheckSum = FT_GET_ULONG();
00395       entry->Offset   = FT_GET_LONG();
00396       entry->Length   = FT_GET_LONG();
00397 
00398       /* ignore invalid tables */
00399       if ( entry->Offset + entry->Length > stream->size )
00400         continue;
00401       else
00402       {
00403         FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx\n",
00404                     (FT_Char)( entry->Tag >> 24 ),
00405                     (FT_Char)( entry->Tag >> 16 ),
00406                     (FT_Char)( entry->Tag >> 8  ),
00407                     (FT_Char)( entry->Tag       ),
00408                     entry->Offset,
00409                     entry->Length,
00410                     entry->CheckSum ));
00411         entry++;
00412       }
00413     }
00414 
00415     FT_FRAME_EXIT();
00416 
00417     FT_TRACE2(( "table directory loaded\n\n" ));
00418 
00419   Exit:
00420     return error;
00421   }
00422 
00423 
00424   /*************************************************************************/
00425   /*                                                                       */
00426   /* <Function>                                                            */
00427   /*    tt_face_load_any                                                   */
00428   /*                                                                       */
00429   /* <Description>                                                         */
00430   /*    Loads any font table into client memory.                           */
00431   /*                                                                       */
00432   /* <Input>                                                               */
00433   /*    face   :: The face object to look for.                             */
00434   /*                                                                       */
00435   /*    tag    :: The tag of table to load.  Use the value 0 if you want   */
00436   /*              to access the whole font file, else set this parameter   */
00437   /*              to a valid TrueType table tag that you can forge with    */
00438   /*              the MAKE_TT_TAG macro.                                   */
00439   /*                                                                       */
00440   /*    offset :: The starting offset in the table (or the file if         */
00441   /*              tag == 0).                                               */
00442   /*                                                                       */
00443   /*    length :: The address of the decision variable:                    */
00444   /*                                                                       */
00445   /*                If length == NULL:                                     */
00446   /*                  Loads the whole table.  Returns an error if          */
00447   /*                  `offset' == 0!                                       */
00448   /*                                                                       */
00449   /*                If *length == 0:                                       */
00450   /*                  Exits immediately; returning the length of the given */
00451   /*                  table or of the font file, depending on the value of */
00452   /*                  `tag'.                                               */
00453   /*                                                                       */
00454   /*                If *length != 0:                                       */
00455   /*                  Loads the next `length' bytes of table or font,      */
00456   /*                  starting at offset `offset' (in table or font too).  */
00457   /*                                                                       */
00458   /* <Output>                                                              */
00459   /*    buffer :: The address of target buffer.                            */
00460   /*                                                                       */
00461   /* <Return>                                                              */
00462   /*    FreeType error code.  0 means success.                             */
00463   /*                                                                       */
00464   FT_LOCAL_DEF( FT_Error )
00465   tt_face_load_any( TT_Face    face,
00466                     FT_ULong   tag,
00467                     FT_Long    offset,
00468                     FT_Byte*   buffer,
00469                     FT_ULong*  length )
00470   {
00471     FT_Error   error;
00472     FT_Stream  stream;
00473     TT_Table   table;
00474     FT_ULong   size;
00475 
00476 
00477     if ( tag != 0 )
00478     {
00479       /* look for tag in font directory */
00480       table = tt_face_lookup_table( face, tag );
00481       if ( !table )
00482       {
00483         error = SFNT_Err_Table_Missing;
00484         goto Exit;
00485       }
00486 
00487       offset += table->Offset;
00488       size    = table->Length;
00489     }
00490     else
00491       /* tag == 0 -- the user wants to access the font file directly */
00492       size = face->root.stream->size;
00493 
00494     if ( length && *length == 0 )
00495     {
00496       *length = size;
00497 
00498       return SFNT_Err_Ok;
00499     }
00500 
00501     if ( length )
00502       size = *length;
00503 
00504     stream = face->root.stream;
00505     /* the `if' is syntactic sugar for picky compilers */
00506     if ( FT_STREAM_READ_AT( offset, buffer, size ) )
00507       goto Exit;
00508 
00509   Exit:
00510     return error;
00511   }
00512 
00513 
00514   /*************************************************************************/
00515   /*                                                                       */
00516   /* <Function>                                                            */
00517   /*    tt_face_load_generic_header                                        */
00518   /*                                                                       */
00519   /* <Description>                                                         */
00520   /*    Loads the TrueType table `head' or `bhed'.                         */
00521   /*                                                                       */
00522   /* <Input>                                                               */
00523   /*    face   :: A handle to the target face object.                      */
00524   /*                                                                       */
00525   /*    stream :: The input stream.                                        */
00526   /*                                                                       */
00527   /* <Return>                                                              */
00528   /*    FreeType error code.  0 means success.                             */
00529   /*                                                                       */
00530   static FT_Error
00531   tt_face_load_generic_header( TT_Face    face,
00532                                FT_Stream  stream,
00533                                FT_ULong   tag )
00534   {
00535     FT_Error    error;
00536     TT_Header*  header;
00537 
00538     static const FT_Frame_Field  header_fields[] =
00539     {
00540 #undef  FT_STRUCTURE
00541 #define FT_STRUCTURE  TT_Header
00542 
00543       FT_FRAME_START( 54 ),
00544         FT_FRAME_ULONG ( Table_Version ),
00545         FT_FRAME_ULONG ( Font_Revision ),
00546         FT_FRAME_LONG  ( CheckSum_Adjust ),
00547         FT_FRAME_LONG  ( Magic_Number ),
00548         FT_FRAME_USHORT( Flags ),
00549         FT_FRAME_USHORT( Units_Per_EM ),
00550         FT_FRAME_LONG  ( Created[0] ),
00551         FT_FRAME_LONG  ( Created[1] ),
00552         FT_FRAME_LONG  ( Modified[0] ),
00553         FT_FRAME_LONG  ( Modified[1] ),
00554         FT_FRAME_SHORT ( xMin ),
00555         FT_FRAME_SHORT ( yMin ),
00556         FT_FRAME_SHORT ( xMax ),
00557         FT_FRAME_SHORT ( yMax ),
00558         FT_FRAME_USHORT( Mac_Style ),
00559         FT_FRAME_USHORT( Lowest_Rec_PPEM ),
00560         FT_FRAME_SHORT ( Font_Direction ),
00561         FT_FRAME_SHORT ( Index_To_Loc_Format ),
00562         FT_FRAME_SHORT ( Glyph_Data_Format ),
00563       FT_FRAME_END
00564     };
00565 
00566 
00567     error = face->goto_table( face, tag, stream, 0 );
00568     if ( error )
00569       goto Exit;
00570 
00571     header = &face->header;
00572 
00573     if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
00574       goto Exit;
00575 
00576     FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));
00577     FT_TRACE3(( "IndexToLoc:   %4d\n", header->Index_To_Loc_Format ));
00578 
00579   Exit:
00580     return error;
00581   }
00582 
00583 
00584   FT_LOCAL_DEF( FT_Error )
00585   tt_face_load_head( TT_Face    face,
00586                      FT_Stream  stream )
00587   {
00588     return tt_face_load_generic_header( face, stream, TTAG_head );
00589   }
00590 
00591 
00592 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00593 
00594   FT_LOCAL_DEF( FT_Error )
00595   tt_face_load_bhed( TT_Face    face,
00596                      FT_Stream  stream )
00597   {
00598     return tt_face_load_generic_header( face, stream, TTAG_bhed );
00599   }
00600 
00601 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
00602 
00603 
00604   /*************************************************************************/
00605   /*                                                                       */
00606   /* <Function>                                                            */
00607   /*    tt_face_load_max_profile                                           */
00608   /*                                                                       */
00609   /* <Description>                                                         */
00610   /*    Loads the maximum profile into a face object.                      */
00611   /*                                                                       */
00612   /* <Input>                                                               */
00613   /*    face   :: A handle to the target face object.                      */
00614   /*                                                                       */
00615   /*    stream :: The input stream.                                        */
00616   /*                                                                       */
00617   /* <Return>                                                              */
00618   /*    FreeType error code.  0 means success.                             */
00619   /*                                                                       */
00620   FT_LOCAL_DEF( FT_Error )
00621   tt_face_load_maxp( TT_Face    face,
00622                      FT_Stream  stream )
00623   {
00624     FT_Error        error;
00625     TT_MaxProfile*  maxProfile = &face->max_profile;
00626 
00627     const FT_Frame_Field  maxp_fields[] =
00628     {
00629 #undef  FT_STRUCTURE
00630 #define FT_STRUCTURE  TT_MaxProfile
00631 
00632       FT_FRAME_START( 6 ),
00633         FT_FRAME_LONG  ( version ),
00634         FT_FRAME_USHORT( numGlyphs ),
00635       FT_FRAME_END
00636     };
00637 
00638     const FT_Frame_Field  maxp_fields_extra[] =
00639     {
00640       FT_FRAME_START( 26 ),
00641         FT_FRAME_USHORT( maxPoints ),
00642         FT_FRAME_USHORT( maxContours ),
00643         FT_FRAME_USHORT( maxCompositePoints ),
00644         FT_FRAME_USHORT( maxCompositeContours ),
00645         FT_FRAME_USHORT( maxZones ),
00646         FT_FRAME_USHORT( maxTwilightPoints ),
00647         FT_FRAME_USHORT( maxStorage ),
00648         FT_FRAME_USHORT( maxFunctionDefs ),
00649         FT_FRAME_USHORT( maxInstructionDefs ),
00650         FT_FRAME_USHORT( maxStackElements ),
00651         FT_FRAME_USHORT( maxSizeOfInstructions ),
00652         FT_FRAME_USHORT( maxComponentElements ),
00653         FT_FRAME_USHORT( maxComponentDepth ),
00654       FT_FRAME_END
00655     };
00656 
00657 
00658     error = face->goto_table( face, TTAG_maxp, stream, 0 );
00659     if ( error )
00660       goto Exit;
00661 
00662     if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) )
00663       goto Exit;
00664 
00665     maxProfile->maxPoints             = 0;
00666     maxProfile->maxContours           = 0;
00667     maxProfile->maxCompositePoints    = 0;
00668     maxProfile->maxCompositeContours  = 0;
00669     maxProfile->maxZones              = 0;
00670     maxProfile->maxTwilightPoints     = 0;
00671     maxProfile->maxStorage            = 0;
00672     maxProfile->maxFunctionDefs       = 0;
00673     maxProfile->maxInstructionDefs    = 0;
00674     maxProfile->maxStackElements      = 0;
00675     maxProfile->maxSizeOfInstructions = 0;
00676     maxProfile->maxComponentElements  = 0;
00677     maxProfile->maxComponentDepth     = 0;
00678 
00679     if ( maxProfile->version >= 0x10000L )
00680     {
00681       if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) )
00682         goto Exit;
00683 
00684       /* XXX: an adjustment that is necessary to load certain */
00685       /*      broken fonts like `Keystrokes MT' :-(           */
00686       /*                                                      */
00687       /*   We allocate 64 function entries by default when    */
00688       /*   the maxFunctionDefs value is smaller.              */
00689 
00690       if ( maxProfile->maxFunctionDefs < 64 )
00691         maxProfile->maxFunctionDefs = 64;
00692 
00693       /* we add 4 phantom points later */
00694       if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )
00695       {
00696         FT_TRACE0(( "tt_face_load_maxp:"
00697                     " too much twilight points in `maxp' table;\n"
00698                     "                  "
00699                     " some glyphs might be rendered incorrectly\n" ));
00700 
00701         maxProfile->maxTwilightPoints = 0xFFFFU - 4;
00702       }
00703 
00704       /* we arbitrarily limit recursion to avoid stack exhaustion */
00705       if ( maxProfile->maxComponentDepth > 100 )
00706       {
00707         FT_TRACE0(( "tt_face_load_maxp:"
00708                     " abnormally large component depth (%d) set to 100\n",
00709                     maxProfile->maxComponentDepth ));
00710         maxProfile->maxComponentDepth = 100;
00711       }
00712     }
00713 
00714     FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));
00715 
00716   Exit:
00717     return error;
00718   }
00719 
00720 
00721   /*************************************************************************/
00722   /*                                                                       */
00723   /* <Function>                                                            */
00724   /*    tt_face_load_names                                                 */
00725   /*                                                                       */
00726   /* <Description>                                                         */
00727   /*    Loads the name records.                                            */
00728   /*                                                                       */
00729   /* <Input>                                                               */
00730   /*    face   :: A handle to the target face object.                      */
00731   /*                                                                       */
00732   /*    stream :: The input stream.                                        */
00733   /*                                                                       */
00734   /* <Return>                                                              */
00735   /*    FreeType error code.  0 means success.                             */
00736   /*                                                                       */
00737   FT_LOCAL_DEF( FT_Error )
00738   tt_face_load_name( TT_Face    face,
00739                      FT_Stream  stream )
00740   {
00741     FT_Error      error;
00742     FT_Memory     memory = stream->memory;
00743     FT_ULong      table_pos, table_len;
00744     FT_ULong      storage_start, storage_limit;
00745     FT_UInt       count;
00746     TT_NameTable  table;
00747 
00748     static const FT_Frame_Field  name_table_fields[] =
00749     {
00750 #undef  FT_STRUCTURE
00751 #define FT_STRUCTURE  TT_NameTableRec
00752 
00753       FT_FRAME_START( 6 ),
00754         FT_FRAME_USHORT( format ),
00755         FT_FRAME_USHORT( numNameRecords ),
00756         FT_FRAME_USHORT( storageOffset ),
00757       FT_FRAME_END
00758     };
00759 
00760     static const FT_Frame_Field  name_record_fields[] =
00761     {
00762 #undef  FT_STRUCTURE
00763 #define FT_STRUCTURE  TT_NameEntryRec
00764 
00765       /* no FT_FRAME_START */
00766         FT_FRAME_USHORT( platformID ),
00767         FT_FRAME_USHORT( encodingID ),
00768         FT_FRAME_USHORT( languageID ),
00769         FT_FRAME_USHORT( nameID ),
00770         FT_FRAME_USHORT( stringLength ),
00771         FT_FRAME_USHORT( stringOffset ),
00772       FT_FRAME_END
00773     };
00774 
00775 
00776     table         = &face->name_table;
00777     table->stream = stream;
00778 
00779     error = face->goto_table( face, TTAG_name, stream, &table_len );
00780     if ( error )
00781       goto Exit;
00782 
00783     table_pos = FT_STREAM_POS();
00784 
00785 
00786     if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
00787       goto Exit;
00788 
00789     /* Some popular Asian fonts have an invalid `storageOffset' value   */
00790     /* (it should be at least "6 + 12*num_names").  However, the string */
00791     /* offsets, computed as "storageOffset + entry->stringOffset", are  */
00792     /* valid pointers within the name table...                          */
00793     /*                                                                  */
00794     /* We thus can't check `storageOffset' right now.                   */
00795     /*                                                                  */
00796     storage_start = table_pos + 6 + 12*table->numNameRecords;
00797     storage_limit = table_pos + table_len;
00798 
00799     if ( storage_start > storage_limit )
00800     {
00801       FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));
00802       error = SFNT_Err_Name_Table_Missing;
00803       goto Exit;
00804     }
00805 
00806     /* Allocate the array of name records. */
00807     count                 = table->numNameRecords;
00808     table->numNameRecords = 0;
00809 
00810     if ( FT_NEW_ARRAY( table->names, count ) ||
00811          FT_FRAME_ENTER( count * 12 )        )
00812       goto Exit;
00813 
00814     /* Load the name records and determine how much storage is needed */
00815     /* to hold the strings themselves.                                */
00816     {
00817       TT_NameEntryRec*  entry = table->names;
00818 
00819 
00820       for ( ; count > 0; count-- )
00821       {
00822         if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) )
00823           continue;
00824 
00825         /* check that the name is not empty */
00826         if ( entry->stringLength == 0 )
00827           continue;
00828 
00829         /* check that the name string is within the table */
00830         entry->stringOffset += table_pos + table->storageOffset;
00831         if ( entry->stringOffset                       < storage_start ||
00832              entry->stringOffset + entry->stringLength > storage_limit )
00833         {
00834           /* invalid entry - ignore it */
00835           entry->stringOffset = 0;
00836           entry->stringLength = 0;
00837           continue;
00838         }
00839 
00840         entry++;
00841       }
00842 
00843       table->numNameRecords = (FT_UInt)( entry - table->names );
00844     }
00845 
00846     FT_FRAME_EXIT();
00847 
00848     /* everything went well, update face->num_names */
00849     face->num_names = (FT_UShort) table->numNameRecords;
00850 
00851   Exit:
00852     return error;
00853   }
00854 
00855 
00856   /*************************************************************************/
00857   /*                                                                       */
00858   /* <Function>                                                            */
00859   /*    tt_face_free_names                                                 */
00860   /*                                                                       */
00861   /* <Description>                                                         */
00862   /*    Frees the name records.                                            */
00863   /*                                                                       */
00864   /* <Input>                                                               */
00865   /*    face :: A handle to the target face object.                        */
00866   /*                                                                       */
00867   FT_LOCAL_DEF( void )
00868   tt_face_free_name( TT_Face  face )
00869   {
00870     FT_Memory     memory = face->root.driver->root.memory;
00871     TT_NameTable  table  = &face->name_table;
00872     TT_NameEntry  entry  = table->names;
00873     FT_UInt       count  = table->numNameRecords;
00874 
00875 
00876     if ( table->names )
00877     {
00878       for ( ; count > 0; count--, entry++ )
00879       {
00880         FT_FREE( entry->string );
00881         entry->stringLength = 0;
00882       }
00883 
00884       /* free strings table */
00885       FT_FREE( table->names );
00886     }
00887 
00888     table->numNameRecords = 0;
00889     table->format         = 0;
00890     table->storageOffset  = 0;
00891   }
00892 
00893 
00894   /*************************************************************************/
00895   /*                                                                       */
00896   /* <Function>                                                            */
00897   /*    tt_face_load_cmap                                                  */
00898   /*                                                                       */
00899   /* <Description>                                                         */
00900   /*    Loads the cmap directory in a face object.  The cmaps themselves   */
00901   /*    are loaded on demand in the `ttcmap.c' module.                     */
00902   /*                                                                       */
00903   /* <Input>                                                               */
00904   /*    face   :: A handle to the target face object.                      */
00905   /*                                                                       */
00906   /*    stream :: A handle to the input stream.                            */
00907   /*                                                                       */
00908   /* <Return>                                                              */
00909   /*    FreeType error code.  0 means success.                             */
00910   /*                                                                       */
00911 
00912   FT_LOCAL_DEF( FT_Error )
00913   tt_face_load_cmap( TT_Face    face,
00914                      FT_Stream  stream )
00915   {
00916     FT_Error  error;
00917 
00918 
00919     error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size );
00920     if ( error )
00921       goto Exit;
00922 
00923     if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) )
00924       face->cmap_size = 0;
00925 
00926   Exit:
00927     return error;
00928   }
00929 
00930 
00931 
00932   /*************************************************************************/
00933   /*                                                                       */
00934   /* <Function>                                                            */
00935   /*    tt_face_load_os2                                                   */
00936   /*                                                                       */
00937   /* <Description>                                                         */
00938   /*    Loads the OS2 table.                                               */
00939   /*                                                                       */
00940   /* <Input>                                                               */
00941   /*    face   :: A handle to the target face object.                      */
00942   /*                                                                       */
00943   /*    stream :: A handle to the input stream.                            */
00944   /*                                                                       */
00945   /* <Return>                                                              */
00946   /*    FreeType error code.  0 means success.                             */
00947   /*                                                                       */
00948   FT_LOCAL_DEF( FT_Error )
00949   tt_face_load_os2( TT_Face    face,
00950                     FT_Stream  stream )
00951   {
00952     FT_Error  error;
00953     TT_OS2*   os2;
00954 
00955     const FT_Frame_Field  os2_fields[] =
00956     {
00957 #undef  FT_STRUCTURE
00958 #define FT_STRUCTURE  TT_OS2
00959 
00960       FT_FRAME_START( 78 ),
00961         FT_FRAME_USHORT( version ),
00962         FT_FRAME_SHORT ( xAvgCharWidth ),
00963         FT_FRAME_USHORT( usWeightClass ),
00964         FT_FRAME_USHORT( usWidthClass ),
00965         FT_FRAME_SHORT ( fsType ),
00966         FT_FRAME_SHORT ( ySubscriptXSize ),
00967         FT_FRAME_SHORT ( ySubscriptYSize ),
00968         FT_FRAME_SHORT ( ySubscriptXOffset ),
00969         FT_FRAME_SHORT ( ySubscriptYOffset ),
00970         FT_FRAME_SHORT ( ySuperscriptXSize ),
00971         FT_FRAME_SHORT ( ySuperscriptYSize ),
00972         FT_FRAME_SHORT ( ySuperscriptXOffset ),
00973         FT_FRAME_SHORT ( ySuperscriptYOffset ),
00974         FT_FRAME_SHORT ( yStrikeoutSize ),
00975         FT_FRAME_SHORT ( yStrikeoutPosition ),
00976         FT_FRAME_SHORT ( sFamilyClass ),
00977         FT_FRAME_BYTE  ( panose[0] ),
00978         FT_FRAME_BYTE  ( panose[1] ),
00979         FT_FRAME_BYTE  ( panose[2] ),
00980         FT_FRAME_BYTE  ( panose[3] ),
00981         FT_FRAME_BYTE  ( panose[4] ),
00982         FT_FRAME_BYTE  ( panose[5] ),
00983         FT_FRAME_BYTE  ( panose[6] ),
00984         FT_FRAME_BYTE  ( panose[7] ),
00985         FT_FRAME_BYTE  ( panose[8] ),
00986         FT_FRAME_BYTE  ( panose[9] ),
00987         FT_FRAME_ULONG ( ulUnicodeRange1 ),
00988         FT_FRAME_ULONG ( ulUnicodeRange2 ),
00989         FT_FRAME_ULONG ( ulUnicodeRange3 ),
00990         FT_FRAME_ULONG ( ulUnicodeRange4 ),
00991         FT_FRAME_BYTE  ( achVendID[0] ),
00992         FT_FRAME_BYTE  ( achVendID[1] ),
00993         FT_FRAME_BYTE  ( achVendID[2] ),
00994         FT_FRAME_BYTE  ( achVendID[3] ),
00995 
00996         FT_FRAME_USHORT( fsSelection ),
00997         FT_FRAME_USHORT( usFirstCharIndex ),
00998         FT_FRAME_USHORT( usLastCharIndex ),
00999         FT_FRAME_SHORT ( sTypoAscender ),
01000         FT_FRAME_SHORT ( sTypoDescender ),
01001         FT_FRAME_SHORT ( sTypoLineGap ),
01002         FT_FRAME_USHORT( usWinAscent ),
01003         FT_FRAME_USHORT( usWinDescent ),
01004       FT_FRAME_END
01005     };
01006 
01007     const FT_Frame_Field  os2_fields_extra[] =
01008     {
01009       FT_FRAME_START( 8 ),
01010         FT_FRAME_ULONG( ulCodePageRange1 ),
01011         FT_FRAME_ULONG( ulCodePageRange2 ),
01012       FT_FRAME_END
01013     };
01014 
01015     const FT_Frame_Field  os2_fields_extra2[] =
01016     {
01017       FT_FRAME_START( 10 ),
01018         FT_FRAME_SHORT ( sxHeight ),
01019         FT_FRAME_SHORT ( sCapHeight ),
01020         FT_FRAME_USHORT( usDefaultChar ),
01021         FT_FRAME_USHORT( usBreakChar ),
01022         FT_FRAME_USHORT( usMaxContext ),
01023       FT_FRAME_END
01024     };
01025 
01026 
01027     /* We now support old Mac fonts where the OS/2 table doesn't  */
01028     /* exist.  Simply put, we set the `version' field to 0xFFFF   */
01029     /* and test this value each time we need to access the table. */
01030     error = face->goto_table( face, TTAG_OS2, stream, 0 );
01031     if ( error )
01032       goto Exit;
01033 
01034     os2 = &face->os2;
01035 
01036     if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) )
01037       goto Exit;
01038 
01039     os2->ulCodePageRange1 = 0;
01040     os2->ulCodePageRange2 = 0;
01041     os2->sxHeight         = 0;
01042     os2->sCapHeight       = 0;
01043     os2->usDefaultChar    = 0;
01044     os2->usBreakChar      = 0;
01045     os2->usMaxContext     = 0;
01046 
01047     if ( os2->version >= 0x0001 )
01048     {
01049       /* only version 1 tables */
01050       if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) )
01051         goto Exit;
01052 
01053       if ( os2->version >= 0x0002 )
01054       {
01055         /* only version 2 tables */
01056         if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) )
01057           goto Exit;
01058       }
01059     }
01060 
01061     FT_TRACE3(( "sTypoAscender:  %4d\n",   os2->sTypoAscender ));
01062     FT_TRACE3(( "sTypoDescender: %4d\n",   os2->sTypoDescender ));
01063     FT_TRACE3(( "usWinAscent:    %4u\n",   os2->usWinAscent ));
01064     FT_TRACE3(( "usWinDescent:   %4u\n",   os2->usWinDescent ));
01065     FT_TRACE3(( "fsSelection:    0x%2x\n", os2->fsSelection ));
01066 
01067   Exit:
01068     return error;
01069   }
01070 
01071 
01072   /*************************************************************************/
01073   /*                                                                       */
01074   /* <Function>                                                            */
01075   /*    tt_face_load_postscript                                            */
01076   /*                                                                       */
01077   /* <Description>                                                         */
01078   /*    Loads the Postscript table.                                        */
01079   /*                                                                       */
01080   /* <Input>                                                               */
01081   /*    face   :: A handle to the target face object.                      */
01082   /*                                                                       */
01083   /*    stream :: A handle to the input stream.                            */
01084   /*                                                                       */
01085   /* <Return>                                                              */
01086   /*    FreeType error code.  0 means success.                             */
01087   /*                                                                       */
01088   FT_LOCAL_DEF( FT_Error )
01089   tt_face_load_post( TT_Face    face,
01090                      FT_Stream  stream )
01091   {
01092     FT_Error        error;
01093     TT_Postscript*  post = &face->postscript;
01094 
01095     static const FT_Frame_Field  post_fields[] =
01096     {
01097 #undef  FT_STRUCTURE
01098 #define FT_STRUCTURE  TT_Postscript
01099 
01100       FT_FRAME_START( 32 ),
01101         FT_FRAME_ULONG( FormatType ),
01102         FT_FRAME_ULONG( italicAngle ),
01103         FT_FRAME_SHORT( underlinePosition ),
01104         FT_FRAME_SHORT( underlineThickness ),
01105         FT_FRAME_ULONG( isFixedPitch ),
01106         FT_FRAME_ULONG( minMemType42 ),
01107         FT_FRAME_ULONG( maxMemType42 ),
01108         FT_FRAME_ULONG( minMemType1 ),
01109         FT_FRAME_ULONG( maxMemType1 ),
01110       FT_FRAME_END
01111     };
01112 
01113 
01114     error = face->goto_table( face, TTAG_post, stream, 0 );
01115     if ( error )
01116       return error;
01117 
01118     if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
01119       return error;
01120 
01121     /* we don't load the glyph names, we do that in another */
01122     /* module (ttpost).                                     */
01123 
01124     FT_TRACE3(( "FormatType:   0x%x\n", post->FormatType ));
01125     FT_TRACE3(( "isFixedPitch:   %s\n", post->isFixedPitch
01126                                         ? "  yes" : "   no" ));
01127 
01128     return SFNT_Err_Ok;
01129   }
01130 
01131 
01132   /*************************************************************************/
01133   /*                                                                       */
01134   /* <Function>                                                            */
01135   /*    tt_face_load_pclt                                                  */
01136   /*                                                                       */
01137   /* <Description>                                                         */
01138   /*    Loads the PCL 5 Table.                                             */
01139   /*                                                                       */
01140   /* <Input>                                                               */
01141   /*    face   :: A handle to the target face object.                      */
01142   /*                                                                       */
01143   /*    stream :: A handle to the input stream.                            */
01144   /*                                                                       */
01145   /* <Return>                                                              */
01146   /*    FreeType error code.  0 means success.                             */
01147   /*                                                                       */
01148   FT_LOCAL_DEF( FT_Error )
01149   tt_face_load_pclt( TT_Face    face,
01150                      FT_Stream  stream )
01151   {
01152     static const FT_Frame_Field  pclt_fields[] =
01153     {
01154 #undef  FT_STRUCTURE
01155 #define FT_STRUCTURE  TT_PCLT
01156 
01157       FT_FRAME_START( 54 ),
01158         FT_FRAME_ULONG ( Version ),
01159         FT_FRAME_ULONG ( FontNumber ),
01160         FT_FRAME_USHORT( Pitch ),
01161         FT_FRAME_USHORT( xHeight ),
01162         FT_FRAME_USHORT( Style ),
01163         FT_FRAME_USHORT( TypeFamily ),
01164         FT_FRAME_USHORT( CapHeight ),
01165         FT_FRAME_BYTES ( TypeFace, 16 ),
01166         FT_FRAME_BYTES ( CharacterComplement, 8 ),
01167         FT_FRAME_BYTES ( FileName, 6 ),
01168         FT_FRAME_CHAR  ( StrokeWeight ),
01169         FT_FRAME_CHAR  ( WidthType ),
01170         FT_FRAME_BYTE  ( SerifStyle ),
01171         FT_FRAME_BYTE  ( Reserved ),
01172       FT_FRAME_END
01173     };
01174 
01175     FT_Error  error;
01176     TT_PCLT*  pclt = &face->pclt;
01177 
01178 
01179     /* optional table */
01180     error = face->goto_table( face, TTAG_PCLT, stream, 0 );
01181     if ( error )
01182       goto Exit;
01183 
01184     if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) )
01185       goto Exit;
01186 
01187   Exit:
01188     return error;
01189   }
01190 
01191 
01192   /*************************************************************************/
01193   /*                                                                       */
01194   /* <Function>                                                            */
01195   /*    tt_face_load_gasp                                                  */
01196   /*                                                                       */
01197   /* <Description>                                                         */
01198   /*    Loads the `gasp' table into a face object.                         */
01199   /*                                                                       */
01200   /* <Input>                                                               */
01201   /*    face   :: A handle to the target face object.                      */
01202   /*                                                                       */
01203   /*    stream :: The input stream.                                        */
01204   /*                                                                       */
01205   /* <Return>                                                              */
01206   /*    FreeType error code.  0 means success.                             */
01207   /*                                                                       */
01208   FT_LOCAL_DEF( FT_Error )
01209   tt_face_load_gasp( TT_Face    face,
01210                      FT_Stream  stream )
01211   {
01212     FT_Error   error;
01213     FT_Memory  memory = stream->memory;
01214 
01215     FT_UInt        j,num_ranges;
01216     TT_GaspRange   gaspranges;
01217 
01218 
01219     /* the gasp table is optional */
01220     error = face->goto_table( face, TTAG_gasp, stream, 0 );
01221     if ( error )
01222       goto Exit;
01223 
01224     if ( FT_FRAME_ENTER( 4L ) )
01225       goto Exit;
01226 
01227     face->gasp.version   = FT_GET_USHORT();
01228     face->gasp.numRanges = FT_GET_USHORT();
01229 
01230     FT_FRAME_EXIT();
01231 
01232     /* only support versions 0 and 1 of the table */
01233     if ( face->gasp.version >= 2 )
01234     {
01235       face->gasp.numRanges = 0;
01236       error = SFNT_Err_Invalid_Table;
01237       goto Exit;
01238     }
01239 
01240     num_ranges = face->gasp.numRanges;
01241     FT_TRACE3(( "numRanges: %u\n", num_ranges ));
01242 
01243     if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) ||
01244          FT_FRAME_ENTER( num_ranges * 4L )      )
01245       goto Exit;
01246 
01247     face->gasp.gaspRanges = gaspranges;
01248 
01249     for ( j = 0; j < num_ranges; j++ )
01250     {
01251       gaspranges[j].maxPPEM  = FT_GET_USHORT();
01252       gaspranges[j].gaspFlag = FT_GET_USHORT();
01253 
01254       FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",
01255                   j,
01256                   gaspranges[j].maxPPEM,
01257                   gaspranges[j].gaspFlag ));
01258     }
01259 
01260     FT_FRAME_EXIT();
01261 
01262   Exit:
01263     return error;
01264   }
01265 
01266 
01267 /* END */

Generated on Sat May 26 2012 04:32:56 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.