From 7663f22288c2d71982ea9e832a1592d4bb63bcda Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 13 Feb 2000 13:37:38 +0000 Subject: [PATCH] Added support for the "attach_file" format-specific driver interface, used to implement FT_Attach_File. Note, this is currently very lightly tested.. --- src/base/ftdriver.h | 12 ++ src/base/ftobjs.c | 273 +++++++++++++++++++++++++++++++++----------- 2 files changed, 220 insertions(+), 65 deletions(-) diff --git a/src/base/ftdriver.h b/src/base/ftdriver.h index 20919138d..ff8e6b2f5 100644 --- a/src/base/ftdriver.h +++ b/src/base/ftdriver.h @@ -118,6 +118,18 @@ typedef void* FT_FormatInterface; + /*************************************************************************/ + /* */ + /* */ + /* FT_Attach_Reader */ + /* */ + /* */ + /* 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 6320e205a..ae9f0143c 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; - } - - - /*************************************************************************/ /* */ /* */ @@ -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 ); @@ -1152,6 +1189,112 @@ } + /*************************************************************************/ + /* */ + /* */ + /* FT_Attach_File */ + /* */ + /* */ + /* "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.. */ + /* */ + /* */ + /* face :: target face object */ + /* */ + /* filepathname :: an 8-bit pathname naming the 'metrics' file. */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* 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 ); + } + + /*************************************************************************/ + /* */ + /* */ + /* FT_Attach_Stream */ + /* */ + /* */ + /* This function is similar to FT_Attach_File with the exception */ + /* that it reads the attachment from an arbitrary stream. */ + /* */ + /* */ + /* face :: target face object */ + /* */ + /* args :: a pointer to an FT_Open_Args structure used to describe */ + /* the input stream to FreeType */ + /* */ + /* 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; + } + + + /*************************************************************************/ /* */ /* */