Commit 7663f22288c2d71982ea9e832a1592d4bb63bcda

David Turner 2000-02-13T13:37:38

Added support for the "attach_file" format-specific driver interface, used to implement FT_Attach_File. Note, this is currently very lightly tested..

diff --git a/src/base/ftdriver.h b/src/base/ftdriver.h
index 2091913..ff8e6b2 100644
--- a/src/base/ftdriver.h
+++ b/src/base/ftdriver.h
@@ -118,6 +118,18 @@
   typedef void*  FT_FormatInterface;
 
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Attach_Reader                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is associated to the "attach_file" driver-specific   */
+  /*    interface. It is used to read additional data for a given face     */
+  /*    from another input stream/file. For example, it is used to         */
+  /*    attach a Type 1 AFM file to a given Type 1 face..                  */
+  /*                                                                       */
+  typedef FT_Error  (*FT_Attach_Reader)( FT_Face  face, FT_Stream  stream );
 
   /*************************************************************************/
   /*************************************************************************/
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 6320e20..ae9f014 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -209,6 +209,79 @@
   }
 
 
+ /***************************************************************************
+  *
+  *  ft_new_input_stream:
+  *
+  *    create a new input stream object from a FT_Open_Args structure..
+  *
+  **************************************************************************/
+  static
+  FT_Error  ft_new_input_stream( FT_Library    library,
+                                 FT_Open_Args* args,
+                                 FT_Stream    *astream )
+  {
+    FT_Error  error;
+    FT_Memory memory;
+    FT_Stream stream;
+    
+    memory = library->memory;
+    if  ( ALLOC( stream, sizeof(*stream) ) )
+      return error;
+      
+    stream->memory = memory;
+    
+    /* is it a memory stream ------------------------- ? */
+    if (args->memory_base && args->memory_size)
+    {
+      FT_New_Memory_Stream( library,
+                            args->memory_base,
+                            args->memory_size,
+                            stream );
+    }
+
+    /* do we have an 8-bit pathname ------------------ ? */
+    else if (args->pathname)
+      error = FT_New_Stream( args->pathname, stream );
+
+    /* do we have a custom stream -------------------- ? */
+    else if (args->stream)
+    {
+      /* copy the content of the argument stream into the new stream object */
+      *stream = *(args->stream);
+      stream->memory = memory;
+    }
+    else
+      error = FT_Err_Invalid_Argument;
+      
+    if (error)
+      FREE(stream);
+      
+    *astream = stream;
+    return error;
+  }
+
+
+ /***************************************************************************
+  *
+  *  ft_done_stream:
+  *
+  *    closes and destroys a stream object.
+  *
+  **************************************************************************/
+  static
+  void ft_done_stream( FT_Stream*  astream )
+  {
+    FT_Stream  stream = *astream;
+    FT_Memory  memory = stream->memory;
+    
+    if (stream->close)
+      stream->close( stream );
+      
+    FREE( stream );
+    *astream = 0;
+  }
+
 
   /*************************************************************************/
   /*************************************************************************/
@@ -259,6 +332,9 @@
     if ( face->generic.finalizer )
       face->generic.finalizer( face );
 
+    /* close the stream for this face */
+    ft_done_stream( &face->stream );    
+
     /* get rid of it */
     FREE( face );
   }
@@ -935,60 +1011,6 @@
   }
 
 
- /***************************************************************************
-  *
-  *  ft_new_input_stream:
-  *
-  *    create a new input stream object from a FT_Open_Args structure..
-  *
-  **************************************************************************/
-  static
-  FT_Error  ft_new_input_stream( FT_Library    library,
-                                 FT_Open_Args* args,
-                                 FT_Stream    *astream )
-  {
-    FT_Error  error;
-    FT_Memory memory;
-    FT_Stream stream;
-    
-    memory = library->memory;
-    if  ( ALLOC( stream, sizeof(*stream) ) )
-      return error;
-      
-    stream->memory = memory;
-    
-    /* is it a memory stream ------------------------- ? */
-    if (args->memory_base && args->memory_size)
-    {
-      FT_New_Memory_Stream( library,
-                            args->memory_base,
-                            args->memory_size,
-                            stream );
-    }
-
-    /* do we have an 8-bit pathname ------------------ ? */
-    else if (args->pathname)
-      error = FT_New_Stream( args->pathname, stream );
-
-    /* do we have a custom stream -------------------- ? */
-    else if (args->stream)
-    {
-      /* copy the content of the argument stream into the new stream object */
-      *stream = *(args->stream);
-      stream->memory = memory;
-    }
-    else
-      error = FT_Err_Invalid_Argument;
-      
-    if (error)
-      FREE(stream);
-      
-    *astream = stream;
-    return error;
-  }
-
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -1024,19 +1046,20 @@
   /*    `*face'.  Its return value should be 0 if the resource is          */
   /*    recognized, or non-zero if not.                                    */
   /*                                                                       */
