X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=subsys%2Fwin32k%2Ffreetype%2Fdocs%2Ftutorial%2Fstep1.html;fp=subsys%2Fwin32k%2Ffreetype%2Fdocs%2Ftutorial%2Fstep1.html;h=0000000000000000000000000000000000000000;hp=e184be7b929c80f1912ddcf66aa5d1c8e7f653b4;hb=7c0db166f81fbe8c8b913d7f26048e337d383605;hpb=e3ed2d773259cc445c7ff8181ebd934931365328 diff --git a/subsys/win32k/freetype/docs/tutorial/step1.html b/subsys/win32k/freetype/docs/tutorial/step1.html deleted file mode 100644 index e184be7..0000000 --- a/subsys/win32k/freetype/docs/tutorial/step1.html +++ /dev/null @@ -1,956 +0,0 @@ - - - - - - FreeType 2 Tutorial - - - - -

- FreeType 2.0 Tutorial
- Step 1 - simple glyph loading -

- -

- © 2000 David Turner - (david@freetype.org)
- © 2000 The FreeType Development Team - (www.freetype.org) -

- -
- - -
- -
- -

- Introduction -

- -

This is the first section of the FreeType 2 tutorial. It will teach - you to do the following:

- -
    -
  • initialise the library
  • -
  • open a font file by creating a new face object
  • -
  • select a character size in points or in pixels
  • -
  • load a single glyph image and convert it to a bitmap
  • -
  • render a very simple string of text
  • -
  • render a rotated string of text easily
  • -
- -
- -

- 1. Header files -

- -

To include the main FreeType header file, simply say

- - -
-    #include <freetype/freetype.h>
-
- -

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.

- -
- -

- 2. Initialize the library -

- -

Simply create a variable of type FT_Library named, for - example, library, and call the function - FT_Init_FreeType() as in

- - -
-    #include <freetype/freetype.h>
-
-    FT_Library  library;
-
-    ...
-
-    {
-      ...
-      error = FT_Init_FreeType( &library );
-      if ( error )
-      {
-        ... an error occurred during library initialization ...
-      }
-    }
-
- -

This function is in charge of the following:

- -
    -
  • -

    Creating a new instance of the FreeType 2 library, and set - the handle library to it.

    -
  • -
  • -

    Load each modules that FreeType knows about in the library. - This means that by default, your new library object is able - to handle TrueType, Type 1, CID-keyed & OpenType/CFF fonts - gracefully.

    -
  • -
- -

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.

- -
- -

- 3. Load a font face -

- -

- a. From a font file -

- -

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.

- - -
-    FT_Library   library;   /* handle to library     */
-    FT_Face      face;      /* handle to face object */
-
-    error = FT_Init_FreeType( &library );
-    if ( error ) { ... }
-
-    error = FT_New_Face( library,
-                         "/usr/share/fonts/truetype/arial.ttf",
-                         0,
-                         &face );
-    if ( error == FT_Err_Unknown_File_Format )
-    {
-      ... the font file could be opened and read, but it appears
-      ... that its font format is unsupported
-    }
-    else if ( error )
-    {
-      ... another error code means that the font file could not
-      ... be opened or read, or simply that it is broken...
-    }
-
- -

As you can certainly imagine, FT_New_Face opens a font - file, then tries to extract one face from it. Its parameters are

- - - - - - - - - - - - - - - - - - -
- library - -

handle to the FreeType library instance where the face object - is created

-
- filepathname - -

the font file pathname (standard C string).

-
- face_index - -

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.

-
- face - -

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.

- -

- b. From memory -

- -

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

- - -
-    FT_Library   library;   /* handle to library     */
-    FT_Face      face;      /* handle to face object */
-
-    error = FT_Init_FreeType( &library );
-    if ( error ) { ... }
-
-    error = FT_New_Memory_Face( library,
-                                buffer,    /* first byte in memory */
-                                size,      /* size in bytes        */
-                                0,         /* face_index           */
-                                &face );
-    if ( error ) { ... }
-
- -

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

- -

- c. From other sources (compressed files, network, etc.) -

- -

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.

- -

Note that providing a custom stream might also be used to access a - TrueType font embedded in a Postscript Type 42 wrapper.

