| <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <meta name="Author" content="David Turner"> |
| <meta name="GENERATOR" content="Mozilla/4.5 [fr] (Win98; I) [Netscape]"> |
| <title>FreeType 2 Internals</title> |
| </head> |
| <body> |
| |
| <body text="#000000" |
| bgcolor="#FFFFFF" |
| link="#0000EF" |
| vlink="#51188E" |
| alink="#FF0000"> |
| |
| <center> |
| <h1> |
| FreeType 2.0 System Interface</h1></center> |
| |
| <center> |
| <h3> |
| © 2000 David Turner (<a href="fichier :///david@freetype.org">david@freetype.org</a>)<br> |
| © 2000 The FreeType Development Team (<a href="fichier :///devel@freetype.org">devel@freetype.org</a>)</h3></center> |
| |
| <p><br> |
| <hr WIDTH="100%"> |
| <br> |
| <h2>Introduction:</h2> |
| <ul> |
| This document explains how the FreeType 2 library performs the low-level and |
| system-specific operations of memory management and i/o access. It is targetted |
| to FreeType hackers, porters and "advanced" developers who want special |
| features like providing their own memory manager or streams. |
| <p> |
| Note that the only system-specific part of the library is a file |
| named "<tt>ftsystem.c</tt>", normally located in the directory |
| "<tt>freetype2/config/<system></tt>" where <tt><system></tt> designates |
| your platform (e.g. "<tt>config/ansi/ftsystem.c</tt>" or |
| "<tt>config/unix/ftsystem.c</tt>"). |
| <p> |
| </ul> |
| |
| <p> |
| <hr> |
| <p> |
| |
| <h2>I. Memory Management</h2> |
| <ul> |
| Memory allocation and releases are performed through a <tt>FT_Memory</tt> object in |
| FreeType. A <tt>FT_Memory</tt> is nothing more than a table of functions plus |
| an arbitrary user data field. It is defined in the file |
| "<tt>freetype2/include/ftsystem.h</tt>" and has the following structure: |
| <p> |
| <ul> |
| <tt>typedef struct</tt><br> |
| <tt>{</tt> |
| <ul> |
| <table> |
| <tr><td><tt><b>void* user</b></tt> <td> // a user-defined pointer. This is zero by default |
| <tr><td><tt><b>void* (*alloc)( FT_System, int)</b></tt> <td> // a function used to allocate a new block |
| <tr><td><tt><b>void* (*realloc)( FT_System, int, int, void* )</b></tt><td> // a function used to reallocate a given block |
| <tr><td><tt><b>void (*free)( FT_System, void*)</b></tt> <td> // a function used to release a given block |
| </table> |
| </ul> |
| <tt>} FT_MemoryRec, *FT_Memory;</tt><br> |
| </ul> |
| <p> |
| You'll notice that:<p> |
| <ul> |
| <li>The <tt>FT_Memory</tt> type is really a pointer to a <tt>FT_MemoryRec</tt>. |
| This is a normal convention for the FreeType code. |
| <li>The <tt>realloc</tt> takes two integer arguments. The first one is the |
| current block size, the second one its new size. |
| </ul> |
| <p> |
| |
| All current implementations of "<tt>ftsystem.c</tt>" provide a very simple |
| implementation of the <tt>FT_Memory</tt> interface by calling directly the |
| standard C <tt>alloc</tt>, <tt>realloc</tt> and <tt>free</tt>. |
| <p> |
| The FreeType source code never invokes directly the function pointers. Rather, |
| it calls <tt>FT_Alloc</tt>, <tt>FT_Realloc</tt> and <tt>FT_Free</tt> functions |
| which are defined in "<tt>freetype2/src/base/ftobjs.c</tt>". These will not be |
| discussed here. |
| <p> |
| <b>If you want to use your own memory allocator</b> rather than the one provided |
| by your build of FreeType, follow these simple steps:<p> |
| <ol> |
| <li>Create your own <tt>FT_Memory</tt> object, with pointers that map to |
| your own memory management routines (beware function signatures though). |
| <p> |
| <li>Call <tt>FT_Build_Library(memory,&library)</tt>. This will create a new |
| <tt>FT_Library</tt> object that uses your own <tt>FT_Memory</tt> exclusively. |
| Note however that this library has no font drivers loaded in !! |
| <p> |
| <li>Load the default font drivers into the new library, either by |
| calling <tt>FT_Default_Drivers(library)</tt>, or by adding them manually |
| through repeated calls to <tt>FT_Add_Driver(library,&driver_interface)</tt> |
| <p> |
| </ol> |
| This will replace the <tt>FT_Init_FreeType(&library)</tt> call that an application |
| must do to initialise one library instance. |
| <p> |
| Notice that you <em>don't need to recompile FreeType 2 to use your own memory |
| manager !!</em>. |
| <p> |
| </ul> |
| |
| <p> |
| <hr> |
| <p> |
| |
| <h2>II. Streams</h2> |
| <ul> |
| <h3>1. Basic Stream Structure</h3> |
| <p> |
| A stream models the array of bytes found in a font file. FreeType 2 separates |
| streams into two families :<p> |
| <ul> |
| <li><b>memory-based streams:</b><br> |
| when the stream's content is entirely found in memory. This is the |
| case for ROM font files, or memory-mapped files. |
| <p> |
| <li><b>disk-based streams:</b><br> |
| when the stream isn't directly accessible in memory. This is the |
| case for local or remote files. |
| <p> |
| </ul> |
| <p> |
| Note that a stream's nature only determines how FreeType accesses its content, not |
| the way it is effectively stored. For example, in the case of a compressed font file, |
| one implementation may choose to uncompress the font in memory, then provide a memory |
| based stream to access it. Another one might chose a disk based stream to perform |
| on-the-fly decompression of the font data. Similarly, the font file can be stored |
| on a local disk, or obtained from a network. This will be completely transparent to |
| FreeType. |
| <p> |
| The stream structure is: |
| <p> |
| <ul> |
| <tt>typedef struct</tt><br> |
| <tt>{</tt><br> |
| <ul><table> |
| <tr><td><tt><b>char* base</b></tt> <td> for memory-based streams, the address |
| of its first byte. |
| |
| <tr><td><tt><b>ulong size</b></tt> <td> the stream's size in bytes. |
| |
| <tr><td><tt><b>ulong pos</b></tt> <td> the current stream position in the file |
| |
| <tr><td><tt><b>descriptor</b></tt><td> a union field used to hold either an |
| integer file descriptor or pointer. |
| This field is not used by FreeType |
| itself, but is left to implementations |
| of "<tt>ftsystem</tt>" |
| <tr><td><tt><b>pathname</b></tt> <td> a union field that can hold either an |
| integer or pointer. It is not used by |
| FreeType itself, but is left to |
| implementations. These can put the |
| file pathname's during debugging for |
| example. |
| |
| <tr><td><tt><b>read</b></tt> <td> a pointer to a function used to seek the |
| stream and/or read a run of bytes from it. |
| |
| <tr><td><tt><b>close</b></tt><td> a pointer to a function called when the |
| stream is closed. |
| |
| <tr><td><tt><b>memory</b></tt> <td> a <tt>FT_Memory</tt> object, which is used |
| to allocate frames for disk-based streams. |
| This field is set and used by FreeType. |
| |
| <tr><td><tt><b>cursor</b></tt> <td> a pointer in memory used when accessing |
| frames. This is set and used by FreeType. |
| |
| <tr><td><tt><b>limit</b></tt> <td> a pointer in memory used when accessing |
| frames. This is set and used by FreeType. |
| </table></ul> |
| <tt>} FT_StreamRec, *FT_Stream</tt> |
| </ul> |
| <p> |
| |
| The following important things must be noticed here:<p> |
| <ul> |
| <li>The <tt>FT_Stream</tt> type is really a pointer to a <tt>FT_StreamRec</tt>. |
| This is a normal convention for the FreeType source. |
| <p> |
| |
| <li>When the <tt>read</tt> field is non NULL, the stream is considered to be |
| disk-based. Otherwise, the stream is memory-based, and the <tt>base</tt> |
| field <em>must</em> be set by "<tt>ftsystem.c</tt>" when the stream is |
| created. |
| <p> |
| |
| <li>The <tt>base</tt> field must be set to 0 when a disk-based stream is created. |
| However, this field will later be set and used by the FreeType library when |
| accessing frames of bytes within the font file (of course, this doesn't |
| happen with memory-based streams). |
| </ul> |
| |
| <h3>2. Stream lifecyles</h3> |
| <p> |
| Each <tt>FT_Face</tt> needs its own stream to access font data. The most common |
| way to create a new <tt>FT_Stream</tt> object is to call the function |
| <tt>FT_New_Face</tt>. This function takes a <em>file pathname</em> argument that |
| is used to create a new stream object. |
| <p> |
| This is possible because each implementation of "<tt>ftsystem.c</tt>" provides |
| a function called <tt>FT_New_Stream</tt> which takes a file pathname and a |
| <tt>FT_Stream</tt> pointer as an argument. The function simply opens the file |
| and initialises the stream structure accordingly. It is called by <tt>FT_New_Face</tt> |
| to create the face's stream object. |
| <p> |
| A stream is only closed when the face is destroyed through <tt>FT_Done_Face</tt>. |
| Its <tt>close</tt> field function will then be called. Note that the function should |
| <em>never</em> destroy the <tt>FT_Stream</tt>. |
| <p> |
| |
| |
| <h3>3. Using your own streams</h3> |
| <p> |
| There are cases where it is interesting to provide your own stream to create |
| a new face object, rather than rely on the default implementation. For example, |
| a filepathname, which is a C string, might not be useful on a system where files |
| are named with a UTF-16 string or via an i-node number of memory address (for ROM files). |
| <p> |
| For this purpose, the <tt>FT_Open_Face</tt> is defined. It simply takes a |
| <tt>FT_Stream</tt> pointer as its second argument, instead of a file pathname (the |
| stream must be allocated and initialised by you, so be careful). |
| <p> |
| Actually, the only thing that <tt>FT_New_Face</tt> does is create a new stream |
| through <tt>FT_New_Stream</tt>, then call <tt>FT_Open_Face</tt> to create the |
| face with it. |
| <p> |
| Note also that you can use the function <tt>FT_New_Memory_Face</tt> to create |
| a new font face for a memory-based font file, whose address and size can be passed |
| as arguments. The function automatically creates the corresponding memory-based |
| stream and use it to create the face. |
| <p> |
| |
| </ul> |
| |
| |
| <p> |
| <hr> |
| <p> |
| |
| <h2>III. Thread synchronisation</h2> |
| <ul> |
| The FreeType library uses no static data. It can be used concurrently by two |
| thread as long as each one uses its own <tt>FT_Library</tt> instance. Otherwise, |
| one can very simply synchronize access to a single library instance by using a |
| mutex to protect each call to one of FreeType's API functions. |
| <p> |
| </ul> |
| |
| |