diff --git a/docs/design/basic-design.png b/docs/design/basic-design.png new file mode 100644 index 000000000..881e1a8de Binary files /dev/null and b/docs/design/basic-design.png differ diff --git a/docs/design/detailed-design.png b/docs/design/detailed-design.png new file mode 100644 index 000000000..174c1a967 Binary files /dev/null and b/docs/design/detailed-design.png differ diff --git a/docs/design/modules.html b/docs/design/modules.html new file mode 100644 index 000000000..118ddd4b3 --- /dev/null +++ b/docs/design/modules.html @@ -0,0 +1,639 @@ + +FreeType 2 - Modules + + + + + +
+ +

FreeType 2 Modules

+ +
+

Introduction

+
+ +

+The purpose of this document is to present in great details the way +FreeType 2 uses and manages modules. Among other things, it answers +the following questions:

+ +
    +
  • + what is a module, and what kind of modules are recognized + by the library? +

  • + +
  • + how are modules registered and managed by the library? +

  • + +
  • + how to write a new module, especially new font drivers? +

  • + +
  • + how to select specific modules for a given build of the + library ? +

  • + +
  • + how to compile modules as stand-alone DLLs / shared objects? +

  • + +
+ +
+

Overview

+
+ + +

1. Library design:

+ +

The design of the library is pretty basic:

+
    +
  • + 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 modules 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, and they form what is called the "low-level + base API". +

  • +
+ +

This is illustrated by the following graphics:

+ +
+ +

Note that, however, FT2 comes with a set of optional +components that can be ommited from certain builds, and whose +purpose vary between two situations:

+ +
    +
  • + some are located on top of the high-level API and provide + convenience functions that make certain things easier + for typical applications. They typically do not call + modules directly, though they can use the low level + base API for certain tasks.

    + +

    As an example, see the the ftglyph component + that is used to manipulate glyph images more conveniently + than the default API.

    +

  • + +
  • + some other components complement the base layer, by providing + additional routines. Most of them allow client applications + to access format-specific data.

    + +

    For example, the ftmm component provides high-level + functions to specify Multiple Master coordinates for MM Type 1 + fonts.

    +

  • +
+ +

This is illustrated by the following graphics:

+ +
+ +
+

Module Classes

+
+ +

+The library is capable of managing and using several kinds of +modules:

+ +
    +
  • + renderer modules are used to convert scalable glyph images + to bitmaps. FreeType 2 comes by default with two of them:

    + +
    +

    raster1

    +
    +

    supports the conversion of vectorial outlines (described by a + FT_Outline object) to monochrome bitmaps. +

    + +

    smooth

    +
    +

    supports the conversion of the same outlines to high-quality + anti-aliased pixmaps.

    +
    + + +

    The specification and interface of renderers is described in + details within this document.

    + +

    Note that most font formats use FT_Outline objects + to describe scalable glyph images. However, FT2 is flexible + and allows specific modules to register and support other + formats. As an example, it's (at least theorically :-) perfectly + possible to write a renderer module that is capable of directly + converting MetaFont glyph definitions to bitmaps or pixmaps ! + (of course, this assumes that you also write a MetaFont font + driver to load the definitions :-). +

  • + +
  • + font driver modules are used to support one or more specific + font format. By default, FT2 comes with the following modules:

    + +
    + +
    +

    truetype

    +
    +

    supports TrueType font files

    +
    + +

    type1

    +
    +

    supports Postscript Type 1 fonts, both in binary (.pfb) or ASCII + (.pfa) formats, including Multiple Master fonts.

    +
    + +

    cid

    +
    +

    supports Postscript CID-keyed fonts

    +
    + +

    cff

    +
    +

    supports OpenType, CFF as well as CEF fonts (CEF is a derivative + of CFF used by Adobe in its SVG viewer).

    +
    + +

    winfonts

    +
    +

    supports Windows bitmap fonts (i.e. ".FON" and ".FNT").

    +
    + +

    Note that font drivers can support bitmapped or scalable glyph + images. A given font driver that supports bezier outlines through + the FT_Outline can also provide its own hinter, or rely + on FreeType's autohinter module. +

  • + +
  • + helper modules are used to hold shared code that is + often used by several font drivers, or even other modules. + Here are a few examples of helper modules that come with + FreeType 2:

    + +
    + sfnt + + used to support font formats based on the "SFNT" + storage scheme. This means TrueType & OpenType fonts as + well as other variants (like TrueType fonts that only + contain embedded bitmaps). +
    + + psnames + + used to provide various useful function related to glyph + names ordering and Postscript encodings/charsets. For example, + this module is capable of automatically synthetizing a Unicode + charmap from a Type 1 glyph name dictionary. +
    +

  • + + +
  • + finally, the autohinter module has a specific role in + FreeType 2, as it can be used automatically during glyph loading + to process individual glyph outlines when a font driver doesn't + provide it's own hinting engine. +

  • +