- -
- -

- 4. Accessing face content -

- -

A face object models all information that globally describes - the face. Usually, this data can be accessed directly by dereferencing - a handle, like

- - - - - - - - - - - - - - - - - - - - - - -
- face->num_glyphs - -

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.

-
- face->flags - -

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.

-
- face->units_per_EM - -

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.

-
- face->num_fixed_sizes - -

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!

-
- face->fixed_sizes - -

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.

- -


- -

- 5. Setting the current pixel size -

- -

FreeType 2 uses "size objects" to model all - information related to a given character size for a given face. - For example, a size object will hold the value of certain metrics - like the ascender or text height, expressed in 1/64th of a pixel, - for a character size of 12 points.

- -

When the FT_New_Face function is called (or one of its - cousins), it automatically creates a new size object for - the returned face. This size object is directly accessible as - face->size.

- -

NOTA BENE: a single face object can deal with one or more size - objects at a time, however, this is something that few programmers - really need to do. We have thus have decided to simplify the API for - the most common use (i.e. one size per face), while keeping this - feature available through additional fuctions.

- -

When a new face object is created, its size object defaults to the - character size of 10 pixels (both horizontally 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:

- - -
-    error = FT_Set_Char_Size(
-              face,    /* handle to face object           */
-              0,       /* char_width in 1/64th of points  */
-              16*64,   /* char_height in 1/64th of points */
-              300,     /* horizontal device resolution    */
-              300 );   /* vertical device resolution      */
-
- -

You will notice that:

- -
    -
  • -

    The character width and heights are specified in 1/64th of - points. A point is a physical distance, equaling 1/72th - of an inch, it's not a pixel..

    -

  • -
  • -

    The horizontal and vertical device resolutions are expressed in - dots-per-inch, or dpi. You can use 72 or - 96 dpi for display devices like the screen. The resolution - is used to compute the character pixel size from the character - point size.

    -
  • -
  • -

    A value of 0 for the character width means "same as - character height", a value of 0 for the character height - means "same as character width". Otherwise, it is possible - to specify different char widths and heights.

    -
  • -
  • -

    Using a value of 0 for the horizontal or vertical resolution means - 72 dpi, which is the default.

    -
  • -
  • -

    The first argument is a handle to a face object, not a size - object. That's normal, and must be seen as a convenience.

    -
  • -
- -

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

- - -
-    error = FT_Set_Pixel_Sizes(
-              face,   /* handle to face object            */
-              0,      /* pixel_width                      */
-              16 );   /* pixel_height                     */
-
- -

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.

- -
- -

- 6. Loading a glyph image -

- -

- a. Converting a character code into a glyph index -

- -

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

- - -
-    glyph_index = FT_Get_Char_Index( face, charcode );
-
- -

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.

- -

- b. Loading a glyph from the face -

- -

Once you have a glyph index, you can load the corresponding glyph - image. The latter can be stored in various formats within the font file. - For fixed-size formats like FNT or PCF, each image is a bitmap. Scalable - formats like TrueType or Type 1 use vectorial shapes, named "outlines" - to describe each glyph. Some formats may have even more exotic ways - of representing glyph (e.g. MetaFont). Fortunately, FreeType 2 is - flexible enough to support any kind of glyph format through - a simple API.

- -

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

- - -
-    error = FT_Load_Glyph( 
-              face,          /* handle to face object */
-              glyph_index,   /* glyph index           */
-              load_flags );  /* load flags, see below */
-
- -

The load_flags value is a set of bit flags used to - indicate some special operations. The default value - FT_LOAD_DEFAULT is 0.

- -

This function will try to load the corresponding glyph image - from the face. Basically, this means that:

- -
    -
  • -

    If a bitmap is found for the corresponding glyph and pixel - size, it will be loaded into the slot (embedded bitmaps are always - favored over native image formats, because we assume that - they are higher-quality versions of the same glyph. This - can be ignored by using the FT_LOAD_NO_BITMAP flag)

    -
  • - -
  • -

    Otherwise, a native image for the glyph will be loaded. - It will also be scaled to the current pixel size, as - well as hinted for certain formats like TrueType and - Type1.

    -
  • -
- -

The field glyph->format describe the format - used to store the glyph image in the slot. If it is not - ft_glyph_format_bitmap, one can immediately - convert it to a bitmap through FT_Render_Glyph, - as in:

- - -
-   error = FT_Render_Glyph(
-                  face->glyph,      /* glyph slot  */
-                  render_mode );    /* render mode */
-      
-
- -

The parameter render_mode is a set of bit flags used - to specify how to render the glyph image. Set it to 0, or the - equivalent ft_render_mode_normal to render a high-quality - anti-aliased (256 gray levels) bitmap, as this is the default. - You can alternatively use ft_render_mode_mono if you - want to generate a 1-bit monochrome bitmap.

- -

Once you have a bitmapped glyph image, you can access it directly - through glyph->bitmap (a simple bitmap descriptor), - and position it through glyph->bitmap_left and - glyph->bitmap_top.

- -

Note that bitmap_left is the horizontal distance from the - current pen position to the left-most border of the glyph bitmap, - while bitmap_top is the vertical distance from the - pen position (on the baseline) to the top-most border of the - glyph bitmap. It is positive to indicate an upwards - distance.

- -

The next section will detail the content of a glyph slot and - how to access specific glyph information (including metrics).

- -

- c. Using other charmaps -

- -

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

- -

There are two ways to select a different charmap with FreeType 2. - The easiest is when the encoding you need already has a corresponding - enumeration defined in <freetype/freetype.h>, as - ft_encoding_big5. In this case, you can simply call - FT_Select_CharMap as in:

- -
-    error = FT_Select_CharMap(
-                    face,                 /* target face object */
-                    ft_encoding_big5 );   /* encoding..         */
-      
- -

Another way is to manually parse the list of charmaps for the - face, this is accessible through the fields - num_charmaps and charmaps - (notice the 's') of the face object. As you could expect, - the first is the number of charmaps in the face, while the - second is a table of pointers to the charmaps - embedded in the face.

- -

Each charmap has a few visible fields used to describe it more - precisely. Mainly, one will look at - charmap->platform_id and - charmap->encoding_id that define a pair of - values that can be used to describe the charmap in a rather - generic way.

- -

Each value pair corresponds to a given encoding. For example, - the pair (3,1) corresponds to Unicode. Their list is - defined in the TrueType specification but you can also use the - file <freetype/ftnameid.h> which defines several - helpful constants to deal with them..

- -

To look for a specific encoding, you need to find a corresponding - value pair in the specification, then look for it in the charmaps - list. Don't forget that some encoding correspond to several - values pair (yes it's a real mess, but blame Apple and Microsoft - on such stupidity..). Here's some code to do it:

- - -
-    FT_CharMap  found = 0;
-    FT_CharMap  charmap;
-    int         n;
-
-    for ( n = 0; n < face->num_charmaps; n++ )
-    {
-      charmap = face->charmaps[n];
-      if ( charmap->platform_id == my_platform_id &&
-           charmap->encoding_id == my_encoding_id )
-      {
-        found = charmap;
-        break;
-      }
-    }
-
-    if ( !found ) { ... }
-
-    /* now, select the charmap for the face object */
-    error = FT_Set_CharMap( face, found );
-    if ( error ) { ... }
-
- -

Once a charmap has been selected, either through - FT_Select_CharMap or FT_Set_CharMap, - it is used by all subsequent calls to - FT_Get_Char_Index().

- - -

- d. Glyph Transforms: -

- -

It is possible to specify an affine transformation to be applied - to glyph images when they're loaded. Of course, this will only - work for scalable (vectorial) font formats.

- -

To do that, simply call FT_Set_Transform, as in:

- -
-   error = FT_Set_Transform(
-                    face,       /* target face object    */
-                    &matrix,    /* pointer to 2x2 matrix */
-                    &delta );   /* pointer to 2d vector  */
-     
- -

This function will set the current transform for a given face - object. Its second parameter is a pointer to a simple - FT_Matrix structure that describes a 2x2 affine matrix. - The third parameter is a pointer to a FT_Vector structure - that describe a simple 2d vector that is used to translate the - glyph image after the 2x2 transform.

- -

Note that the matrix pointer can be set to NULL, (in which case - the identity transform will be used). Coefficients of the matrix - are otherwise in 16.16 fixed float units.

