ttload.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:44k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ttload.c                                                               */
  4. /*                                                                         */
  5. /*    Load the basic TrueType tables, i.e., tables that can be either in   */
  6. /*    TTF or OTF fonts (body).                                             */
  7. /*                                                                         */
  8. /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by             */
  9. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  10. /*                                                                         */
  11. /*  This file is part of the FreeType project, and may only be used,       */
  12. /*  modified, and distributed under the terms of the FreeType project      */
  13. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  14. /*  this file you indicate that you have read the license and              */
  15. /*  understand and accept it fully.                                        */
  16. /*                                                                         */
  17. /***************************************************************************/
  18. #include <ft2build.h>
  19. #include FT_INTERNAL_DEBUG_H
  20. #include FT_INTERNAL_STREAM_H
  21. #include FT_TRUETYPE_TAGS_H
  22. #include "ttload.h"
  23. #include "sferrors.h"
  24.   /*************************************************************************/
  25.   /*                                                                       */
  26.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  27.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  28.   /* messages during execution.                                            */
  29.   /*                                                                       */
  30. #undef  FT_COMPONENT
  31. #define FT_COMPONENT  trace_ttload
  32.   /*************************************************************************/
  33.   /*                                                                       */
  34.   /* <Function>                                                            */
  35.   /*    tt_face_lookup_table                                               */
  36.   /*                                                                       */
  37.   /* <Description>                                                         */
  38.   /*    Looks for a TrueType table by name.                                */
  39.   /*                                                                       */
  40.   /* <Input>                                                               */
  41.   /*    face :: A face object handle.                                      */
  42.   /*                                                                       */
  43.   /*    tag  :: The searched tag.                                          */
  44.   /*                                                                       */
  45.   /* <Return>                                                              */
  46.   /*    A pointer to the table directory entry.  0 if not found.           */
  47.   /*                                                                       */
  48.   FT_LOCAL_DEF( TT_Table  )
  49.   tt_face_lookup_table( TT_Face   face,
  50.                         FT_ULong  tag  )
  51.   {
  52.     TT_Table  entry;
  53.     TT_Table  limit;
  54.     FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
  55.                 face,
  56.                 (FT_Char)( tag >> 24 ),
  57.                 (FT_Char)( tag >> 16 ),
  58.                 (FT_Char)( tag >> 8  ),
  59.                 (FT_Char)( tag       ) ));
  60.     entry = face->dir_tables;
  61.     limit = entry + face->num_tables;
  62.     for ( ; entry < limit; entry++ )
  63.     {
  64.       /* For compatibility with Windows, we consider 0-length */
  65.       /* tables the same as missing tables.                   */
  66.       if ( entry->Tag == tag && entry->Length != 0 )
  67.       {
  68.         FT_TRACE4(( "found table.n" ));
  69.         return entry;
  70.       }
  71.     }
  72.     FT_TRACE4(( "could not find table!n" ));
  73.     return 0;
  74.   }
  75.   /*************************************************************************/
  76.   /*                                                                       */
  77.   /* <Function>                                                            */
  78.   /*    tt_face_goto_table                                                 */
  79.   /*                                                                       */
  80.   /* <Description>                                                         */
  81.   /*    Looks for a TrueType table by name, then seek a stream to it.      */
  82.   /*                                                                       */
  83.   /* <Input>                                                               */
  84.   /*    face   :: A face object handle.                                    */
  85.   /*                                                                       */
  86.   /*    tag    :: The searched tag.                                        */
  87.   /*                                                                       */
  88.   /*    stream :: The stream to seek when the table is found.              */
  89.   /*                                                                       */
  90.   /* <Output>                                                              */
  91.   /*    length :: The length of the table if found, undefined otherwise.   */
  92.   /*                                                                       */
  93.   /* <Return>                                                              */
  94.   /*    FreeType error code.  0 means success.                             */
  95.   /*                                                                       */
  96.   FT_LOCAL_DEF( FT_Error )
  97.   tt_face_goto_table( TT_Face    face,
  98.                       FT_ULong   tag,
  99.                       FT_Stream  stream,
  100.                       FT_ULong*  length )
  101.   {
  102.     TT_Table  table;
  103.     FT_Error  error;
  104.     table = tt_face_lookup_table( face, tag );
  105.     if ( table )
  106.     {
  107.       if ( length )
  108.         *length = table->Length;
  109.       if ( FT_STREAM_SEEK( table->Offset ) )
  110.        goto Exit;
  111.     }
  112.     else
  113.       error = SFNT_Err_Table_Missing;
  114.   Exit:
  115.     return error;
  116.   }
  117.   /* Here, we                                                              */
  118.   /*                                                                       */
  119.   /* - check that `num_tables' is valid                                    */
  120.   /* - look for a `head' table, check its size, and parse it to check      */
  121.   /*   whether its `magic' field is correctly set                          */
  122.   /*                                                                       */
  123.   /* When checking directory entries, ignore the tables `glyx' and `locx'  */
  124.   /* which are hacked-out versions of `glyf' and `loca' in some PostScript */
  125.   /* Type 42 fonts, and which are generally invalid.                       */
  126.   /*                                                                       */
  127.   static FT_Error
  128.   check_table_dir( SFNT_Header  sfnt,
  129.                    FT_Stream    stream )
  130.   {
  131.     FT_Error        error;
  132.     FT_UInt         nn;
  133.     FT_UInt         has_head = 0, has_sing = 0, has_meta = 0;
  134.     FT_ULong        offset = sfnt->offset + 12;
  135.     const FT_ULong  glyx_tag = FT_MAKE_TAG( 'g', 'l', 'y', 'x' );
  136.     const FT_ULong  locx_tag = FT_MAKE_TAG( 'l', 'o', 'c', 'x' );
  137.     static const FT_Frame_Field  table_dir_entry_fields[] =
  138.     {
  139. #undef  FT_STRUCTURE
  140. #define FT_STRUCTURE  TT_TableRec
  141.       FT_FRAME_START( 16 ),
  142.         FT_FRAME_ULONG( Tag ),
  143.         FT_FRAME_ULONG( CheckSum ),
  144.         FT_FRAME_ULONG( Offset ),
  145.         FT_FRAME_ULONG( Length ),
  146.       FT_FRAME_END
  147.     };
  148.     if ( sfnt->num_tables == 0                         ||
  149.          offset + sfnt->num_tables * 16 > stream->size )
  150.       return SFNT_Err_Unknown_File_Format;
  151.     if ( FT_STREAM_SEEK( offset ) )
  152.       return error;
  153.     for ( nn = 0; nn < sfnt->num_tables; nn++ )
  154.     {
  155.       TT_TableRec  table;
  156.       if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
  157.         return error;
  158.       if ( table.Offset + table.Length > stream->size &&
  159.            table.Tag != glyx_tag                      &&
  160.            table.Tag != locx_tag                      )
  161.         return SFNT_Err_Unknown_File_Format;
  162.       if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )
  163.       {
  164.         FT_UInt32  magic;
  165. #ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  166.         if ( table.Tag == TTAG_head )
  167. #endif
  168.           has_head = 1;
  169.         /*
  170.          * The table length should be 0x36, but certain font tools make it
  171.          * 0x38, so we will just check that it is greater.
  172.          *
  173.          * Note that according to the specification, the table must be
  174.          * padded to 32-bit lengths, but this doesn't apply to the value of
  175.          * its `Length' field!
  176.          *
  177.          */
  178.         if ( table.Length < 0x36 )
  179.           return SFNT_Err_Unknown_File_Format;
  180.         if ( FT_STREAM_SEEK( table.Offset + 12 ) ||
  181.              FT_READ_ULONG( magic )              )
  182.           return error;
  183.         if ( magic != 0x5F0F3CF5UL )
  184.           return SFNT_Err_Unknown_File_Format;
  185.         if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )
  186.           return error;
  187.       }
  188.       else if ( table.Tag == TTAG_SING )
  189.         has_sing = 1;
  190.       else if ( table.Tag == TTAG_META )
  191.         has_meta = 1;
  192.     }
  193.     /* if `sing' and `meta' tables are present, there is no `head' table */
  194.     if ( has_head || ( has_sing && has_meta ) )
  195.       return SFNT_Err_Ok;
  196.     else
  197.       return SFNT_Err_Unknown_File_Format;
  198.   }
  199.   /*************************************************************************/
  200.   /*                                                                       */
  201.   /* <Function>                                                            */
  202.   /*    tt_face_load_font_dir                                              */
  203.   /*                                                                       */
  204.   /* <Description>                                                         */
  205.   /*    Loads the header of a SFNT font file.                              */
  206.   /*                                                                       */
  207.   /* <Input>                                                               */
  208.   /*    face       :: A handle to the target face object.                  */
  209.   /*                                                                       */
  210.   /*    stream     :: The input stream.                                    */
  211.   /*                                                                       */
  212.   /* <Output>                                                              */
  213.   /*    sfnt       :: The SFNT header.                                     */
  214.   /*                                                                       */
  215.   /* <Return>                                                              */
  216.   /*    FreeType error code.  0 means success.                             */
  217.   /*                                                                       */
  218.   /* <Note>                                                                */
  219.   /*    The stream cursor must be at the beginning of the font directory.  */
  220.   /*                                                                       */
  221.   FT_LOCAL_DEF( FT_Error )
  222.   tt_face_load_font_dir( TT_Face    face,
  223.                          FT_Stream  stream )
  224.   {
  225.     SFNT_HeaderRec  sfnt;
  226.     FT_Error        error;
  227.     FT_Memory       memory = stream->memory;
  228.     TT_TableRec*    entry;
  229.     TT_TableRec*    limit;
  230.     static const FT_Frame_Field  offset_table_fields[] =
  231.     {
  232. #undef  FT_STRUCTURE
  233. #define FT_STRUCTURE  SFNT_HeaderRec
  234.       FT_FRAME_START( 8 ),
  235.         FT_FRAME_USHORT( num_tables ),
  236.         FT_FRAME_USHORT( search_range ),
  237.         FT_FRAME_USHORT( entry_selector ),
  238.         FT_FRAME_USHORT( range_shift ),
  239.       FT_FRAME_END
  240.     };
  241.     FT_TRACE2(( "tt_face_load_font_dir: %08pn", face ));
  242.     /* read the offset table */
  243.     sfnt.offset = FT_STREAM_POS();
  244.     if ( FT_READ_ULONG( sfnt.format_tag )                    ||
  245.          FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )
  246.       return error;
  247.     /* many fonts don't have these fields set correctly */
  248. #if 0
  249.     if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 )        ||
  250.          sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
  251.       return SFNT_Err_Unknown_File_Format;
  252. #endif
  253.     /* load the table directory */
  254.     FT_TRACE2(( "-- Tables count:   %12un",  sfnt.num_tables ));
  255.     FT_TRACE2(( "-- Format version: %08lxn", sfnt.format_tag ));
  256.     /* check first */
  257.     error = check_table_dir( &sfnt, stream );
  258.     if ( error )
  259.     {
  260.       FT_TRACE2(( "tt_face_load_font_dir: invalid table directory!n" ));
  261.       return error;
  262.     }
  263.     face->num_tables = sfnt.num_tables;
  264.     face->format_tag = sfnt.format_tag;
  265.     if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
  266.       return error;
  267.     if ( FT_STREAM_SEEK( sfnt.offset + 12 )       ||
  268.          FT_FRAME_ENTER( face->num_tables * 16L ) )
  269.       return error;
  270.     entry = face->dir_tables;
  271.     limit = entry + face->num_tables;
  272.     for ( ; entry < limit; entry++ )
  273.     {
  274.       entry->Tag      = FT_GET_TAG4();
  275.       entry->CheckSum = FT_GET_ULONG();
  276.       entry->Offset   = FT_GET_LONG();
  277.       entry->Length   = FT_GET_LONG();
  278.       FT_TRACE2(( "  %c%c%c%c  -  %08lx  -  %08lxn",
  279.                   (FT_Char)( entry->Tag >> 24 ),
  280.                   (FT_Char)( entry->Tag >> 16 ),
  281.                   (FT_Char)( entry->Tag >> 8  ),
  282.                   (FT_Char)( entry->Tag       ),
  283.                   entry->Offset,
  284.                   entry->Length ));
  285.     }
  286.     FT_FRAME_EXIT();
  287.     FT_TRACE2(( "table directory loadednn" ));
  288.     return error;
  289.   }
  290.   /*************************************************************************/
  291.   /*                                                                       */
  292.   /* <Function>                                                            */
  293.   /*    tt_face_load_any                                                   */
  294.   /*                                                                       */
  295.   /* <Description>                                                         */
  296.   /*    Loads any font table into client memory.                           */
  297.   /*                                                                       */
  298.   /* <Input>                                                               */
  299.   /*    face   :: The face object to look for.                             */
  300.   /*                                                                       */
  301.   /*    tag    :: The tag of table to load.  Use the value 0 if you want   */
  302.   /*              to access the whole font file, else set this parameter   */
  303.   /*              to a valid TrueType table tag that you can forge with    */
  304.   /*              the MAKE_TT_TAG macro.                                   */
  305.   /*                                                                       */
  306.   /*    offset :: The starting offset in the table (or the file if         */
  307.   /*              tag == 0).                                               */
  308.   /*                                                                       */
  309.   /*    length :: The address of the decision variable:                    */
  310.   /*                                                                       */
  311.   /*                If length == NULL:                                     */
  312.   /*                  Loads the whole table.  Returns an error if          */
  313.   /*                  `offset' == 0!                                       */
  314.   /*                                                                       */
  315.   /*                If *length == 0:                                       */
  316.   /*                  Exits immediately; returning the length of the given */
  317.   /*                  table or of the font file, depending on the value of */
  318.   /*                  `tag'.                                               */
  319.   /*                                                                       */
  320.   /*                If *length != 0:                                       */
  321.   /*                  Loads the next `length' bytes of table or font,      */
  322.   /*                  starting at offset `offset' (in table or font too).  */
  323.   /*                                                                       */
  324.   /* <Output>                                                              */
  325.   /*    buffer :: The address of target buffer.                            */
  326.   /*                                                                       */
  327.   /* <Return>                                                              */
  328.   /*    FreeType error code.  0 means success.                             */
  329.   /*                                                                       */
  330.   FT_LOCAL_DEF( FT_Error )
  331.   tt_face_load_any( TT_Face    face,
  332.                     FT_ULong   tag,
  333.                     FT_Long    offset,
  334.                     FT_Byte*   buffer,
  335.                     FT_ULong*  length )
  336.   {
  337.     FT_Error   error;
  338.     FT_Stream  stream;
  339.     TT_Table   table;
  340.     FT_ULong   size;
  341.     if ( tag != 0 )
  342.     {
  343.       /* look for tag in font directory */
  344.       table = tt_face_lookup_table( face, tag );
  345.       if ( !table )
  346.       {
  347.         error = SFNT_Err_Table_Missing;
  348.         goto Exit;
  349.       }
  350.       offset += table->Offset;
  351.       size    = table->Length;
  352.     }
  353.     else
  354.       /* tag == 0 -- the user wants to access the font file directly */
  355.       size = face->root.stream->size;
  356.     if ( length && *length == 0 )
  357.     {
  358.       *length = size;
  359.       return SFNT_Err_Ok;
  360.     }
  361.     if ( length )
  362.       size = *length;
  363.     stream = face->root.stream;
  364.     /* the `if' is syntactic sugar for picky compilers */
  365.     if ( FT_STREAM_READ_AT( offset, buffer, size ) )
  366.       goto Exit;
  367.   Exit:
  368.     return error;
  369.   }
  370.   /*************************************************************************/
  371.   /*                                                                       */
  372.   /* <Function>                                                            */
  373.   /*    tt_face_load_generic_header                                        */
  374.   /*                                                                       */
  375.   /* <Description>                                                         */
  376.   /*    Loads the TrueType table `head' or `bhed'.                         */
  377.   /*                                                                       */
  378.   /* <Input>                                                               */
  379.   /*    face   :: A handle to the target face object.                      */
  380.   /*                                                                       */
  381.   /*    stream :: The input stream.                                        */
  382.   /*                                                                       */
  383.   /* <Return>                                                              */
  384.   /*    FreeType error code.  0 means success.                             */
  385.   /*                                                                       */
  386.   static FT_Error
  387.   tt_face_load_generic_header( TT_Face    face,
  388.                                FT_Stream  stream,
  389.                                FT_ULong   tag )
  390.   {
  391.     FT_Error    error;
  392.     TT_Header*  header;
  393.     static const FT_Frame_Field  header_fields[] =
  394.     {
  395. #undef  FT_STRUCTURE
  396. #define FT_STRUCTURE  TT_Header
  397.       FT_FRAME_START( 54 ),
  398.         FT_FRAME_ULONG ( Table_Version ),
  399.         FT_FRAME_ULONG ( Font_Revision ),
  400.         FT_FRAME_LONG  ( CheckSum_Adjust ),
  401.         FT_FRAME_LONG  ( Magic_Number ),
  402.         FT_FRAME_USHORT( Flags ),
  403.         FT_FRAME_USHORT( Units_Per_EM ),
  404.         FT_FRAME_LONG  ( Created[0] ),
  405.         FT_FRAME_LONG  ( Created[1] ),
  406.         FT_FRAME_LONG  ( Modified[0] ),
  407.         FT_FRAME_LONG  ( Modified[1] ),
  408.         FT_FRAME_SHORT ( xMin ),
  409.         FT_FRAME_SHORT ( yMin ),
  410.         FT_FRAME_SHORT ( xMax ),
  411.         FT_FRAME_SHORT ( yMax ),
  412.         FT_FRAME_USHORT( Mac_Style ),
  413.         FT_FRAME_USHORT( Lowest_Rec_PPEM ),
  414.         FT_FRAME_SHORT ( Font_Direction ),
  415.         FT_FRAME_SHORT ( Index_To_Loc_Format ),
  416.         FT_FRAME_SHORT ( Glyph_Data_Format ),
  417.       FT_FRAME_END
  418.     };
  419.     error = face->goto_table( face, tag, stream, 0 );
  420.     if ( error )
  421.       goto Exit;
  422.     header = &face->header;
  423.     if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
  424.       goto Exit;
  425.     FT_TRACE3(( "Units per EM: %4un", header->Units_Per_EM ));
  426.     FT_TRACE3(( "IndexToLoc:   %4dn", header->Index_To_Loc_Format ));
  427.   Exit:
  428.     return error;
  429.   }
  430.   FT_LOCAL_DEF( FT_Error )
  431.   tt_face_load_head( TT_Face    face,
  432.                      FT_Stream  stream )
  433.   {
  434.     return tt_face_load_generic_header( face, stream, TTAG_head );
  435.   }
  436. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  437.   FT_LOCAL_DEF( FT_Error )
  438.   tt_face_load_bhed( TT_Face    face,
  439.                      FT_Stream  stream )
  440.   {
  441.     return tt_face_load_generic_header( face, stream, TTAG_bhed );
  442.   }
  443. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  444.   /*************************************************************************/
  445.   /*                                                                       */
  446.   /* <Function>                                                            */
  447.   /*    tt_face_load_max_profile                                           */
  448.   /*                                                                       */
  449.   /* <Description>                                                         */
  450.   /*    Loads the maximum profile into a face object.                      */
  451.   /*                                                                       */
  452.   /* <Input>                                                               */
  453.   /*    face   :: A handle to the target face object.                      */
  454.   /*                                                                       */
  455.   /*    stream :: The input stream.                                        */
  456.   /*                                                                       */
  457.   /* <Return>                                                              */
  458.   /*    FreeType error code.  0 means success.                             */
  459.   /*                                                                       */
  460.   FT_LOCAL_DEF( FT_Error )
  461.   tt_face_load_maxp( TT_Face    face,
  462.                      FT_Stream  stream )
  463.   {
  464.     FT_Error        error;
  465.     TT_MaxProfile*  maxProfile = &face->max_profile;
  466.     const FT_Frame_Field  maxp_fields[] =
  467.     {
  468. #undef  FT_STRUCTURE
  469. #define FT_STRUCTURE  TT_MaxProfile
  470.       FT_FRAME_START( 6 ),
  471.         FT_FRAME_LONG  ( version ),
  472.         FT_FRAME_USHORT( numGlyphs ),
  473.       FT_FRAME_END
  474.     };
  475.     const FT_Frame_Field  maxp_fields_extra[] =
  476.     {
  477.       FT_FRAME_START( 26 ),
  478.         FT_FRAME_USHORT( maxPoints ),
  479.         FT_FRAME_USHORT( maxContours ),
  480.         FT_FRAME_USHORT( maxCompositePoints ),
  481.         FT_FRAME_USHORT( maxCompositeContours ),
  482.         FT_FRAME_USHORT( maxZones ),
  483.         FT_FRAME_USHORT( maxTwilightPoints ),
  484.         FT_FRAME_USHORT( maxStorage ),
  485.         FT_FRAME_USHORT( maxFunctionDefs ),
  486.         FT_FRAME_USHORT( maxInstructionDefs ),
  487.         FT_FRAME_USHORT( maxStackElements ),
  488.         FT_FRAME_USHORT( maxSizeOfInstructions ),
  489.         FT_FRAME_USHORT( maxComponentElements ),
  490.         FT_FRAME_USHORT( maxComponentDepth ),
  491.       FT_FRAME_END
  492.     };
  493.     error = face->goto_table( face, TTAG_maxp, stream, 0 );
  494.     if ( error )
  495.       goto Exit;
  496.     if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) )
  497.       goto Exit;
  498.     maxProfile->maxPoints             = 0;
  499.     maxProfile->maxContours           = 0;
  500.     maxProfile->maxCompositePoints    = 0;
  501.     maxProfile->maxCompositeContours  = 0;
  502.     maxProfile->maxZones              = 0;
  503.     maxProfile->maxTwilightPoints     = 0;
  504.     maxProfile->maxStorage            = 0;
  505.     maxProfile->maxFunctionDefs       = 0;
  506.     maxProfile->maxInstructionDefs    = 0;
  507.     maxProfile->maxStackElements      = 0;
  508.     maxProfile->maxSizeOfInstructions = 0;
  509.     maxProfile->maxComponentElements  = 0;
  510.     maxProfile->maxComponentDepth     = 0;
  511.     if ( maxProfile->version >= 0x10000L )
  512.     {
  513.       if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) )
  514.         goto Exit;
  515.       /* XXX: an adjustment that is necessary to load certain */
  516.       /*      broken fonts like `Keystrokes MT' :-(           */
  517.       /*                                                      */
  518.       /*   We allocate 64 function entries by default when    */
  519.       /*   the maxFunctionDefs field is null.                 */
  520.       if ( maxProfile->maxFunctionDefs == 0 )
  521.         maxProfile->maxFunctionDefs = 64;
  522.     }
  523.     FT_TRACE3(( "numGlyphs: %un", maxProfile->numGlyphs ));
  524.   Exit:
  525.     return error;
  526.   }
  527.   /*************************************************************************/
  528.   /*                                                                       */
  529.   /* <Function>                                                            */
  530.   /*    tt_face_load_names                                                 */
  531.   /*                                                                       */
  532.   /* <Description>                                                         */
  533.   /*    Loads the name records.                                            */
  534.   /*                                                                       */
  535.   /* <Input>                                                               */
  536.   /*    face   :: A handle to the target face object.                      */
  537.   /*                                                                       */
  538.   /*    stream :: The input stream.                                        */
  539.   /*                                                                       */
  540.   /* <Return>                                                              */
  541.   /*    FreeType error code.  0 means success.                             */
  542.   /*                                                                       */
  543.   FT_LOCAL_DEF( FT_Error )
  544.   tt_face_load_name( TT_Face    face,
  545.                      FT_Stream  stream )
  546.   {
  547.     FT_Error      error;
  548.     FT_Memory     memory = stream->memory;
  549.     FT_ULong      table_pos, table_len;
  550.     FT_ULong      storage_start, storage_limit;
  551.     FT_UInt       count;
  552.     TT_NameTable  table;
  553.     static const FT_Frame_Field  name_table_fields[] =
  554.     {
  555. #undef  FT_STRUCTURE
  556. #define FT_STRUCTURE  TT_NameTableRec
  557.       FT_FRAME_START( 6 ),
  558.         FT_FRAME_USHORT( format ),
  559.         FT_FRAME_USHORT( numNameRecords ),
  560.         FT_FRAME_USHORT( storageOffset ),
  561.       FT_FRAME_END
  562.     };
  563.     static const FT_Frame_Field  name_record_fields[] =
  564.     {
  565. #undef  FT_STRUCTURE
  566. #define FT_STRUCTURE  TT_NameEntryRec
  567.       /* no FT_FRAME_START */
  568.         FT_FRAME_USHORT( platformID ),
  569.         FT_FRAME_USHORT( encodingID ),
  570.         FT_FRAME_USHORT( languageID ),
  571.         FT_FRAME_USHORT( nameID ),
  572.         FT_FRAME_USHORT( stringLength ),
  573.         FT_FRAME_USHORT( stringOffset ),
  574.       FT_FRAME_END
  575.     };
  576.     table         = &face->name_table;
  577.     table->stream = stream;
  578.     error = face->goto_table( face, TTAG_name, stream, &table_len );
  579.     if ( error )
  580.       goto Exit;
  581.     table_pos = FT_STREAM_POS();
  582.     if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
  583.       goto Exit;
  584.     /* Some popular Asian fonts have an invalid `storageOffset' value   */
  585.     /* (it should be at least "6 + 12*num_names").  However, the string */
  586.     /* offsets, computed as "storageOffset + entry->stringOffset", are  */
  587.     /* valid pointers within the name table...                          */
  588.     /*                                                                  */
  589.     /* We thus can't check `storageOffset' right now.                   */
  590.     /*                                                                  */
  591.     storage_start = table_pos + 6 + 12*table->numNameRecords;
  592.     storage_limit = table_pos + table_len;
  593.     if ( storage_start > storage_limit )
  594.     {
  595.       FT_ERROR(( "invalid `name' tablen" ));
  596.       error = SFNT_Err_Name_Table_Missing;
  597.       goto Exit;
  598.     }
  599.     /* Allocate the array of name records. */
  600.     count                 = table->numNameRecords;
  601.     table->numNameRecords = 0;
  602.     if ( FT_NEW_ARRAY( table->names, count ) ||
  603.          FT_FRAME_ENTER( count * 12 )        )
  604.       goto Exit;
  605.     /* Load the name records and determine how much storage is needed */
  606.     /* to hold the strings themselves.                                */
  607.     {
  608.       TT_NameEntryRec*  entry = table->names;
  609.       for ( ; count > 0; count-- )
  610.       {
  611.         if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) )
  612.           continue;
  613.         /* check that the name is not empty */
  614.         if ( entry->stringLength == 0 )
  615.           continue;
  616.         /* check that the name string is within the table */
  617.         entry->stringOffset += table_pos + table->storageOffset;
  618.         if ( entry->stringOffset                       < storage_start ||
  619.              entry->stringOffset + entry->stringLength > storage_limit )
  620.         {
  621.           /* invalid entry - ignore it */
  622.           entry->stringOffset = 0;
  623.           entry->stringLength = 0;
  624.           continue;
  625.         }
  626.         entry++;
  627.       }
  628.       table->numNameRecords = (FT_UInt)( entry - table->names );
  629.     }
  630.     FT_FRAME_EXIT();
  631.     /* everything went well, update face->num_names */
  632.     face->num_names = (FT_UShort) table->numNameRecords;
  633.   Exit:
  634.     return error;
  635.   }
  636.   /*************************************************************************/
  637.   /*                                                                       */
  638.   /* <Function>                                                            */
  639.   /*    tt_face_free_names                                                 */
  640.   /*                                                                       */
  641.   /* <Description>                                                         */
  642.   /*    Frees the name records.                                            */
  643.   /*                                                                       */
  644.   /* <Input>                                                               */
  645.   /*    face :: A handle to the target face object.                        */
  646.   /*                                                                       */
  647.   FT_LOCAL_DEF( void )
  648.   tt_face_free_name( TT_Face  face )
  649.   {
  650.     FT_Memory     memory = face->root.driver->root.memory;
  651.     TT_NameTable  table  = &face->name_table;
  652.     TT_NameEntry  entry  = table->names;
  653.     FT_UInt       count  = table->numNameRecords;
  654.     if ( table->names )
  655.     {
  656.       for ( ; count > 0; count--, entry++ )
  657.       {
  658.         FT_FREE( entry->string );
  659.         entry->stringLength = 0;
  660.       }
  661.       /* free strings table */
  662.       FT_FREE( table->names );
  663.     }
  664.     table->numNameRecords = 0;
  665.     table->format         = 0;
  666.     table->storageOffset  = 0;
  667.   }
  668.   /*************************************************************************/
  669.   /*                                                                       */
  670.   /* <Function>                                                            */
  671.   /*    tt_face_load_cmap                                                  */
  672.   /*                                                                       */
  673.   /* <Description>                                                         */
  674.   /*    Loads the cmap directory in a face object.  The cmaps themselves   */
  675.   /*    are loaded on demand in the `ttcmap.c' module.                     */
  676.   /*                                                                       */
  677.   /* <Input>                                                               */
  678.   /*    face   :: A handle to the target face object.                      */
  679.   /*                                                                       */
  680.   /*    stream :: A handle to the input stream.                            */
  681.   /*                                                                       */
  682.   /* <Return>                                                              */
  683.   /*    FreeType error code.  0 means success.                             */
  684.   /*                                                                       */
  685.   FT_LOCAL_DEF( FT_Error )
  686.   tt_face_load_cmap( TT_Face    face,
  687.                      FT_Stream  stream )
  688.   {
  689.     FT_Error  error;
  690.     error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size );
  691.     if ( error )
  692.       goto Exit;
  693.     if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) )
  694.       face->cmap_size = 0;
  695.   Exit:
  696.     return error;
  697.   }
  698.   /*************************************************************************/
  699.   /*                                                                       */
  700.   /* <Function>                                                            */
  701.   /*    tt_face_load_os2                                                   */
  702.   /*                                                                       */
  703.   /* <Description>                                                         */
  704.   /*    Loads the OS2 table.                                               */
  705.   /*                                                                       */
  706.   /* <Input>                                                               */
  707.   /*    face   :: A handle to the target face object.                      */
  708.   /*                                                                       */
  709.   /*    stream :: A handle to the input stream.                            */
  710.   /*                                                                       */
  711.   /* <Return>                                                              */
  712.   /*    FreeType error code.  0 means success.                             */
  713.   /*                                                                       */
  714.   FT_LOCAL_DEF( FT_Error )
  715.   tt_face_load_os2( TT_Face    face,
  716.                     FT_Stream  stream )
  717.   {
  718.     FT_Error  error;
  719.     TT_OS2*   os2;
  720.     const FT_Frame_Field  os2_fields[] =
  721.     {
  722. #undef  FT_STRUCTURE
  723. #define FT_STRUCTURE  TT_OS2
  724.       FT_FRAME_START( 78 ),
  725.         FT_FRAME_USHORT( version ),
  726.         FT_FRAME_SHORT ( xAvgCharWidth ),
  727.         FT_FRAME_USHORT( usWeightClass ),
  728.         FT_FRAME_USHORT( usWidthClass ),
  729.         FT_FRAME_SHORT ( fsType ),
  730.         FT_FRAME_SHORT ( ySubscriptXSize ),
  731.         FT_FRAME_SHORT ( ySubscriptYSize ),
  732.         FT_FRAME_SHORT ( ySubscriptXOffset ),
  733.         FT_FRAME_SHORT ( ySubscriptYOffset ),
  734.         FT_FRAME_SHORT ( ySuperscriptXSize ),
  735.         FT_FRAME_SHORT ( ySuperscriptYSize ),
  736.         FT_FRAME_SHORT ( ySuperscriptXOffset ),
  737.         FT_FRAME_SHORT ( ySuperscriptYOffset ),
  738.         FT_FRAME_SHORT ( yStrikeoutSize ),
  739.         FT_FRAME_SHORT ( yStrikeoutPosition ),
  740.         FT_FRAME_SHORT ( sFamilyClass ),
  741.         FT_FRAME_BYTE  ( panose[0] ),
  742.         FT_FRAME_BYTE  ( panose[1] ),
  743.         FT_FRAME_BYTE  ( panose[2] ),
  744.         FT_FRAME_BYTE  ( panose[3] ),
  745.         FT_FRAME_BYTE  ( panose[4] ),
  746.         FT_FRAME_BYTE  ( panose[5] ),
  747.         FT_FRAME_BYTE  ( panose[6] ),
  748.         FT_FRAME_BYTE  ( panose[7] ),
  749.         FT_FRAME_BYTE  ( panose[8] ),
  750.         FT_FRAME_BYTE  ( panose[9] ),
  751.         FT_FRAME_ULONG ( ulUnicodeRange1 ),
  752.         FT_FRAME_ULONG ( ulUnicodeRange2 ),
  753.         FT_FRAME_ULONG ( ulUnicodeRange3 ),
  754.         FT_FRAME_ULONG ( ulUnicodeRange4 ),
  755.         FT_FRAME_BYTE  ( achVendID[0] ),
  756.         FT_FRAME_BYTE  ( achVendID[1] ),
  757.         FT_FRAME_BYTE  ( achVendID[2] ),
  758.         FT_FRAME_BYTE  ( achVendID[3] ),
  759.         FT_FRAME_USHORT( fsSelection ),
  760.         FT_FRAME_USHORT( usFirstCharIndex ),
  761.         FT_FRAME_USHORT( usLastCharIndex ),
  762.         FT_FRAME_SHORT ( sTypoAscender ),
  763.         FT_FRAME_SHORT ( sTypoDescender ),
  764.         FT_FRAME_SHORT ( sTypoLineGap ),
  765.         FT_FRAME_USHORT( usWinAscent ),
  766.         FT_FRAME_USHORT( usWinDescent ),
  767.       FT_FRAME_END
  768.     };
  769.     const FT_Frame_Field  os2_fields_extra[] =
  770.     {
  771.       FT_FRAME_START( 8 ),
  772.         FT_FRAME_ULONG( ulCodePageRange1 ),
  773.         FT_FRAME_ULONG( ulCodePageRange2 ),
  774.       FT_FRAME_END
  775.     };
  776.     const FT_Frame_Field  os2_fields_extra2[] =
  777.     {
  778.       FT_FRAME_START( 10 ),
  779.         FT_FRAME_SHORT ( sxHeight ),
  780.         FT_FRAME_SHORT ( sCapHeight ),
  781.         FT_FRAME_USHORT( usDefaultChar ),
  782.         FT_FRAME_USHORT( usBreakChar ),
  783.         FT_FRAME_USHORT( usMaxContext ),
  784.       FT_FRAME_END
  785.     };
  786.     /* We now support old Mac fonts where the OS/2 table doesn't  */
  787.     /* exist.  Simply put, we set the `version' field to 0xFFFF   */
  788.     /* and test this value each time we need to access the table. */
  789.     error = face->goto_table( face, TTAG_OS2, stream, 0 );
  790.     if ( error )
  791.       goto Exit;
  792.     os2 = &face->os2;
  793.     if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) )
  794.       goto Exit;
  795.     os2->ulCodePageRange1 = 0;
  796.     os2->ulCodePageRange2 = 0;
  797.     os2->sxHeight         = 0;
  798.     os2->sCapHeight       = 0;
  799.     os2->usDefaultChar    = 0;
  800.     os2->usBreakChar      = 0;
  801.     os2->usMaxContext     = 0;
  802.     if ( os2->version >= 0x0001 )
  803.     {
  804.       /* only version 1 tables */
  805.       if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) )
  806.         goto Exit;
  807.       if ( os2->version >= 0x0002 )
  808.       {
  809.         /* only version 2 tables */
  810.         if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) )
  811.           goto Exit;
  812.       }
  813.     }
  814.     FT_TRACE3(( "sTypoAscender:  %4dn",   os2->sTypoAscender ));
  815.     FT_TRACE3(( "sTypoDescender: %4dn",   os2->sTypoDescender ));
  816.     FT_TRACE3(( "usWinAscent:    %4un",   os2->usWinAscent ));
  817.     FT_TRACE3(( "usWinDescent:   %4un",   os2->usWinDescent ));
  818.     FT_TRACE3(( "fsSelection:    0x%2xn", os2->fsSelection ));
  819.   Exit:
  820.     return error;
  821.   }
  822.   /*************************************************************************/
  823.   /*                                                                       */
  824.   /* <Function>                                                            */
  825.   /*    tt_face_load_postscript                                            */
  826.   /*                                                                       */
  827.   /* <Description>                                                         */
  828.   /*    Loads the Postscript table.                                        */
  829.   /*                                                                       */
  830.   /* <Input>                                                               */
  831.   /*    face   :: A handle to the target face object.                      */
  832.   /*                                                                       */
  833.   /*    stream :: A handle to the input stream.                            */
  834.   /*                                                                       */
  835.   /* <Return>                                                              */
  836.   /*    FreeType error code.  0 means success.                             */
  837.   /*                                                                       */
  838.   FT_LOCAL_DEF( FT_Error )
  839.   tt_face_load_post( TT_Face    face,
  840.                      FT_Stream  stream )
  841.   {
  842.     FT_Error        error;
  843.     TT_Postscript*  post = &face->postscript;
  844.     static const FT_Frame_Field  post_fields[] =
  845.     {
  846. #undef  FT_STRUCTURE
  847. #define FT_STRUCTURE  TT_Postscript
  848.       FT_FRAME_START( 32 ),
  849.         FT_FRAME_ULONG( FormatType ),
  850.         FT_FRAME_ULONG( italicAngle ),
  851.         FT_FRAME_SHORT( underlinePosition ),
  852.         FT_FRAME_SHORT( underlineThickness ),
  853.         FT_FRAME_ULONG( isFixedPitch ),
  854.         FT_FRAME_ULONG( minMemType42 ),
  855.         FT_FRAME_ULONG( maxMemType42 ),
  856.         FT_FRAME_ULONG( minMemType1 ),
  857.         FT_FRAME_ULONG( maxMemType1 ),
  858.       FT_FRAME_END
  859.     };
  860.     error = face->goto_table( face, TTAG_post, stream, 0 );
  861.     if ( error )
  862.       return error;
  863.     if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
  864.       return error;
  865.     /* we don't load the glyph names, we do that in another */
  866.     /* module (ttpost).                                     */
  867.     FT_TRACE3(( "FormatType:   0x%xn", post->FormatType ));
  868.     FT_TRACE3(( "isFixedPitch:   %sn", post->isFixedPitch
  869.                                         ? "  yes" : "   no" ));
  870.     return SFNT_Err_Ok;
  871.   }
  872.   /*************************************************************************/
  873.   /*                                                                       */
  874.   /* <Function>                                                            */
  875.   /*    tt_face_load_pclt                                                  */
  876.   /*                                                                       */
  877.   /* <Description>                                                         */
  878.   /*    Loads the PCL 5 Table.                                             */
  879.   /*                                                                       */
  880.   /* <Input>                                                               */
  881.   /*    face   :: A handle to the target face object.                      */
  882.   /*                                                                       */
  883.   /*    stream :: A handle to the input stream.                            */
  884.   /*                                                                       */
  885.   /* <Return>                                                              */
  886.   /*    FreeType error code.  0 means success.                             */
  887.   /*                                                                       */
  888.   FT_LOCAL_DEF( FT_Error )
  889.   tt_face_load_pclt( TT_Face    face,
  890.                      FT_Stream  stream )
  891.   {
  892.     static const FT_Frame_Field  pclt_fields[] =
  893.     {
  894. #undef  FT_STRUCTURE
  895. #define FT_STRUCTURE  TT_PCLT
  896.       FT_FRAME_START( 54 ),
  897.         FT_FRAME_ULONG ( Version ),
  898.         FT_FRAME_ULONG ( FontNumber ),
  899.         FT_FRAME_USHORT( Pitch ),
  900.         FT_FRAME_USHORT( xHeight ),
  901.         FT_FRAME_USHORT( Style ),
  902.         FT_FRAME_USHORT( TypeFamily ),
  903.         FT_FRAME_USHORT( CapHeight ),
  904.         FT_FRAME_BYTES ( TypeFace, 16 ),
  905.         FT_FRAME_BYTES ( CharacterComplement, 8 ),
  906.         FT_FRAME_BYTES ( FileName, 6 ),
  907.         FT_FRAME_CHAR  ( StrokeWeight ),
  908.         FT_FRAME_CHAR  ( WidthType ),
  909.         FT_FRAME_BYTE  ( SerifStyle ),
  910.         FT_FRAME_BYTE  ( Reserved ),
  911.       FT_FRAME_END
  912.     };
  913.     FT_Error  error;
  914.     TT_PCLT*  pclt = &face->pclt;
  915.     /* optional table */
  916.     error = face->goto_table( face, TTAG_PCLT, stream, 0 );
  917.     if ( error )
  918.       goto Exit;
  919.     if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) )
  920.       goto Exit;
  921.   Exit:
  922.     return error;
  923.   }
  924.   /*************************************************************************/
  925.   /*                                                                       */
  926.   /* <Function>                                                            */
  927.   /*    tt_face_load_gasp                                                  */
  928.   /*                                                                       */
  929.   /* <Description>                                                         */
  930.   /*    Loads the `gasp' table into a face object.                         */
  931.   /*                                                                       */
  932.   /* <Input>                                                               */
  933.   /*    face   :: A handle to the target face object.                      */
  934.   /*                                                                       */
  935.   /*    stream :: The input stream.                                        */
  936.   /*                                                                       */
  937.   /* <Return>                                                              */
  938.   /*    FreeType error code.  0 means success.                             */
  939.   /*                                                                       */
  940.   FT_LOCAL_DEF( FT_Error )
  941.   tt_face_load_gasp( TT_Face    face,
  942.                      FT_Stream  stream )
  943.   {
  944.     FT_Error   error;
  945.     FT_Memory  memory = stream->memory;
  946.     FT_UInt        j,num_ranges;
  947.     TT_GaspRange   gaspranges;
  948.     /* the gasp table is optional */
  949.     error = face->goto_table( face, TTAG_gasp, stream, 0 );
  950.     if ( error )
  951.       goto Exit;
  952.     if ( FT_FRAME_ENTER( 4L ) )
  953.       goto Exit;
  954.     face->gasp.version   = FT_GET_USHORT();
  955.     face->gasp.numRanges = FT_GET_USHORT();
  956.     FT_FRAME_EXIT();
  957.     /* only support versions 0 and 1 of the table */
  958.     if ( face->gasp.version >= 2 )
  959.     {
  960.       face->gasp.numRanges = 0;
  961.       error = SFNT_Err_Invalid_Table;
  962.       goto Exit;
  963.     }
  964.     num_ranges = face->gasp.numRanges;
  965.     FT_TRACE3(( "numRanges: %un", num_ranges ));
  966.     if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) ||
  967.          FT_FRAME_ENTER( num_ranges * 4L )      )
  968.       goto Exit;
  969.     face->gasp.gaspRanges = gaspranges;
  970.     for ( j = 0; j < num_ranges; j++ )
  971.     {
  972.       gaspranges[j].maxPPEM  = FT_GET_USHORT();
  973.       gaspranges[j].gaspFlag = FT_GET_USHORT();
  974.       FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%xn",
  975.                   j,
  976.                   gaspranges[j].maxPPEM,
  977.                   gaspranges[j].gaspFlag ));
  978.     }
  979.     FT_FRAME_EXIT();
  980.   Exit:
  981.     return error;
  982.   }
  983. /* END */