+ +

We will now study how modules are described, then managed by + the library.

+ +

1. The FT_Module_Class structure:

+ +

As described later in this document, library initialisation is + performed by calling the FT_Init_FreeType function. The + latter is in charge of creating a new "empty" FT_Library + object, then register each "default" module by repeatedly calling + the FT_Add_Module function.

+ +

Similarly, client applications can call FT_Add_Module + any time they wish in order to register a new module in the library. + Let's take a look at this function's declaration:

+ +

+    extern FT_Error  FT_Add_Module( FT_Library              library,
+                                    const FT_Module_Class*  clazz );
+
+ +

As one can see, this function expects a handle to a library object, + as well as a pointer to a FT_Module_Class structure. It + returns an error code. In case of success, a new module object is + created and added to the library. Note by the way that the module + isn't returned directly by the call !.

+ +

Let's study the definition of FT_Module_Class, and explain it + a bit. The following code is taken from + <freetype/ftmodule.h>:

+ +

+  typedef struct  FT_Module_Class_
+  {
+    FT_ULong               module_flags;
+    FT_Int                 module_size;
+    const FT_String*       module_name;
+    FT_Fixed               module_version;
+    FT_Fixed               module_requires;
+
+    const void*            module_interface;
+
+    FT_Module_Constructor  module_init;
+    FT_Module_Destructor   module_done;
+    FT_Module_Requester    get_interface;
+
+  } FT_Module_Class;
+
+ +

here's a description of its fields:

+ +
+

module_flags

+
+

this is a set of bit flags used to describe the module's +category. Valid values are:

+
    +
  • + ft_module_font_driver if the module is a font driver +

  • + +
  • + ft_module_renderer if the module is a renderer +

  • + +
  • + ft_module_hinter if the module is an auto-hinter +

  • + +
  • + ft_module_driver_scalable if the module is a font + driver supporting scalable glyph formats. +

  • + +
  • + ft_module_driver_no_outlines if the module is a + font driver supporting scalable glyph formats that cannot + be described by a FT_Outline object +

  • + +
  • + ft_module_driver_has_hinter if the module is a font + driver that provides its own hinting scheme/algorithm +

  • +
+
+ +

module_size

+
+

an integer that gives the size in bytes of a given module +object. This should never be less than +sizeof(FT_ModuleRec), but can be more when the module +needs to sub-class the base FT_ModuleRec class.

+
+ +

module_name

+
+

this is the module's internal name, coded as a simple ASCII C +string. There can't be two modules with the same name registered +in a given FT_Library object. However, FT_Add_Module +uses the module_version field to detect module upgrades +and perform them cleanly, even at run-time.

+
+ +

module_version

+
+

a 16.16 fixed float number giving the module's major and minor + version numbers. It is used to determine wether a module needs + to be upgraded when calling FT_Add_Module.

+
+ +

module_requires

+
+

a 16.16 fixed float number giving the version of FreeType 2 that + is required to install this module. By default, should be 0x20000 + for FreeType 2.0

+
+ +

module_requires

+
+

most modules support one or more "interfaces", i.e. tables of function +pointers. This field is used to point to the module's main interface, +where there is one. It's a short-cut that prevents users of the module +to call "get_interface" each time they need to access one of the object's +common entry points.

+ +

Note that is is optional, and can be set to NULL. Other interfaces +can also be accessed through the get_interface field.

+
+ +

module_init

+
+

this is a pointer to a function used to initialise the fields of +a fresh new FT_Module object. It is called after the module's +base fields have been set by the library, and is generally used to +initialise the fields of FT_ModuleRec subclasses.

+ +

Most module classes set it to NULL to indicate that no extra +initialisation is necessary

+
+ +

module_done

+
+

this is a pointer to a function used to finalise the fields of +a given FT_Module object. Note that it is called before the +library unsets the module's base fields, and is generally used to +finalize the fields of FT_ModuleRec subclasses.

+ +

Most module classes set it to NULL to indicate that no extra +finalisation is necessary

+
+ +

get_interface

+
+

this is a pointer to a function used to request the address of +a given module interface. Set it to NULL if you don't need to support +additional interfaces but the main one.

+
+ +
+ + +

2. The FT_Module type:

+ +

the FT_Module type is a handle (i.e. a pointer) to a given + module object / instance, whose base structure is given by the + internal FT_ModuleRec type (we will not detail its + structure here).

+ +

When FT_Add_Module is called, it first allocate a new + module instance, using the module_size class + field to determine its byte size. The function initializes + a the root FT_ModuleRec fields, then calls + the class-specific initializer module_init + when this field is not set to NULL.

+ + + + +
+

Renderer Modules

+
+ +

As said previously, renderers are used to convert scalable + glyph images to bitmaps or pixmaps. Each renderer module is defined + through a renderer class, whose definition is found in the + file <freetype/ftrender.h>. However, a few concepts + need to be explained before having a detailed look at this structure. +

+ +

1. Glyph formats:

+ +

Each glyph image that is loaded by FreeType (either through + FT_Load_Glyph or FT_Load_Char), has a given + image format, described by the field + face->glyph->format. It is a 32-byte integer that + can take any value. However, the file <freetype/ftimage.h> + defines at least the following values:

+ +
+ + + + + + + + +
+ft_glyph_format_bitmap + +this value is used to indicate that the glyph image is a bitmap or pixmap. +Its content can then be accessed directly from +face->glyph->bitmap after the glyph was loaded. +
+ft_glyph_format_outline + +this value is used to indicate that the glyph image is a scalable vectorial +outline, that can be described by a FT_Outline object. Its content +can be accessed directly from +face->glyph->outline after the glyph was loaded. +this is the format that is commonly returned by TrueType, Type1 and +OpenType / CFF fonts. +
+ft_glyph_format_plotter + +this value is equivalent to ft_glyph_format_outline except +that the outline stored corresponds to path strokes, instead of filled +outlines. It can be returned from certain Type 1 fonts (notably the Hershey +collection of free fonts). +
+ft_glyph_format_composite + +this value is used to indicate that the glyph image is really a "compound" +of several other "sub-glyphs". This value is only returned when a glyph +is loaded with the FT_LOAD_NO_RECURSE flag. The list of +subglyphs that make up the composite can be accessed directly as +face->glyph->subglyphs after the glyph was loaded. +
+ +

Note that this is only a list of pre-defined formats supported by + FreeType. Nothing prevents an application to install a new font + driver that creates other kinds of glyph images. For example, one + could imagine a MetaFont font driver, that would be capable to + parse font definition files and create in-memory "glyph programs", + that could be returned in face->glyph->other.

+ +

2. The FT_Outline type:

+ +

This structure, which is also defined, and heavily commented, in + the file <freetype/ftimage.h>, is used to hold + a scalable glyph image that is made of one or more contours, each + contour being described by line segments or bezier arcs (either + quadratic or cubic). The outline itself is stored in a compact + way that makes processing it easy.

+ +

Points are placed in a 2D plane that uses the y-upwards convention, + and their coordinates are stored in 1/64th of pixels (also known + as the 26.6 fixed point format). Pixels correspond to single squares + whose borders are on integer coordinates (i.e. mutiples of 64). + In other words, pixel centers are located on half pixel coordinates.

+ +

Outlines can be very easily transformed (translated, rotated, etc..) + before being converted to bitmap, which allows for sophisticated + use of text. FreeType 2 comes by default with two "outline renderer" + modules:

+ +

    +
  • raster1, used to convert them to monochrome bitmaps
  • +
  • smooth, used to convert them to high-quality anti-aliased + pixmaps
  • +

+ +

3. Bitmaps and scan-conversion:

+ +

Bitmaps and pixmaps are described through a FT_Bitmap + structure, which is defined and heavily commented in + <freetype/ftimage.h> + + +


+  typedef struct  FT_Renderer_Class_
+  {
+    FT_Module_Class       root;
+
+    FT_Glyph_Format       glyph_format;
+
+    FTRenderer_render     render_glyph;
+    FTRenderer_transform  transform_glyph;
+    FTRenderer_getCBox    get_glyph_cbox;
+    FTRenderer_setMode    set_mode;
+
+    FT_Raster_Funcs*      raster_class;
+
+  } FT_Renderer_Class;
+
+ +
+

Font Driver Modules

+
+ +
+

Library Initialisation & Dynamic Builds

+
+ +

By default, all components of FreeType 2 are compiled independently, + then grouped into a single static library file that can be installed + or used directly to compile client applications

+ +

Such applications must normally call the FT_Init_FreeType + function before using the library. This function is in charge of + two things:

