shithub: freetype+ttf2subf

Download patch

ref: 65863a5712376b796ce82b3b0db26b85a64ea33f
parent: f5aa47beb077998675f5adc38c94aaf7ee8a447e
author: Wu, Chia-I (吳佳一) <[email protected]>
date: Tue Feb 14 02:01:29 EST 2006

Clean up the SFNT_Interface.  In this pass, we want to treat the font
directory (offset table and table directory) as a normal table like
the others.  This also means that TTC is no longer recognized there,
but in `init_face'.

* include/freetype/internal/sfnt.h (SFNT_Interface),
src/sfnt/sfdriver.c: `load_sfnt_header' and `load_directory' are
combined and renamed to `load_font_dir'.

* src/sfnt/ttload.h, src/sfnt/ttload.c:
s/sfnt_dir_check/check_table_dir/.
`sfnt_init' is moved to sfobjs.c and renamed to `sfnt_open_font'.
`tt_face_load_sfnt_header' and `tt_face_load_directory' are combined
and renamed to `tt_face_load_font_dir'.

* src/sfnt/sfobjs.c (sfnt_init_face): Recognize TTC here.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2006-02-13  Chia-I Wu  <[email protected]>
 
+	Clean up the SFNT_Interface.  In this pass, we want to treat the font
+	directory (offset table and table directory) as a normal table like
+	the others.  This also means that TTC is no longer recognized there,
+	but in `init_face'.
+
+	* include/freetype/internal/sfnt.h (SFNT_Interface),
+	src/sfnt/sfdriver.c: `load_sfnt_header' and `load_directory' are
+	combined and renamed to `load_font_dir'.
+
+	* src/sfnt/ttload.h, src/sfnt/ttload.c:
+	s/sfnt_dir_check/check_table_dir/.
+	`sfnt_init' is moved to sfobjs.c and renamed to `sfnt_open_font'.
+	`tt_face_load_sfnt_header' and `tt_face_load_directory' are combined
+	and renamed to `tt_face_load_font_dir'.
+
+	* src/sfnt/sfobjs.c (sfnt_init_face): Recognize TTC here.
+
+2006-02-13  Chia-I Wu  <[email protected]>
+
 	Clean up the SFNT_Interface.  Table loading functions are now named
 	after the tables' tags;  `hdmx' is TrueType-specific and thus the code
 	is moved to the truetype module; `get_metrics' is moved here from the
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -128,73 +128,6 @@
   /*************************************************************************/
   /*                                                                       */
   /* <FuncType>                                                            */
-  /*    TT_Load_SFNT_HeaderRec_Func                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Load the header of a SFNT font file.  Supports collections.        */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face       :: A handle to the target face object.                  */
-  /*                                                                       */
-  /*    stream     :: The input stream.                                    */
-  /*                                                                       */
-  /*    face_index :: The index of the TrueType font, if we are opening a  */
-  /*                  collection.                                          */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    sfnt       :: The SFNT header.                                     */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The stream cursor must be at the font file's origin.               */
-  /*                                                                       */
-  /*    This function recognizes fonts embedded in a `TrueType             */
-  /*    collection'.                                                       */
-  /*                                                                       */
-  /*    This function checks that the header is valid by looking at the    */
-  /*    values of `search_range', `entry_selector', and `range_shift'.     */
-  /*                                                                       */
-  typedef FT_Error
-  (*TT_Load_SFNT_HeaderRec_Func)( TT_Face      face,
-                                  FT_Stream    stream,
-                                  FT_Long      face_index,
-                                  SFNT_Header  sfnt );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    TT_Load_Directory_Func                                             */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Load the table directory into a face object.                       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face      :: A handle to the target face object.                   */
-  /*                                                                       */
-  /*    stream    :: The input stream.                                     */
-  /*                                                                       */
-  /*    sfnt      :: The SFNT header.                                      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The stream cursor must be on the first byte after the 4-byte font  */
-  /*    format tag.  This is the case just after a call to                 */
-  /*    TT_Load_Format_Tag().                                              */
-  /*                                                                       */
-  typedef FT_Error
-  (*TT_Load_Directory_Func)( TT_Face      face,
-                             FT_Stream    stream,
-                             SFNT_Header  sfnt );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
   /*    TT_Load_Any_Func                                                   */
   /*                                                                       */
   /* <Description>                                                         */