- -

The vector pointer can also be set to NULL (in which case a delta - of (0,0) will be used). The vector coordinates are expressed in - 1/64th of a pixel (also known as 26.6 fixed floats).

- - -

NOTA BENE: The transform is applied to every glyph that is loaded - through FT_Load_Glyph and is completely independent - of any hinting process. This means that you won't get the same - results if you load a glyph at the size of 24 pixels, or a glyph at - the size at 12 pixels scaled by 2 through a transform, because the - hints will have been computed differently (unless, of course you - disabled hints).

- -

If you ever need to use a non-orthogonal transform with optimal - hints, you first need to decompose your transform into a scaling part - and a rotation/shearing part. Use the scaling part to compute a new - character pixel size, then the other one to call FT_Set_Transform. - This is explained in details in a later section of this tutorial.

- -

Note also that loading a glyph bitmap with a non-identity transform - will produce an error..

-
- -

- 7. Simple Text Rendering: -

- -

We will now present you with a very simple example used to render - a string of 8-bit Latin-1 text, assuming a face that contains a - Unicode charmap

- -

The idea is to create a loop that will, on each iteration, load one - glyph image, convert it to an anti-aliased bitmap, draw it on the - target surface, then increment the current pen position

- -

a. basic code :

- -

The following code performs our simple text rendering with the - functions previously described.

- -
-       FT_GlyphSlot  slot = face->glyph;  // a small shortcut
-       int           pen_x, pen_y, n;
-
-       .. initialise library ..
-       .. create face object ..
-       .. set character size ..
-       
-       pen_x = 300;
-       pen_y = 200;
-       
-       for ( n = 0; n < num_chars; n++ )
-       {
-         FT_UInt  glyph_index;
-         
-         // retrieve glyph index from character code
-         glyph_index = FT_Get_Char_Index( face, text[n] );
-         
-         // load glyph image into the slot (erase previous one)
-         error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
-         if (error) continue;  // ignore errors
-         
-         // convert to an anti-aliased bitmap
-         error = FT_Render_Glyph( face->glyph, ft_render_mode_normal );
-         if (error) continue;
-         
-         // now, draw to our target surface
-         my_draw_bitmap( &slot->bitmap,
-                         pen_x + slot->bitmap_left,
-                         pen_y - slot->bitmap_top );
-                         
-         // increment pen position 
-         pen_x += slot->advance.x >> 6;
-         pen_y += slot->advance.y >> 6;   // unuseful for now..
-       }
-    
- -

This code needs a few explanations:

-
    -
  • - we define a handle named slot that points to the - face object's glyph slot. (the type FT_GlyphSlot is - a pointer). That's a convenience to avoid using - face->glyph->XXX every time. -

  • - -
  • - we increment the pen position with the vector slot->advance, - which correspond to the glyph's advance width (also known - as its escapement). The advance vector is expressed in - 64/th of pixels, and is truncated to integer pixels on each - iteration.

    -

  • - -
  • - The function my_draw_bitmap is not part of FreeType, but - must be provided by the application to draw the bitmap to the target - surface. In this example, it takes a pointer to a FT_Bitmap descriptor - and the position of its top-left corner as arguments. -

  • - -
  • - The value of slot->bitmap_top is positive for an - upwards vertical distance. Assuming that the coordinates - taken by my_draw_bitmap use the opposite convention - (increasing Y corresponds to downwards scanlines), we substract - it to pen_y, instead of adding it.. -

  • - -
- -

b. refined code:

- -

The following code is a refined version of the example above. It - uses features and functions of FreeType 2 that have not yet been - introduced, and they'll be explained below:

- -
-       FT_GlyphSlot  slot = face->glyph;  // a small shortcut
-       FT_UInt       glyph_index;
-       int           pen_x, pen_y, n;
-
-       .. initialise library ..
-       .. create face object ..
-       .. set character size ..
-       
-       pen_x = 300;
-       pen_y = 200;
-       
-       for ( n = 0; n < num_chars; n++ )
-       {
-         // load glyph image into the slot (erase previous one)
-         error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
-         if (error) continue;  // ignore errors
-         
-         // now, draw to our target surface
-         my_draw_bitmap( &slot->bitmap,
-                         pen_x + slot->bitmap_left,
-                         pen_y - slot->bitmap_top );
-                         
-         // increment pen position 
-         pen_x += slot->advance.x >> 6;
-       }
-    
- -

