From 4f2c5544bbbe663483544da8d15675dfce9c0f89 Mon Sep 17 00:00:00 2001 From: David Turner <david@freetype.org> Date: Fri, 12 May 2000 10:19:41 +0000 Subject: [PATCH] additional changes, this time in order to pass extra parameters to font drivers when creating a new face object. The FT_Open_Args structure has been changed to simplify its use and allow generic parameters too.. --- docs/tutorial/index.html | 122 +++++++++++++-------------- include/freetype/freetype.h | 113 +++++++++++++++++++++---- include/freetype/internal/ftdriver.h | 17 ++-- src/base/ftobjs.c | 103 +++++++++++----------- src/truetype/ttdriver.c | 10 ++- src/truetype/ttobjs.c | 14 ++- src/truetype/ttobjs.h | 8 +- src/type1/t1objs.c | 10 ++- src/type1/t1objs.h | 8 +- src/type1/t1tokens.c | 2 +- src/type1z/t1objs.c | 11 ++- src/type1z/t1objs.h | 8 +- src/type1z/t1parse.c | 2 +- 13 files changed, 272 insertions(+), 156 deletions(-) diff --git a/docs/tutorial/index.html b/docs/tutorial/index.html index 8158e5069..f6413cbca 100644 --- a/docs/tutorial/index.html +++ b/docs/tutorial/index.html @@ -164,18 +164,18 @@ FreeType 2.0 Tutorial</h1></center> <p> <font color="blue"><pre> - FT_Library library; /* handle to library */ - FT_Face face; /* handle to face object */ - - error = FT_Init_FreeType( &library ); - if (error) { ..... } - - error = FT_New_Memory_Face( library, - buffer, /* first byte in memory */ - size, /* size in bytes */ - 0, /* face_index */ - &face ); - if (error) { ... } + FT_Library library; /* handle to library */ + FT_Face face; /* handle to face object */ + + error = FT_Init_FreeType( &library ); + if (error) { ..... } + + error = FT_New_Memory_Face( library, + buffer, /* first byte in memory */ + size, /* size in bytes */ + 0, /* face_index */ + &face ); + if (error) { ... } </pre></font> <p> As you can see, <tt>FT_New_Memory_Face</tt> simply takes a pointer to @@ -185,38 +185,17 @@ FreeType 2.0 Tutorial</h1></center> </ul> <p> - <h4>c. From other sources:</h4> + <h4>c. From other sources: (compressed files, network, etc..)</h4> <ul> There are cases where using a filepathname or preloading the file in memory is simply not enough. With FreeType 2, it is possible to provide - your own implementation of i/o routines through the <tt>FT_Stream</tt> - type. + your own implementation of i/o routines. <p> - Basically, one has to set up a <tt>FT_Stream</tt> object, according to - the rules defined in the document named - <a href="#">FreeType 2 System Interface</a>, then pass it to the function - <tt>FT_Open_Face</tt> as in: - <p> - <font color="blue"><pre> - - FT_Library library; /* handle to library */ - FT_Face face; /* handle to face object */ - - error = FT_Init_FreeType( &library ); - if (error) { ..... } - - ... set up stream object, with handle "stream" ... - - error = FT_Open_Face( library, - stream, /* handle to stream objects */ - 0, /* face_index */ - &face ); - if (error) { ... } - </pre></font> - <p> - custom implementations of <tt>FT_Stream</tt> are great to provide advanced - features like automatic support of compressed files, network transparency, - using UTF-16 file pathnames, etc.. + This is done through the <tt>FT_Open_Face</tt> function, which can be + used to open a new font face with a custom input stream, select a specific + driver for opening, or even pass extra parameters to the font driver + when creating the object. We advise you to refer to the FreeType 2 + Reference in order to learn how to use it. <p> </ul> <p> @@ -396,7 +375,7 @@ FreeType 2.0 Tutorial</h1></center> The glyph image is always stored in a special object called a <em>glyph slot</em>. As it names suggests, a glyph slot is simply a container that is able to hold one glyph image at a time, be it a bitmap, - an outline, or something else. Each face object has a single glyph + an outline, or something else. Each face object has a single glyph slot object that can be accessed as <b><tt>face−>glyph</tt></b>. <p> Loading a glyph image into the slot is performed by calling @@ -440,14 +419,16 @@ FreeType 2.0 Tutorial</h1></center> As said before, when a new face object is created, it will look for a Unicode, Latin-1 or ASCII charmap and select it. The currently selected charmap is accessed via <b><tt>face−>charmap</tt></b>. This - field is NULL when no charmap is selected. + field is NULL when no charmap is selected, which typically happen when you + create a new <tt>FT_Face</tt> object from a font file that doesn't contain + an ASCII, Latin-1 or Unicode charmap (rare stuff). <p> - The field <b><tt>face−>num_charmaps</tt></b> and + The fields <b><tt>face−>num_charmaps</tt></b> and <b><tt>face−>charmaps</tt></b> (notice the 's') can be used by client applications to look at what charmaps are available in a given face. <p> - <b><tt>face−charmaps</tt></b> is an array of <em>pointers</em> + <b><tt>face−>charmaps</tt></b> is an array of <em>pointers</em> to the <tt><b>face−>num_charmaps</b></tt> charmaps contained in the font face. <p> @@ -493,23 +474,31 @@ FreeType 2.0 Tutorial</h1></center> <h3>7. Accessing glyph image data:</h3> <ul> - Glyph image data is accessible through <tt><b>face−glyph</b></tt>. - See the definition of the <tt>FT_GlyphSlot</tt> type on more details. You - can perfectly create a shortcut to the glyph slot as in: + Glyph image data is accessible through <tt><b>face−>glyph</b></tt>. + See the definition of the <tt>FT_GlyphSlot</tt> type for more details. As + stated previously, each face has a single glyph slot, where <em>one</em> glyph + image <em>at a time</em> can be loaded. Each time you call + <tt>FT_Load_Glyph</tt>, you erase the content of the glyph slot with a new + glyph image. + <p> + Note however that the glyph slot object itself doesn't change, only its + content, which means that you can perfectly create a "shortcut" to access + it as in: <p> <font color="blue"><pre> { - FT_GlyphSlot glyph; + FT_GlyphSlot glyph = face->glyph; /* shortcut to glyph slot */ - .... load glyph ... - - glyph = face->glyph; /* shortcut to glyph data */ - - .... access glyph data as glyph->xxxx + for ( n = 0; n < face->num_glyphs; n++ ) + { + .... load glyph n... + .... access glyph data as glyph->xxxx + } } </pre></font> - <p> - For example, one can access the following fields: + <p> + The <tt>glyph</tt> variable will be valid until its parent <tt>face</tt> + is destroyed. Here are a few important fields of the glyph slot: <p> <table cellpadding=10> <tr valign="top"> @@ -521,30 +510,41 @@ FreeType 2.0 Tutorial</h1></center> <tr valign="top"> <td><tt><b>glyph−>metrics</b></tt> <td>A simple structure used to hold the glyph image's metrics. Note - that <em>all distances are expressed in 1/64th of pixels !</em> + that <em>most distances are expressed in 1/64th of pixels !</em> See the API reference or User Guide for a description of the <tt>FT_Glyph_Metrics</tt> structure. - + <tr valign="top"> <td><tt><b>glyph−>bitmap</b></tt> <td>When the glyph slot contains a bitmap, a simple <tt>FT_Bitmap</tt> that describes it. See the API reference or user guide for a description of the <tt>FT_Bitmap</tt> structure. - + <tr valign="top"> <td><tt><b>glyph−>outline</b></tt> <td>When the glyph slot contains a scalable outline, this structure describes it. See the definition of the <tt>FT_Outline</tt> structure. - </table> + </table> <p> </ul> <h3>8. Rendering glyph outlines into bitmaps:</h3> <ul> - When the glyph image loaded in a glyph slot is a bitmap, you can use - your favorite graphics library to blit it to your own surfaces. + You can easily test the format of the glyph image by inspecting the + <tt>face->glyph->format</tt> variable. If its value is + <tt>ft_glyph_format_bitmap</tt>, the glyph image that was loaded is + a bitmap that can be directly blit to your own surfaces through your + favorite graphics library (FreeType 2 doesn't provide bitmap blitting + routines, as you may imagine :-) <p> + On the other hand, when the format if <tt>ft_glyph_format_outline</tt> + or something else, the library provides a means to convert such glyph + images to bitmaps through what are called <b>rasters</b>. + <p> + + + On the other hand, when the image is a scalable outline, or something else, FreeType provides a function to convert the glyph image into a pre-existing bitmap that you'll handle to it, named diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index ae87c5106..3ebff27c0 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -1378,24 +1378,51 @@ /*************************************************************************/ /* */ /* <Function> */ - /* FT_Stream_Type */ + /* FT_Open_Flags */ /* */ /* <Description> */ - /* An enumeration used to list the possible ways to open a new */ - /* input stream. It is used by the FT_Open_Args structure.. */ + /* An enumeration used to list the bit flags used within FT_Open_Args */ /* */ /* <Fields> */ - /* ft_stream_memory :: this is a memory-based stream */ - /* ft_stream_copy :: copy the stream from the "stream" field */ - /* ft_stream_pathname :: create a new input stream from a C pathname */ + /* ft_open_memory :: this is a memory-based stream */ + /* ft_open_stream :: copy the stream from the "stream" field */ + /* ft_open_pathname :: create a new input stream from a C pathname */ + /* ft_open_driver :: use the "driver" field */ + /* ft_open_params :: use the "num_params" & "params" field */ /* */ typedef enum { - ft_stream_memory = 1, - ft_stream_copy = 2, - ft_stream_pathname = 3 + ft_open_memory = 1, + ft_open_stream = 2, + ft_open_pathname = 4, + ft_open_driver = 8, + ft_open_params = 16 - } FT_Stream_Type; + } FT_Open_Flags; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Parameter */ + /* */ + /* <Description> */ + /* A simple structure used to pass more or less generic parameters */ + /* to FT_Open_Face.. */ + /* */ + /* <Fields> */ + /* tag :: 4-byte identification tag */ + /* data :: pointer to parameter data */ + /* */ + /* <Note> */ + /* the id and role of parameters is driver-specific */ + /* */ + typedef struct FT_Parameter_ + { + FT_ULong tag; + FT_Pointer data; + + } FT_Parameter; /************************************************************************* * @@ -1408,7 +1435,7 @@ * function FT_Open_Face & FT_Attach_Stream. * * <Fields> - * stream_type :: type of input stream + * flags :: set of bit flags indicating how to use the structure * * memory_base :: first byte of file in memory * memory_size :: size in bytes of file in memory @@ -1422,6 +1449,10 @@ * the face. If set to 0, FreeType will try to load * the face with each one of the drivers in its list. * + * num_params :: number of parameters + * params :: extra parameters passed to the font driver when + * opening a new face + * * <Note> * The stream_type determines which fields are used to create a new * input stream. @@ -1441,12 +1472,14 @@ typedef struct FT_Open_Args_ { - FT_Stream_Type stream_type; - FT_Byte* memory_base; - FT_Long memory_size; - FT_String* pathname; - FT_Stream stream; - FT_Driver driver; + FT_Open_Flags flags; + FT_Byte* memory_base; + FT_Long memory_size; + FT_String* pathname; + FT_Stream stream; + FT_Driver driver; + FT_Int num_params; + FT_Parameter* params; } FT_Open_Args; @@ -1493,6 +1526,52 @@ FT_Face* face ); + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory_Face */ + /* */ + /* <Description> */ + /* Creates a new face object from a given resource and typeface index */ + /* using a font file already loaded into memory. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* file_base :: A pointer to the beginning of the font data. */ + /* file_size :: The size of the memory chunk used by the font data. */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index 0. */ + /* <Output> */ + /* face :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object which can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* Note that additional slots can be added to each face with the */ + /* FT_New_GlyphSlot() API function. Slots are linked in a single */ + /* list through their `next' field. */ + /* */ + /* FT_New_Memory_Face() can be used to determine and/or check the */ + /* font format of a given font resource. If the `face_index' field */ + /* is negative, the function will _not_ return any face handle in */ + /* `*face'. Its return value should be 0 if the resource is */ + /* recognized, or non-zero if not. */ + /* */ + EXPORT_DEF + FT_Error FT_New_Memory_Face( FT_Library library, + void* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face* face ); + + /*************************************************************************/ /* */ /* <Function> */ diff --git a/include/freetype/internal/ftdriver.h b/include/freetype/internal/ftdriver.h index 2f6117f60..68d416bf7 100644 --- a/include/freetype/internal/ftdriver.h +++ b/include/freetype/internal/ftdriver.h @@ -160,13 +160,14 @@ /* */ /* <InOut> */ /* stream :: The input stream. */ + /* face :: A handle to the new target face. */ /* */ /* <Input> */ /* typeface_index :: The face index in the font resource. Used to */ /* access individual faces in collections. */ /* */ - /* <Output> */ - /* face :: A handle to the new target face. */ + /* num_params :: number of optional generic parameters */ + /* parameters :: table of generic parameters */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ @@ -178,12 +179,18 @@ /* immediately with an error code of 0 (meaning success). The field */ /* `num_faces' should be set. */ /* */ + /* The generic parameters are a way to pass additional data to a */ + /* given font driver when creating a new face object. In most cases */ + /* they will be simply ignored.. */ + /* */ /* FTDriver_doneFace() will be called subsequently, whatever the */ /* result was. */ /* */ - typedef FT_Error (*FTDriver_initFace)( FT_Stream stream, - FT_Long typeface_index, - FT_Face face ); + typedef FT_Error (*FTDriver_initFace)( FT_Stream stream, + FT_Face face, + FT_Int typeface_index, + FT_Int num_params, + FT_Parameter* parameters ); /*************************************************************************/ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 436cee36a..6d662b4c3 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -233,38 +233,28 @@ stream->memory = memory; - /* now, look at the stream type */ - switch ( args->stream_type ) + /* now, look at the stream flags */ + if ( args->flags & ft_open_memory ) { - /***** is it a memory-based stream ? *****************************/ - case ft_stream_memory: - { - FT_New_Memory_Stream( library, - args->memory_base, - args->memory_size, - stream ); - break; - } - - /***** is is a pathname stream ? ********************************/ - case ft_stream_pathname: - { - error = FT_New_Stream( args->pathname, stream ); - stream->pathname.pointer = args->pathname; - break; - } - - case ft_stream_copy: - { - if ( args->stream) - { - *stream = *(args->stream); - stream->memory = memory; - break; - } - } - default: - error = FT_Err_Invalid_Argument; + error = 0; + FT_New_Memory_Stream( library, + args->memory_base, + args->memory_size, + stream ); + } + else if (args->flags & ft_open_pathname) + { + error = FT_New_Stream( args->pathname, stream ); + stream->pathname.pointer = args->pathname; + } + else if (args->flags & ft_open_stream && args->stream) + { + *stream = *(args->stream); + stream->memory = memory; + } + else + { + error = FT_Err_Invalid_Argument; } if ( error ) @@ -938,10 +928,12 @@ /* This function does some work for FT_Open_Face(). */ /* */ static - FT_Error open_face( FT_Driver driver, - FT_Stream stream, - FT_Long face_index, - FT_Face* aface ) + FT_Error open_face( FT_Driver driver, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter* params, + FT_Face* aface ) { FT_Memory memory; FT_DriverInterface* interface; @@ -960,7 +952,7 @@ face->memory = memory; face->stream = stream; - error = interface->init_face( stream, face_index, face ); + error = interface->init_face( stream, face, face_index, num_params, params ); if ( error ) goto Fail; @@ -1024,9 +1016,8 @@ { FT_Open_Args args; - args.stream_type = ft_stream_pathname; - args.driver = 0; - args.pathname = (char*)pathname; + args.flags = ft_open_pathname; + args.pathname = (char*)pathname; return FT_Open_Face( library, &args, face_index, aface ); } @@ -1078,10 +1069,9 @@ { FT_Open_Args args; - args.stream_type = ft_stream_memory; + args.flags = ft_open_memory; args.memory_base = file_base; args.memory_size = file_size; - args.driver = 0; return FT_Open_Face( library, &args, face_index, face ); } @@ -1152,13 +1142,23 @@ /* if the font driver is specified in the `args' structure, use */ /* it. Otherwise, we'll scan the list of registered drivers. */ - if ( args->driver ) + if ( args->flags & ft_open_driver && 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 ); + FT_Int num_params = 0; + FT_Parameter* params = 0; + + if ( args->flags & ft_open_params ) + { + num_params = args->num_params; + params = args->params; + } + + error = open_face( driver, stream, face_index, + num_params, params, &face ); if ( !error ) goto Success; } @@ -1173,14 +1173,23 @@ FT_Driver* cur = library->drivers; FT_Driver* limit = cur + library->num_drivers; - for ( ; cur < limit; cur++ ) { driver = *cur; /* not all drivers directly support face objects, so check... */ if ( driver->interface.face_object_size ) { - error = open_face( driver, stream, face_index, &face ); + FT_Int num_params = 0; + FT_Parameter* params = 0; + + if ( args->flags & ft_open_params ) + { + num_params = args->num_params; + params = args->params; + } + + error = open_face( driver, stream, face_index, + num_params, params, &face ); if ( !error ) goto Success; @@ -1287,8 +1296,8 @@ { FT_Open_Args open; - open.stream_type = ft_stream_pathname; - open.pathname = (char*)filepathname; + open.flags = ft_open_pathname; + open.pathname = (char*)filepathname; return FT_Attach_Stream( face, &open ); } diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 82bcd6ccb..587defb0f 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -137,14 +137,16 @@ /* Done_Face() will be called subsequently, whatever the result was. */ /* */ static - TT_Error Init_Face( FT_Stream stream, - TT_Long typeface_index, - TT_Face face ) + TT_Error Init_Face( FT_Stream stream, + TT_Face face, + FT_Int typeface_index, + FT_Int num_params, + FT_Parameter* params ) { TT_Error error; /* initialize the TrueType face object */ - error = TT_Init_Face( stream, typeface_index, face ); + error = TT_Init_Face( stream, face, typeface_index, num_params, params ); /* now set up root fields */ if ( !error && typeface_index >= 0 ) diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 2023f36f2..fa23c7f3c 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -153,15 +153,21 @@ /* TrueType error code. 0 means success. */ /* */ LOCAL_DEF - TT_Error TT_Init_Face( FT_Stream stream, - TT_Long face_index, - TT_Face face ) + TT_Error TT_Init_Face( FT_Stream stream, + TT_Face face, + TT_Int face_index, + TT_Int num_params, + FT_Parameter* params ) { TT_Error error; TT_ULong format_tag; SFNT_Interface* sfnt; PSNames_Interface* psnames; + /* for now, parameters are unused */ + (void)num_params; + (void)params; + sfnt = (SFNT_Interface*)face->sfnt; if (!sfnt) { @@ -205,7 +211,7 @@ format_tag != TTAG_true ) /* Mac fonts */ { FT_TRACE2(( "[not a valid TTF font]" )); - error = TT_Err_Invalid_File_Format; + error = FT_Err_Unknown_File_Format; goto Exit; } diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index ac57b7b44..33457e028 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -367,9 +367,11 @@ /*************************************************************************/ /* Face Funcs */ - LOCAL_DEF TT_Error TT_Init_Face( FT_Stream stream, - TT_Long face_index, - TT_Face face ); + LOCAL_DEF TT_Error TT_Init_Face( FT_Stream stream, + TT_Face face, + TT_Int face_index, + TT_Int num_params, + FT_Parameter* params ); LOCAL_DEF void TT_Done_Face( TT_Face face ); diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c index 23b6a900c..07b218099 100644 --- a/src/type1/t1objs.c +++ b/src/type1/t1objs.c @@ -220,14 +220,18 @@ ******************************************************************/ LOCAL_FUNC - T1_Error T1_Init_Face( FT_Stream stream, - FT_Int face_index, - T1_Face face ) + T1_Error T1_Init_Face( FT_Stream stream, + T1_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) { T1_Tokenizer tokenizer; T1_Error error; PSNames_Interface* psnames; + (void)num_params; + (void)params; (void)face_index; (void)face; diff --git a/src/type1/t1objs.h b/src/type1/t1objs.h index 51c71861a..53fe3dbe1 100644 --- a/src/type1/t1objs.h +++ b/src/type1/t1objs.h @@ -147,9 +147,11 @@ ******************************************************************/ LOCAL_DEF - T1_Error T1_Init_Face( FT_Stream stream, - FT_Int face_index, - T1_Face face ); + T1_Error T1_Init_Face( FT_Stream stream, + T1_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); diff --git a/src/type1/t1tokens.c b/src/type1/t1tokens.c index f4aca2831..15654cbc9 100644 --- a/src/type1/t1tokens.c +++ b/src/type1/t1tokens.c @@ -323,7 +323,7 @@ strncmp( (const char*)tokzer->base, "%!FontType", 10 ) ) ) { FT_TRACE2(( "Not a Type1 font\n" )); - error = T1_Err_Invalid_File_Format; + error = FT_Err_Unknown_File_Format; goto Fail; } } diff --git a/src/type1z/t1objs.c b/src/type1z/t1objs.c index 43d876b38..38928c718 100644 --- a/src/type1z/t1objs.c +++ b/src/type1z/t1objs.c @@ -200,15 +200,18 @@ ******************************************************************/ LOCAL_FUNC - T1_Error T1_Init_Face( FT_Stream stream, - FT_Int face_index, - T1_Face face ) + T1_Error T1_Init_Face( FT_Stream stream, + T1_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) { T1_Error error; PSNames_Interface* psnames; + UNUSED(num_params); + UNUSED(params); UNUSED(face_index); - UNUSED(face); UNUSED(stream); face->root.num_faces = 1; diff --git a/src/type1z/t1objs.h b/src/type1z/t1objs.h index 5b41f3a8d..15f1e99a3 100644 --- a/src/type1z/t1objs.h +++ b/src/type1z/t1objs.h @@ -146,9 +146,11 @@ ******************************************************************/ LOCAL_DEF - T1_Error T1_Init_Face( FT_Stream stream, - FT_Int face_index, - T1_Face face ); + T1_Error T1_Init_Face( FT_Stream stream, + T1_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); diff --git a/src/type1z/t1parse.c b/src/type1z/t1parse.c index 3cb47a928..42743c389 100644 --- a/src/type1z/t1parse.c +++ b/src/type1z/t1parse.c @@ -690,7 +690,7 @@ strncmp( (const char*)parser->base_dict, "%!FontType", 10 ) ) ) { FT_TRACE2(( "Not a Type1 font\n" )); - error = T1_Err_Invalid_File_Format; + error = FT_Err_Unknown_File_Format; } else {