+ +
    +
  • + First, it creates a FT_Library object (by calling + the public function FT_New_Library). This new + object is "empty" and has no module registered in it. +

  • + +
  • + Then, it registers all "default modules" by repeatedly calling + FT_Add_Module. +

  • +
+ +

It is important to notice that the default implementation of + FT_Init_FreeType, which is located in the source + file "src/base/ftinit.c" always uses a static + list of modules that is generated at compile time from the + configuration file <freetype/config/ftmodule.h>. +

+ +

There are cases where this may be inadequate. For example, one + might want to compile modules as independent DLLs in a specific + location (like "/usr/lib/freetype/module/"), and have + the library initialisation function load the modules dynamically + by parsing the directory's content

+ +

This is possible, and we're going to explain how to do it.

+ + +

a. Building the library as a DLL (i.e. "shared object" on Unix)

+ +

But first of all, let's explain how to build FreeType 2 as a single + DLL or shared object, i.e. one that includes the base layer, all + default modules and optional components into a single file.

+ +

When building dynamic libraries, certain compilers require specific + directives to declare exported DLL entry points. For example, the + "__cdecl" directive is required by Win32 compilers, as it forces + the use of the "C" parameter passing convention (instead of "smarter" + schemes, which usually use registers and the stack to pass parameters).

+ +

To make matter worse, some of these compilers require the directive + before the function's return type, while some others want it between + the return type and the function's identifier.

+ +

To allow such compilations, the FT_EXPORT_DEF() macro is + used in all public header files in order to declare each high-level + API function of FreeType 2, as in the following example, taken from + <freetype/freetype.h>:

+ +

+   FT_EXPORT_DEF(FT_Error)  FT_Init_FreeType( void );
+
+ +

the definition of FT_EXPORT_DEF(x) defaults to "extern x", + except when a specific definition is given in the library's system-specific + configuration file <freetype/config/ftconfig.h>. This + allows project builders to specify the exact compilation directive + they need.

+ +

Similarly, the FT_EXPORT_FUNC(x) macro is defined and used to + define exported functions within the FreeType 2 source code. + However, it is only used at compilation time.

+ + +

Note that on Unix, there is no need for specific exportation directives. + However, the code must be compiled in a special way, named Position + Independent Code ("PIC"), which is normally selected through specific + compiler flags (like "-PIC" with gcc).

+ + +

b. Building modules as DLLs

+ +

In order to build modules as dynamic libraries, we first need to compile + the base layer (and optional components) as a single DLL. This is very + similar to the case we just described, except that we also need to + export all functions that are part of the "low level base API", + as these will get called by the modules in various cases.

+ +

Similarly to the high-level API, all functions of the low-level base + API are declared in the internal header files of FreeType 2 with the + BASE_DEF(x) macro. The latter is similar to + FT_EXPORT_DEF and defaults to "extern x" unless + you specify a specific definition in + <freetype/config/ftconfig.h>.

+

+ +


+ +
+

Conclusion

+
+ +
+ + diff --git a/docs/docmaker.py b/docs/docmaker.py index 812b5993d..b71d81f02 100644 --- a/docs/docmaker.py +++ b/docs/docmaker.py @@ -101,12 +101,15 @@ source_footer = """ # The first two markers contain arbitrary text, while the last one contains # a list of field # -# # each field is simple of the format: WORD :: TEXT.... # # Note that typically, each comment block is followed by some source # code declaration that may need to be kept in the reference.. # +# Note that markers can alternatively be written as "@MARKER:" +# instead of "". All marker identifiers are converted to +# lower case during parsing, in order to simply sorting.. +# def make_block_list(): @@ -323,8 +326,8 @@ class DocParagraph: # # but older Python versions don't have the `extend' attribute # - self.words[len( self.words ) : len( self.words )] = \ - string.split( line ) + last = len(self.words) + self.words[last:last] = string.split( line ) def dump( self ): @@ -360,6 +363,30 @@ class DocParagraph: # # DocContent is used to store the content of a given marker. # +# the "self.items" list contains (field,elements) record, where +# "field" corresponds to a given structure fields or function +# parameter (indicated by a "::"), or NULL for a normal section +# of text/code +# +# hence, the following example: +# +# +# this is an example of what can be put in a content section, +# +# a second line of example text +# +# x :: a simple test field, with some content +# y :: even before, this field has some code content +# { +# y = x+2; +# } +# +# should be stored as +# [ ( None, [ DocParagraph, DocParagraph] ), +# ( "x", [ DocParagraph ] ), +# ( "y", [ DocParagraph, DocCode ] ) ] +# +# class DocContent: def __init__( self, lines_list ):