@@ -505,7 +438,7 @@
   /*                                                                       */
   /* <Note>                                                                */
   /*    The function will use `face->goto_table' to seek the stream to     */
-  /*    the start of the table.                                            */
+  /*    the start of the table, except in loading font directory.          */
   /*                                                                       */
   typedef FT_Error
   (*TT_Load_Table_Func)( TT_Face    face,
@@ -570,8 +503,10 @@
     FT_Module_Requester          get_interface;
 
     TT_Load_Any_Func             load_any;
-    TT_Load_SFNT_HeaderRec_Func  load_sfnt_header;
-    TT_Load_Directory_Func       load_directory;
+
+    /* load the font directory, i.e. the offset table and */
+    /* the table directory                                */
+    TT_Load_Table_Func           load_font_dir;
 
     /* these functions are called by `load_face' but they can also  */
     /* be called from external modules, if there is a need to do so */
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -386,8 +386,7 @@
     sfnt_get_interface,
 
     tt_face_load_any,
-    tt_face_load_sfnt_header,
-    tt_face_load_directory,
+    tt_face_load_font_dir,
 
     tt_face_load_head,
     tt_face_load_hhea,
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -345,6 +345,85 @@
   }
 
 
+  /* Fill in face->ttc_header.  If the font is not a TTC, it is */
+  /* synthesized into a TTC with one offset table.              */
+  static FT_Error
+  sfnt_open_font( FT_Stream  stream,
+                  TT_Face    face )
+  {
+    FT_Memory  memory = stream->memory;
+    FT_Error   error;
+    FT_ULong   tag, offset;
+
+    static const FT_Frame_Field  ttc_header_fields[] =
+    {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  TTC_HeaderRec
+
+      FT_FRAME_START( 8 ),
+        FT_FRAME_LONG( version ),
+        FT_FRAME_LONG( count   ),
+      FT_FRAME_END
+    };
+
+
+    face->ttc_header.tag     = 0;
+    face->ttc_header.version = 0;
+    face->ttc_header.count   = 0;
+
+    offset = FT_STREAM_POS();
+
+    if ( FT_READ_ULONG( tag ) )
+      return error;
+
+    if ( tag != 0x00010000UL                      &&
+         tag != TTAG_ttcf                         &&
+         tag != FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) &&
+         tag != TTAG_true                         &&
+         tag != 0x00020000UL                      )
+      return SFNT_Err_Unknown_File_Format;
+
+    face->ttc_header.tag = TTAG_ttcf;
+
+    if ( tag == TTAG_ttcf )
+    {
+      FT_Int  n;
+
+
+      FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));
+
+      if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
+        return error;
+
+      /* now read the offsets of each font in the file */
+      if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
+        return error;
+
+      if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
+        return error;
+
+      for ( n = 0; n < face->ttc_header.count; n++ )
+        face->ttc_header.offsets[n] = FT_GET_ULONG();
+
+      FT_FRAME_EXIT();
+    }
+    else
+    {
+      FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));
+
+      face->ttc_header.version = 1 << 16;
+      face->ttc_header.count   = 1;
+
+      if ( FT_NEW( face->ttc_header.offsets) )
+        return error;
+
+      face->ttc_header.offsets[0] = offset;
+    }
+
+    return error;
+  }
+
+
   FT_LOCAL_DEF( FT_Error )
   sfnt_init_face( FT_Stream      stream,
                   TT_Face        face,
@@ -355,8 +434,8 @@
     FT_Error        error;
     FT_Library      library = face->root.driver->root.library;
     SFNT_Service    sfnt;
-    SFNT_HeaderRec  sfnt_header;
 
+
     /* for now, parameters are unused */
     FT_UNUSED( num_params );
     FT_UNUSED( params );
@@ -367,10 +446,7 @@
     {
       sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
       if ( !sfnt )
-      {
-        error = SFNT_Err_Invalid_File_Format;
-        goto Exit;
-      }
+        return SFNT_Err_Invalid_File_Format;
 
       face->sfnt       = sfnt;
       face->goto_table = sfnt->goto_table;
@@ -378,24 +454,28 @@
 
     FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
 
-    /* check that we have a valid TrueType file */
-    error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header );
+    error = sfnt_open_font( stream, face );
     if ( error )
-      goto Exit;
+      return error;
 
-    face->format_tag = sfnt_header.format_tag;
-    face->num_tables = sfnt_header.num_tables;
+    FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index ));
 