We've reduced the size of our code, but it does exactly the same thing, - as:

- -
    -
  • - We use the function FT_Load_Char instead of - FT_Load_Glyph. As you probably imagine, it's equivalent - to calling FT_Get_Char_Index then FT_Get_Load_Glyph. -

  • - -
  • - We do not use FT_LOAD_DEFAULT for the loading mode, but - the bit flag FT_LOAD_RENDER. It indicates that - the glyph image must be immediately converted to an anti-aliased - bitmap. This is of course a shortcut that avoids calling - FT_Render_Glyph explicitely but is strictly equivalent.

    - -

    - Note that you can also specify that you want a monochrome bitmap - instead by using the addition FT_LOAD_MONOCHROME - load flag. -

  • -
- -

c. more advanced rendering:

- -

Let's try to render transformed text now (for example through a - rotation). We can do this using FT_Set_Transform. Here's - how to do it:

- -
-       FT_GlyphSlot  slot = face->glyph;  // a small shortcut
-       FT_Matrix     matrix;              // transformation matrix
-       FT_UInt       glyph_index;
-       FT_Vector     pen;                 // untransformed origin
-       int           pen_x, pen_y, n;
-
-       .. initialise library ..
-       .. create face object ..
-       .. set character size ..
-
-       // set up matrix
-       matrix.xx = (FT_Fixed)( cos(angle)*0x10000);
-       matrix.xy = (FT_Fixed)(-sin(angle)*0x10000);
-       matrix.yx = (FT_Fixed)( sin(angle)*0x10000);
-       matrix.yy = (FT_Fixed)( cos(angle)*0x10000);
-              
-       // the pen position in 26.6 cartesian space coordinates
-       pen.x = 300 * 64;
-       pen.y = ( my_target_height - 200 ) * 64;
-       
-       for ( n = 0; n < num_chars; n++ )
-       {
-         // set transform
-         FT_Set_Transform( face, &matrix, &pen );
-         
-         // load glyph image into the slot (erase previous one)
-         error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
-         if (error) continue;  // ignore errors
-         
-         // now, draw to our target surface (convert position)
-         my_draw_bitmap( &slot->bitmap,
-                         slot->bitmap_left,
-                         my_target_height - slot->bitmap_top );
-                         
-         // increment pen position 
-         pen.x += slot->advance.x;
-         pen.y += slot->advance.y;
-       }
-    
- -

You'll notice that:

- -
    -
  • - we now use a vector, of type FT_Vector to store the pen - position, with coordinates expressed as 1/64th of pixels, hence - a multiplication. The position is expressed in cartesian space. -

  • - -
  • - glyph images are always loaded, transformed and described in the - cartesian coordinate system in FreeType (which means that - increasing Y corresponds to upper scanlines), unlike the system - typically used for bitmaps (where the top-most scanline has - coordinate 0). We must thus convert between the two systems - when we define the pen position, and when we compute the top-left - position of the bitmap. -

  • - -
  • - we set the transform on each glyph, to indicate the rotation - matrix, as well as a delta that will move the transformed image - to the current pen position (in cartesian space, not bitmap space). -

  • - -
  • - the advance is always returned transformed, which is why it can - be directly added to the current pen position. Note that it is - not rounded this time. -

  • - -
- -

It is important to note that, while this example is a bit more - complex than the previous one, it is strictly equivalent - for the case where the transform is the identity.. Hence it can - be used as a replacement (but a more powerful one).

- -

It has however a few short comings that we will explain, and solve, - in the next part of this tutorial.

- -
- -

- Conclusion -

- -

In this first section, you have learned the basics of FreeType 2, - as well as sufficient knowledge to know how to render rotated text. - Woww ! Congratulations..

- -

The next section will dive into more details of the API in order - to let you access glyph metrics and images directly, as well as - how to deal with scaling, hinting, kerning, etc..

- -

The third section will discuss issues like modules, caching and a - few other advanced topics like how to use multiple size objects - with a single face. -

- -
-
- - -