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..VER-2-0-4-PATCH
@ -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> |