Commit 43764232 authored by David Turner's avatar David Turner
Browse files

removing obsolete files:

the design of FT2 has evolved considerably since
these documents were written, and it's better not to
include them in order to avoid confusion among
users of the library..
parent 59266f23
This diff is collapsed.
This diff is collapsed.
<!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">
<title>FreeType 2 Internals - I/O Frames</title>
</head>
<body text="#000000"
bgcolor="#FFFFFF"
link="#0000EF"
vlink="#51188E"
alink="#FF0000">
<h1 align=center>
FreeType 2.0 I/O Frames
</h1>
<h3 align=center>
&copy; 2000 David Turner
(<a href="mailto:david@freetype.org">david@freetype.org</a>)<br>
&copy; 2000 The FreeType Development Team
(<a href="http://www.freetype.org">www.freetype.org</a>)
</h3>
<center>
<table width="70%">
<tr><td>
<hr>
<h2>
Introduction
</h2>
<p>This document explains the concept of I/O <b>frames</b> as used in the
FreeType&nbsp;2 source code. It also enumerates the various functions and
macros that can be used to read them.</p>
<p>It is targeted to FreeType hackers, or more simply to developers who
would like a better understanding of the library's source code.</p>
<hr>
<h2>
I. What frames are
</h2>
<p>Simply speaking, a frame is an array of bytes in a font file that is
`preloaded' into memory in order to be rapidly parsed. Frames are useful
to ensure that every `load' is checked against end-of-file overruns, and
provides nice functions to extract data in a variety of distinct
formats.</p>
<p>But an example is certainly more meaningful than anything else. The
following code</p>
<font color="blue">
<pre>
error = read_short( stream, &str.value1 );
if ( error ) goto ...
error = read_ulong( stream, &str.value2 );
if ( error ) goto ...
error = read_ulong( stream, &str.value3 );
if ( error ) goto ...</pre>
</font>
<p>can easily be replaced with</p>
<font color="blue">
<pre>
error = FT_Access_Frame( stream, 2 + 4 + 4 );
if ( error ) goto ...
str.value1 = FT_Get_Short( stream );
str.value2 = FT_Get_ULong( stream );
str.value3 = FT_Get_ULong( stream );
FT_Forget_Frame( stream );</pre>
</font>
<p>Here, the call to <code>FT_Access_Frame()</code> will</p>
<ul>
<li>
<p>Ensure that there are at least 2+4+4=10 bytes left in the
stream.</p>
</li>
<li>
<p>`Preload' (for disk-based streams) 10&nbsp;bytes from the current
stream position.</p>
</li>
<li>
<p>Set the frame `cursor' to the first byte in the frame.</p>
</li>
</ul>
<p>Each <code>FT_Get_Short()</code> or <code>FT_Get_ULong()</code> call
will read a big-endian integer from the stream (2&nbsp;bytes for
<code>FT_Get_Short()</code>, 4&nbsp;bytes for <code>FT_Get_ULong</code>)
and advance the frame cursor accordingly.</p>
<p><code>FT_Forget_Frame()</code> `releases' the frame from memory.</p>
<p>There are several advantages to using frames:</p>
<ul>
<li>
<p>Single-check when loading tables.</p>
</li>
<li>
<p><em>Making code clearer</em> by providing simple parsing functions
<em>while keeping code safe</em> from file over-runs and invalid
offsets.</p>
</li>
</ul>
<hr>
<h2>
II. Accessing and reading a frame with macros
</h2>
<p>By convention in the FreeType source code, macros are able to use two
implicit variables named <var>error</var> and <var>stream</var>. This is
useful because these two variables are extremely often used in the
library, and doing this only reduces our typing requirements and make the
source code much clearer.</p>
<p>Note that <var>error</var> must be a local variable of type
<code>FT_Error</code>, while <var>stream</var> must be a local variable or
argument of type <code>FT_Stream</code>.</p>
<p>The macro used to access a frame is <font
color="purple"><code><b>ACCESS_Frame(_size_)</b></code></font>, it will
translate to</p>
<font color="blue">
<pre>
( error = FT_Access_Frame( stream, _size_ ) )
!= FT_Err_Ok</pre>
</font>
<p>Similarly, the macro <font
color="purple"><b><code>FORGET_Frame()</code></b></font> translates to</p>
<font color="blue">
<pre>
FT_Forget_Frame( stream )</pre>
</font>
<p>Extracting integers can be performed with the <code>GET_xxx()</code>
macros, like</p>
<table align=center
cellpadding=5>
<tr valign="top">
<th>
Macro name
</th>
<th>
Translation
</th>
<th>
Description
</th>
</tr>
<tr valign="top">
<td>
<font color="purple"><code><b>GET_Byte()</b></code></font>
</td>
<td>
<font color="blue"><code>FT_Get_Byte(stream)</code></font>
</td>
<td>
<p>Reads an 8-bit unsigned byte.</p>
</td>
</tr>
<tr valign="top">
<td>
<font color="purple"><code><b>GET_Char()</b></code></font>
</td>
<td>
<font color="blue"><code>(FT_Char)<br>
FT_Get_Byte(stream)</code></font>
</td>
<td>
<p>Reads an 8-bit <em>signed</em> byte.</p>
</td>
</tr>
<tr valign="top">
<td>
<font color="purple"><code><b>GET_Short()</b></code></font>
</td>
<td>
<font color="blue"><code>FT_Get_Short(stream)</code></font>
</td>
<td>
Reads a 16-bit signed big-endian integer.
</td>
</tr>
<tr valign="top">
<td>
<font color="purple"><code><b>GET_UShort()</b></code></font>
</td>
<td>
<font color="blue"><code>(FT_UShort)<br>
FT_Get_Short(stream)</code></font>
</td>
<td>
Reads a 16-bit unsigned big-endian integer.
</td>
</tr>
<tr valign="top">
<td>
<font color="purple"><code><b>GET_Offset()</b></code></font>
</td>
<td>
<font color="blue"><code>FT_Get_Offset(stream)</code></font>
</td>
<td>
Reads a 24-bit signed big-endian integer.
</td>
</tr>
<tr valign="top">
<td>
<font color="purple"><code><b>GET_UOffset()</b></code></font>
</td>
<td>
<font color="blue"><code>(FT_UOffset)<br>
FT_Get_Offset(stream)</code></font>
</td>
<td>
Reads a 24-bit unsigned big-endian integer.
</td>
</tr>
<tr valign="top">
<td>
<font color="purple"><code><b>GET_Long()</b></code></font>
</td>
<td>
<font color="blue"><code>FT_Get_Long(stream)</code></font>
</td>
<td>
Reads a 32-bit signed big-endian integer.
</td>
</tr>
<tr valign="top">
<td>
<font color="purple"><code><b>GET_ULong()</b></code></font>
</td>
<td>
<font color="blue"><code>(FT_ULong)<br>
FT_Get_Long(stream)</code></font>
</td>
<td>
Reads a 32-bit unsigned big-endian integer.
</td>
</tr>
</table>
<p>(Note that an <b>Offset</b> is an integer stored with 3&nbsp;bytes on
the file.)</p>
<p>All this means that the following code</p>
<font color="blue">
<pre>
error = FT_Access_Frame( stream, 2 + 4 + 4 );
if ( error ) goto ...
str.value1 = FT_Get_Short( stream );
str.value2 = FT_Get_ULong( stream );
str.value3 = FT_Get_ULong( stream );
FT_Forget_Frame( stream );</pre>
</font>
<p>can be simplified with macros:</p>
<font color="blue">
<pre>
if ( ACCESS_Frame( 2 +4 + 4 ) ) goto ...
str.value1 = GET_Short();
str.value2 = GET_ULong();
str.value3 = GET_ULong();
FORGET_Frame();</pre>
</font>
<p>Which is clearer. Notice that <var>error</var> and <var>stream</var>
must be defined locally though for this code to work!</p>
<hr>
<h2>
III. Alternatives
</h2>
<p>It is sometimes useful to read small integers from a font file without
using a frame. Some functions have been introduced in FreeType&nbsp;2 to
do just that, and they are of the form <font
color="blue"><code>FT_Read_xxxx</code></font>.</p>
<p>For example, <font color="blue"><code>FT_Read_Short(stream,
&error)</code></font> reads and returns a 2-byte big-endian integer from a
<var>stream</var>, and places an error code in the <var>error</var>
variable.</p>
<p>Thus, reading a single big-endian integer is shorter than using a frame
for it.</p>
<p>Note that there are also macros <font
color="purple"><code>READ_xxx()</code></font> which translate to</p>
<font color="blue">
<pre>
FT_Read_xxx( stream, &error ), error != FT_Err_Ok</pre>
</font>
<p>and can be used as in</p>
<font color="blue">
<pre>
if ( READ_UShort( variable1 ) ||
READ_ULong ( variable2 ) )
goto Fail;</pre>
</font>
<p>if <var>error</var> and <var>stream</var> are already defined
locally.</p>
</td></tr>
</table>
</center>
</body>
</html>
<!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>
&copy; 2000 David Turner (<a href="fichier :///david@freetype.org">david@freetype.org</a>)<br>
&copy; 2000 The FreeType Development Team (<a href="fichier :///devel@freetype.org">devel@freetype.org</a>)</h3></center>
<p><br>
<hr WIDTH="100%">
<br>&nbsp;
<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/&lt;system&gt;</tt>" where <tt>&lt;system&gt;</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>
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment