2000-10-31 08:36:53 +01:00
|
|
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en"
|
|
|
|
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
2000-10-26 01:42:02 +02:00
|
|
|
<html>
|
2000-10-31 08:36:53 +01:00
|
|
|
<head>
|
|
|
|
<meta http-equiv="Content-Type"
|
|
|
|
content="text/html; charset=iso-8859-1">
|
|
|
|
<meta name="Author"
|
|
|
|
content="David Turner">
|
|
|
|
<title>The Design of FreeType 2 - Internal Objects</title>
|
2000-10-26 01:42:02 +02:00
|
|
|
</head>
|
2000-10-31 08:36:53 +01:00
|
|
|
|
|
|
|
<body text="#000000"
|
|
|
|
bgcolor="#ffffff">
|
|
|
|
|
|
|
|
<h1 align=center>
|
|
|
|
The Design of FreeType 2
|
|
|
|
</h1>
|
|
|
|
|
|
|
|
<center>
|
|
|
|
<table width="75%">
|
|
|
|
<tr><td>
|
|
|
|
|
|
|
|
<table width="100%">
|
|
|
|
<tr bgcolor="#ccccee"><td>
|
|
|
|
<h1>
|
|
|
|
III. Internal Objects and Classes
|
|
|
|
</h1>
|
|
|
|
</td></tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<p>Let us have a look now at the <em>internal</em> objects that
|
|
|
|
FreeType 2 uses, i.e., those not directly available to client
|
|
|
|
applications, and see how they fit into the picture.</p>
|
|
|
|
|
|
|
|
<h2>
|
|
|
|
1. Memory management
|
|
|
|
</h2>
|
|
|
|
|
|
|
|
<p>All memory management operations are performed through three specific
|
|
|
|
routines of the base layer, namely: <tt>FT_Alloc()</tt>,
|
|
|
|
<tt>FT_Realloc()</tt>, and <tt>FT_Free()</tt>. Each one of these
|
|
|
|
functions expects a <tt>FT_Memory</tt> handle as its first
|
|
|
|
parameter.</p>
|
|
|
|
|
|
|
|
<p>The latter is a pointer to a simple object used to describe the
|
|
|
|
current memory pool/manager. It contains a simple table of
|
|
|
|
alloc/realloc/free functions. A memory manager is created at library
|
|
|
|
initialization time by <tt>FT_Init_FreeType()</tt>, calling the function
|
|
|
|
<tt>FT_New_Memory()</tt> provided by the <tt>ftsystem</tt>
|
|
|
|
component.</p>
|
|
|
|
|
|
|
|
<p>By default, this manager uses the ANSI <tt>malloc()</tt>,
|
|
|
|
<tt>realloc()</tt>, and <tt>free()</tt> functions. However, as
|
|
|
|
<tt>ftsystem</tt> is a replaceable part of the base layer, a specific
|
|
|
|
build of the library could provide a different default memory
|
|
|
|
manager.</p>
|
|
|
|
|
|
|
|
<p>Even with a default build, client applications are still able to
|
|
|
|
provide their own memory manager by not calling
|
|
|
|
<tt>FT_Init_FreeType()</tt> but follow these simple steps:</p>
|
|
|
|
|
|
|
|
<ol>
|
|
|
|
<li>
|
|
|
|
<p>Create a new <tt>FT_Memory</tt> object by hand. The definition
|
|
|
|
of <tt>FT_MemoryRec</tt> is located in the public file
|
|
|
|
<tt><freetype/ftsystem.h></tt>.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>Call <tt>FT_New_Library()</tt> to create a new library instance
|
|
|
|
using your custom memory manager. This new library doesn't yet
|
|
|
|
contain any registered modules.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>Register the set of default modules by calling the function
|
|
|
|
<tt>FT_Add_Default_Modules()</tt> provided by the <tt>ftinit</tt>
|
|
|
|
component, or manually register your drivers by repeatedly
|
|
|
|
calling <tt>FT_Add_Module()</tt>.</p>
|
|
|
|
</li>
|
|
|
|
</ol>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
|
|
<h2>
|
|
|
|
2. Input streams
|
|
|
|
</h2>
|
|
|
|
|
|
|
|
<p>Font files are always read through <tt>FT_Stream</tt> objects. The
|
|
|
|
definition of <tt>FT_StreamRec</tt> is located in the public file
|
|
|
|
<tt><freetype/ftsystem.h></tt>, which allows client developers to
|
|
|
|
provide their own implementation of streams if they wish so.</p>
|
|
|
|
|
|
|
|
<p>The function <tt>FT_New_Face()</tt> will always automatically create
|
|
|
|
a new stream object from the C pathname given as its second
|
|
|
|
argument. This is achieved by calling the function
|
|
|
|
<tt>FT_New_Stream()</tt> provided by the <tt>ftsystem</tt> component.
|
|
|
|
As the latter is replaceable, the implementation of streams may vary
|
|
|
|
greatly between platforms.</p>
|
|
|
|
|
|
|
|
<p>As an example, the default implementation of streams is located in
|
|
|
|
the file <tt>src/base/ftsystem.c</tt> and uses the ANSI
|
|
|
|
<tt>fopen()</tt>, <tt>fseek()</tt>, and <tt>fread()</tt> calls.
|
|
|
|
However, the Unix build of FreeType 2 provides an alternative
|
|
|
|
implementation that uses memory-mapped files, when available on the host
|
|
|
|
platform, resulting in a significant access speed-up.</p>
|
|
|
|
|
|
|
|
<p>FreeType distinguishes between memory-based and disk-based streams.
|
|
|
|
In the first case, all data is directly accessed in memory (e.g.
|
|
|
|
ROM-based, write-only static data and memory-mapped files), while in the
|
|
|
|
second, portions of the font files are read in chunks called
|
|
|
|
<em>frames</em>, and temporarily buffered similarly through typical
|
|
|
|
seek/read operations.</p>
|
|
|
|
|
|
|
|
<p>The FreeType stream sub-system also implements extremely efficient
|
|
|
|
algorithms to very quickly load structures from font files while
|
|
|
|
ensuring complete safety in the case of a "broken file".</p>
|
|
|
|
|
|
|
|
<p>The function <tt>FT_New_Memory_Face()</tt> can be used to directly
|
|
|
|
create/open a <tt>FT_Face</tt> object from data that is readily
|
|
|
|
available in memory (including ROM-based fonts).</p>
|
|
|
|
|
|
|
|
<p>Finally, in the case where a custom input stream is needed, client
|
|
|
|
applications can use the function <tt>FT_Open_Face()</tt>, which can
|
|
|
|
accept custom input streams. This may be useful in the case of
|
|
|
|
compressed or remote font files, or even embedded font files that need
|
|
|
|
to be extracted from certain documents.</p>
|
|
|
|
|
|
|
|
<p>Note that each face owns a single stream, which is also destroyed by
|
|
|
|
<tt>FT_Done_Face()</tt>. Generally speaking, it is certainly
|
|
|
|
<em>not</em> a good idea to keep numerous <tt>FT_Face</tt> objects
|
|
|
|
opened.</p>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
|
|
<h2>
|
|
|
|
3. Modules
|
|
|
|
</h2>
|
|
|
|
|
|
|
|
<p>A FreeType 2 module is itself a piece of code. However, the
|
|
|
|
library creates a single <tt>FT_Module</tt> object for each module that
|
|
|
|
is registered when <tt>FT_Add_Module()</tt> is called.</p>
|
|
|
|
|
|
|
|
<p>The definition of <tt>FT_ModuleRec</tt> is not publicly available to
|
|
|
|
client applications. However, each <em>module type</em> is described by
|
|
|
|
a simple public structure named <tt>FT_Module_Class</tt>, defined in
|
|
|
|
<tt><freetype/ftmodule.h></tt>, and is described later in this
|
|
|
|
document:</p>
|
|
|
|
|
|
|
|
<p>You need a pointer to an <tt>FT_Module_Class</tt> structure when
|
|
|
|
calling <tt>FT_Add_Module()</tt>, whose declaration is:</p>
|
|
|
|
|
|
|
|
<font color="blue"><pre>
|
|
|
|
FT_Error FT_Add_Module( FT_Library library,
|
|
|
|
const FT_Module_Class* clazz );</pre>
|
|
|
|
</font>
|
|
|
|
|
|
|
|
<p>Calling this function will do the following:</p>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
<p>It will check whether the library already holds a module object
|
|
|
|
corresponding to the same module name as the one found in
|
|
|
|
<tt>FT_Module_Class</tt>.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>If this is the case, it will compare the module version number to
|
|
|
|
see whether it is possible to <em>upgrade</em> the module to a new
|
|
|
|
version. If the module class's version number is smaller than the
|
|
|
|
already installed one, the function returns immediately. Similarly,
|
|
|
|
it checks that the version of FreeType 2 that is running is
|
|
|
|
correct compared to the one required by the module.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>It creates a new <tt>FT_Module</tt> object, using data and flags
|
|
|
|
of the module class to determine its byte size and how to properly
|
|
|
|
initialize it.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>If a module initializer is present in the module class, it will
|
|
|
|
be called to complete the module object's initialization.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>The new module is added to the library's list of "registered"
|
|
|
|
modules. In case of an upgrade, the previous module object is
|
|
|
|
simply destroyed.</p>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>Note that this function doesn't return an <tt>FT_Module</tt> handle,
|
|
|
|
given that module objects are completely internal to the library (and
|
|
|
|
client applications shouldn't normally mess with them :-)</p>
|
|
|
|
|
|
|
|
<p>Finally, it is important to understand that FreeType 2
|
|
|
|
recognizes and manages several kinds of modules. These will be
|
|
|
|
explained in more details later in this document, but we will list for
|
|
|
|
now the following types:</p>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
<p><em>Renderer</em> modules are used to convert native glyph images
|
|
|
|
to bitmaps/pixmaps. FreeType 2 comes with two renderer modules
|
|
|
|
by default: one to generate monochrome bitmaps, the other to
|
|
|
|
generate high-quality anti-aliased pixmaps.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p><em>Font driver</em> modules are used to support one or more font
|
|
|
|
formats. Typically, each font driver provides a specific
|
|
|
|
implementation/derivative of <tt>FT_Face</tt>, <tt>FT_Size</tt>,
|
|
|
|
<tt>FT_GlyphSlot</tt>, as well as <tt>FT_CharMap</tt>.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p><em>Helper</em> modules are shared by several font drivers. For
|
|
|
|
example, the <tt>sfnt</tt> module parses and manages tables found in
|
|
|
|
SFNT-based font formats; it is then used by both the TrueType and
|
|
|
|
OpenType font drivers.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>Finally, the <em>auto-hinter</em> module has a specific place in
|
|
|
|
the library's design, as its role is to process vectorial glyph
|
|
|
|
outlines, independently of their native font format, to produce
|
|
|
|
optimal results at small pixel sizes.</p>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>Note that every <tt>FT_Face</tt> object is <em>owned</em> by the
|
|
|
|
corresponding font driver, depending on the original font file's format.
|
|
|
|
This means that all face objects are destroyed when a module is
|
|
|
|
removed/unregistered from a library instance (typically by calling the
|
|
|
|
<tt>FT_Remove_Module()</tt> function).</p>
|
|
|
|
|
|
|
|
<p><em>Because of this, you should always take care that no
|
|
|
|
<tt>FT_Face</tt> object is opened when you upgrade or remove a module
|
|
|
|
from a library, as this could cause unexpected object deletion!</em></p>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
|
|
<h2>
|
|
|
|
4. Libraries
|
|
|
|
</h2>
|
|
|
|
|
|
|
|
<p>We now come back to our well-known <tt>FT_Library</tt> object. From
|
|
|
|
what have been said before, we already know that a library instance owns
|
|
|
|
at least the following:</p>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
<p>A memory manager object (<tt>FT_Memory</tt>), used for all
|
|
|
|
allocation/releases within the instance.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>A list of <tt>FT_Module</tt> objects, corresponding to the
|
|
|
|
"installed" or "registered" modules of the instance. This list can
|
|
|
|
be changed at any time through <tt>FT_Add_Module()</tt> and
|
|
|
|
<tt>FT_Remove_Module()</tt>.</p>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<p>Remember that face objects are owner by font drivers that are
|
|
|
|
themselves modules owned by the library.</p>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p>There is however another object owned by the library instance that
|
|
|
|
hasn't been described yet: the <em>raster pool</em>.</p>
|
|
|
|
|
|
|
|
<p>The <em>raster pool</em> is simply a block of memory of fixed size
|
|
|
|
that is used internally as a "scratch area" for various memory-hungry
|
|
|
|
transient operations, avoiding memory allocation. For example, it is
|
|
|
|
used by each renderer when converting a vectorial glyph outline into a
|
|
|
|
bitmap (actually, that's where its name comes from :-).</p>
|
|
|
|
|
|
|
|
<p>The size of the raster pool is fixed at initialisation time (it
|
|
|
|
defaults to 16kByte) and cannot be changed at run-time (though we could
|
|
|
|
fix this if there is a real need for that).</p>
|
|
|
|
|
|
|
|
<p>When a transient operation needs more memory than the pool's size, it
|
|
|
|
can decide to either allocate a heap block as an exceptional condition,
|
|
|
|
or sub-divide recursively the task to perform in order to never exceed
|
|
|
|
the pool's threshold.</p>
|
|
|
|
|
|
|
|
<p>This extremely memory-conservative behaviour is certainly one of the
|
|
|
|
keys to FreeType's performance in certain areas (most importantly in
|
|
|
|
glyph rendering/scanline-conversion).</p>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
|
|
<h2>
|
|
|
|
5. Summary
|
|
|
|
</h2>
|
|
|
|
|
|
|
|
<p>Finally, the following picture illustrates what has been said in this
|
|
|
|
section, as well as the previous, by presenting the complete object
|
|
|
|
graph of FreeType 2's base design:</p>
|
|
|
|
|
|
|
|
<center>
|
|
|
|
<img alt="to be done">
|
|
|
|
</center>
|
|
|
|
|
|
|
|
</td></tr>
|
|
|
|
</table>
|
|
|
|
</center>
|
2000-10-26 01:42:02 +02:00
|
|
|
</body>
|
|
|
|
</html>
|