Added support for the "attach_file" format-specific driver
interface, used to implement FT_Attach_File. Note, this is currently very lightly tested..
This commit is contained in:
parent
818336fdf4
commit
7663f22288
|
@ -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 );
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
|
|
@ -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;
|
||||
FT_Open_Args args = ft_default_open_args;
|
||||
|
||||
args.memory_base = 0;
|
||||
args.memory_size = 0;
|
||||
args.stream = 0;
|
||||
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 @@
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <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> */
|
||||
|
|
Loading…
Reference in New Issue