+
+  static
+  const FT_Open_Args  ft_default_open_args = 
+    { 0, 0, 0, 0, 0 };
+
   EXPORT_FUNC
   FT_Error  FT_New_Face( FT_Library   library,
                          const char*  pathname,
                          FT_Long      face_index,
                          FT_Face     *aface )
   {
-    FT_Open_Args  args;
-
-    args.memory_base = 0;
-    args.memory_size = 0;
-    args.stream      = 0;
-    args.pathname    = (FT_Byte*)pathname;
+    FT_Open_Args  args = ft_default_open_args;
     
+    args.pathname = (FT_Byte*)pathname;
     return FT_Open_Face( library, &args, face_index, aface );
   }
 
@@ -1048,13 +1071,10 @@
                                 FT_Long      face_index,
                                 FT_Face*     face )
   {
-    FT_Open_Args  args;
+    FT_Open_Args  args = ft_default_open_args;
 
     args.memory_base = file_base;
     args.memory_size = file_size;
-    args.pathname    = 0;
-    args.stream      = 0;
-
     return FT_Open_Face( library, &args, face_index, face );
   }
 
@@ -1083,6 +1103,23 @@
 
     memory = library->memory;
 
+    /* if the font driver is specified in the args structure, use */
+    /* it. Otherwise, we'll scan the list of registered drivers.. */
+    if (args->driver)
+    {
+      driver = args->driver;
+      /* not all drivers directly support face objects, so check.. */
+      if (driver->interface.face_object_size)
+      {
+        error = open_face( driver, stream, face_index, &face );
+        if (!error) goto Success;
+      }
+      else
+        error = FT_Err_Invalid_Handle;
+
+      goto Fail;
+    }
+    
     {
       /* check each font driver for an appropriate format */
       FT_Driver*  cur   = library->drivers;
@@ -1091,7 +1128,7 @@
       for ( ; cur < limit; cur++ )
       {
         driver = *cur;
-       /* not all drivers directly support face object, so check.. */
+       /* not all drivers directly support face objects, so check.. */
         if (driver->interface.face_object_size)
         {
           error = open_face( driver, stream, face_index, &face );
@@ -1155,6 +1192,112 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Attach_File                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    "Attach" a given font file to an existing face. This is usually    */
+  /*    to read additionnal information for a single face object. For      */
+  /*    example, it is used to read the AFM files that come with Type 1    */
+  /*    fonts in order to add kerning data and other metrics..             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face         :: target face object                                 */
+  /*                                                                       */
+  /*    filepathname :: an 8-bit pathname naming the 'metrics' file.       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    If your font file is in memory, or if you want to provide your     */
+  /*    own input stream object, see FT_Attach_Stream.                     */
+  /*                                                                       */
+  /*    The meaning of the "attach" (i.e. what really happens when the     */
+  /*    new file is read) is not fixed by FreeType itself. It really       */
+  /*    depends on the font format (and thus the font driver).             */
+  /*                                                                       */
+  /*    Client applications are expected to know what they're doing        */
+  /*    when invoking this function. Most drivers simply do not implement  */
+  /*    file attachments..                                                 */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Attach_File( FT_Face      face,
+                            const char*  filepathname )
+  {
+    FT_Open_Args  open = ft_default_open_args;
+
+    open.pathname = (char*)filepathname;
+    return FT_Attach_Stream( face, &open );
+  }
+                            
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Attach_Stream                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is similar to FT_Attach_File with the exception      */
+  /*    that it reads the attachment from an arbitrary stream.             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: target face object                                         */
+  /*                                                                       */
+  /*    args :: a pointer to an FT_Open_Args structure used to describe    */
+  /*            the input stream to FreeType                               */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /*    The meaning of the "attach" (i.e. what really happens when the     */
+  /*    new file is read) is not fixed by FreeType itself. It really       */
+  /*    depends on the font format (and thus the font driver).             */
+  /*                                                                       */
+  /*    Client applications are expected to know what they're doing        */
+  /*    when invoking this function. Most drivers simply do not implement  */
+  /*    file attachments..                                                 */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Attach_Stream( FT_Face       face,
+                              FT_Open_Args* parameters )
+  {
+    FT_Stream  stream;
+    FT_Error   error;
+    FT_Driver  driver;
+    
+    FTDriver_getInterface  get_interface;
+    
+    if ( !face || !face->driver )
+      return FT_Err_Invalid_Handle;
+      
+    driver = face->driver;
+    error = ft_new_input_stream( driver->library, parameters, &stream );
+    if (error) goto Exit;
+    
+    /* we implement FT_Attach_Stream in each driver through the */
+    /* "attach_file" interface..                                */
+    error = FT_Err_Unimplemented_Feature;
+
+    get_interface = driver->interface.get_interface;
+    if (get_interface)    
+    {
+      FT_Attach_Reader  reader;
+      
+      reader = (FT_Attach_Reader)get_interface( driver, "attach_file" );
+      if (reader)
+        error = reader( face, stream );
+    }
+    
+    /* close the attached stream */
+    ft_done_stream( &stream );
+    
+  Exit:
+    return error;
+  }
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Done_Face                                                       */
   /*                                                                       */
   /* <Description>                                                         */