diff --git a/docs/design/io-frames.html b/docs/design/io-frames.html index 6bd515a19..2b249b691 100644 --- a/docs/design/io-frames.html +++ b/docs/design/io-frames.html @@ -1,12 +1,12 @@
- - - -
-
- It is targetted to FreeType hackers, or more simply to developers who would - like a better understanding of the library's source code. -
- -
- But an example is certainly more meaningful than anything else. - The following code: -
-
- error = read_short(stream, &str.value1);
- if (error) goto ...
-
- error = read_ulong(stream, &str.value2);
- if (error) goto ...
-
- error = read_ulong(stream, &str.value3);
- if (error) goto ...
-
- can easily be replaced with:
-
-
- error = FT_Access_Frame(stream, 2+4+4);
- if (error) goto ...
-
- str.value1 = FT_Get_Short(stream);
- str.value2 = FT_Get_ULong(stream);
- str.value3 = FT_Get_ULong(stream);
-
- FT_Forget_Frame(stream);
-
-
- Here, the call to FT_Access_Frame will:
+
+
+ + + + Introduction ++ +This document explains the concept of I/O frames as used in the + FreeType 2 source code. It also enumerates the various functions and + macros that can be used to read them. + +It is targeted to FreeType hackers, or more simply to developers who + would like a better understanding of the library's source code. + ++ + + I. What frames are ++ +Simply speaking, a frame is an array of bytes in a font file that is + "preloaded" into memory in order to be rapidly parsed. Frames are useful + to ensure that every "load" is checked against end-of-file overruns, and + provides nice functions to extract data in a variety of distinct + formats. + +But an example is certainly more meaningful than anything else. The + following code + + ++ error = read_short( stream, &str.value1 ); + if ( error ) goto ... + + error = read_ulong( stream, &str.value2 ); + if ( error ) goto ... + + error = read_ulong( stream, &str.value3 ); + if ( error ) goto ...+ + + can easily be replaced with + + ++ error = FT_Access_Frame( stream, 2 + 4 + 4 ); + if ( error ) goto ... + + str.value1 = FT_Get_Short( stream ); + str.value2 = FT_Get_ULong( stream ); + str.value3 = FT_Get_ULong( stream ); + + FT_Forget_Frame( stream );+ + + Here, the call to FT_Access_Frame() will +
- Each FT_Get_Short or FT_Get_ULong call will read a - big-endian integer from the stream (2 bytes for FT_Get_Short, - 4 bytes for FT_Get_ULong) and advance the frame cursor accordingly. - - FT_Forget_Frame "releases" the frame from memory - - There are several advantages to using frames : + + Each FT_Get_Short() or FT_Get_ULong() call will read + a big-endian integer from the stream (2 bytes for + FT_Get_Short(), 4 bytes for FT_Get_ULong) and + advance the frame cursor accordingly. + +FT_Forget_Frame() "releases" the frame from memory. + +There are several advantages to using frames: +
- - - - - II. Accessing and reading a frame with macros:-
- Note that error must be a local variable of type FT_Error, - The macro used to access a frame is - ACCESS_Frame(_size_), it will - translate to: -
- Similarly, the macro - FORGET_Frame() - translates to: -
- Extracting integers can be performed with the GET_xxx macros, like: -
- (Note that an Offset is an integer stored with 3 bytes on the file). - - All this means that the following code:
- - Can be replaced with macros by:
- - Which is clearer. Notice that error and stream must be defined - locally though for this code to work.. !! - - - III. Alternatives:-
- For example, - FT_Read_Short( stream, &error ) reads and - returns a 2-byte big-endian integer from a stream, and place an - error code in the error variable. - - Thus, reading a single big-endian integer is shorter than using a frame - for it. - - Note that there is also the macros - READ_xxx() which translate to:
- - and can be used as in:
- - when error and stream are already defined locally.. - + + + II. Accessing and reading a frame with macros ++ +By convention in the FreeType source code, macros are able to use two + implicit variables named error and stream. This is + useful because these two variables are extremely often used in the + library, and doing this only reduces our typing requirements and make the + source code much clearer. + +Note that error must be a local variable of type + FT_Error, while stream must be a local variable or + argument of type FT_Stream. + +The macro used to access a frame is ACCESS_Frame(_size_), it will + translate to + + ++ ( error = FT_Access_Frame( stream, _size_ ) ) + != FT_Err_Ok+ + + Similarly, the macro FORGET_Frame() translates to + + ++ FT_Forget_Frame( stream )+ + + Extracting integers can be performed with the GET_xxx() + macros, like + +
(Note that an Offset is an integer stored with 3 bytes on + the file.) + +All this means that the following code + + ++ error = FT_Access_Frame( stream, 2 + 4 + 4 ); + if ( error ) goto ... + + str.value1 = FT_Get_Short( stream ); + str.value2 = FT_Get_ULong( stream ); + str.value3 = FT_Get_ULong( stream ); + + FT_Forget_Frame( stream );+ + + can be simplified with macros: + + ++ if ( ACCESS_Frame( 2 +4 + 4 ) ) goto ... + + str.value1 = GET_Short(); + str.value2 = GET_ULong(); + str.value3 = GET_ULong(); + + FORGET_Frame();+ + + Which is clearer. Notice that error and stream + must be defined locally though for this code to work! + ++ + + III. Alternatives ++ +It is sometimes useful to read small integers from a font file without + using a frame. Some functions have been introduced in FreeType 2 to + do just that, and they are of the form FT_Read_xxxx. + +For example, FT_Read_Short(stream, + &error) reads and returns a 2-byte big-endian integer from a + stream, and places an error code in the error + variable. + +Thus, reading a single big-endian integer is shorter than using a frame + for it. + +Note that there are also macros READ_xxx() which translate to + + ++ FT_Read_xxx( stream, &error ), error != FT_Err_Ok+ + + and can be used as in + + ++ if ( READ_UShort( variable1 ) || + READ_ULong ( variable2 ) ) + goto Fail;+ + + if error and stream are already defined locally. + + |
-
-
- - Introduction:-
- - 1. Header files :-
-
- - - 2. Initialise the library:-
- #include <freetype/freetype.h> - - FT_Library library; - - .... - - { - .. - error = FT_Init_FreeType( &library ); - if (error) { .. an error occured during library initialisation .. } - } -- - This function is in charge of the following: -
- As you can see, the function returns an error code, like most others in the - FreeType API. An error code of 0 always means that the operation - was succesful; otherwise, the value describes the error, and library - is set to NULL. - - - 3. Load a font face:-
a. From a font file:-
- This short tutorial will teach you how to use the FreeType 2
+ library in your own applications. To include the main FreeType header file, simply say in your application code. Note that other files are available in the
+ FreeType include directory, most of them being included by
+ "freetype.h". They will be described later in this
+ tutorial. Simply create a variable of type FT_Library named, for
+ example, library, and call the function
+ FT_Init_FreeType() as in This function is in charge of the following: As you can see, the function returns an error code, like most others
+ in the FreeType API. An error code of 0 always means that
+ the operation was successful; otherwise, the value describes the error,
+ and library is set to NULL. Create a new face object by calling FT_New_Face.
+ A face describes a given typeface and style. For example,
+ "Times New Roman Regular" and "Times New Roman Italic" correspond to
+ two different faces. As you can certainly imagine, FT_New_Face opens a font
+ file, then tries to extract one face from it. Its parameters are handle to the FreeType library instance where the face object
+ is created the font file pathname (standard C string). Certain font formats allow several font faces to be embedded
+ in a single file. This index tells which face you want to load. An error will
+ be returned if its value is too large. Index 0 always work though. A pointer to the handle that will be set to describe
+ the new face object. It is set to NULL in case of error. To know how many faces a given font file contains, simply load its
+ first face (use face_index=0), then see the value of
+ face->num_faces which indicates how many faces are embedded
+ in the font file. In the case where you have already loaded the font file in memory,
+ you can similarly create a new face object for it by calling
+ FT_New_Memory_Face as in As you can see, FT_New_Memory_Face() simply takes a
+ pointer to the font file buffer and its size in bytes instead of a
+ file pathname. Other than that, it has exactly the same semantics as
+ FT_New_Face(). There are cases where using a file pathname or preloading the file
+ in memory is simply not enough. With FreeType 2, it is possible
+ to provide your own implementation of i/o routines. This is done through the FT_Open_Face() function, which
+ can be used to open a new font face with a custom input stream, select
+ a specific driver for opening, or even pass extra parameters to the
+ font driver when creating the object. We advise you to refer to the
+ FreeType 2 reference manual in order to learn how to use it. A face object models all information that globally describes
+ the face. Usually, this data can be accessed directly by dereferencing
+ a handle, like Gives the number of glyphs available in the font face.
+ A glyph is simply a character image. It doesn't necessarily
+ correspond to a character code though. A 32-bit integer containing bit flags used to describe some
+ face properties. For example, the flag
+ FT_FACE_FLAG_SCALABLE is used to indicate that the face's
+ font format is scalable and that glyph images can be rendered for
+ all character pixel sizes. For more information on face flags,
+ please read the FreeType 2 API Reference. This field is only valid for scalable formats (it is set to 0
+ otherwise). It indicates the number of font units covered by the
+ EM. This field gives the number of embedded bitmap strikes
+ in the current face. A strike is simply a series of
+ glyph images for a given character pixel size. For example, a
+ font face could include strikes for pixel sizes 10, 12
+ and 14. Note that even scalable font formats can have
+ embedded bitmap strikes! this is a pointer to an array of FT_Bitmap_Size
+ elements. Each FT_Bitmap_Size indicates the horizontal
+ and vertical pixel sizes for each of the strikes that are
+ present in the face. For a complete listing of all face properties and fields, please read
+ the FreeType 2 API Reference.
+
+ A face object also holds a handle to a size object in its
+ face->size field. The size object is used to model
+ all information for the face that is relative to a given character
+ size. When a new face object is created, its size object defaults to the
+ character size of 10 pixels (both horizontall and vertically) for
+ scalable formats. For fixed-sizes formats, the size is more or less
+ undefined, which is why you must set it before trying to load a
+ glyph. To do that, simply call FT_Set_Char_Size(). Here is an
+ example where the character size is set to 16pt for a 300x300 dpi
+ device: You will notice that: This function computes the character pixel size that corresponds to
+ the character width and height and device resolutions. However, if you
+ want to specify the pixel sizes yourself, you can simply call
+ FT_Set_Pixel_Sizes(), as in This example will set the character pixel sizes to 16x16 pixels.
+ As previously, a value of 0 for one of the dimensions means
+ "same as the other". Note that both functions return an error code. Usually, an error
+ occurs with a fixed-size font format (like FNT or PCF) when trying to
+ set the pixel size to a value that is not listed in the
+ face->fixed_sizes array. Usually, an application wants to load a glyph image based on its
+ character code, which is a unique value that defines the
+ character for a given encoding. For example, the character
+ code 65 represents the `A' in ASCII encoding. A face object contains one or more tables, called
+ charmaps, that are used to convert character codes to glyph
+ indices. For example, most TrueType fonts contain two charmaps. One
+ is used to convert Unicode character codes to glyph indices, the other
+ is used to convert Apple Roman encoding into glyph indices. Such
+ fonts can then be used either on Windows (which uses Unicode) and
+ Macintosh (which uses Apple Roman, bwerk). Note also that a given
+ charmap might not map to all the glyphs present in the font. By default, when a new face object is created, it lists all the
+ charmaps contained in the font face and selects the one that supports
+ Unicode character codes if it finds one. Otherwise, it tries to find
+ support for Latin-1, then ASCII. We will describe later how to look for specific charmaps in a face.
+ For now, we will assume that the face contains at least a Unicode
+ charmap that was selected during FT_New_Face(). To convert a
+ Unicode character code to a font glyph index, we use
+ FT_Get_Char_Index() as in This will look the glyph index corresponding to the given
+ charcode in the charmap that is currently selected for the
+ face. If charmap is selected, the function simply returns the
+ charcode. Note that this is one of the rare FreeType functions that do not
+ return an error code. However, when a given character code has no
+ glyph image in the face, the value&nbso;0 is returned. By convention,
+ it always correspond to a special glyph image called the missing
+ glyph, which usually is represented as a box or a space. Once you have a glyph index, you can load the corresponding glyph
+ image. Note that the glyph image can be in several formats. For
+ example, it will be a bitmap for fixed-size formats like FNT, FON, or
+ PCF. It will also be a scalable vector outline for formats like
+ TrueType or Type 1. The glyph image can also be stored in an
+ alternate way that is not known at the time of writing this
+ documentation. The glyph image is always stored in a special object called a
+ glyph slot. As its name suggests, a glyph slot is simply a
+ container that is able to hold one glyph image at a time, be it a
+ bitmap, an outline, or something else. Each face object has a single
+ glyph slot object that can be accessed as
+ face->glyph. Loading a glyph image into the slot is performed by calling
+ FT_Load_Glyph() as in The load_flags value is a set of bit flags used to
+ indicate some special operations. The default value
+ FT_LOAD_DEFAULT is 0. The function performs the
+ following: There are a few others FT_LOAD_xxx flags defined. For
+ more details see the FreeType 2 API
+ Reference. As said before, when a new face object is created, it will look for
+ a Unicode, Latin-1, or ASCII charmap and select it. The currently
+ selected charmap is accessed via face->charmap. This
+ field is NULL when no charmap is selected, which typically happens
+ when you create a new FT_Face object from a font file that
+ doesn't contain an ASCII, Latin-1, or Unicode charmap (rare
+ stuff). The fields face->num_charmaps and
+ face->charmaps (notice the `s') can be used by client
+ applications to check which charmaps are available in a given
+ face. face->charmaps is an array of pointers to
+ the face->num_charmaps charmaps contained in the font
+ face. Each charmap has a few visible fields used to describe it in more
+ detail. For example, charmap->encoding is an
+ enumeration type that describes the charmap with FreeType codes. One
+ can also look at charmap->platform_id and
+ charmap->encoding_id for more exotic needs. Here's an example code that looks for a Chinese Big 5 charmap,
+ then selects it via FT_Set_CharMap(): One might now call FT_Get_Char_Index() with Big 5
+ character codes to retrieve glyph indices. Glyph image data is accessible through face->glyph.
+ See the definition of the FT_GlyphSlot type for more details.
+ As stated previously, each face has a single glyph slot, where
+ one glyph image at a time can be loaded. Each time
+ you call FT_Load_Glyph(), you erase the content of the glyph
+ slot with a new glyph image. Note however that the glyph slot object itself doesn't change, only
+ its content, which means that you can perfectly create a "shortcut" to
+ access it as in
- As you certainly imagine, FT_New_Face opens a font file then
- tries to extract one face from it. Its parameters are :
- The glyph variable will be valid until its parent
+ face is destroyed. Here are a few important fields of the
+ glyph slot:
+
Indicates the type of the loaded glyph image. Can be either
+ ft_glyph_format_bitmap, ft_glyph_format_outline,
+ or other values. A simple structure used to hold the glyph image's metrics.
+ Note that most distances are expressed in 1/64th of
+ pixels! See the API reference or the user guide for a
+ description of the FT_Glyph_Metrics structure. If the glyph slot contains a bitmap, a simple
+ FT_Bitmap that describes it. See the API reference or
+ user guide for a description of the FT_Bitmap
+ structure. When the glyph slot contains a scalable outline, this structure
+ describes it. See the definition of the FT_Outline
+ structure.
- To known how many faces a given font file contains, simply load its
- first face (use face_index=0), then see the value of
- face->num_faces which indicates how many faces are embedded in
- the font file.
-
-
-
-
-
- As you can see, FT_New_Memory_Face simply takes a pointer to
- the font file buffer and its size in bytes instead of a file pathname.
- Other than that, it has exactly the same semantics than
- FT_New_Face.
-
-
-
- This is done through the FT_Open_Face function, which can be
- used to open a new font face with a custom input stream, select a specific
- driver for opening, or even pass extra parameters to the font driver
- when creating the object. We advise you to refer to the FreeType 2
- Reference in order to learn how to use it.
-
-
-
-
-
-
-
-
- For a complete listing of all face properties and fields, please read
- the FreeType 2 API Reference.
-
-
-
- When a new face object is created, its size object defaults to the
- character size of 10 pixels (both horizontall and vertically) for
- scalable formats. For fixed-sizes formats, the size is more or less
- undefined, which is why you must set it before trying to load a
- glyph.
-
- To do that, simply call FT_Set_Char_Size. Here's an example
- where the character size is set to 16 pts for a 300x300 dpi device:
-
-
- You'll notice that:
-
- This function computes the character pixel size that corresponds to the
- character width and height and device resolutions. However, if you want
- to specify the pixel sizes yourself, you can simply call
- FT_Set_Pixel_Sizes, as in:
-
-
- This example will set the character pixel sizes to 16x16 pixels. As
- previously, a value of 0 for one of the dimensions means "same as
- the other".
-
- Note that both functions return an error code. Usually, an error occurs
- with a fixed-size font format (like FNT or PCF) when trying to set the
- pixel size to a value that is not listed in the
- face->fixed_sizes array.
-
-
-
- A face object contains one or more tables, called charmaps,
- that are used to convert character codes to glyph indices. For example,
- most TrueType fonts contain two charmaps. One is used to convert Unicode
- character codes to glyph indices, the other is used to convert
- Apple Roman encoding into glyph indices. Such fonts can then be used
- either on Windows (which uses Unicode) and Macintosh (which uses
- Apple Roman, bwerk..). Note also that a given charmap might not map to all
- the glyphs present in the font.
-
- By default, when a new face object is created, it lists all the charmaps
- contained in the font face and selects the one that supports Unicode
- character codes if it finds one. Otherwise, it tries to find support for
- Latin-1, then ASCII.
-
- We'll describe later how to look for specific charmaps in a face. For
- now, we'll assume that the face contains at least a Unicode charmap that
- was selected during FT_New_Face. To convert a Unicode character
- code to a font glyph index, we use FT_Get_Char_Index as in:
-
-
- This will look the glyph index corresponding to the given charcode
- in the charmap that is currently selected for the face. If charmap is
- selected, the function simply returns the charcode.
-
- Note that this is one of the rare FreeType functions that do not return
- an error code. However, when a given character code has no glyph image in
- the face, the value 0 is returned. By convention, it always correspond to
- a special glyph image called the missing glyph, which usually is
- represented as a box or a space.
-
-
-
-
- The glyph image is always stored in a special object called a
- glyph slot. As it names suggests, a glyph slot is simply a
- container that is able to hold one glyph image at a time, be it a bitmap,
- an outline, or something else. Each face object has a single glyph slot
- object that can be accessed as face−>glyph.
-
- Loading a glyph image into the slot is performed by calling
- FT_Load_Glyph as in:
-
-
- The load_flags value is a set of bit flags used to indicate
- some special operations. The default value FT_LOAD_DEFAULT is
- 0. The function performs the following :
-
- There are a few others FT_LOAD_xxx flags defined. For more
- details see the FreeType 2 API Reference.
-
-
-
- The fields face−>num_charmaps and
- face−>charmaps (notice the 's') can be used by
- client applications to look at what charmaps are available in a given
- face.
-
- face−>charmaps is an array of pointers
- to the face−>num_charmaps charmaps contained in the
- font face.
-
- Each charmap has a few visible fields used to describe it in more details.
- For example, charmap->encoding is an enumeration type
- that describes the charmap with FreeType codes. One can also look at
- charmap->platform_id and
- charmap->encoding_id for more exotic needs.
-
- Here's an example code that looks for a chinese Big5 charmap then
- selects it via FT_Set_CharMap:
-
-
- One might now call FT_Get_Char_Index with Big5 character codes
- to retrieve glyph indices.
-
-
-
-
-
- Note however that the glyph slot object itself doesn't change, only its
- content, which means that you can perfectly create a "shortcut" to access
- it as in:
-
-
- The glyph variable will be valid until its parent face
- is destroyed. Here are a few important fields of the glyph slot:
-
-
-
- On the other hand, when the format if ft_glyph_format_outline
- or something else, the library provides a means to convert such glyph
- images to bitmaps through what are called rasters.
-
-
-
-
- On the other hand, when the image is a scalable outline, or something else,
- FreeType provides a function to convert the glyph image into a
- pre-existing bitmap that you'll handle to it, named
- FT_Get_Glyph_Bitmap. Here's a simple example code
- that renders an outline into a monochrome bitmap :
-
-
- You should note that FT_Get_Glyph_Bitmap doesn't create the
- bitmap. It only needs a descriptor, of type FT_Bitmap,
- and writes directly into it.
-
- Note that the FreeType scan-converter for outlines can also generate
- anti-aliased glyph bitmaps with 128 level of grays. For now, it is
- restricted to rendering to 8-bit gray-level bitmaps, though this may
- change in the future. Here's some code to do just that:
-
-
- You'll notice that :
-
- You can easily test the format of the glyph image by inspecting the
+ face->glyph->format variable. If its value is
+ ft_glyph_format_bitmap, the glyph image that was loaded is a
+ bitmap that can be directly blit to your own surfaces through your
+ favorite graphics library (FreeType 2 doesn't provide bitmap
+ blitting routines, as you may imagine :-) If the format is ft_glyph_format_outline or something else,
+ the library provides a means to convert such glyph images to bitmaps
+ through what are called rasters. On the other hand, if the image is a scalable outline or something
+ else, FreeType provides a function to convert the glyph image into a
+ pre-existing bitmap that you will handle to it, named
+ FT_Get_Glyph_Bitmap. Here's a simple example code
+ that renders an outline into a monochrome bitmap: You should note that FT_Get_Glyph_Bitmap() doesn't
+ create the bitmap. It only needs a descriptor, of type
+ FT_Bitmap, and writes directly into it. Note that the FreeType scan-converter for outlines can also generate
+ anti-aliased glyph bitmaps with 128 level of grays. For now, it is
+ restricted to rendering to 8-bit gray-level bitmaps, though this may
+ change in the future. Here is some code to do just that: You will notice that |