-    /* Load font directory */
-    error = sfnt->load_directory( face, stream, &sfnt_header );
+    if ( face_index < 0 )
+      face_index = 0;
+
+    if ( face_index >= face->ttc_header.count )
+        return SFNT_Err_Bad_Argument;
+
+    if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
+      return error;
+
+    /* check that we have a valid TrueType file */
+    error = sfnt->load_font_dir( face, stream );
     if ( error )
-      goto Exit;
+      return error;
 
     face->root.num_faces = face->ttc_header.count;
-    if ( face->root.num_faces < 1 )
-      face->root.num_faces = 1;
 
-  Exit:
     return error;
   }
 
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -145,8 +145,8 @@
   /* Type 42 fonts, and which are generally invalid.                       */
   /*                                                                       */
   static FT_Error
-  sfnt_dir_check( SFNT_Header  sfnt,
-                  FT_Stream    stream )
+  check_table_dir( SFNT_Header  sfnt,
+                   FT_Stream    stream )
   {
     FT_Error        error;
     FT_UInt         nn;
@@ -156,7 +156,7 @@
     const FT_ULong  glyx_tag = FT_MAKE_TAG( 'g', 'l', 'y', 'x' );
     const FT_ULong  locx_tag = FT_MAKE_TAG( 'l', 'o', 'c', 'x' );
 
-    static const FT_Frame_Field  sfnt_dir_entry_fields[] =
+    static const FT_Frame_Field  table_dir_entry_fields[] =
     {
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  TT_TableRec
@@ -182,7 +182,7 @@
       TT_TableRec  table;
 
 
-      if ( FT_STREAM_READ_FIELDS( sfnt_dir_entry_fields, &table ) )
+      if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
         return error;
 
       if ( table.Offset + table.Length > stream->size &&
@@ -194,6 +194,7 @@
       {
         FT_UInt32  magic;
 
+
 #ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
         if ( table.Tag == TTAG_head )
 #endif
@@ -235,92 +236,13 @@
   }
 
 
-  /* Fill in face->ttc_header.  If the font is not a TTC, it is */
-  /* synthesized into a TTC with one offset table.              */
-  static FT_Error
-  sfnt_init( FT_Stream  stream,
-             TT_Face    face )
-  {
-    FT_Memory  memory = stream->memory;
-    FT_Error   error;
-    FT_ULong   tag, offset;
-
-    static const FT_Frame_Field  ttc_header_fields[] =
-    {
-#undef  FT_STRUCTURE
-#define FT_STRUCTURE  TTC_HeaderRec
-
-      FT_FRAME_START( 8 ),
-        FT_FRAME_LONG( version ),
-        FT_FRAME_LONG( count   ),
-      FT_FRAME_END
-    };
-
-
-    face->ttc_header.tag     = 0;
-    face->ttc_header.version = 0;
-    face->ttc_header.count   = 0;
-
-    offset = FT_STREAM_POS();
-
-    if ( FT_READ_ULONG( tag ) )
-      return error;
-
-    if ( tag != 0x00010000UL                      &&
-         tag != TTAG_ttcf                         &&
-         tag != FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) &&
-         tag != TTAG_true                         &&
-         tag != 0x00020000UL                      )
-      return SFNT_Err_Unknown_File_Format;
-
-    face->ttc_header.tag = TTAG_ttcf;
-
-    if ( tag == TTAG_ttcf )
-    {
-      FT_Int  n;
-
-
-      FT_TRACE3(( "sfnt_init: file is a collection\n" ));
-
-      if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
-        return error;
-
-      /* now read the offsets of each font in the file */
-      if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
-        return error;
-
-      if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
-        return error;
-
-      for ( n = 0; n < face->ttc_header.count; n++ )
-        face->ttc_header.offsets[n] = FT_GET_ULONG();
-
-      FT_FRAME_EXIT();
-    }
-    else
-    {
-      FT_TRACE3(( "sfnt_init: synthesize TTC\n" ));
-
-      face->ttc_header.version = 1 << 16;
-      face->ttc_header.count   = 1;
-
-      if ( FT_NEW( face->ttc_header.offsets) )
-        return error;
-
-      face->ttc_header.offsets[0] = offset;
-    }
-
-    return error;
-  }
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    tt_face_load_sfnt_header                                           */
+  /*    tt_face_load_font_dir                                              */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Loads the header of a SFNT font file.  Supports collections.       */
+  /*    Loads the header of a SFNT font file.                              */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face       :: A handle to the target face object.                  */
@@ -327,9 +249,6 @@
   /*                                                                       */
   /*    stream     :: The input stream.                                    */
   /*                                                                       */
-  /*    face_index :: If the font is a collection, the number of the font  */
-  /*                  in the collection.  Must be zero otherwise.          */
-  /*                                                                       */
   /* <Output>                                                              */
   /*    sfnt       :: The SFNT header.                                     */
   /*                                                                       */
@@ -337,22 +256,19 @@
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    The stream cursor must be at the font file's origin.               */
+  /*    The stream cursor must be at the beginning of the font directory.  */
   /*                                                                       */
-  /*    This function recognizes fonts embedded in a `TrueType collection' */
-  /*                                                                       */
-  /*    The header will be checked whether it is valid by looking at the   */
-  /*    values of `search_range', `entry_selector', and `range_shift'.     */
-  /*                                                                       */
   FT_LOCAL_DEF( FT_Error )
-  tt_face_load_sfnt_header( TT_Face      face,
-                            FT_Stream    stream,
-                            FT_Long      face_index,
-                            SFNT_Header  sfnt )
+  tt_face_load_font_dir( TT_Face      face,
+                         FT_Stream    stream )
   {
-    FT_Error  error;
+    SFNT_HeaderRec  sfnt;
+    FT_Error        error;
+    FT_Memory       memory = stream->memory;
+    TT_TableRec*    entry;
+    TT_TableRec*    limit;
 
-    static const FT_Frame_Field  sfnt_header_fields[] =
+    static const FT_Frame_Field  offset_table_fields[] =
     {
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  SFNT_HeaderRec
@@ -366,101 +282,52 @@
     };
 
 
-    FT_TRACE2(( "tt_face_load_sfnt_header: %08p, %ld\n",
-                face, face_index ));
+    FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));
 
-    error = sfnt_init( stream, face );
-    if ( error )
-      return error;
+    /* read the offset table */
 
-    if ( face_index < 0 )
-      face_index = 0;
+    sfnt.offset = FT_STREAM_POS();
 
-    if ( face_index >= face->ttc_header.count )
-        return SFNT_Err_Bad_Argument;
-
-    sfnt->offset = face->ttc_header.offsets[face_index];
-
-    if ( FT_STREAM_SEEK( sfnt->offset ) )
+    if ( FT_READ_ULONG( sfnt.format_tag )                    ||
+         FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )
       return error;
 
-    /* read offset table */
-    if ( FT_READ_ULONG( sfnt->format_tag )                 ||
-         FT_STREAM_READ_FIELDS( sfnt_header_fields, sfnt ) )
-      return error;
-
     /* many fonts don't have these fields set correctly */
 #if 0
-    if ( sfnt->search_range != 1 << ( sfnt->entry_selector + 4 )         ||
-         sfnt->search_range + sfnt->range_shift != sfnt->num_tables << 4 )
+    if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 )         ||
+         sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
       return SFNT_Err_Unknown_File_Format;
 #endif
 
