The Design of FreeType 2
It's better to describe FreeType 2 as a collection of
components. Each one of them is a more or less abstract
part of the library that is in charge of one specific task. We will
now explicit the connections and relationships between them.
A first brief description of this system of components could be:
client applications typically call the FreeType 2 high-level
API, whose functions are implemented in a single component
called the Base Layer.
depending on the context or the task, the base
layer then calls one or more module components to
perform the work. In most cases, the client application doesn't
need to know what module was called.
the base layer also contains a set of routines that are
used for generic things like memory allocation, list
processing, i/o stream parsing, fixed point computation,
etc.. these functions can also be called by a module
at any time, and they form what is called the low-level
base API.
This is illustrated by the following graphics (note that component
entry points are represented as colored triangles):
Now, a few additional things must be added to complete this picture:
some parts of the base layer can be replaced for specific builds
of the library, and can thus be considered as components themselves.
this is the case for the ftsystem component, which is in
charge of implementing memory management & input stream access,
as well as the ftinit, which is in charge of library
initialisation (i.e. implementing FT_Init_FreeType).
FreeType 2 comes also with a set of optional components,
which can be used either as a convenience for client applications
(e.g. the ftglyph component, used to provide a simple API
to manage glyph images independently of their internal representation),
or to access format-specific features (e.g. the ftmm component
used to access and manage Multiple Masters data in Type 1 fonts)
Finally, a module is capable of calling functions provided by
another module. This is very useful to share code and tables
between several font driver modules (for example, the truetype
and cff both use the routines provided by the sfnt
module).
Hence, a more complete picture would be:
Please take note of the following important points:
an optional component can use either the high-level or base
API. This is the case of ftglyph in the above picture.
some optional component can use module-specific interfaces
ignored by the base layer. In the above example, ftmm
directly accesses the Type 1 module to set/query data
a replacable component can provide a function of the high-level
API. For example, ftinit provides FT_Init_FreeType
to client applications.
|