+
+
+
+
+ II. Public Objects and Classes
+
+ |
+
+
+ We will now explain 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 FreeType 2 source
+ code:
+
+
+ -
+
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
+ FreeType 2. We would define the following structure and handle
+ types as follows:
+
+
+ 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.
+
+ -
+
Class derivation is achieved internally by wrapping base class
+ structures into new ones. As an example, we 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 returns a FT_Foo handle to client applications,
+ the object can be really implemented as a FT_FooBar or any
+ derived class from "foo".
+
+
+
+ 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
+ actions.
+
+ 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: an 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), and 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
+ FreeType 2 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 contents 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
+ structure, 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 explicitly provide
+ data to compute a slot's maximum size.
+
+ Another reason for glyph slots is that they are also used to hold
+ format-specific hints for a given glyphs as 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 Type 1-specific T1_GlyphSlotRec structure holds glyph
+ hints during glyph loading, as well as additional logic used to properly
+ hint the glyphs when a native Type 1 hinter is used.
+
+ Finally, each face object has a single glyph slot that is directly
+ accessible as face->glyph.
+
+
+
+
+ 6. The FT_CharMap class
+
+
+ The FT_CharMap type is used as a handle to character map
+ objects, or charmaps. 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 encodings.
+
+ 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 Design of FreeType 2
+ The following diagram summarizes what we have just said regarding the
+ public objects managed by the library, as well as explicitely describes
+ their relationships
-
-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:
-
-
-
- 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.
-
-
-
-
- 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".
-
-
-
-
-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.
-
- |