-    return error;
-  }
+    /* load the table directory */
 
+    FT_TRACE2(( "-- Tables count:   %12u\n",  sfnt.num_tables ));
+    FT_TRACE2(( "-- Format version: %08lx\n", sfnt.format_tag ));
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    tt_face_load_directory                                             */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Loads the table directory into a face object.                      */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    face   :: A handle to the target face object.                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    stream :: The input stream.                                        */
-  /*                                                                       */
-  /*    sfnt   :: The SFNT directory header.                               */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The stream cursor must be at the font file's origin.               */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
-  tt_face_load_directory( TT_Face      face,
-                          FT_Stream    stream,
-                          SFNT_Header  sfnt )
-  {
-    FT_Error     error;
-    FT_Memory    memory = stream->memory;
-
-    TT_TableRec  *entry, *limit;
-
-
-    FT_TRACE2(( "tt_face_load_directory: %08p\n", face ));
-
-    FT_TRACE2(( "-- Tables count:   %12u\n",  sfnt->num_tables ));
-    FT_TRACE2(( "-- Format version: %08lx\n", sfnt->format_tag ));
-
     /* check first */
-    error = sfnt_dir_check( sfnt, stream );
+    error = check_table_dir( &sfnt, stream );
     if ( error )
     {
-      FT_TRACE2(( "tt_face_load_directory: directory checking failed!\n" ));
+      FT_TRACE2(( "tt_face_load_font_dir: invalid table directory!\n" ));
 
       return error;
     }
 
-    face->num_tables = sfnt->num_tables;
+    face->num_tables = sfnt.num_tables;
+    face->format_tag = sfnt.format_tag;
 
     if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
-      goto Exit;
+      return error;
 
-    if ( FT_STREAM_SEEK( sfnt->offset + 12 )      ||
+    if ( FT_STREAM_SEEK( sfnt.offset + 12 )       ||
          FT_FRAME_ENTER( face->num_tables * 16L ) )
-      goto Exit;
+      return error;
 
     entry = face->dir_tables;
     limit = entry + face->num_tables;
 
     for ( ; entry < limit; entry++ )
-    {                    /* loop through the tables and get all entries */
+    {
       entry->Tag      = FT_GET_TAG4();
       entry->CheckSum = FT_GET_ULONG();
       entry->Offset   = FT_GET_LONG();
@@ -477,9 +344,8 @@
 
     FT_FRAME_EXIT();
 
-    FT_TRACE2(( "Directory loaded\n\n" ));
+    FT_TRACE2(( "table directory loaded\n\n" ));
 
-  Exit:
     return error;
   }
 
--- a/src/sfnt/ttload.h
+++ b/src/sfnt/ttload.h
@@ -41,15 +41,9 @@
 
 
   FT_LOCAL( FT_Error )
-  tt_face_load_sfnt_header( TT_Face      face,
-                            FT_Stream    stream,
-                            FT_Long      face_index,
-                            SFNT_Header  sfnt );
+  tt_face_load_font_dir( TT_Face      face,
+                         FT_Stream    stream );
 
-  FT_LOCAL( FT_Error )
-  tt_face_load_directory( TT_Face      face,
-                          FT_Stream    stream,
-                          SFNT_Header  sfnt );
 
   FT_LOCAL( FT_Error )
   tt_face_load_any( TT_Face    face,