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..
|
@ -1,910 +0,0 @@
|
|||
<!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 - I/O Frames</title>
|
||||
<basefont face="Georgia, Arial, Helvetica, Geneva">
|
||||
<style content="text/css">
|
||||
P { text-align=justify }
|
||||
H1 { text-align=center }
|
||||
H2 { text-align=center }
|
||||
LI { text-align=justify }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body text="#000000"
|
||||
bgcolor="#FFFFFF"
|
||||
link="#0000EF"
|
||||
vlink="#51188E"
|
||||
alink="#FF0000">
|
||||
|
||||
<center>
|
||||
<h1>FreeType 2.0 Build System</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="mailto:devel@freetype.org">devel@freetype.org</a>)
|
||||
</h3></center>
|
||||
|
||||
<center><table width=650><tr><td>
|
||||
|
||||
<p><hr WIDTH="100%"></p>
|
||||
|
||||
<h2>Table of Content</h2>
|
||||
|
||||
<center><table><tr><td>
|
||||
<p><font size="+1"><a href="#introduction">Introduction</a></font></p>
|
||||
<p><font size="+1"><a href="#features">I. Features & Background</a></font></p>
|
||||
<ul>
|
||||
<li><a href="#features-1">1. Convenience, not Requirement</a>
|
||||
<li><a href="#features-2">2. Compiler and platform independence</a>
|
||||
<li><a href="#features-3">3. Uses GNU Make</a>
|
||||
<li><a href="#features-4">4. Automatic host platform detection</a>
|
||||
<li><a href="#features-5">5. User-selectable builds</a>
|
||||
<li><a href="#features-6">6. Robustness</a>
|
||||
<li><a href="#features-7">7. Simple modules management</a>
|
||||
</ul>
|
||||
<p><font size="+1"><a href="#overview">II. Overview of the build process</a></font></p>
|
||||
<ul>
|
||||
<p><li><a href="#overview-1">1. Build setup</a>
|
||||
<ul>
|
||||
<li><a href="#overview-1-a">a. Default build setup</a>
|
||||
<li><a href="#overview-1-b">b. Selecting another build configuration</a>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<li><a href="#overview-2">2. Library compilation</a>
|
||||
</ul>
|
||||
<p><font size="+1"><a href="#setup">III. Build setup details</a></font></p>
|
||||
<p><font size="+1"><a href="#compilation">IV. Library compilation details</a></font></p>
|
||||
<ul>
|
||||
<li><a href="#compilation-1">a. Compiling the <tt>ftsystem</tt> component</a>
|
||||
<li><a href="#compilation-2">b. Compiling the base layer and optional components</a>
|
||||
<li><a href="#compilation-3">c. Compiling the modules</a>
|
||||
<li><a href="#compilation-4">d. Compiling the <tt>ftinit</tt> component</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</td></tr></table></center>
|
||||
|
||||
<hr><a name="introduction">
|
||||
<h2>Introduction:</h2>
|
||||
|
||||
<p>This document describes the new build system that was introduced
|
||||
with FreeType 2.</p>
|
||||
|
||||
<p><hr></p>
|
||||
<a name="features">
|
||||
<h2>I. Features and Background:</h2>
|
||||
|
||||
<p>The FreeType 2 build system is a set of Makefiles and sub-Makefiles that
|
||||
are used to build the library on a very large variety of systems easily.
|
||||
One of its main features are the following:</p>
|
||||
|
||||
<a name="features-1">
|
||||
<h3>1. Convenience, not Requirement</h3>
|
||||
<ul>
|
||||
<p>Even though the build system is rather sophisticated, it simply is a
|
||||
convenience that was written simply to allow the compilation of the
|
||||
FreeType 2 library on as many platforms as possible, as easily as
|
||||
possible. However, it is not a requirement and the library can be
|
||||
compiled manually or in a graphical IDE without using it, with minimal
|
||||
efforts</p>
|
||||
|
||||
<p>(for more information on this topic, see the <tt>BUILD</tt>
|
||||
document that comes with your release of FreeType, in its <em>Detailed
|
||||
Compilation Guide</em> section).</p>
|
||||
</ul>
|
||||
|
||||
<a name="features-2">
|
||||
<h3>2. Compiler and platform independence</h3>
|
||||
<ul>
|
||||
<p>The FreeType 2 build system can be used with any compiler, on any platform.
|
||||
It is independent of object file suffix, executable file suffix, directory
|
||||
separator convention (i.e. "/" or "\"), and compiler flags for path
|
||||
inclusion, macro definition, output naming, ansi compliance, etc..</p>
|
||||
|
||||
<p>Supporting a new compiler is trivial and only requires writing a minimal
|
||||
configuration sub-makefile that contains several Makefile variables
|
||||
definitions that are later used by the rest of the build system. This is
|
||||
described in details later in the document.</p>
|
||||
</ul>
|
||||
|
||||
<a name="features-3">
|
||||
<h3>3. Uses GNU Make</h3>
|
||||
<ul>
|
||||
<p>The build system works <em>exclusively</em> with <b>GNU Make</b>. Reason
|
||||
is that it is the only make utility that has all the features required to
|
||||
implement the build system as described below. Moreover, it is already
|
||||
ported to hundreds of various distinct platforms and is widely and
|
||||
freely available.</p>
|
||||
|
||||
<p>It also uses the native command line shell. <em>You thus
|
||||
don't need a Unix-like shell on your platform</em>.
|
||||
For example, FreeType 2 already compiles on Unix, Dos, Windows
|
||||
and OS/2 right "out of the box" (assuming you have GNU Make
|
||||
installed).</p>
|
||||
|
||||
<p>Finally, note that the build system is <em>specifically</em> designed
|
||||
for gnu make and will <em>fail</em> with any other make tool. We have
|
||||
<em>no plans</em> to support a different tools, as you'll rapidly
|
||||
understand by reading this document or looking at the sub-makefiles
|
||||
themselves.</p>
|
||||
</ul>
|
||||
|
||||
<a name="features-4">
|
||||
<h3>4. Automatic host platform detection</h3>
|
||||
<ul>
|
||||
<p>When you launch the build system for the first time, by simply invoking
|
||||
GNU make in the top-level directory, it automatically tries to detect
|
||||
your current platform in order to choose the best configuration
|
||||
sub-makefile available. It then displays what it found. If everything
|
||||
is ok, you can then launch compilation of the library, by invoking make
|
||||
a second time.</p>
|
||||
|
||||
<p>The following platforms are currently automatically detected:</p>
|
||||
<ul>
|
||||
<li>Dos (plain-dos, windows in Dos mode, or Dos session under OS/2)
|
||||
<li>Windows 95, 98 + Windows NT (a.k.a win32)
|
||||
<li>OS/2
|
||||
<li>Unix (uses Autoconf/Automake)
|
||||
</ul>
|
||||
|
||||
<p>Note that adding support for a new platform requires writing a minimal
|
||||
number of very small files, and simply putting them in a new sub-directory
|
||||
of <tt>freetype2/config</tt>.</p>
|
||||
</ul>
|
||||
|
||||
<a name="features-5">
|
||||
<h3>5. User-selectable builds</h3>
|
||||
<ul>
|
||||
<p>The platform auto-detection rules try to setup the build for a default
|
||||
compiler (<em>gcc</em> for most platforms), with default build options
|
||||
for the library (which normally is
|
||||
<em>"all features enable, no debugging"</em>), as well as the default
|
||||
list of modules (which is <em>"all modules in <tt>freetype2/src</tt>"</em>)</p>
|
||||
|
||||
<p>There are cases where it is important to specify a different compiler,
|
||||
different build options or simply a different module list. The FreeType 2
|
||||
build system is designed in such a way that all of this is easily possible
|
||||
from the command line, <em>without having to touch a single file</em>.
|
||||
The latter is crucial when dealing with projects that need specific
|
||||
builds of the library without modifying a single file from the FreeType
|
||||
distribution.</p>
|
||||
|
||||
<p>The exact mechanism and implementation to do this is described later in
|
||||
this document. It allows, for example, to compile FreeType with any of
|
||||
the following compilers on Win32: gcc, Visual C++, Win32-LCC.</p>
|
||||
</ul>
|
||||
|
||||
<a name="features-6">
|
||||
<h3>6. Robustness</h3>
|
||||
<ul>
|
||||
<p>The build system uses a single top-level Makefile that includes
|
||||
one or more sub-makefiles to build the entire library (base layer
|
||||
plus all modules).
|
||||
|
||||
<font color="red">
|
||||
To understand why this is important, we <em>strongly</em> recommend
|
||||
the following article to all of our readers:</font></p>
|
||||
<p>
|
||||
<center>
|
||||
<font size="+2"><a href="http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html">
|
||||
Recursive Make Considered Dangerous
|
||||
</a>
|
||||
</font>
|
||||
</center>
|
||||
</p>
|
||||
|
||||
<p>As an example, here's a short list of files that make up the
|
||||
build system. Note that each sub-makefile contains rules corresponding
|
||||
to a very specific purpose, and that they all use the "<tt>.mk</tt>"
|
||||
suffix:</p>
|
||||
<ul>
|
||||
<li><tt>freetype2/Makefile</tt>
|
||||
<li><tt>freetype2/config/detect.mk</tt>
|
||||
<li><tt>freetype2/config/freetype.mk</tt>
|
||||
<li><tt>freetype2/config/<em><system></em>/detect.mk</tt>
|
||||
<li><tt>freetype2/src/<em><module></em>/rules.mk</tt>
|
||||
<li><tt>freetype2/src/<em><module></em>/module.mk</tt>
|
||||
</ul>
|
||||
|
||||
</ul>
|
||||
|
||||
<a name="features-7">
|
||||
<h3>7. Simple Module Management</h3>
|
||||
<ul>
|
||||
<p>FreeType 2 has a very modular design, and is made of a core
|
||||
<em>base layer</em> that provides its high-level API as well as
|
||||
generic services used by one or more <em>modules</em>.
|
||||
|
||||
Most modules are used to support a specific font format (like TrueType
|
||||
or Type 1), and they are called <em>font drivers</em>. However, some of
|
||||
them do not support font files directly, but rather provide helper
|
||||
services to the font drivers.</p>
|
||||
|
||||
<p>FreeType 2 is designed so that adding modules at run-time is possible
|
||||
and easy. Similarly, we expect many more modules to come in the near
|
||||
future and wanted a build system that makes such additions to the
|
||||
source package itself dead easy.
|
||||
|
||||
Indeed, all source code (base + modules) is located in the
|
||||
<tt>freetype2/src</tt> directory hierarchy. And the build system is
|
||||
capable of re-generating automatically the list of known modules
|
||||
from the contents of this directory. Hence, adding a new font driver
|
||||
to the FreeType sources simply requires to:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>Add a new sub-directory to <tt>freetype2/src</tt>
|
||||
<li><p>Re-launch the build system</p>
|
||||
</ul>
|
||||
|
||||
<p>There is thus no need to edit a source file</p>
|
||||
</ul>
|
||||
|
||||
<p><hr><p>
|
||||
<a name="overview">
|
||||
<h2>II. Overview of the build process(es):</h2>
|
||||
|
||||
<p>Before describing in details how the build system works, it is essential
|
||||
to give a few examples of how it's used. This section presents
|
||||
what's the build process is to the typical developer:</p>
|
||||
|
||||
<p>Compiling the library is normally done in two steps: the first one
|
||||
configures the build according to the current platform and possible
|
||||
additional parameters, while the second simply compiles the library with
|
||||
the information gathered in the configuration step.</p>
|
||||
|
||||
<a name="overview-1">
|
||||
<h3>1. Build Setup</h3>
|
||||
|
||||
<a name="overview-1-a">
|
||||
<h4>a. Default build setup</h4>
|
||||
<ul>
|
||||
<p>To configure the build, simply invoke gnu make from the top-level FreeType
|
||||
directory. This will launch a series of rules that will detect your current
|
||||
host platform, and choose a configuration file for you. It will then display
|
||||
what it found. For example, here's the output of typing the command "make"
|
||||
on a win32 platform (assuming this calls GNU make):</p>
|
||||
|
||||
<pre><font color="blue">
|
||||
<font color="purple">C:\FreeType> make</font>
|
||||
|
||||
FreeType build system -- automatic system detection
|
||||
|
||||
The following settings are used:
|
||||
|
||||
platform win32
|
||||
compiler gcc
|
||||
configuration directory ./config/win32
|
||||
configuration rules ./config/win32/w32-gcc.mk
|
||||
|
||||
If this does not correspond to your system or settings please remove the file
|
||||
'config.mk' from this directory then read the INSTALL file for help.
|
||||
|
||||
Otherwise, simply type 'make' again to build the library.
|
||||
|
||||
<font color="purple">C:\FreeType></font>
|
||||
</font></pre>
|
||||
|
||||
<p>Note that this step copies the selected configuration file (here
|
||||
<tt>./config/win32/w32-gcc.mk</tt>) to <em>the current directory</em>, under
|
||||
the name <tt><b>config.mk</b></tt>. This file contains data that is used
|
||||
to drive the library compilation of the second step. It correspond to
|
||||
the platform and compiler selected by the auto-detection phase.</p>
|
||||
|
||||
<p>Note that you can re-generate the <tt><b>config.mk</b></tt> file anytime
|
||||
by invoking <tt>make setup</tt> whenever you need it, even when the file is
|
||||
already present in the current directory.</p>
|
||||
|
||||
<p>Finally, if your platform is not correctly detected, the build system will
|
||||
display and use configuration information for the virtual "ansi" platform.
|
||||
</p>
|
||||
</ul>
|
||||
<a name="overview-1-b">
|
||||
<h4>b. Selecting another build configuration</h4>
|
||||
<ul>
|
||||
<p>You may not be really satisfied by the configuration file selected by the
|
||||
auto-detection routines. Typically, you might be using a compiler that is
|
||||
not the default one for your platform. It is however possible to re-launch
|
||||
the build setup phase with an additional argument, used to specify a
|
||||
different compiler/config file. For example, you can type the following
|
||||
commands on Win32 systems:</p>
|
||||
|
||||
<p align=center><table width="80%" cellpadding=10><tr valign=top><td>
|
||||
<p><b><tt>make setup</tt></b></p>
|
||||
</td><td>
|
||||
<p>re-run the platform detection phase, and select the default compiler for it.
|
||||
On Win32, this is <em>gcc</em>.</p>
|
||||
</td></tr><tr valign=top><td>
|
||||
<p><b><tt>make setup visualc</tt></b></p>
|
||||
</td><td>
|
||||
<p>re-run the platform detection phase, and select a config file that
|
||||
corresponds to the <em>Visual C++</em> compiler</p>
|
||||
</td></tr><tr valign=top><td>
|
||||
<p><b><tt>make setup lcc</tt></b></p>
|
||||
</td><td>
|
||||
<p>re-run the platform detection phase, and select a config file that
|
||||
corresponds to the <em>Win32-LCC</em> compiler</p>
|
||||
</td></tr></table>
|
||||
</p>
|
||||
|
||||
<p>Note that a specific configuration is selected with a command that
|
||||
looks like : <tt><b>make setup <em>compiler</em></b></tt>,
|
||||
where the <em><tt>compiler</tt></em> keywords depends on the platform.
|
||||
Moreover, each one of them corresponds to a specific configuration
|
||||
sub-makefile that is copied as <b><tt>config.mk</tt></b> in the current
|
||||
directory.</p>
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="overview-2">
|
||||
<h3>2. Library compilation</h3>
|
||||
|
||||
<p>Once you're satisfied with the version of <b><tt>config.mk</tt></b> that
|
||||
has been copied to your current directory, you can simply re-invoke
|
||||
gnu make <em>with no arguments</em>. The top-level Makefile will
|
||||
automatically detect the config sub-makefile in the current directory,
|
||||
and use it to drive the library compilation. The latter can be seen
|
||||
as a series of different steps decribed here:</p>
|
||||
|
||||
<ul>
|
||||
<li><p><b>Compiling the <tt>ftsystem</tt> component</b><br><ul>
|
||||
It encapsulates all low-level operations (memory management +
|
||||
i/o access) for the library. Its default version, located in
|
||||
<tt>./src/base/ftsystem.c</tt> uses the ANSI C library but
|
||||
system-specific implementations are also available to
|
||||
improve performance (e.g. memory-mapped files on Unix).
|
||||
</ul></p>
|
||||
|
||||
<li><p><b>Compiling the <em>base layer</em> and optional components</b><br><ul>
|
||||
They provide the library's high-level API as well as various useful
|
||||
routines for client applications. Many features of the base layer can
|
||||
be activated or not depending on a configuration file named
|
||||
<tt>ftoption.h</tt>
|
||||
</ul></p>
|
||||
|
||||
<li><p><b>Compiling the <em>modules</em></b><br><ul>
|
||||
Each module is used to support a specific font format (it is then
|
||||
called a <em>font driver</em>), or to provide helper services to
|
||||
the drivers (e.g. the auto-hinter). They are all located in
|
||||
sub-directories of <tt>./src</tt>, like <tt>./src/truetype</tt>,
|
||||
<tt>./src/type1</tt>.
|
||||
</ul></p>
|
||||
|
||||
<li><p><b>Compiling the <tt>ftinit</tt> component</b><br><ul>
|
||||
This one is in charge of implementing <tt>FT_Init_FreeType</tt>,
|
||||
the library initialisation routine. It also selects what modules
|
||||
are activated when a new library instance is created.
|
||||
</ul></p>
|
||||
</ul>
|
||||
<p><hr><p>
|
||||
<a name="setup">
|
||||
<h2>II. Details of the build setup.</h2>
|
||||
|
||||
<p>When the top-level <tt>Makefile</tt> is invoked, it looks for a
|
||||
file named <b><tt>config.mk</tt></b> in the <em>current directory</em>.
|
||||
If this file is found, it is used directly to build the library
|
||||
(skip to <a href="library">Section III</a> for details then).</p>
|
||||
|
||||
<p>Otherwise, the file <b><tt>./config/detect.mk</tt></b> is included
|
||||
by the top-level <tt>Makefile</tt> and parsed. Its purpose is to drive the
|
||||
platform-detection phase, by:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>Defining the <tt>PLATFORM</tt> variable, which indicates
|
||||
what the currently detected platform is. It is initially
|
||||
set to the default value "<tt><b>ansi</b></tt>".
|
||||
</p>
|
||||
|
||||
<li><p>Searching for a <tt>detect.mk</tt> file in <em>all
|
||||
subdirectories</em> of <b><tt>./config</tt></b>.
|
||||
Each such file is included and parsed. Each of these files must
|
||||
try to detect if the host platform is a system it knows
|
||||
about. If so, it changes the value of the <tt>PLATFORM</tt> variable
|
||||
accordingly.</p>
|
||||
|
||||
<li><p>Copying the selected configuration submakefile to the current directory
|
||||
under the name <tt><b>config.mk</b></tt>.</p>
|
||||
</ul>
|
||||
<p>This is illustrated by the following graphics :</p>
|
||||
<p><center>
|
||||
<img src="platform-detection.png" border=0>
|
||||
</center></p>
|
||||
|
||||
<p>Each system-specific <b><tt>detect.mk</tt></b> works as follows:</p>
|
||||
<ul>
|
||||
<li><p>It checks that the value of <tt>PLATFORM</tt> is currently set
|
||||
to <b>ansi</b>, which indicates that no platform was detected
|
||||
for now. If this isn't true, it doesn't do anything</p>
|
||||
|
||||
<li><p>Otherwise, it runs a series of test to see wether it is on a
|
||||
system it knows about. Here are a few examples of tests:</p>
|
||||
|
||||
<p><center><table width="80%" cellpadding=5><tr valign=top><td>
|
||||
<em><b>Unix</b></em>
|
||||
</td><td>
|
||||
<p>checks for a file named <tt>/sbin/init</tt>, and runs, when it found
|
||||
it, a 'configure' script to generate the relevant config sub-makefile</p>
|
||||
</td></tr><tr valign=top><td>
|
||||
<em><b>Dos</b></em>
|
||||
</td><td>
|
||||
<p>checks for the <tt>COMSPEC</tt> environment variable, then tries to
|
||||
run the "<tt>ver</tt>" command on the current shell to check that there
|
||||
is a "Dos" substring in its output; if not, it tries to find the
|
||||
substring "<tt>MDOS\COMMAND</tt>" in <tt>COMSPEC</tt>, which indicates
|
||||
a Dos session under OS/2.</p>
|
||||
</td></tr><tr valign=top><td>
|
||||
<em><b>Win32</b></em>
|
||||
</td><td>
|
||||
<p>if the environment variable <tt>OS</tt> is defined and has the value
|
||||
<tt>Windows_NT</tt>, or if <tt>COMSPEC</tt> is defined and the
|
||||
"<tt>ver</tt>" returns a string that contains <tt>Windows</tt> in it,
|
||||
we're on a Win32 system.</p>
|
||||
</td></tr></table></center>
|
||||
</p>
|
||||
|
||||
<li><p>It sets the value of <tt>PLATFORM</tt> to a new value corresponding
|
||||
to its platform.</p>
|
||||
|
||||
<li><p>It then tries to select a configuration
|
||||
sub-makefile, depending on the current platform and any optional
|
||||
make target (like "visualc" or "devel", etc..). Note that it can
|
||||
even generate the file, as on Unix through Autoconf/Automake.</p>
|
||||
|
||||
<li><p>It copies the selected configuration sub-makefile to the current
|
||||
directory, under the name <tt><b>config.mk</b></tt>
|
||||
</ul>
|
||||
|
||||
<p>If one wants to support a new platform in the build system, it simply needs
|
||||
to provide:</p>
|
||||
|
||||
<ul>
|
||||
<li>A new subdirectory, in <tt>./config</tt>, with a file named
|
||||
<tt>detect.mk</tt> in it, containing relevant checks for the system.
|
||||
|
||||
<li>One or more configuration sub-makefiles that will get copied to
|
||||
<tt>config.mk</tt> at build setup time. You can use the one in
|
||||
<tt>./config/ansi/config.mk</tt> as a template.
|
||||
</ul>
|
||||
|
||||
<p>Similary, supporting a new compiler on an existing system simply means:</p>
|
||||
<ul>
|
||||
<li>Writing a new config sub-makefile that contains definitions used to
|
||||
specify the compiler and flags for the build.
|
||||
|
||||
<li>Change your <tt>./config/<em>system</em>/detect.mk</tt> to recognize
|
||||
a new optional build target that will copy your new config sub-makefile
|
||||
instead of the default one.
|
||||
</ul>
|
||||
|
||||
|
||||
<p><hr><p>
|
||||
<h2>III. Details of the library compilation.</h2>
|
||||
|
||||
<p>When the top-level Makefile is invoked, it looks for a file named
|
||||
<tt>config.mk</tt> in the current directory. If one is found, it
|
||||
defines the <tt>BUILD_FREETYPE</tt> variable, then includes and parses it.
|
||||
The structure of this file is the following:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><p>First, it defines a series of Make variables that describe
|
||||
the host environment, like the compiler, compilation flags,
|
||||
object file suffix, the directory where all object files are
|
||||
placed, etc..</p>
|
||||
|
||||
<li><p>If <tt>BUILD_FREETYPE</tt> is defined, it includes the file
|
||||
<tt><b>./config/freetype.mk</b></tt>, which is in charge of
|
||||
defining all the rules used to build the library object files.
|
||||
(The test is useful to use the <tt>config.mk</tt> file to
|
||||
compile other projects that rely on FreeType 2, like its
|
||||
demonstration programs).</p>
|
||||
|
||||
<li><p>Finally, it defines the rule(s) used to link FreeType 2 object files
|
||||
into a library file (e.g. <tt>libfreetype.a</tt>, <tt>freetype.lib</tt>,
|
||||
<tt>freetype.dll</tt>, ...). Unfortunately, the command line interface of link tools is
|
||||
a <em>lot less</em> standardized than those of compilers, which
|
||||
explains why this rule must be defined in the system-specific
|
||||
<tt>config.mk</tt>.</p>
|
||||
</ul>
|
||||
|
||||
<p>The following is an explanation of what <tt><b>./config/freetype.mk</b></tt>
|
||||
does to build the library objects:
|
||||
</p>
|
||||
|
||||
<h4>a. Include paths</h4>
|
||||
<ul>
|
||||
<p>To avoid namespace pollution, the <tt><em>freetype</em></tt> directory prefix
|
||||
is used to include all public header files of the library. This means
|
||||
that a client application will typically use lines like:</p>
|
||||
|
||||
<pre><font color="blue">
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/ftglyph.h>
|
||||
</font></pre>
|
||||
|
||||
<p>to include one the FreeType 2 public header files. <tt>freetype.mk</tt>
|
||||
uses a variable named <tt><b>INCLUDES</b></tt> to hold the inclusion
|
||||
paths list, and thus starts by adding <tt>./include</tt> to it. However,
|
||||
nothing prevents
|
||||
|
||||
<p><tt>freetype.mk</tt> uses a variable named <tt><b>INCLUDES</b></tt>
|
||||
to hold directory inclusion-path to be used when compiling the library.
|
||||
It always add <tt>./include</tt> to this variable, which means
|
||||
|
||||
</ul>
|
||||
|
||||
<h4>b. Configuration header files:</h4>
|
||||
<ul>
|
||||
<p>Three header files used to configure the compilation of the
|
||||
FreeType 2 library. Their default versions are all located in the
|
||||
directory <tt><b>./include/freetype/config/</b></tt>, even though
|
||||
project specific versions can be provided on a given build, as
|
||||
described later:</p>
|
||||
|
||||
<ul>
|
||||
<p><b><tt>#include <freetype/config/ftoption.h></tt></b><br><ul>
|
||||
This file contains a set of configuration macro definitions that
|
||||
can be toggled to activate or deactivate certain features of the
|
||||
library. By changing one of these definitions, it is possible to
|
||||
compile <em>only the features that are needed</em> for a specific
|
||||
project. Note that by default, all options are enabled.
|
||||
<br><br>
|
||||
You might need to provide an alternative version of <tt>ftoption.h</tt>
|
||||
for one of your own projects.
|
||||
</ul></p>
|
||||
|
||||
<p><b><tt>#include <freetype/config/ftconfig.h></tt></b><br><ul>
|
||||
This file includes <tt>ftoption.h</tt> but also contains some automatic
|
||||
macro definitions used to indicate some important system-specific
|
||||
features (e.g: word size in bytes, DLL export prefix macros, etc..).
|
||||
<br><br>
|
||||
You shouldn't normally need to change or provide an alternative
|
||||
version of this file.
|
||||
</ul></p>
|
||||
|
||||
|
||||
<p><b><tt>#include <freetype/config/ftmodule.h></tt></b><br><ul>
|
||||
This file is very special, as it is normally machine-generated, and
|
||||
used by the <tt>ftinit</tt> component that is described below. To
|
||||
understand it, one must reminds that FreeType 2 has an extremely
|
||||
modular design and that it's possible to change, <em>at run-time</em>,
|
||||
the modules it's using. The <tt>ftmodule.h</tt> file simply contains
|
||||
the list of modules that are registered with each new instance of
|
||||
the library.
|
||||
<br><br>
|
||||
Note that the file can be re-generated automatically by invoking
|
||||
<tt>make setup</tt> from the top-level directory. The re-generated
|
||||
list contains all the modules that were found in subdirectories of
|
||||
<tt>./src</tt>.
|
||||
</ul></p>
|
||||
</ul>
|
||||
|
||||
<p>Note that we strongly advise you to avoid modifying the config files
|
||||
within the FreeType 2 source directory hierarchy. Rather, it's possible
|
||||
to specify alternative versions through the help of a build-specific
|
||||
include path that is include before <tt>./include</tt> in the inclusion
|
||||
path.</p>
|
||||
|
||||
<p>For example, imagine that your platform, named <em>foo</em>, needs a
|
||||
specific version of <tt>ftoption.h</tt>
|
||||
</ul>
|
||||
|
||||
<h4>a. Compiling the <b><tt>ftsystem</tt></b> component:</h4>
|
||||
<ul>
|
||||
<p>FreeType 2 encapsulates all low-level operations (i.e. memory management
|
||||
and i/o access) within a single component called <tt><b>ftsystem</b></tt>.
|
||||
Its default implementation uses the <em>ANSI C Library</em> and is located
|
||||
in <tt>./src/base/ftsystem.c</tt>.</p>
|
||||
|
||||
<p>However, some alternate, system-specific, implementations of
|
||||
<tt>ftsystem</tt> are provided with the library in order to support more
|
||||
efficient and advanced features. As an example, the file
|
||||
<tt>./config/unix/ftsystem.c</tt> is an implementation that
|
||||
uses memory-mapped files rather than the slow ANSI <tt>fopen</tt>,
|
||||
<tt>fread</tt> and <tt>fseek</tt>, boosting performance significantly.</p>
|
||||
|
||||
<p>The build system is thus capable of managing alternate implementations
|
||||
of <tt>ftsystem</tt></p>
|
||||
</ul>
|
||||
|
||||
<h4>b. Compiling the base layer and optional components:</h4>
|
||||
<ul>
|
||||
<p>The high-level API of the library is provided by a component called the
|
||||
<em>base layer</em>, whose source is located in <tt>./src/base</tt>. This
|
||||
directory also contains one or more components that are optional, i.e.
|
||||
that are not required by the library but provide valuable routines to
|
||||
client applications.</p>
|
||||
|
||||
<p>The features of the base library and other components are selected through
|
||||
a single configuration file named
|
||||
<tt><b>./include/freetype/config/ftoption.h</b></tt>. It contains a list
|
||||
of commented configuration macro definitions, that can be toggled to
|
||||
activate or de-activate a certain feature or component at build time.</p>
|
||||
|
||||
<p>For example, the code in <tt>./src/base/ftdebug.c</tt> will be compiled
|
||||
only if one of these two macros are defined in <tt>ftoption.h</tt>:
|
||||
<tt>FT_DEBUG_LEVEL_ERROR</tt> or <tt>FT_DEBUG_LEVEL_TRACE</tt></p>
|
||||
</ul>
|
||||
|
||||
<h4>c. Compiling the modules:</h4>
|
||||
<ul>
|
||||
<p>Once the base layer is completed, the build system starts to compile each
|
||||
additional module independently. These are simply defined as all source
|
||||
code located in a sub-directory of <tt>./src</tt> that contains a file
|
||||
named <tt><b>rules.</b></tt>, for example:
|
||||
<tt>src/sfnt</tt>, <tt>src/truetype</tt>, <tt>src/type1</tt>, ...</p>
|
||||
|
||||
<p>The <tt><b>rules.</b></tt> file simply contains directives used by the
|
||||
build system to compile the corresponding module into a single object
|
||||
file.</p>
|
||||
</ul>
|
||||
|
||||
<h4>d. Compiling the <b><tt>ftinit</tt></b> component:</h4>
|
||||
<ul>
|
||||
<p>The file <tt><b>./src/base/ftinit.c</b></tt> is special because it is used
|
||||
to implement the library initialisation function <tt>FT_Init_FreeType</tt>.
|
||||
</p>
|
||||
</ul>
|
||||
|
||||
<p>Typically, you will end up with all object files, as well as the
|
||||
corresponding library file, residing in the <tt>freetype2/obj</tt>
|
||||
directory.</p>
|
||||
|
||||
|
||||
<h3>1. Purpose of the configuration sub-makefile</h3>
|
||||
|
||||
<h3>2. Managing module dependencies</h3>
|
||||
|
||||
<h3>3. </h3>
|
||||
|
||||
<p><hr><p>
|
||||
<a name="modules">
|
||||
<h2>IV. Managing the modules list</h2>
|
||||
|
||||
<p><hr><p>
|
||||
The build system features some important points, which are all detailed
|
||||
in the following sections:<p>
|
||||
<ul>
|
||||
<li><b>Automatic host platform detection</b><br>
|
||||
The first time the top <tt>Makefile</tt> is invoked, it will
|
||||
run a series of rules to detect your platform. It will then
|
||||
create a system-specific configuration sub-Makefile in the
|
||||
current directory, called <b><tt>config.mk</tt></b>. You can now
|
||||
invoke the top <tt>Makefile</tt> a second time to compile the
|
||||
library directly.
|
||||
<p>
|
||||
The configuration sub-makefile can be regenerated any time
|
||||
by invoking "<tt>make setup</tt>", which will re-run the
|
||||
detection rules even if a <tt>config.mk</tt> is already present.
|
||||
<p>
|
||||
|
||||
|
||||
<li><b>User-selectable builds</b><br>
|
||||
<p>
|
||||
|
||||
|
||||
|
||||
<li><b>Automatic detection of font drivers</b><br>
|
||||
FreeType is made of a "base" layer that invokes several
|
||||
separately-compiled modules. Each module is a given
|
||||
font driver, in charge of supporting a given font format.
|
||||
<p>
|
||||
The list of font drivers is located in the file
|
||||
"<tt>freetype2/config/<em>system</em>/ftmodule.h</tt>", however
|
||||
it can be regenerated on-demand. Adding a new module to the
|
||||
FreeType source tree is thus as easy as:<p>
|
||||
<ul>
|
||||
<li>create a new directory in "<tt>freetype2/src</tt>" and
|
||||
put the new driver's source code and sub-makefiles there.
|
||||
<p>
|
||||
|
||||
<li>invoke the top <tt>Makefile</tt> with target
|
||||
"<tt>modules</tt>" (as in "<tt>make modules</tt>"),
|
||||
as this will automatically regenerate the list of
|
||||
available drivers by detecting the new directory and
|
||||
its content.
|
||||
</ul>
|
||||
<p>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<p><hr><p>
|
||||
|
||||
<h2>II. Host Platform Detection</h2>
|
||||
<ul>
|
||||
When the top-level <tt>Makefile</tt> is invoked, it looks for a
|
||||
file named <tt>config.mk</tt> in the current directory. If this
|
||||
file is found, it is used to build the library
|
||||
(see <a href="library">Section III</a>).
|
||||
<p>
|
||||
Otherwise, the file <tt>freetype2/config/detect.mk</tt> is included
|
||||
and parsed. Its purpose is to:<p>
|
||||
<ul>
|
||||
<li>Define the <tt>PLATFORM</tt> variable, which indicates
|
||||
what is the currently detected platform. It is initially
|
||||
set to the default value "<tt>ansi</tt>".
|
||||
<p>
|
||||
|
||||
<li>It searches for a <tt>detect.mk</tt> file in all
|
||||
subdirectories of <tt>freetype2/config</tt>. Each such
|
||||
file is included and parsed. Each of these files must
|
||||
try to detect if the host platform is a system it knows
|
||||
about. If so, it changes the value of the <tt>PLATFORM</tt>
|
||||
accordingly.
|
||||
</ul>
|
||||
<p>
|
||||
This is illustrated by the following graphics :<p>
|
||||
<center>
|
||||
<img src="platform-detection.png" border=0>
|
||||
</center>
|
||||
<p>
|
||||
Note that each system-specific <tt>detect.mk</tt> is in charge
|
||||
of copying a valid configuration makefile to the current directory
|
||||
(i.e. the one where <tt>make</tt> was invoked), depending on the
|
||||
current targets. For example, the Win32 <tt>detect.mk</tt> will
|
||||
be able to detect a "<tt>visualc</tt>" or "<tt>lcc</tt>" target,
|
||||
as described in section I. Similarly, the OS/2 <tt>detect.mk</tt>
|
||||
can detect targets like "<tt>borlandc</tt>", "<tt>watcom</tt>"
|
||||
or "<tt>visualage</tt>", etc..
|
||||
</ul>
|
||||
|
||||
<p><hr><p>
|
||||
|
||||
<h2>III. Building the library</h2>
|
||||
<ul>
|
||||
When the top-level <tt>Makefile</tt> is invoked and that it finds
|
||||
a <tt>config.mk</tt> file in the current directory, it defines
|
||||
the variable <tt>BUILD_FREETYPE</tt>, then includes and parses the
|
||||
configuration sub-makefile.
|
||||
<p>
|
||||
The latter defines a number of important variables that describe
|
||||
the compilation process to the build system. Among other things:<p>
|
||||
<ul>
|
||||
<li>the extension to be used for object files and library files
|
||||
(i.e. <tt>.o</tt> and <tt>.a</tt> on Unix, <tt>.obj</tt>
|
||||
and <tt>.lib</tt> on Dos-Windows-OS/2, etc..).
|
||||
<p>
|
||||
|
||||
<li>the directory where all object files will be stored
|
||||
(usually <tt>freetype2/obj</tt>), as well as the one
|
||||
containing the library file (usually the same as for
|
||||
objects).
|
||||
<p>
|
||||
|
||||
<li>the command line compiler, and its compilation flags for
|
||||
indicating a new include path (usually "<tt>-I</tt>"),
|
||||
a new macro declaration (usually "<tt>-D</tt>") or
|
||||
the target object file (usually "<tt>-o </tt>")
|
||||
</ul>
|
||||
<p>
|
||||
Once these variable are defined, <tt>config.mk</tt> test for the
|
||||
definition of the <tt>BUILD_FREETYPE</tt> variable. If it exists,
|
||||
the makefile then includes "<tt>freetype2/config/freetype.mk</tt>"
|
||||
which contains the rules required to compile the library.
|
||||
<p>
|
||||
Note that <tt>freetype.mk</tt> also scans the subdirectories of
|
||||
"<tt>freetype2/src</tt>" for a file called "<tt>rules.mk</tt>".
|
||||
Each <tt>rules.mk</tt> contains, as it names suggests, the rules
|
||||
required to compile a given font driver or module.
|
||||
<p>
|
||||
Once all this parsing is done, the library can be compiled. Usually,
|
||||
each font driver is compiled as a standalone object file (e.g.
|
||||
<tt>sfnt.o</tt>, <tt>truetype.o</tt> and <tt>type1.o</tt>).
|
||||
<p>
|
||||
This process can be illustrated by the following graphics:<p>
|
||||
<center>
|
||||
<img src="library-compilation.png" border=0>
|
||||
</center>
|
||||
<p>
|
||||
</ul>
|
||||
|
||||
<p><hr><p>
|
||||
|
||||
<h2>IIV. Managing the list of modules</h2>
|
||||
<ul>
|
||||
The makefile <tt>freetype.mk</tt> only determines how to compile
|
||||
each one of the modules that are located in the sub-directories of
|
||||
<tt>freetype2/src</tt>.
|
||||
<p>
|
||||
However, when the function <tt>FT_Init_FreeType</tt> is invoked at
|
||||
the start of an application, it must create a new <tt>FT_Library</tt>
|
||||
object, and registers all <em>known</em> font drivers to it by
|
||||
repeatly calling <tt>FT_Add_Driver</tt>.
|
||||
<p>
|
||||
The list of <em>known</em> drivers is located in the file
|
||||
"<tt>freetype2/config/<em>system</em>/ftmodule.h</tt>", and is used
|
||||
exclusively by the internal function <tt>FT_Default_Drivers</tt>. The
|
||||
list in <tt>ftmodule.h</tt> must be re-generated each time you add
|
||||
or remove a module from <tt>freetype2/src</tt>.
|
||||
<p>
|
||||
This is normally performed by invoking the top-level <tt>Makefile</tt>
|
||||
with the <tt>modules</tt> target, as in:<p>
|
||||
<ul>
|
||||
<tt>make modules</tt>
|
||||
</ul>
|
||||
<p>
|
||||
This will trigger a special rule that will re-generate
|
||||
<tt>ftmodule.h</tt>. To do so, the Makefile will parse all module
|
||||
directories for a file called "<tt>module.mk</tt>". Each
|
||||
<tt>module.mk</tt> is a tiny sub-Makefile used to add a single
|
||||
module to the driver list.
|
||||
<p>
|
||||
This is illustrated by the following graphics:<p>
|
||||
<center>
|
||||
<img src="drivers-list.png" border=0>
|
||||
</center>
|
||||
<p>
|
||||
Note that the new list of modules is displayed in a very human-friendly
|
||||
way after a "<tt>make modules</tt>". Here's an example with the current
|
||||
source tree (on 11 Jan 2000):<p>
|
||||
<ul><pre>
|
||||
Regenerating the font drivers list in ./config/unix/ftmodule.h
|
||||
* driver: sfnt ( pseudo-driver for TrueType & OpenType formats )
|
||||
* driver: truetype ( Windows/Mac font files with extension *.ttf or *.ttc )
|
||||
* driver: type1 ( Postscript font files with extension *.pfa or *.pfb )
|
||||
-- done --
|
||||
</pre></ul>
|
||||
|
||||
</ul>
|
||||
|
||||
<p><hr><p>
|
||||
|
||||
<h2>V. Building the demonstration programs</h2>
|
||||
<ul>
|
||||
Several demonstration programs are located in the
|
||||
"<tt>freetype2/demos</tt>" directory hierarchy. This directory also
|
||||
includes a tiny graphics sub-system that is able to blit glyphs to
|
||||
a great variety of surfaces, as well as display these in various
|
||||
graphics libraries or windowed environments.
|
||||
<p>
|
||||
This section describes how the demonstration programs are compiled,
|
||||
using the configuration <tt>freetype2/config.mk</tt> and their own
|
||||
<tt>freetype2/demos/Makefile</tt>.
|
||||
<p>
|
||||
To compile the demonstration programs, <em>after the library</em>,
|
||||
simply go to <tt>freetype2/demos</tt> then invoke GNU make with no
|
||||
arguments.
|
||||
<p>
|
||||
The top-level Makefile will detect the <tt>config.mk</tt> in the
|
||||
<em>upper</em> directory and include it. Because it doesn't define
|
||||
the <tt>BUILD_FREETYPE</tt> variable, this will not force the
|
||||
inclusion of <tt>freetype2/config/freetype.mk</tt> as described in
|
||||
the previous section.
|
||||
<p>
|
||||
the <tt>Makefile</tt> will then include the makefile called
|
||||
"<tt>freetype2/demos/graph/rules.mk</tt>". The graphics <tt>rules.mk</tt>
|
||||
defines the rules required to compile the graphics sub-system.
|
||||
<p>
|
||||
Because the graphics syb-system is also designed modularly, it is able
|
||||
to use any number of "modules" to display surfaces on the screen.
|
||||
The graphics modules are located in the subdirectories of
|
||||
<tt>freetype2/demos/config</tt>. Each such directory contains a file
|
||||
named <tt>rules.mk</tt> which is in charge of:<p>
|
||||
<ul>
|
||||
<li>detecting wether the corresponding graphics library is
|
||||
available at the time of compilation.
|
||||
<p>
|
||||
<li>if it is, alter the compilation rules to include the graphics
|
||||
module in the build of the <tt>graph</tt> library.
|
||||
</ul>
|
||||
<p>
|
||||
When the <tt>graph</tt> library is built in <tt>demos/obj</tt>, the
|
||||
demonstration programs executables are generated by the top-level
|
||||
Makefile.
|
||||
<p>
|
||||
This is illustrated by the following graphics:<p>
|
||||
<center>
|
||||
<img src="demo-programs.png" border="0">
|
||||
</center>
|
||||
</ul>
|
||||
|
||||
<p><hr>
|
||||
</td></tr></table></center>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.8 KiB |
|
@ -1,791 +0,0 @@
|
|||
<!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 Internals</h1></center>
|
||||
|
||||
<center>
|
||||
<h2>
|
||||
Version 1.2</h2></center>
|
||||
|
||||
<center>
|
||||
<h3>
|
||||
© 1999-2000 David Turner (<a href="fichier :///david@freetype.org">david@freetype.org</a>)<br>
|
||||
© 1999-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>
|
||||
|
||||
<p>This document describes in great deatils the internals of FreeType 2.
|
||||
It is a must read for porters and developers alike. Its purpose is to
|
||||
|
||||
present the
|
||||
<blockquote>This document describes in great details the internals of the
|
||||
FreeType 2.0 library. It is a must read for porters and developers alike.
|
||||
Its purpose is to present the engine's objects, their roles and interactions.
|
||||
It is assumed that the <b><i>FreeType Glyph Conventions</i></b> document
|
||||
has been read.
|
||||
<p>We advise porters to also read the <b><i>FreeType Porting Guide</i></b>
|
||||
after this document. Would-be hackers and maintainers are of course encouraged
|
||||
to read the <b><i>FreeType Coding Conventions</i></b> document too. The
|
||||
development of a new driver is described in more details in the <b><i>FreeType
|
||||
Driver HowTo</i></b> document.</blockquote>
|
||||
|
||||
<p><br>
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
I. Overview :</h2>
|
||||
|
||||
<blockquote>
|
||||
<h3>
|
||||
1. Features (and what's new) :</h3>
|
||||
|
||||
<blockquote>FreeType 2.0 has a number of important new features that were
|
||||
not found in the 1.x releases :
|
||||
<br>
|
||||
<blockquote><b>font-format independent API</b>
|
||||
<br>FreeType 2.0 is able to support any kind of font format, be it fixed
|
||||
or scalable, through the use of pluggable "font drivers". These drivers
|
||||
can be added or replaced at run time, while applications use a new font
|
||||
format-independent API.
|
||||
<p><b>advanced stream caching</b>
|
||||
<br>2.0 is able to control the number of concurrently opened streams when
|
||||
using fonts. It is thus possible to open dozens or hundreds of font faces
|
||||
without running out of system resources.
|
||||
<p><b>real reentrancy support</b>
|
||||
<br>It is now possible to use FreeType as a shared library with no static
|
||||
data in a multi-threaded environment. The synchronization model has also
|
||||
been simplified in order to make font driver writing easier. Of course,
|
||||
you can build FreeType with no thread support to get a smaller library.
|
||||
<p><b>support for cubic beziers and 17-levels anti-aliasing</b>
|
||||
<br>The FreeType scan-line converter (a.k.a. raster) now supports cubic
|
||||
bezier arcs seamlessly. It also provides a new anti-aliasing mode which
|
||||
uses a palette of 17 levels of grays.
|
||||
<br> </blockquote>
|
||||
It also features the following :
|
||||
<blockquote><b>performance improvements :</b>
|
||||
<br>The FreeType raster has been optimized, and the generation of anti-aliased
|
||||
pixmaps is now 60% faster than in the 1.x release. Moreover, the TrueType
|
||||
bytecode interpreter has been profiled and greatly optimised.
|
||||
<p><b>easier portability</b>
|
||||
<br>Porting and configuring FreeType is now much easier. A single file
|
||||
must be provided for system-specific operations (like memory, i/o, thread
|
||||
management), and a single configuration header is used to select the build
|
||||
you need.
|
||||
<br> </blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h3>
|
||||
2. Architecture :</h3>
|
||||
|
||||
<blockquote>The engine is now split in several parts, which are :
|
||||
<h4>
|
||||
a. The base layer :</h4>
|
||||
|
||||
<blockquote>This part contains all the font-format independent features
|
||||
of the engine which are :
|
||||
<ul>
|
||||
<li>
|
||||
computations/scaling</li>
|
||||
|
||||
<li>
|
||||
list processing</li>
|
||||
|
||||
<li>
|
||||
outline processing</li>
|
||||
|
||||
<li>
|
||||
scan-line converter</li>
|
||||
|
||||
<li>
|
||||
stream manager</li>
|
||||
|
||||
<li>
|
||||
base object classes</li>
|
||||
|
||||
<li>
|
||||
debugging & traces</li>
|
||||
|
||||
<li>
|
||||
high-level API functions</li>
|
||||
|
||||
<li>
|
||||
low-level system object (memory, i/o, threads)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
|
||||
<h4>
|
||||
b. The font drivers :</h4>
|
||||
|
||||
<blockquote>Each font format is managed with the use of a single font driver
|
||||
object. The base layer is able to manage several drivers, and these can
|
||||
be easily added, removed or upgraded at runtime. Each driver has the following
|
||||
features and functions :
|
||||
<ul>
|
||||
<li>
|
||||
auto-check font format when opening a font resource (i.e. file)</li>
|
||||
|
||||
<li>
|
||||
access, load and/or extract all tables and data from the font file</li>
|
||||
|
||||
<li>
|
||||
grid-fit/hint the glyph outlines (in the case of scalable formats like
|
||||
TrueType or Type1)</li>
|
||||
|
||||
<li>
|
||||
provide extensions to access font format-specific data and tables from
|
||||
the font file</li>
|
||||
</ul>
|
||||
Note that FreeType 2.0 is a font service. Its purpose is to provide a unified
|
||||
API for all kinds of fonts and extract individual glyph images and metrics.
|
||||
However, it does not render text itself, as this operation is left to the
|
||||
developer, or to higher-level libraries built on top of FreeType. Here
|
||||
are a few features that are thus not implemented :
|
||||
<blockquote>1) Text string rendering
|
||||
<br>2) Glyph bitmap/outline caching for improved performance
|
||||
<br>3) Synthetic fonts (i.e. italicising, emboldening, underlining)
|
||||
<br>4) Contextual glyph substitution and other advanced layout processes</blockquote>
|
||||
Note that features 1 through 3 should be provided by the SemTex library,
|
||||
which may soon become part of the standard FreeType distribution.</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<p><br>
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
II. Design :</h2>
|
||||
|
||||
<blockquote>
|
||||
<h3>
|
||||
1. Objects :</h3>
|
||||
|
||||
<blockquote>They are several kinds of objects in FreeType, which can be
|
||||
described as follows :
|
||||
<blockquote><b>Base objects</b>
|
||||
<br>These objects do not relate directly to font data, but to the way it
|
||||
is organised and managed. It is the basic core and provides functions that
|
||||
are heavily used by each font driver. Examples are the resource objects,
|
||||
used to describe font files, the system object used to manage low-level
|
||||
system operations, or the raster object, used to convert vector outlines
|
||||
into bitmaps or anti-aliased pixmaps. Most of the base objects are not
|
||||
directly visible for client applications of FreeType.
|
||||
<p><b>Font objects</b>
|
||||
<br>The font objects directly model the data as it is found in font files.
|
||||
The root classes implemented in the base layer like <tt>FT_Face</tt>, <tt>FT_Size</tt>,
|
||||
<tt>FT_GlyphSlot</tt>,
|
||||
must be derived in each font driver.</blockquote>
|
||||
Objects are defined in the files "<tt>base/freetype.h</tt>" and "<tt>base/ftobjs.h</tt>".
|
||||
The former contains all the public object definitions usable by client
|
||||
applications. The latter contains private definitions used by the rest
|
||||
of the base layer and each font driver.</blockquote>
|
||||
|
||||
<h3>
|
||||
2. List management</h3>
|
||||
|
||||
<blockquote>The "<tt>base/ftlist.c</tt>" component a very simple doubly-linked
|
||||
list facility which is used by the rest of the engine to create and process
|
||||
lists, including iteration and finalisation. The definition of the list
|
||||
node and functions are placed in the "<tt>base/freetype.h</tt>" to let
|
||||
client applications access listed objects as they like.
|
||||
<p>The base list type is <tt>FT_List</tt>, which links nodes of type <tt>FT_ListNode</tt>
|
||||
together.
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
3. Limited encapsulation</h3>
|
||||
|
||||
<blockquote>Unlike what happened in the 1.x releases, the <tt>FT_Face</tt>,
|
||||
<tt>FT_Size</tt>,
|
||||
<tt>FT_GlyphSlot</tt> and <tt>FT_CharMap</tt> types are no longer blind
|
||||
pointers to opaque types. Rather, the corresponding structures are now
|
||||
public (and defined in "<tt>base/freetype.h</tt>", see <tt>FT_FaceRec</tt>,
|
||||
<tt>FT_SizeRec</tt>,
|
||||
etc..) in order to let client applications read directly the various object
|
||||
attributes they're interested in.
|
||||
<p>This breaks encapsulation of implementation, famed by OOP, but was chosen
|
||||
because:
|
||||
<br>
|
||||
<ul>
|
||||
<li>
|
||||
it simplifies a lot the work of client applications and libraries which
|
||||
don't need to perform a function call everytime they want to read one important
|
||||
object attribute (nor does it force them to cache these attributes in their
|
||||
own structures).</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
It reduces greatly the API, as many <tt>FT_Get_XXX</tt> functions are avoided.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Higher-level libraries are able to access data directly. When it
|
||||
is used frequently, they don't need to cache it in their own structures.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
It is possible to tightly link FreeType objects with higher-level ones,
|
||||
in a clearer and more efficient way. This is very important when one wants
|
||||
to write a C++ wrapper or a text rendering library on top of FreeType (actually,
|
||||
both projects were performed in an earlier version of FreeType 2.0 which
|
||||
featured classic encapsulation through get/set methods. The resulting code
|
||||
was ugly and slow. Moving to a limited encapsulation approach simplified
|
||||
so many things that the compiled code size was reduced by a factor of two
|
||||
!).</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Finally, the API and font object structures were designed after the creation
|
||||
of two scalable font drivers and one bitmap font driver. They are now very
|
||||
stable and the public (visible) attributes are not going to change.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<p><br>
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
III. Base objects :</h2>
|
||||
|
||||
<blockquote>This section describes the FreeType base object classes :
|
||||
<br>
|
||||
<h3>
|
||||
1. System objects :</h3>
|
||||
|
||||
<blockquote>The system class is in charge of managing all low-level and
|
||||
system-specific operations. This means simply memory management, i/o access
|
||||
and thread synchronisation. It is implemented by the "<tt>ftsys.c</tt>"
|
||||
component, whose source must be located in the configuration directory
|
||||
when building FreeType. (e.g. "<tt>lib/arch/ansi/ftsys.c</tt>" for an ANSI
|
||||
build, "<tt>lib/arch/unix/ftsys.c</tt>" for a Unix one, etc..).
|
||||
<p>Porting FreeType 2.0 really means providing a new implementation of
|
||||
<tt>ftsys</tt>
|
||||
(along with a few configuration file changes). Note however that its interface
|
||||
is common to all ports, and located in "<tt>base/ftsys.h</tt>".</blockquote>
|
||||
|
||||
<h3>
|
||||
2. Resources and Streams:</h3>
|
||||
|
||||
<blockquote>The concepts of files as storages, and files as streams has
|
||||
been separated for FreeType 2.0. The "<b><i>resource</i></b>" concept was
|
||||
introduced while the "<b><i>stream</i></b>" one has been redefined. Here
|
||||
is how they work together :
|
||||
<ul>
|
||||
<li>
|
||||
a "<b>resource</b>" is an object which models a file, seen as a storage.
|
||||
There are several classes of resources, which differ usually in two ways
|
||||
: the way their data is accessed by applications, and the way they're named
|
||||
within the system.</li>
|
||||
</ul>
|
||||
|
||||
<ul>For example, when parsing files with the ANSI C library, data has to
|
||||
be read (through fseek/fread) into intermediate buffers before it can be
|
||||
decoded. This scheme is highly portable, but rather inefficient; when using
|
||||
it, we'll describe the file as a disk-based resource.
|
||||
<p>As most modern operating systems now provide memory-mapped files, which
|
||||
allow direct access while improving performance and reducing memory usage.
|
||||
Because data can be read directly in memory, we'll speak of a memory-based
|
||||
resource in this case. For embedded systems (like printers, PDAs, etc..),
|
||||
ROM-fonts fit into this category as well.
|
||||
<p>Regarding naming, most systems use a string to name files in their storage
|
||||
hierarchy. Though a typical pathname is an ASCII string (<tt>'c:\windows\fonts\times.ttf'</tt>
|
||||
on Windows, <tt>'/home/fonts/times.ttf'</tt> on Unix), some OSes use different
|
||||
schemes, varying from Unicode character strings to file i-node numbers.
|
||||
These details are platform-specific and must be hidden to the rest of the
|
||||
library in resource objects.
|
||||
<p>A resource encapsulates the lowest details regarding a file, though
|
||||
it should have NO STATE. Note that the nature or type of a resource (i.e.
|
||||
disk or memory based) is important to the "stream" component only. The
|
||||
rest of the library and font drivers work transparently from their implementation.
|
||||
<p>Note also that it is perfectly possible to mix resources of distinct
|
||||
natures in a single build</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
a "<b>stream</b>" is an object which is used to extract bytes from a resource.
|
||||
Only resource objects can create streams, through its <i><tt>Open_Stream()</tt></i>
|
||||
method. A stream has state, which typically consist of a file "cursor",
|
||||
some intermediate buffers, a "current frame" and, of course, methods used
|
||||
to extract the data from streams, resolving endianess and alignement issues.</li>
|
||||
</ul>
|
||||
Data can be extracted from streams through direct reads, or through the
|
||||
use of <b>frames</b>. A frame models <i>a run of contiguous bytes</i> starting
|
||||
from the current stream position, and of liberal size.
|
||||
<p>Methods exist to extract successive integers of any sizes, while resolving
|
||||
endianess and alignement issues. Rather than a long rethorical explanation,
|
||||
here's how frames are typically used :
|
||||
<blockquote><tt>{</tt>
|
||||
<br><tt> …</tt>
|
||||
<br><tt> FT_Error error;</tt>
|
||||
<p><tt> error = FT_Access_Frame( stream, 14 );</tt>
|
||||
<br><tt> if (error) goto Fail;</tt>
|
||||
<p><tt> val1 = FT_Get_Short(stream);</tt>
|
||||
<br><tt> val2 = FT_Get_Long(stream);</tt>
|
||||
<br><tt> val3 = FT_Get_Long(stream);</tt>
|
||||
<br><tt> val4 = FT_Get_Long(stream);</tt>
|
||||
<p><tt> FT_Forget_Frame(stream);</tt>
|
||||
<br><tt> …</tt>
|
||||
<br><tt>}</tt></blockquote>
|
||||
This code does the following :
|
||||
<blockquote>
|
||||
<ol>
|
||||
<li>
|
||||
first, it "loads" the next 14 bytes from the current cursor position
|
||||
into the stream's frame, using the <tt>FT_Access_Frame</tt> API. An error
|
||||
is returned if, for example, less than 14 bytes are left in the stream
|
||||
when the call occurs..</li>
|
||||
</ol>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
it extract four integers (one 16-bit short, three 32-bit longs) from
|
||||
the frame using <tt>FT_Get_Short</tt> and <tt>FT_Get_Long</tt>. These function
|
||||
increment the frame's cursor finally, it "releases" the stream's frame.</li>
|
||||
</ol>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Each stream has its own frame which can be accessed independently,
|
||||
however, nested frame accesses are not allowed. Note also that the bytes
|
||||
are effectively read from the stream on the call to <tt>FT_Access_Frame</tt>.
|
||||
Any subsequent read will occur after these 14 bytes, even if less are extracted
|
||||
through <tt>FT_Get_xxxx</tt> functions.</li>
|
||||
</ol>
|
||||
</blockquote>
|
||||
The implementation of the resource class is located in the system component
|
||||
(i.e. "<tt>arch/<i><system></i>/ftsys.c</tt>") and can thus be tailored
|
||||
for a specific port of the engine.
|
||||
<p>A resource can be created through the <tt>FT_New_Resource</tt> API;
|
||||
however this function only accepts an 8-bit pathname to name the target
|
||||
font file, which may be inappropriate for systems using a different naming
|
||||
scheme (e.g. UTF-16 pathname, i-node number, etc..). It's up to the porter
|
||||
then to provide its own resource creation function (like. <tt>FT_New_UTF16_Resource</tt>,
|
||||
for example) in its version of "<tt>ftsys.c</tt>".
|
||||
<p>Note that <tt>FT_New_Resource</tt> will fail and return an error code
|
||||
if the font file cannot be found, or when its font format isn't recognized
|
||||
by one of the drivers installed in the library. The list or resources created
|
||||
for a given library instance is thus the list of "installed font files".
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
3. Stream Manager :</h3>
|
||||
|
||||
<blockquote>As said before, resources do not bear states, while streams
|
||||
do. Stream creation is also a very lengthy process, depending on the target
|
||||
operating system (e.g. "<tt>fopen</tt>" is usually very slow).
|
||||
<p>Because a typical font driver will want to use a new stream on each
|
||||
access to individual glyphs, being able to cache the most recently used
|
||||
streams is a requirement in order to avoid considerable performance penalties.
|
||||
<p>Stream caching is thus implemented in the "<tt>ftstream</tt>" component.
|
||||
It maintains a simple LRU list of the least recently used streams. Each
|
||||
stream in the cache is still opened and available for immediate processing.
|
||||
When a resource is destroyed, the stream cache is parsed to remove all
|
||||
related cached streams.
|
||||
<p>Stream caching can also be disabled with a configuration macro when
|
||||
using only ROM based resources (where stream opening is really quick).
|
||||
It is implemented through a Stream Manager object (see <tt>ftstream.c</tt>).
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
4. Raster :</h3>
|
||||
|
||||
<blockquote>The raster is the component is charge of generating bitmaps
|
||||
and anti-aliased pixmaps from vectorial outline definitions. It is also
|
||||
sometimes called the scan-line converter. It has been completely rewritten
|
||||
for FreeType 2.0 in order to support third-order bezier arcs, 17-levels
|
||||
anti-aliasing (through 4x4 sub-sampling), improved performance, as well
|
||||
as stand-alone compilation (in order to include it in other graphics package
|
||||
without requiring the rest of the FreeType engine).
|
||||
<p>Because it was designed for easy re-use and embedded systems, the raster
|
||||
is a rtaher 'unusual' piece of code, because it doesn't perform a single
|
||||
memory allocation, nor contain any static or global variable. Rather, it
|
||||
is up to client applications to allocate a raster object in their own heap
|
||||
or memory space.
|
||||
<p>Each raster object also needs a rather large block of memory called
|
||||
its render pool. The pool is used during rendering (and only during it)
|
||||
in order to perform the scan-line conversion. Because it accesses and manages
|
||||
data directly within the pool, the raster yelds impressive performance
|
||||
as well as bounded memory consumption. It can also automatically decompose
|
||||
large requests into smaller individual sub-tasks.
|
||||
<p>Finally, it never creates bitmaps or pixmaps, but simply renders into
|
||||
them (providing clipping too). These must be described to the raster with
|
||||
the help of a <tt>FT_Raster_Map</tt> structure (a very simple bitmap/pixmap
|
||||
descriptor).
|
||||
<p>Note that when rendering anti-aliased pixmaps, the raster doesn't use
|
||||
an intermediate bitmap buffer, as filtering is part of the scan-line conversion
|
||||
process.
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
5. Library objects :</h3>
|
||||
|
||||
<blockquote>A library object models a single instance of the FreeType engine.
|
||||
This is useful when FreeType is compiled as a shared object (DLL), as it
|
||||
can then be used by several applications, each with its own resources and
|
||||
objects.
|
||||
<p>The <tt>FT_Library</tt> type is an opaque handle to a library object.
|
||||
Such an object is created through a call to <tt>FT_Init_FreeType</tt>.
|
||||
Once you don't need it anymore, one can destroy a library object through
|
||||
<tt>FT_Done_FreeType</tt>.
|
||||
<p>Note that in reentrant builds, several threads can access a single library
|
||||
object concurrently. Such a build can be chosen by switching one configuration
|
||||
macro in the file '<tt>arch/<i><system></i>/ftconfig.h</tt>'</blockquote>
|
||||
|
||||
<h3>
|
||||
6. Driver objects :</h3>
|
||||
|
||||
<blockquote>A driver object models an instance of a given font driver,
|
||||
i.e. an element of FreeType code in charge of handling a given font format,
|
||||
like TrueType, Type1, FNT, PCF, etc..
|
||||
<p>Each library object contains a given set of driver objects when it is
|
||||
created through FT_Init_FreeType, this set being determined at compile
|
||||
time (see the file 'base/ftapi.c'). However, removing or adding drivers
|
||||
is possible at run-time, in order to make upgrades easy.</blockquote>
|
||||
|
||||
<h3>
|
||||
7. Diagram</h3>
|
||||
|
||||
<blockquote>This diagram show the object relationships for the sole base
|
||||
layer. The library object is the root of the object graph :
|
||||
<center>
|
||||
<p><img SRC="objects_diagram.png" height=300 width=562></center>
|
||||
|
||||
<p>It can be read as follows :
|
||||
<br>
|
||||
<ul>
|
||||
<li>
|
||||
Each library object has one system, one raster and one stream manager objects.
|
||||
These objects can only belong to one given library.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Each library contains one list of 0 or more resources, as well as one list
|
||||
of 0 or more driver objects.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Each stream manager holds a bounded list ("0..n" where 'n' is the stream
|
||||
cache's size) of stream objects. Each stream is related to one given resource
|
||||
object. Each resource may be related to zero or one stream.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Each resource is related to one driver object. A driver is related to 0
|
||||
or more resources.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<p><br>
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
IV. Font objects :</h2>
|
||||
|
||||
<blockquote>Font objects are used to directly map the information found
|
||||
in font files into several categories :
|
||||
<br>
|
||||
<h3>
|
||||
1. Face objects :</h3>
|
||||
|
||||
<blockquote>Face objects are used to model individual font faces. They
|
||||
encapsulate data which isn't related to a specific character size, or a
|
||||
specific glyph or glyph set. Usually, this means :
|
||||
<ul>
|
||||
<li>
|
||||
the font face's family and style names (e.g. "Palatino" + "Regular")</li>
|
||||
|
||||
<li>
|
||||
some flags indicating which kind of font this is (scalable or fixed ? fixed-width
|
||||
or proportional ? horizontal or vertical ? etc…)</li>
|
||||
|
||||
<li>
|
||||
the number of glyphs, charmaps and eventually fixed character sizes (for
|
||||
bitmap formats) found in the font face.</li>
|
||||
|
||||
<li>
|
||||
for scalable formats, some important metrics like the ascender, descender,
|
||||
global font bounding box, maximum advance width, etc.. expressed in notional
|
||||
font/grid units (as well as the number of units on the EM grid).</li>
|
||||
</ul>
|
||||
A face is created from a resource object, with the <tt>FT_New_Face</tt>
|
||||
API. Each driver contains a list of opened face objects for the resources
|
||||
it manages. When a driver is removed or destroyed, all its child faces
|
||||
are discarded automatically with it.</blockquote>
|
||||
|
||||
<h3>
|
||||
2. Size objects :</h3>
|
||||
|
||||
<blockquote>Size objects are used to model a given character dimension
|
||||
for a given device resolution (which really means a given character pixel
|
||||
dimensions).
|
||||
<p>Each size object is created from a parent face object. The object can
|
||||
be reset to new dimensions at any time. Each face object holds a list of
|
||||
all its child sizes, these are destroyed automatically when the face object
|
||||
is discarded.
|
||||
<p>The metrics contains metrics, expressed in pixels, for the ascender,
|
||||
descender, maximum advance width, etc..
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
3. Glyph Slot objects :</h3>
|
||||
|
||||
<blockquote>A glyph slot is a container where one can load individual glyphs,
|
||||
be they in vector of bitmap format. Each slot also contains metrics for
|
||||
the glyph it contains.
|
||||
<p>Each face object contains one or more glyph slot object : the first
|
||||
glyph slot is created automatically with its parent face, and it is possible
|
||||
to add new glyph slots (this is rarely used outside of debugging purposes).
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
4. CharMap objects :</h3>
|
||||
|
||||
<blockquote>A charmap object is a sort of dictionary whose task is to translate
|
||||
character codes in a given character encoding (like ShiftJIS, Unicode,
|
||||
ANSI, etc..) into glyph indexes in a given font face.
|
||||
<p>A face object contains one or more charmap objects. All charmap objects
|
||||
are created when the parent face is created, though they're not directly
|
||||
visible to client applications (rather, they can be enumerated through
|
||||
FT_Get_First_CharMap and FT_Get_Next_CharMap, or more simply picked adequately
|
||||
with FT_Find_CharMap for a set of given encodings).
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
5. Diagram</h3>
|
||||
|
||||
<blockquote>The following diagram illustrates the relationships between
|
||||
font objects :
|
||||
<center>
|
||||
<p><img SRC="objects_diagram2.png" height=327 width=561></center>
|
||||
|
||||
<p>Which can be read as :
|
||||
<br>
|
||||
<ul>
|
||||
<li>
|
||||
each resource may have zero or more child face objects "opened" for it.
|
||||
The number of faces is bounded by the number of font faces within the font
|
||||
resource.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
each driver holds a list of all the faces opened for the resources it manages.
|
||||
When the driver is removed, its child faces are discarded automatically.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
each face object has one single parent resource, and one single driver.</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
each face has one or more charmaps, and one or more glyph slots</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
each face holds a list of zero or more child size objects</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
each charmap, glyph slot and size is related to one given parent face.
|
||||
These objects are destroyed automatically when the parent face is discarded.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<p><br>
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
V. Driver Interface :</h2>
|
||||
|
||||
<blockquote>A font driver is added to a given library object through the
|
||||
<tt>FT_Add_Driver</tt>
|
||||
API. This function receives a structure known as a <tt>FT_DriverInterface</tt>,
|
||||
which describes the driver's basic properties.
|
||||
<p>The <tt>FT_DriverInterface</tt> contains a set of function pointers
|
||||
used for the base FreeType functionalities. However, each driver can also
|
||||
provide a font-format-specific extended interface to allow client applications
|
||||
to use more advanced features.
|
||||
<br>
|
||||
<h3>
|
||||
1. Common Interface</h3>
|
||||
|
||||
<blockquote>The structure of <tt>FT_DriverInterface</tt> is rather simple,
|
||||
and defined in "<tt>base/ftdriver.h</tt>". It must be well known by any
|
||||
developer who wants to write a new driver for the engine. We advise reading
|
||||
the <b><i>FreeType Driver HowTo</i></b> as well as the source code of existing
|
||||
drivers. Source comments.</blockquote>
|
||||
|
||||
<h3>
|
||||
2. Driver-specific extensions</h3>
|
||||
|
||||
<blockquote>The field of the <tt>FT_DriverInterface</tt> structure is a
|
||||
typeless pointer to a format-specific interface. This extended interface
|
||||
is usually a structure containing function pointers as well as other kind
|
||||
of information related to the driver.
|
||||
<p>It is assumed that client applications that wish to use the driver-specific
|
||||
extensions are able to <tt>#include</tt> the relevant header files to understand
|
||||
the format-specific interface structure.</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<hr WIDTH="100%">
|
||||
<h2>
|
||||
VI. Configuration:</h2>
|
||||
|
||||
<blockquote>This section relates to the configuration of the FreeType library.
|
||||
By configuration, we mean selection of build options as well as the choice
|
||||
of font drivers to be used for each new library object.
|
||||
<br>
|
||||
<h3>
|
||||
1. Configuration files :</h3>
|
||||
|
||||
<blockquote>A single file is used to configure the FreeType base engine.
|
||||
As it is considered system-specific, it is located in the architecture
|
||||
directories of the library, under the name "arch/<system>/ftconfig.h".
|
||||
Note that the same directory should also contain a platform-specific implementation
|
||||
of "ftsys.c".
|
||||
<p>The configuration files is a simple C header which is included by the
|
||||
engine's sources during compilation. It is not included in "freetype.h",
|
||||
and hence doesn't need to be copied when installing the FreeType headers
|
||||
on your system.
|
||||
<p>It is made of a series of #define or #undef statements, which are used
|
||||
to select or turn off a specific option. Each option is documented with
|
||||
heavy comments, and some of them are explained below.</blockquote>
|
||||
|
||||
<h3>
|
||||
2. Building and Makefiles :</h3>
|
||||
|
||||
<blockquote>FreeType 2.0 is more complex than its 1.x release. In order
|
||||
to facilitate maintenance, as well as ease considerably the writing of
|
||||
new font drivers, <b><i>only GNU Make is supported with FreeType 2.0</i></b>.
|
||||
However, it is possible to use any compiler, as well as any object or library
|
||||
prefix (<tt>.o, .obj, .a, .lib</tt> etc..) with them.
|
||||
<p>To build FreeType 2.0, one has to be in the library directory, then
|
||||
invoke its platform-specific makefile. For a Unix system, this would be
|
||||
:
|
||||
<blockquote>
|
||||
<blockquote><tt>% cd freetype2/lib</tt>
|
||||
<br><tt>% make -f arch/unix/Makefile</tt>
|
||||
<p>where '<tt>make</tt>' is really GNU Make !</blockquote>
|
||||
</blockquote>
|
||||
The system-specific <tt>Makefile</tt> located in '<tt>arch/<i><system></i></tt>'
|
||||
is a tiny file used to define several variables. It then includes the file
|
||||
<tt>freetype2/lib/Makefile.lib</tt>,
|
||||
which contains all the gory details about library compilation. The system-specific
|
||||
<tt>Makefile</tt> can be very easily modified to accomodate a new compiler/platform
|
||||
(see the comments within one of these files).
|
||||
<p>Each font driver is located in a directory like "<tt>freetype2/lib/drivers/<i><formatdir></i></tt>".
|
||||
For example, the TrueType driver is located in "<tt>drivers/truetype</tt>".
|
||||
Each driver directory must contain a <tt>Makefile</tt> which will be included
|
||||
by <tt>Makefile.lib</tt>. The former is used to define and build driver
|
||||
object files.
|
||||
<br>
|
||||
<p><br>
|
||||
<center>
|
||||
<p><img SRC="build_diagram.png" height=284 width=559></center>
|
||||
</blockquote>
|
||||
|
||||
<h3>
|
||||
3. Make options :</h3>
|
||||
|
||||
<blockquote>The base layer, as well as each font driver, are made up of
|
||||
several C sources. Traditionally, one compiles each source (i.e. '<tt>.c</tt>'
|
||||
file) into an object ('<tt>.o</tt>' or '<tt>.obj</tt>') file, and all of
|
||||
them are grouped into a library file (i.e. '<tt>.a</tt>' or '<tt>.lib</tt>').
|
||||
<p>By default, FreeType takes a slightly different approach when it comes
|
||||
to compiling each part of the engine. Usually, a single tiny source is
|
||||
compiled, which includes all other component sources. This results in a
|
||||
single object files, with the benefits or reduced code size, usually better
|
||||
compilation as well as a drastic reduction of the number of symbols exported
|
||||
by the library. Of course, it is made possible through the use of specific
|
||||
declaration macros in the FreeType source (see the definition of <tt>LOCAL_DEF</tt>
|
||||
and <tt>LOCAL_FUNC</tt> in <tt>ftconfig.h</tt> for details).
|
||||
<p>For a concrete example, see the source code in "<tt>base/ftbase.c</tt>"
|
||||
which generates the whole base layer in a single object file. The same
|
||||
build process is applied to font drivers, in order to generate one single
|
||||
object file per given font format (e.g. <tt>truetype.o</tt>, <tt>type1.o</tt>,
|
||||
etc..).
|
||||
<p>Compiling the library and drivers in "normal" mode is possible, through
|
||||
the use of the '<tt>multi</tt>' target (which really means « multiple
|
||||
objects »). For example, calling :
|
||||
<blockquote><tt>% make -f arch/ansi/Makefile multi</tt></blockquote>
|
||||
Will build the FreeType library by compiling each source file to an individual
|
||||
object, then linking them together. You'll notice that the library is significantly
|
||||
bigger in this case. Creating a shared dll from a 'multi' build is certainly
|
||||
a very poor idea, as this will export a huge quantity of symbols that aren't
|
||||
useful to any client application.</blockquote>
|
||||
|
||||
<h3>
|
||||
4. Adding a driver at compile time</h3>
|
||||
|
||||
<blockquote>A driver can be included very easily in the build process by
|
||||
including its <tt>Makefile</tt> in <tt>Makefile.lib</tt>. For example,
|
||||
the TrueType driver is simply included with the following lines (see <tt>Makefile.lib</tt>):
|
||||
<blockquote><tt># TrueType driver rules</tt>
|
||||
<br><tt>#</tt>
|
||||
<br><tt>include $(DRIVERS_DIR)/truetype/Makefile</tt></blockquote>
|
||||
|
||||
<p><br>Where <tt>DRIVERS_DIR</tt> really is "<tt>freetype2/lib/drivers</tt>",
|
||||
though this can be redefined. You can, of course specify a different path
|
||||
if you want to place your driver sources in another location.
|
||||
<p>Note that this only adds the driver's object files to the generated
|
||||
library file. A few more steps are needed to make your <tt>FT_Library</tt>
|
||||
objects use the driver. They consist in modifying the file "<tt>base/ftinit.c</tt>",
|
||||
whose sole purpose is to define the set of driver objects that are to be
|
||||
created with each new library object.
|
||||
<br> </blockquote>
|
||||
|
||||
<h3>
|
||||
5. Adding a driver at run time</h3>
|
||||
|
||||
<blockquote>New driver objects can be added at run-time through the <tt>FT_Add_Driver</tt>
|
||||
API. This function takes a handle to an existing library object, as well
|
||||
as a pointer to a given driver interface. This interface is used to create
|
||||
a new driver object and register it within the library.
|
||||
<p>Similarly, a single driver can be removed from a library anytime through
|
||||
<tt>FT_Remove_Driver</tt>.
|
||||
This will automatically discard the resources and face objects managed
|
||||
by the driver.</blockquote>
|
||||
|
||||
<h3>
|
||||
6. Custom library objects :</h3>
|
||||
|
||||
<blockquote>Finally, it is possible to build custom library objects. You
|
||||
need to pass a handle to a valid <tt>FT_System</tt> object to the <tt>FT_Build_Library</tt>
|
||||
API. The function will return a handle to the new fresh library object.
|
||||
Note that the library has no registered drivers after the call, developers
|
||||
have to add them by hand with <tt>FT_Add_Driver</tt>.
|
||||
<p>It is thus possible to create two distinct library objects with distinct
|
||||
<tt>FT_System</tt>
|
||||
implementations in the same session, which can be useful for debugging
|
||||
purpose.</blockquote>
|
||||
|
||||
<br> </blockquote>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,343 +0,0 @@
|
|||
<!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>
|
||||
© 2000 David Turner
|
||||
(<a href="mailto:david@freetype.org">david@freetype.org</a>)<br>
|
||||
© 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 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 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 bytes for
|
||||
<code>FT_Get_Short()</code>, 4 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 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 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>
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 870 B |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.7 KiB |
|
@ -1,258 +0,0 @@
|
|||
<!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>
|
||||
|
||||
|
|
@ -1,871 +0,0 @@
|
|||
<!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 Tutorial</title>
|
||||
</head>
|
||||
|
||||
<body text="#000000"
|
||||
bgcolor="#FFFFFF"
|
||||
link="#0000EF"
|
||||
vlink="#51188E"
|
||||
alink="#FF0000">
|
||||
|
||||
<h1 align=center>
|
||||
FreeType 2.0 Tutorial
|
||||
</h1>
|
||||
|
||||
<h3 align=center>
|
||||
© 2000 David Turner
|
||||
(<a href="mailto:david@freetype.org">david@freetype.org</a>)<br>
|
||||
© 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 short tutorial will teach you how to use the FreeType 2
|
||||
library in your own applications.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>
|
||||
1. Header files
|
||||
</h3>
|
||||
|
||||
<p>To include the main FreeType header file, simply say</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
#include <freetype/freetype.h></pre>
|
||||
</font>
|
||||
|
||||
<p>in your application code. Note that other files are available in the
|
||||
FreeType include directory, most of them being included by
|
||||
<tt>"freetype.h"</tt>. They will be described later in this
|
||||
tutorial.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>
|
||||
2. Initialize the library
|
||||
</h3>
|
||||
|
||||
<p>Simply create a variable of type <tt>FT_Library</tt> named, for
|
||||
example, <tt>library</tt>, and call the function
|
||||
<tt>FT_Init_FreeType()</tt> as in</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
#include <freetype/freetype.h>
|
||||
|
||||
FT_Library library;
|
||||
|
||||
...
|
||||
|
||||
{
|
||||
...
|
||||
error = FT_Init_FreeType( &library );
|
||||
if ( error )
|
||||
{
|
||||
... an error occurred during library initialization ...
|
||||
}
|
||||
}</pre>
|
||||
</font>
|
||||
|
||||
<p>This function is in charge of the following:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>Creating a new instance of the FreeType 2 library, and set
|
||||
the handle <tt>library</tt> to it.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Load each modules that FreeType knows about in the library.
|
||||
This means that by default, your new <tt>library</tt> object is able
|
||||
to handle TrueType, Type 1, CID-keyed & OpenType/CFF fonts
|
||||
gracefully.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>As you can see, the function returns an error code, like most others
|
||||
in the FreeType API. An error code of 0 <em>always</em> means that
|
||||
the operation was successful; otherwise, the value describes the error,
|
||||
and <tt>library</tt> is set to NULL.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>
|
||||
3. Load a font face
|
||||
</h3>
|
||||
|
||||
<h4>
|
||||
a. From a font file
|
||||
</h4>
|
||||
|
||||
<p>Create a new <em>face</em> object by calling <tt>FT_New_Face</tt>.
|
||||
A <em>face</em> describes a given typeface and style. For example,
|
||||
"Times New Roman Regular" and "Times New Roman Italic" correspond to
|
||||
two different faces.</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_Face( library,
|
||||
"/usr/share/fonts/truetype/arial.ttf",
|
||||
0,
|
||||
&face );
|
||||
if ( error == FT_Err_Unknown_File_Format )
|
||||
{
|
||||
... the font file could be opened and read, but it appears
|
||||
... that its font format is unsupported
|
||||
}
|
||||
else if ( error )
|
||||
{
|
||||
... another error code means that the font file could not
|
||||
... be opened or read, or simply that it is broken...
|
||||
}</pre>
|
||||
</font>
|
||||
|
||||
<p>As you can certainly imagine, <tt>FT_New_Face</tt> opens a font
|
||||
file, then tries to extract one face from it. Its parameters are</p>
|
||||
|
||||
<table cellpadding=5>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>library</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>handle to the FreeType library instance where the face object
|
||||
is created</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>filepathname</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>the font file pathname (standard C string).</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>face_index</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>Certain font formats allow several font faces to be embedded
|
||||
in a single file.</p>
|
||||
|
||||
<p>This index tells which face you want to load. An error will
|
||||
be returned if its value is too large.</p>
|
||||
|
||||
<p>Index 0 always work though.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>face</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>A <em>pointer</em> to the handle that will be set to describe
|
||||
the new face object.</p>
|
||||
|
||||
<p>It is set to NULL in case of error.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>To know how many faces a given font file contains, simply load its
|
||||
first face (use <tt>face_index</tt>=0), then see the value of
|
||||
<tt>face->num_faces</tt> which indicates how many faces are embedded
|
||||
in the font file.</p>
|
||||
|
||||
<h4>
|
||||
b. From memory
|
||||
</h4>
|
||||
|
||||
<p>In the case where you have already loaded the font file in memory,
|
||||
you can similarly create a new face object for it by calling
|
||||
<tt>FT_New_Memory_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 ) { ... }
|
||||
|
||||
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 the font file buffer and its size in bytes instead of a
|
||||
file pathname. Other than that, it has exactly the same semantics as
|
||||
<tt>FT_New_Face()</tt>.</p>
|
||||
|
||||
<h4>
|
||||
c. From other sources (compressed files, network, etc.)
|
||||
</h4>
|
||||
|
||||
<p>There are cases where using a file pathname 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.</p>
|
||||
|
||||
<p>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 manual in order to learn how to use it.</p>
|
||||
|
||||
<p>Note that providing a custom stream might also be used to access a
|
||||
TrueType font embedded in a Postscript Type 42 wrapper.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>
|
||||
4. Accessing face content
|
||||
</h3>
|
||||
|
||||
<p>A <em>face object</em> models all information that globally describes
|
||||
the face. Usually, this data can be accessed directly by dereferencing
|
||||
a handle, like</p>
|
||||
|
||||
<table cellpadding=5>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>face->num_glyphs</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>Gives the number of <em>glyphs</em> available in the font face.
|
||||
A glyph is simply a character image. It doesn't necessarily
|
||||
correspond to a <em>character code</em> though.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>face->flags</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>A 32-bit integer containing bit flags used to describe some
|
||||
face properties. For example, the flag
|
||||
<tt>FT_FACE_FLAG_SCALABLE</tt> is used to indicate that the face's
|
||||
font format is scalable and that glyph images can be rendered for
|
||||
all character pixel sizes. For more information on face flags,
|
||||
please read the <a href="#">FreeType 2 API Reference</a>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>face->units_per_EM</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>This field is only valid for scalable formats (it is set to 0
|
||||
otherwise). It indicates the number of font units covered by the
|
||||
EM.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>face->num_fixed_sizes</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>This field gives the number of embedded bitmap <em>strikes</em>
|
||||
in the current face. A <em>strike</em> is simply a series of
|
||||
glyph images for a given character pixel size. For example, a
|
||||
font face could include strikes for pixel sizes 10, 12
|
||||
and 14. Note that even scalable font formats can have
|
||||
embedded bitmap strikes!</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>face->fixed_sizes</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>this is a pointer to an array of <tt>FT_Bitmap_Size</tt>
|
||||
elements. Each <tt>FT_Bitmap_Size</tt> indicates the horizontal
|
||||
and vertical <em>pixel sizes</em> for each of the strikes that are
|
||||
present in the face.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>For a complete listing of all face properties and fields, please read
|
||||
the <a href="#">FreeType 2 API Reference</a>.<p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>
|
||||
5. Setting the current pixel size
|
||||
</h3>
|
||||
|
||||
<p>FreeType 2 uses "<em>size objects</em>" to model all
|
||||
information related to a given character size for a given face.
|
||||
For example, a size object will hold the value of certain metrics
|
||||
like the ascender or text height, expressed in 1/64th of a pixel,
|
||||
for a character size of 12 points.</p>
|
||||
|
||||
<p>When the <tt>FT_New_Face</tt> function is called (or one of its
|
||||
cousins), it <b>automatically</b> creates a new size object for
|
||||
the returned face. This size object is directly accessible as
|
||||
<b><tt>face->size</tt></b>.</p>
|
||||
|
||||
<p><em>NOTA BENE: a single face object can deal with one or more size
|
||||
objects at a time, however, this is something that few programmers
|
||||
really need to do. We have thus have decided to simplify the API for
|
||||
the most common use (i.e. one size per face), while keeping this
|
||||
feature available through additional fuctions.</em></p>
|
||||
|
||||
<p>When a new face object is created, its size object defaults to the
|
||||
character size of 10 pixels (both horizontally and vertically) for
|
||||
scalable formats. For fixed-sizes formats, the size is more or less
|
||||
undefined, which is why you must set it before trying to load a
|
||||
glyph.</p>
|
||||
|
||||
<p>To do that, simply call <tt>FT_Set_Char_Size()</tt>. Here is an
|
||||
example where the character size is set to 16pt for a 300x300 dpi
|
||||
device:</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
error = FT_Set_Char_Size(
|
||||
face, /* handle to face object */
|
||||
0, /* char_width in 1/64th of points */
|
||||
16*64, /* char_height in 1/64th of points */
|
||||
300, /* horizontal device resolution */
|
||||
300 ); /* vertical device resolution */</pre>
|
||||
</font>
|
||||
|
||||
<p>You will notice that:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>The character width and heights are specified in 1/64th of
|
||||
points. A point is a <em>physical</em> distance, equaling 1/72th
|
||||
of an inch, it's not a pixel..<p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The horizontal and vertical device resolutions are expressed in
|
||||
<em>dots-per-inch</em>, or <em>dpi</em>. You can use 72 or
|
||||
96 dpi for display devices like the screen. The resolution
|
||||
is used to compute the character pixel size from the character
|
||||
point size.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>A value of 0 for the character width means "<em>same as
|
||||
character height</em>", a value of 0 for the character height
|
||||
means "<em>same as character width</em>". Otherwise, it is possible
|
||||
to specify different char widths and heights.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Using a value of 0 for the horizontal or vertical resolution means
|
||||
72 dpi, which is the default.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The first argument is a handle to a face object, not a size
|
||||
object. That's normal, and must be seen as a convenience.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>This function computes the character pixel size that corresponds to
|
||||
the character width and height and device resolutions. However, if you
|
||||
want to specify the pixel sizes yourself, you can simply call
|
||||
<tt>FT_Set_Pixel_Sizes()</tt>, as in</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
error = FT_Set_Pixel_Sizes(
|
||||
face, /* handle to face object */
|
||||
0, /* pixel_width */
|
||||
16 ); /* pixel_height */</pre>
|
||||
</font>
|
||||
|
||||
<p>This example will set the character pixel sizes to 16x16 pixels.
|
||||
As previously, a value of 0 for one of the dimensions means
|
||||
"<em>same as the other</em>".</p>
|
||||
|
||||
<p>Note that both functions return an error code. Usually, an error
|
||||
occurs with a fixed-size font format (like FNT or PCF) when trying to
|
||||
set the pixel size to a value that is not listed in the
|
||||
<tt><b>face->fixed_sizes</b></tt> array.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>
|
||||
6. Loading a glyph image
|
||||
</h3>
|
||||
|
||||
<h4>
|
||||
a. Converting a character code into a glyph index
|
||||
</h4>
|
||||
|
||||
<p>Usually, an application wants to load a glyph image based on its
|
||||
<em>character code</em>, which is a unique value that defines the
|
||||
character for a given <em>encoding</em>. For example, the character
|
||||
code 65 represents the `A' in ASCII encoding.</p>
|
||||
|
||||
<p>A face object contains one or more tables, called
|
||||
<em>charmaps</em>, that are used to convert character codes to glyph
|
||||
indices. For example, most TrueType fonts contain two charmaps. One
|
||||
is used to convert Unicode character codes to glyph indices, the other
|
||||
is used to convert Apple Roman encoding into glyph indices. Such
|
||||
fonts can then be used either on Windows (which uses Unicode) and
|
||||
Macintosh (which uses Apple Roman, bwerk). Note also that a given
|
||||
charmap might not map to all the glyphs present in the font.</p>
|
||||
|
||||
<p>By default, when a new face object is created, it lists all the
|
||||
charmaps contained in the font face and selects the one that supports
|
||||
Unicode character codes if it finds one. Otherwise, it tries to find
|
||||
support for Latin-1, then ASCII.</p>
|
||||
|
||||
<p>We will describe later how to look for specific charmaps in a face.
|
||||
For now, we will assume that the face contains at least a Unicode
|
||||
charmap that was selected during <tt>FT_New_Face()</tt>. To convert a
|
||||
Unicode character code to a font glyph index, we use
|
||||
<tt>FT_Get_Char_Index()</tt> as in</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
glyph_index = FT_Get_Char_Index( face, charcode );</pre>
|
||||
</font>
|
||||
|
||||
<p>This will look the glyph index corresponding to the given
|
||||
<tt>charcode</tt> in the charmap that is currently selected for the
|
||||
face. If charmap is selected, the function simply returns the
|
||||
charcode.</p>
|
||||
|
||||
<p>Note that this is one of the rare FreeType functions that do not
|
||||
return an error code. However, when a given character code has no
|
||||
glyph image in the face, the value 0 is returned. By convention,
|
||||
it always correspond to a special glyph image called the <b>missing
|
||||
glyph</b>, which usually is represented as a box or a space.</p>
|
||||
|
||||
<h4>
|
||||
b. Loading a glyph from the face
|
||||
</h4>
|
||||
|
||||
<p>Once you have a glyph index, you can load the corresponding glyph
|
||||
image. Note that the glyph image can be in several formats. For
|
||||
example, it will be a bitmap for fixed-size formats like FNT, FON, or
|
||||
PCF. It will also be a scalable vector outline for formats like
|
||||
TrueType or Type 1. The glyph image can also be stored in an
|
||||
alternate way that is not known at the time of writing this
|
||||
documentation.</p>
|
||||
|
||||
<p>The glyph image is always stored in a special object called a
|
||||
<em>glyph slot</em>. As its name 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 slot object that can be accessed as
|
||||
<b><tt>face->glyph</tt></b>.</p>
|
||||
|
||||
<p>Loading a glyph image into the slot is performed by calling
|
||||
<tt>FT_Load_Glyph()</tt> as in</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
error = FT_Load_Glyph(
|
||||
face, /* handle to face object */
|
||||
glyph_index, /* glyph index */
|
||||
load_flags ); /* load flags, see below */</pre>
|
||||
</font>
|
||||
|
||||
<p>The <tt>load_flags</tt> value is a set of bit flags used to
|
||||
indicate some special operations. The default value
|
||||
<tt>FT_LOAD_DEFAULT</tt> is 0.</p>
|
||||
|
||||
<p>This function will try to load the corresponding glyph image
|
||||
from the face. Basically, this means that:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>If a bitmap is found for the corresponding glyph and pixel
|
||||
size, it will in the slot (embedded bitmaps are always
|
||||
favored over native image formats, because we assume that
|
||||
they are higher-quality versions of the same image. This
|
||||
can be ignored by using the FT_LOAD_NO_BITMAP flag)</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>Otherwise, a native image for the glyph will be loaded.
|
||||
It will also be scaled to the current pixel size, as
|
||||
well as hinted for certain formats like TrueType and
|
||||
Type1.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>The field <tt><b>glyph->format</b></tt> describe the format
|
||||
used to store the glyph image in the slot. If it is not
|
||||
<tt>ft_glyph_format_bitmap</tt>, one can immediately
|
||||
convert it to a bitmap through <tt>FT_Render_Glyph</tt>,
|
||||
as in:</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
error = FT_Render_Glyph(
|
||||
face->glyph, /* glyph slot */
|
||||
render_mode ); /* render mode */
|
||||
</pre>
|
||||
</font>
|
||||
|
||||
<p>The parameter <tt>render_mode</tt> is a set of bit flags used
|
||||
to specify how to render the glyph image. Set it to 0 to render
|
||||
a monochrome bitmap, or to <tt>ft_render_mode_antialias</tt> to
|
||||
generate a high-quality (256 gray levels) anti-aliased bitmap
|
||||
from the glyph image.</p>
|
||||
|
||||
<p>Once you have a bitmap glyph image, you can access it directly
|
||||
through <tt><b>glyph->bitmap</b></tt> (a simple bitmap descriptor),
|
||||
and position it through <tt><b>glyph->bitmap_left</b></tt> and
|
||||
<tt><b>glyph->bitmap_top</b></tt>.</p>
|
||||
|
||||
<p>Note that <tt>bitmap_left</tt> is the horizontal distance from the
|
||||
current pen position to the left-most border of the glyph bitmap,
|
||||
while <tt>bitmap_top</tt> is the vertical distance from the
|
||||
pen position (on the baseline) to the top-most border of the
|
||||
glyph bitmap. <em>It is positive to indicate an upwards
|
||||
distance</em>.</p>
|
||||
|
||||
<p>The next section will detail the content of a glyph slot and
|
||||
how to access specific glyph information (including metrics).</p>
|
||||
|
||||
<h4>
|
||||
c. Using other charmaps
|
||||
</h4>
|
||||
|
||||
<p>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, which typically happens
|
||||
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>
|
||||
|
||||
<p>There are two ways to select a different charmap with FreeType 2.
|
||||
The easiest is when the encoding you need already has a corresponding
|
||||
enumeration defined in <tt><freetype/freetype.h></tt>, as
|
||||
<tt>ft_encoding_big5</tt>. In this case, you can simply call
|
||||
<tt>FT_Select_CharMap</tt> as in:</p>
|
||||
|
||||
<font color="blue"><pre>
|
||||
error = FT_Select_CharMap(
|
||||
face, /* target face object */
|
||||
ft_encoding_big5 ); /* encoding.. */
|
||||
</pre></font>
|
||||
|
||||
<p>Another way is to manually parse the list of charmaps for the
|
||||
face, this is accessible through the fields
|
||||
<tt><b>num_charmaps</b></tt> and <tt><b>charmaps</b></tt>
|
||||
(notice the 's') of the face object. As you could expect,
|
||||
the first is the number of charmaps in the face, while the
|
||||
second is <em>a table of pointers to the charmaps</em>
|
||||
embedded in the face.</p>
|
||||
|
||||
<p>Each charmap has a few visible fields used to describe it more
|
||||
precisely. Mainly, one will look at
|
||||
<tt><b>charmap->platform_id</b></tt> and
|
||||
<tt><b>charmap->encoding_id</b></tt> that define a pair of
|
||||
values that can be used to describe the charmap in a rather
|
||||
generic way.</p>
|
||||
|
||||
<p>Each value pair corresponds to a given encoding. For example,
|
||||
the pair (3,1) corresponds to Unicode. Their list is
|
||||
defined in the TrueType specification but you can also use the
|
||||
file <tt><freetype/ftnameid.h></tt> which defines several
|
||||
helpful constants to deal with them..</p>
|
||||
|
||||
<p>To look for a specific encoding, you need to find a corresponding
|
||||
value pair in the specification, then look for it in the charmaps
|
||||
list. Don't forget that some encoding correspond to several
|
||||
values pair (yes it's a real mess, but blame Apple and Microsoft
|
||||
on such stupidity..). Here's some code to do it:</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
FT_CharMap found = 0;
|
||||
FT_CharMap charmap;
|
||||
int n;
|
||||
|
||||
for ( n = 0; n < face->num_charmaps; n++ )
|
||||
{
|
||||
charmap = face->charmaps[n];
|
||||
if ( charmap->platform_id == my_platform_id &&
|
||||
charmap->encoding_id == my_encoding_id )
|
||||
{
|
||||
found = charmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found ) { ... }
|
||||
|
||||
/* now, select the charmap for the face object */
|
||||
error = FT_Set_CharMap( face, found );
|
||||
if ( error ) { ... }</pre>
|
||||
</font>
|
||||
|
||||
<p>Once a charmap has been selected, either through
|
||||
<tt>FT_Select_CharMap</tt> or <tt>FT_Set_CharMap</tt>,
|
||||
it is used by all subsequent calls to
|
||||
<tt>FT_Get_Char_Index()</tt>.</p>
|
||||
|
||||
|
||||
<h4>
|
||||
d. Glyph Transforms:
|
||||
</h4>
|
||||
|
||||
<p>It is possible to specify an affine transformation to be applied
|
||||
to glyph images when they're loaded. Of course, this will only
|
||||
work for scalable (vectorial) font formats.</p>
|
||||
|
||||
<p>To do that, simply call <tt>FT_Set_Transform</tt>, as in:</p>
|
||||
|
||||
<font color="blue"><pre>
|
||||
error = FT_Set_Transform(
|
||||
face, /* target face object */
|
||||
&matrix, /* pointer to 2x2 matrix */
|
||||
&delta ); /* pointer to 2d vector */
|
||||
</pre></font>
|
||||
|
||||
<p>This function will set the current transform for a given face
|
||||
object. Its second parameter is a pointer to a simple
|
||||
<tt>FT_Matrix</tt> structure that describes a 2x2 affine matrix.
|
||||
The third parameter is a pointer to a <tt>FT_Vector</tt> structure
|
||||
that describe a simple 2d vector.</p>
|
||||
|
||||
<p>Note that the matrix pointer can be set to NULL, (in which case
|
||||
the identity transform will be used). Coefficients of the matrix
|
||||
are in 16.16 fixed float units.</p>
|
||||
|
||||
<p>The vector pointer can also be set to NULL (in which case a delta
|
||||
of (0,0) will be used). The vector coordinates are expressed in
|
||||
1/64th of a pixel (also known as 26.6 fixed floats).</p>
|
||||
|
||||
<p><em>NOTA BENE: The transform is applied every glyph that is loaded
|
||||
through <tt>FT_Load_Glyph</tt>. Note that loading a glyph bitmap
|
||||
with a non-trivial transform will produce an error..</em></p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>
|
||||
7. Accessing glyph image data
|
||||
</h3>
|
||||
|
||||
<p>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>
|
||||
|
||||
<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>
|
||||
{
|
||||
/* shortcut to glyph slot */
|
||||
FT_GlyphSlot glyph = face->glyph;
|
||||
|
||||
for ( n = 0; n < face->num_glyphs; n++ )
|
||||
{
|
||||
... load glyph n ...
|
||||
... access glyph data as glyph->xxxx
|
||||
}
|
||||
}</pre>
|
||||
</font>
|
||||
|
||||
<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=5>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>glyph->format</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>Indicates the type of the loaded glyph image. Can be either
|
||||
<tt>ft_glyph_format_bitmap</tt>, <tt>ft_glyph_format_outline</tt>,
|
||||
or other values.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>glyph->metrics</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>A simple structure used to hold the glyph image's metrics.
|
||||
Note that <em>most distances are expressed in 1/64th of
|
||||
pixels!</em> See the API reference or the user guide for a
|
||||
description of the <tt>FT_Glyph_Metrics</tt> structure.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>glyph->bitmap</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>If 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.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<tt><b>glyph->outline</b></tt>
|
||||
</td>
|
||||
<td>
|
||||
<p>When the glyph slot contains a scalable outline, this structure
|
||||
describes it. See the definition of the <tt>FT_Outline</tt>
|
||||
structure.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>
|
||||
8. Rendering glyph outlines into bitmaps
|
||||
</h3>
|
||||
|
||||
<p>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>
|
||||
|
||||
<p>If the format is <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>
|
||||
|
||||
<p>On the other hand, if 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 will handle to it, named
|
||||
<tt>FT_Get_Glyph_Bitmap</tt>. Here's a <em>simple</em> example code
|
||||
that renders an outline into a <b>monochrome</b> bitmap:</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
{
|
||||
FT_GlyphSlot glyph;
|
||||
|
||||
... load glyph ...
|
||||
|
||||
glyph = face->glyph; /* shortcut to glyph data */
|
||||
if ( glyph->format == ft_glyph_format_outline )
|
||||
{
|
||||
FT_Bitmap bit;
|
||||
|
||||
/* set-up a bitmap descriptor for our target bitmap */
|
||||
bit.rows = bitmap_height;
|
||||
bit.width = bitmap_width;
|
||||
bit.pitch = bitmap_row_bytes;
|
||||
/* render into a mono bitmap */
|
||||
bit.pixel_mode = ft_pixel_mode_mono;
|
||||
bit.buffer = bitmap_buffer;
|
||||
|
||||
/* render the outline directly into the bitmap */
|
||||
error = FT_Get_Glyph_Bitmap( face, &bit );
|
||||
if ( error ) { ... }
|
||||
}
|
||||
}</pre>
|
||||
</font>
|
||||
|
||||
<p>You should note that <b><em><tt>FT_Get_Glyph_Bitmap()</tt> doesn't
|
||||
create the bitmap</em></b>. It only needs a descriptor, of type
|
||||
<tt>FT_Bitmap</tt>, and writes directly into it.</p>
|
||||
|
||||
<p>Note that the FreeType scan-converter for outlines can also generate
|
||||
anti-aliased glyph bitmaps with 128 level of grays. For now, it is
|
||||
restricted to rendering to 8-bit gray-level bitmaps, though this may
|
||||
change in the future. Here is some code to do just that:</p>
|
||||
|
||||
<font color="blue">
|
||||
<pre>
|
||||
{
|
||||
FT_GlyphSlot glyph;
|
||||
|
||||
... load glyph ...
|
||||
|
||||
glyph = face->glyph; /* shortcut to glyph data */
|
||||
if ( glyph->format == ft_glyph_format_outline )
|
||||
{
|
||||
FT_Bitmap bit;
|
||||
|
||||
/* set-up a bitmap descriptor for our target bitmap */
|
||||
bit.rows = bitmap_height;
|
||||
bit.width = bitmap_width;
|
||||
bit.pitch = bitmap_row_bytes;
|
||||
/* 8-bit gray-level bitmap */
|
||||
bit.pixel_mode = ft_pixel_mode_gray;
|
||||
/* MUST be 128 for now */
|
||||
bit.grays = 128;
|
||||
bit.buffer = bitmap_buffer;
|
||||
|
||||
/* clean the bitmap - IMPORTANT */
|
||||
memset( bit.buffer, 0, bit.rows*bit.pitch );
|
||||
|
||||
/* render the outline directly into the bitmap */
|
||||
error = FT_Get_Glyph_Bitmap( face, &bit );
|
||||
if ( error ) { ... }
|
||||
}
|
||||
}</pre>
|
||||
</font>
|
||||
|
||||
<p>You will notice that</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>As previously, <tt>FT_Get_Glyph_Bitmap()</tt> doesn't generate
|
||||
the bitmap, it simply renders to it.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The target bitmap must be cleaned before calling the function.
|
||||
This is a limitation of our current anti-aliasing algorithm and is
|
||||
EXTREMELY important.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The anti-aliaser uses 128 levels of grays exclusively for
|
||||
now (this will probably change in a near future). This means that
|
||||
you <b>must</b> set <tt>bit.grays</tt> to 128. The generated
|
||||
image uses values from 0 (back color) to 127 (foreground color).</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>It is <b>not</b> possible to render directly an anti-aliased
|
||||
outline into a pre-existing gray-level bitmap, or even any
|
||||
colored-format one (like RGB16 or paletted 8-bits). We will not
|
||||
discuss this issue in great details here, but the reason is that we
|
||||
do not want to deal with graphics composition (or alpha-blending)
|
||||
within FreeType.<p/>
|
||||
</li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
</table>
|
||||
</center>
|
||||
|
||||
</body>
|
||||
</html>
|