From 4cd68a09c52289fd27ca556e7d83055b51c3f295 Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 25 Oct 2000 23:42:02 +0000 Subject: [PATCH] updating the FT2 design documentation - note that the "modules.html" will soon disappear, it is now replaced by a more general and more detailed series of pages named "design-??.html" - the images have been seriously reworked, more will come tomorrow --- docs/design/basic-design.png | Bin 990 -> 2047 bytes docs/design/design-1.html | 82 +++++++++ docs/design/design-2.html | 112 +++++++++++++ docs/design/design-3.html | 263 +++++++++++++++++++++++++++++ docs/design/design-4.html | 289 ++++++++++++++++++++++++++++++++ docs/design/detailed-design.png | Bin 1868 -> 2462 bytes 6 files changed, 746 insertions(+) create mode 100644 docs/design/design-1.html create mode 100644 docs/design/design-2.html create mode 100644 docs/design/design-3.html create mode 100644 docs/design/design-4.html diff --git a/docs/design/basic-design.png b/docs/design/basic-design.png index 881e1a8de21705924c5f828d42b892112db06f7d..5acdccc54ad84ec78d74d3b997451fe288cbe0ad 100644 GIT binary patch literal 2047 zcmZ`)4K&kj8=tgS&zL^^iy8?JHnfnhC}z#f$1}5tgz{NJWRj52B2%F$@)2XKW>caE z%SRiNg-v7`;hCbOFQL?9JUs8yd(Qiw^Pcm&?%(ge?sK1WUFY2Q@5&_L?V*qz5D*9i zb--bWAdn1sHTJESUCksY#x1VWMuM}O-O9?!ssydAE1+Z$=y78)2qahSfU$Lp9sW=v z6T{R~Narh}N1!i1mYq2KSunl)V*cVL6gbqLP`teIa^zis@%K%BIU71ro7UU@8{pg) zUnsmr(5Zt=UI&zcz;Kidgs>)6IN-l|Ej9Z9h-ohv`dpV-g7e!w&~Gu`0_FvFlIR{l zWiJQbh~Wgi$fz=G#ry`&qRV$YAmlt;ZrkG;IH?|Q6_A-G@dQMap~%g#dLm_h#LB_< zC(9*jC#IH2ob=R@T+LPoECQZ~8g^$3=#g4BxoAfsUgAW++gkmLENEqGN8HftUc_;- zNVRXgY#vor5*WciT|V*k@2?2Xb|H)yZ(e(#j~&hQy1sks?S9BpwYiwFL}A}6(0B#c zp{XBCxM~X-v%uYV#zk2l0HAO^Dd>*{BFribZ_bhYe(mwB)_sS0wu@&jKv>L~dT)@h zRf;s-m`DpRbmfH>K$9+YRmO*#c(QG;_WMLnnC}f|;Oy1m(1XltP^ZmBjJt(-amJ^C zYf|GhK`QRI8zuXv#8}A?+zaZr&!t7jMHzM}pb7cf>q2xGW30Zf<0`kdmsUgTt9p8h znz?#bLF}j^FW=&=-nkFdTXw*nU@K3Sx_zoy*aysLu^x%@T}?g!3zdI-$(>SrUIWZ) zx3Ll;w5LywU*#rN?yRJ~QLZMWYlh z9*A2(0NO1=abwyrWkNa|yPh05j;+Z$>PkaW_ZRn28Snaftt$s-kZVsjDa+p#{PEH3 zepOzSW|fa(YB>x%9kz?(c+~rr`0X~p_)lVS$|bEr1-WO-w3`Uh4{-^)HRV*k0lkmf zsEbe#hVhd|{Vij4*;q;ESfF4#44!aL2g)<8Fl=Tkz=$|=O6ra1P5lIKEy&a|AUk$u`d&Up?au@iLp6%>=LTsgcfqC1 zL+K?>vm>;(?KrjjsoVq{Dda41Z^@v+M}G8)DwpaPdUxw?$0tns_76Iw_!rYq zMtEYGiY|h1g#y4KpALnuYy&LEmIag2c*4cmn7D?YBH_k2xr#f^uV!NtnvQ+Swm;uS z%PqH*F2FiR_~(6w)qQVkUTGN6>OdKM%gFE1-1F)~cg}kWM4-cyE)anRxOr0A#Nt7R zGLRkq3?*0wFwdcvZ4Rc(^7J3Zm8sa4so1Y#k8N$?<<~dkppdIUAl||%2fUGFns0@7 zK69#%+k^H)8C{;R=w>1O2@9$I@eRl}Eee&!h``VKIq8^JY_J_XM=vYqkHVko{QThm_#2jXUo3Rg1XD-|kz&`uud}}O z*!tZ{-#Ii5J8f8l+UL!};$1yu9 z7*i?$VNgI6%7EK!P=}e~MUBv8d3vx0Ropi5l2fG;J0z;W|Ad)HwTls264$?FhS}7O zr3d$4^xwN$o61D|^J`%*V~%eiw=4dSU;l0018^ifkT^ zY(zZ1Cxw!?f^QAC?5t@v&$ePtMMIp!5{$$pF}%IoCnaJa)r{dE80^GvMj=s9~zJ4^k*0tF^FBDfL z2X0Cymy?>ZAGGG11Zvb1?ooTrk>$ImMNDr2d?;TaGG#@~C+wc6K_6=xx-Urx)NgzF zMV)uyRR2oNAeW lhi7G&7R7m_lkS?j zgSvodvYi#w6p>Ck>29H0wO89Jqt#p?!WVqg3~(gM7!r=JsyQUwUI>Sa6C-=stl6J? zU0mAqcRP3mVH3o`zy|(pRB10`aHna}feebEDsIj|S>ZOh%lW$qG7tjX8Qhip$0dS= zL0Ff|g>z>@I_adlvMy|$cskIzjY=n- zbT`R0*4T|-lB@N&umE@9b07;gU*{-7;Vx=rtSnfxW`gpiUzwlNdXiOazpb?O8qbzRYT1i3LHN> z^l*-4(8 zI_i8KD9-mr$*rGE+qqe8=a7$cx1^Kq*1NSM$93+W=Z@GKcj+`ER5(Rpy5)5uiykFa z%8NNfw$~gt+39so7NtpMyFZ^DH>G=>lSS#*ic{{c7KQtkY-vxs&dK7gSXd?scT<>$ za8N|W*;(9)!vvB1%RP)U+;CyS4BtkCyV@tt2M z>q=Z#(n)tyoKIa+ac*70&W5)xVO8Sl|G!Q;=`P~b!}apIv;0(ak}-Re@Y3Sg4RKep z{|TfEw}$LT(ZW&v*ol3mlH?`Li>1bqOIk9Y}4b0VH{gCGm&4=1YK}u)`A*@z*yc`F|grnFEN<0Ak2_y z67AODtf^@UsHO}anUvRoPsoJOAOL5#wZyF13xGCRcJt8V20$K}Kr;})!~$T@1Oxz* z5(NSBy2OjTVFIv@dUi03gTZ|e?TM3eSz}Bej|**_XwL1nnp^1I-&nd0JU(pQooG?g z@Waf<+>&SfDq-3~sCxJ5XB`!N!D5m<`_yyVQ~0Y`lj}-4>28nv2OjaYnQ{Hr5&!@I M07*qoM6N<$f)Zu;6#xJL diff --git a/docs/design/design-1.html b/docs/design/design-1.html new file mode 100644 index 000000000..604fbc873 --- /dev/null +++ b/docs/design/design-1.html @@ -0,0 +1,82 @@ + +The Design of FreeType 2 - Introduction + + + + + +
+ +

The Design of FreeType 2

+ +
+

Introduction

+
+ +

This document provides details on the design and implementation + of the FreeType 2 library. Its goal is to allow developers to + better understand the way FT2 is organized, in order to let them + extend, customize and debug it.

+ +

Before anything else, it is important to understand the purpose + of this library, i.e. why it has been written:

+ +
    +
  • first of all, to allow client applications to access font files + easily, wherever they could be stored, and as independently + of font format as possible.

  • + +
  • to allow easy retrieval of global font data most commonly + found in normal font formats (i.e. global metrics, + encoding/charmaps, etc..)

  • + +
  • to allow easy retrieval of individual glyph data + (metrics, images, name, anything else)

  • + +
  • to allow access to font format-specific "features" + whenever possible (e.g. SFNT tables, Multiple Masters, + OpenType Layout tables, etc..)

  • +
+ +

its design has also severely been influenced by the following + requirements:

+ +
    +
  • high portability, as the library must be able to run + on any kind of environment. this requirement introduces a few + drastic choices that are part of FreeType 2's low-level system + interface.

  • + +
  • extendibility, as new features should be added with + the least modifications in the library's code base. this + requirements induces an extremely simple design where nearly + all operations are provided by modules. +

  • + +
  • customization, it should be easy to build a version + of the library that only contains the features needed by a + specific project. This really is important when you need to + integrate it in a font server for embedded graphics libraries.

  • + +
  • compactness and efficiency, given that the + primary target for this library is embedded systems with low + cpu and memory resources.

  • +
+ +

The rest of this document is divided in several sections. First, a + few chapters will present the library's basic design as well as the + objects/data managed internally by FreeType 2.

+ +

A later section is then dedicated to library customization, relating + such topics as system-specific interfaces, how to write your own + module and how to tailor library initialisation & compilation + to your needs.

+ +
+ + diff --git a/docs/design/design-2.html b/docs/design/design-2.html new file mode 100644 index 000000000..fba5c9887 --- /dev/null +++ b/docs/design/design-2.html @@ -0,0 +1,112 @@ + +The Design of FreeType 2 - Basic Design + + + + + +
+ +

The Design of FreeType 2

+ +
+

I. Components and APIs

+
+ +

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. +

  • +
+ +
+ + diff --git a/docs/design/design-3.html b/docs/design/design-3.html new file mode 100644 index 000000000..83900f278 --- /dev/null +++ b/docs/design/design-3.html @@ -0,0 +1,263 @@ + +The Design of FreeType 2 - Public Objects + + + + + +
+ +

The Design of FreeType 2

+ +
+

II. Public Objects and Classes

+
+ +

We will now detail the abstractions provided by FreeType 2 to + client applications to manage font files and data. As you would + normally expect, these are implemented through objects/classes.

+ +

1. Object Orientation in FreeType 2:

+ +

Though written in ANSI C, the library employs a few + techniques, inherited from object-oriented programming, to make + it easy to extend. Hence, the following conventions apply in + the FT2 source code:

+ +
    +
  1. + each object type/class has a corresponding structure type and + a corresponding structure pointer type. the latter is called the + handle type for the type/class.

    + +

    Consider that we need to manage objects of type "foo" in FT2. + We would define the following structure and handle types as + follow:

    + +
    
    +     typedef struct FT_FooRec_*    FT_Foo;
    +
    +     typedef struct FT_FooRec_
    +     {
    +       // fields for the "foo" class
    +       ...
    +
    +     } FT_FooRec;
    +  
    + +

    As a convention, handle types use simple but meaningful identifiers + beginning with "FT_", as in "FT_Foo", while structures use the same + name with a "Rec" suffix appended to it ('Rec' is short for "record"). + Note that each class type has a corresponding handle type. +

    + + +
  2. + class derivation is achieved internally by wrapping base class + structures into new ones. As an example, let's define a "foobar" + class that is derived from "foo". We would do something like:

    + +
    
    +     typedef struct FT_FooBarRec_*    FT_FooBar;
    +
    +     typedef struct FT_FooBarRec_
    +     {
    +       // the base "foo" class fields
    +       FT_FooRec     root;
    +
    +       // fields proper to the "foobar" class
    +       ...
    +
    +     } FT_FooBarRec;
    +  
    + +

    As you can see, we ensure that a "foobar" object is also a "foo" + object by placing a FT_FooRec at the start of the + FT_FooBarRec definition. It is called root + by convention.

    + +

    Note that a FT_FooBar handle also points to a "foo" object + and can be typecasted to FT_Foo. Similarly, when the + library handles a FT_Foo handle to client applications, + the object can be really implemented as a FT_FooBar or any + derived class from "foo".

    + +

  3. + + +

    Note that in the following sections of this chapter, we will refer + to "the FT_Foo class" to indicate the type of objects + handled through FT_Foo pointers, be they implemented as + "foo" or "foobar".

    + +
    + +

    2. The FT_Library class:

    + +

    This type corresponds to a handle to a single instance of the + library. Note that the corresponding structure FT_LibraryRec + is not defined in public header files, making client applications + unable to access its internal fields.

    + +

    The library object is the "parent" of all other objects in FreeType 2. + You need to create a new library instance before doing anything else + with the library. Similarly, destroying it will automatically + destroy all its children (i.e. faces and modules).

    + +

    Typical client applications should call FT_Init_FreeType, + in order to create a new library object, ready to be used for + further action.

    + +

    Another alternative is to create a fresh new library instance + by calling the function FT_New_Library, defined in the + <freetype/ftmodule.h> public header file. This + function will however return an "empty" library instance with + no module registered in it. You can "install" modules in the + instance by calling FT_Add_Module manually.

    + +

    Calling FT_Init_FreeType is a lot more convenient, because + this function basically registers a set of default modules into + each new library instance. The way this list is accessed and/or + computed is determined at build time, and depends on the content + of the ftinit component. This process is explained in + details later in this document.

    + +

    For now, one should consider that library objects are created + with FT_Init_FreeType, and destroyed along with all + children with FT_Done_FreeType.

    +
    + +

    3. The FT_Face class:

    + +

    A face object corresponds to a single font face, i.e. + a specific typeface with a specific style. For example, "Arial" + and "Arial Italic" correspond to two distinct faces.

    + +

    A face object is normally created through FT_New_Face. + This function takes the following parameters: a FT_Library + handle, a C file pathname used to indicate which font file to + open, an index used to decide which face to load from the file + (a single file may contain several faces in certain cases), + as well as the address of a FT_Face handle. It returns + an error code:

    + +
    
    +  FT_Error  FT_New_Face( FT_Library   library,
    +                         const char*  filepathname,
    +                         FT_Long      face_index,
    +                         FT_Face     *face );
    +
    + +

    in case of success, the function will return 0, and the handle + pointed to by the "face" parameter will be set to a non-NULL value.

    + +

    Note that the face object contains several fields used to + describe global font data that can be accessed directly by + client applications. For example, the total number of glyphs + in the face, the face's family name, style name, the EM size + for scalable formats, etc.. For more details, look at the + FT_FaceRec definition in the FT2 API Reference.

    + +
    + +

    4. The FT_Size class:

    + +

    Each FT_Face object has one or more FT_Size + objects. A size object is used to store data specific to a + given character width and height. Each newly created face object + has one size, which is directly accessible as face->size.

    + +

    The content of a size object can be changed by calling either + FT_Set_Pixel_Sizes or FT_Set_Char_Size.

    + +

    A new size object can be created with FT_New_Size, and + destroyed manually with FT_Done_Size. Note that typical + applications don't need to do this normally: they tend to use + the default size object provided with each FT_Face.

    + +

    The public fields of FT_Size objects are defined in + a very small structure named FT_SizeRec. However, it is + important to understand that some font drivers define their own + derivatives of FT_Size to store important internal data + that is re-computed each time the character size changes. Most of + the time, these are size-specific font hints./p> + +

    For example, the TrueType driver stores the scaled CVT table that + results from the execution of the "cvt" program in a TT_Size, + while the Type 1 driver stores scaled global metrics (like blue zones) + in a T1_Size object. Don't worry if you don't understand + the current paragraph, most of this stuff is highly font format + specific and doesn't need to be explained to client developers :-)

    + +
    + +

    5. The FT_GlyphSlot class:

    + +

    The purpose of a glyph slot is to provide a place where glyph + images can be loaded one by one easily, independently of the + glyph image format (bitmap, vector outline, or anything else).

    + +

    Ideally, once a glyph slot is created, any glyph image can + be loaded into it without additional memory allocation. In practice, + this is only possible with certain formats like TrueType which + explicitely provide data to compute a slot's maximum size.

    + +

    Another reason for glyph slots is that they're also used to hold + format-specific hints for a given glyphs has well as all other + data necessary to correctly load the glyph.

    + +

    The base FT_GlyphSlotRec structure only presents glyph + metrics and images to client applications, while actual implementation + may contain more sophisticated data.

    + +

    As an example, the TrueType-specific TT_GlyphSlotRec + structure contains additional fields to hold glyph-specific bytecode, + transient outlines used during the hinting process, and a few other + things. + + the Type1-specific T1_GlyphSlotRec structure holds + glyph hints during glyph loading, as well as additional logic used + to properly hint the glyphs when a native T1 hinter is used.

    + +

    Finally, each face object has a single glyph slot, that is directly + accessible as face->glyph.

    + +
    + +

    6. The FT_CharMap class:

    + +

    Finally, the FT_CharMap type is used as a handle to + character map objects, or "charmaps" to be brief. A charmap is + simply some sort of table or dictionary which is used to translate + character codes in a given encoding into glyph indices for the + font.

    + +

    A single face may contain several charmaps. Each one of them + corresponds to a given character repertoire, like Unicode, Apple Roman, + Windows codepages, and other ugly "standards".

    + +

    Each FT_CharMap object contains a "platform" and an "encoding" + field used to identify precisely the character repertoire corresponding + to it.

    + +

    Each font format provides its own derivative of FT_CharMapRec + and thus needs to implement these objects.

    + +
    +

    7. Objects relationships:

    + +

    The following diagram summarizes what we just said regarding the + public objects managed by the library, as well as explicitely + describes their relationships:

    + +

    Note that this picture will be updated at the end of the next + chapter, related to internal objects.

    + +
+ + diff --git a/docs/design/design-4.html b/docs/design/design-4.html new file mode 100644 index 000000000..0a0c63338 --- /dev/null +++ b/docs/design/design-4.html @@ -0,0 +1,289 @@ + +The Design of FreeType 2 - Internal Objects + + + + + +
+ +

The Design of FreeType 2

+ +
+

III. Internal Objects and Classes

+
+ +

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.

+ +

1. Memory management:

+ +

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.

+ +

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.

+ +

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.

+ +

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:

+ +
    +
  1. + create a new FT_Memory object by hand. The definition of + FT_MemoryRec is located in the public file + <freetype/ftsystem.h>. +

  2. + +
  3. + 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. +

  4. + +
  5. + 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. +

  6. +
+ + +
+

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.

+ +

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, 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 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 + 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).

+ +

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's certainly + not a good idea to keep numerous FT_Face objects + opened.

+ +
+

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.

+ +

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:

+ +

You need a pointer to a 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 );
+
+ +

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 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. +

  • + +
  • + 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. +

  • + +
  • + when a module initializer is present in the module class, it will + be called to complete the module object's initialisation. +

  • + +
  • + 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 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:

+ +
    +
  • + 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. +

  • + +
  • + 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. +

  • + +
  • + 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. +

  • + +
  • + 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.. +

  • +
+ +

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).

+ + +

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 !!

+
+ +
+

4. Libraries:

+ +

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. +

  • + +
  • + 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, 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:

+ +
+ +
+ + diff --git a/docs/design/detailed-design.png b/docs/design/detailed-design.png index 174c1a967cbece91bf09cf2d8005e224f95d1d22..d27f761a1858a08b1aafddd5757f90c96f2d02c4 100644 GIT binary patch literal 2462 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 G_QCIzy?>zq literal 1868 zcmV-S2ebHzP)r00000qVtTt000LQNkl4L^|3+xU>9+!4Fy&V*mECNEN##teTl`o1w<#Z!UkE9 zJPZj2KV(LeXm5R*QXoxO=SnfEgQ`K|sAz$?27RIfVrv0gJS#$URw?p!CsK|{$tK;} zn3LTB7LVlTU#H{ocp^``$Y#>YuKy>#yelFJ0gj_W8k}>^Ip>cEzvwOQ65_<*3y{9h zRVyAZ(;XUJMRXB^=NVs&%{6GguxGJQu&Tw~=EQU)pMxK1(6W{+dkW5g=;$iYAQF>h zTg^i)nx6z(fpTM-@?zvig&NTEj04K;$cluJa*HOQ(rgsJcgB3W)PMNi&C$YF=9$w` z+)D_BHf$*`7B|H^66c(A&iT*en;h!NZ!*^FzAj_i#ypUu8ydTYptCQisITxW>Xx=-<>&_ zI59LN_Fp=PqxdN#LpX0_AiQgdFp_JGSB!L}QmLaje5|bc+}az1XI6P7PIQ$PoR!_O zVsN2YI5$3YErA199E@XcK) zNoVw!S8dKYf86-89EbbE_>Fm?ldq6CyeY@v=FjF%EdEm~l63I(?h^HcJ1n`yWzs!4 z;kV$NbIu<*&bm%BKDRXzzCXQ{{Ig{fS8t9^#N#V+5@Oe~ZpST*s8U`wV)E}sPvYeV zH{$Zy6B^DvFuHTrZ6|`9mOW=%LEh6NJY8*g{7T?34Lxrz>`PbA1-LqreW`}MN6Ttw zBd`exaBU=aeQ|w`!yHkLihaAyiDJH!mqPqhivutPXY71*i`39n@H)z<>{;>V_;f4| z0Pr}7%|Yu)bPO&O>0!df(_fiq3VUOoeAt@+;Kbw&kJn6M zFXa}CPCqIu(_L0}_O1uQW%pxH&ZbEtc9?{|UyZWE)IZ+;w{Xq)G3a3$U4HLXA*#*z zF?MbP=A3iRw}NjxFkI!Gb8bT^Ffb&MY27JWoO8~3kZaAQ)-v1r;wRjp88WvHzd^Zc zwXz1|{~;EeSPz}#C8VgSmGlNy&ESc~D0-&@BY8Mwe#FTcndqr;k~jXSwcu>SfXgBX-&u70|BQDoaaUJn+gF?=}tGpERVjw`Q`)N6K1$5PT(tPyQ3 zcV@5c0hdLL$39L%ThGaIdhm!_U-&VV#>p~PtRE6UXwsy@Q;XOQHVLmOaUGtx{3hVOiYGT{X8>_iy zM<&eS!@kp@S2h2Ua+35Bx3>#7*78c5SBOGfy@OXLdjERqx$2jHyk)*Hxv%u$@bffZ z`~K|@6UPQhQ{Nn0336)&q(<}#7&rnyI;t!4xx;UP zmXhlA-Fg-sh2=a^%ia5y4(-V8|Oqge_SBmdHH<`UXIY9Go)rN0hNSkMe zKdCN+D$*}o;78-DNeow{oAB3#E_%5b=0By)aL)M-;Qs~hQzetgtJ1{)0000