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