949 lines
34 KiB
HTML
949 lines
34 KiB
HTML
<!doctype html public "-//w3c//dtd html 4.0 transitional//en"
|
|
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type"
|
|
content="text/html; charset=iso-8859-1">
|
|
<meta name="Author"
|
|
content="David Turner">
|
|
<title>FreeType 2 Tutorial</title>
|
|
</head>
|
|
|
|
<body text="#000000"
|
|
bgcolor="#FFFFFF"
|
|
link="#0000EF"
|
|
vlink="#51188E"
|
|
alink="#FF0000">
|
|
|
|
<h1 align=center>
|
|
FreeType 2.0 Tutorial<br>
|
|
Step 1 -- simple glyph loading
|
|
</h1>
|
|
|
|
<h3 align=center>
|
|
© 2000 David Turner
|
|
(<a href="mailto:david@freetype.org">david@freetype.org</a>)<br>
|
|
© 2000 The FreeType Development Team
|
|
(<a href="http://www.freetype.org">www.freetype.org</a>)
|
|
</h3>
|
|
|
|
<center>
|
|
<table width="550">
|
|
<tr><td>
|
|
|
|
<hr>
|
|
|
|
<h2>
|
|
Introduction
|
|
</h2>
|
|
|
|
<p>This is the first part of the FreeType 2 tutorial. It will
|
|
teach you to do the following:</p>
|
|
|
|
<ul>
|
|
<li>initialize the library</li>
|
|
<li>open a font file by creating a new face object</li>
|
|
<li>select a character size in points or in pixels</li>
|
|
<li>load a single glyph image and convert it to a bitmap</li>
|
|
<li>render a very simple string of text</li>
|
|
<li>render a rotated string of text easily</li>
|
|
</ul>
|
|
|
|
<hr>
|
|
|
|
<h3>
|
|
1. Header files
|
|
</h3>
|
|
|
|
<p>To include the main FreeType header file, say</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
#include <freetype/freetype.h></pre>
|
|
</font>
|
|
|
|
<p>in your application code. Note that other files are available in the
|
|
FreeType include directory, most of them being included by
|
|
<tt>freetype.h</tt> and other (internal) files. Some of them will be
|
|
described later in this tutorial.</p>
|
|
|
|
<hr>
|
|
|
|
<h3>
|
|
2. Initialize the library
|
|
</h3>
|
|
|
|
<p>Simply create a variable of type <tt>FT_Library</tt> named, for
|
|
example, <tt>library</tt>, and call the function
|
|
<tt>FT_Init_FreeType()</tt> as in</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
#include <freetype/freetype.h>
|
|
|
|
FT_Library library;
|
|
|
|
...
|
|
|
|
{
|
|
...
|
|
error = FT_Init_FreeType( &library );
|
|
if ( error )
|
|
{
|
|
... an error occurred during library initialization ...
|
|
}
|
|
}</pre>
|
|
</font>
|
|
|
|
<p>This function is in charge of the following:</p>
|
|
|
|
<ul>
|
|
<li>
|
|
Creating a new instance of the FreeType 2 library, and set the
|
|
handle <tt>library</tt> to it.
|
|
</li>
|
|
<li>
|
|
Load each module that FreeType knows about in the library. This
|
|
means that by default, your new <tt>library</tt> object is able to
|
|
handle TrueType, Type 1, Windows FON, CID-keyed & OpenType/CFF
|
|
fonts gracefully.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>As you can see, the function returns an error code, like most others
|
|
in the FreeType API. An error code of 0 <em>always</em> means that
|
|
the operation was successful; otherwise, the value describes the error,
|
|
and <tt>library</tt> is set to <tt>NULL</tt>.</p>
|
|
|
|
<hr>
|
|
|
|
<h3>
|
|
3. Load a font face
|
|
</h3>
|
|
|
|
<h4>
|
|
a. From a font file
|
|
</h4>
|
|
|
|
<p>Create a new <em>face</em> object by calling
|
|
<tt>FT_New_Face()</tt>. A <em>face</em> describes a given typeface
|
|
and style. For example, "Times New Roman Regular" and "Times New
|
|
Roman Italic" correspond to two different faces.</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
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 that it is broken
|
|
}</pre>
|
|
</font>
|
|
|
|
<p>As you can certainly imagine, <tt>FT_New_Face()</tt> opens a font
|
|
file, then tries to extract one face from it. Its parameters are</p>
|
|
|
|
<table cellpadding=5>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>library</tt>
|
|
</td>
|
|
<td>
|
|
<p>A handle to the FreeType library instance where the face
|
|
object is created</p>
|
|
</td>
|
|
</tr>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>filepathname</tt>
|
|
</td>
|
|
<td>
|
|
<p>The font file pathname (a standard C string).</p>
|
|
</td>
|
|
</tr>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>face_index</tt>
|
|
</td>
|
|
<td>
|
|
<p>Certain font formats allow several font faces to be embedded
|
|
in a single file.</p>
|
|
|
|
<p>This index tells which face you want to load. An error will
|
|
be returned if its value is too large.</p>
|
|
|
|
<p>Index 0 always work though.</p>
|
|
</td>
|
|
</tr>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>face</tt>
|
|
</td>
|
|
<td>
|
|
<p>A <em>pointer</em> to the handle that will be set to describe
|
|
the new face object.</p>
|
|
|
|
<p>It is set to <tt>NULL</tt> in case of error.</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p>To know how many faces a given font file contains, load its first
|
|
face (use <tt>face_index</tt>=0), then check the value of
|
|
<tt>face->num_faces</tt> which indicates how many faces are embedded
|
|
in the font file.</p>
|
|
|
|
<h4>
|
|
b. From memory
|
|
</h4>
|
|
|
|
<p>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
|
|
<tt>FT_New_Memory_Face()</tt> as in</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
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 ) { ... }</pre>
|
|
</font>
|
|
|
|
<p>As you can see, <tt>FT_New_Memory_Face()</tt> 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
|
|
<tt>FT_New_Face()</tt>.</p>
|
|
|
|
<h4>
|
|
c. From other sources (compressed files, network, etc.)
|
|
</h4>
|
|
|
|
<p>There are cases where using a file pathname or preloading the file
|
|
in memory is not sufficient. With FreeType 2, it is possible to
|
|
provide your own implementation of I/O routines.</p>
|
|
|
|
<p>This is done through the <tt>FT_Open_Face()</tt> 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 API reference in order to learn how to use it.</p>
|
|
|
|
<p>Note that providing a custom stream might also be used to access a
|
|
TrueType font embedded in a Postscript Type 42 wrapper.</p>
|
|
|
|
<hr>
|
|
|
|
<h3>
|
|
4. Accessing face contents
|
|
</h3>
|
|
|
|
<p>A <em>face object</em> models all information that globally describes
|
|
the face. Usually, this data can be accessed directly by dereferencing
|
|
a handle, like</p>
|
|
|
|
<table cellpadding=5>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>face->num_glyphs</tt>
|
|
</td>
|
|
<td>
|
|
<p>Gives the number of <em>glyphs</em> available in the font face.
|
|
A glyph is simply a character image. It doesn't necessarily
|
|
correspond to a <em>character code</em> though.</p>
|
|
</td>
|
|
</tr>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>face->flags</tt>
|
|
</td>
|
|
<td>
|
|
<p>A 32-bit integer containing bit flags used to describe some
|
|
face properties. For example, the flag
|
|
<tt>FT_FACE_FLAG_SCALABLE</tt> 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 <a href="#">FreeType 2 API Reference</a>.</p>
|
|
</td>
|
|
</tr>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>face->units_per_EM</tt>
|
|
</td>
|
|
<td>
|
|
<p>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.</p>
|
|
</td>
|
|
</tr>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>face->num_fixed_sizes</tt>
|
|
</td>
|
|
<td>
|
|
<p>This field gives the number of embedded bitmap <em>strikes</em>
|
|
in the current face. A <em>strike</em> is 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!</p>
|
|
</td>
|
|
</tr>
|
|
<tr valign="top">
|
|
<td>
|
|
<tt>face->fixed_sizes</tt>
|
|
</td>
|
|
<td>
|
|
<p>This is a pointer to an array of <tt>FT_Bitmap_Size</tt>
|
|
elements. Each <tt>FT_Bitmap_Size</tt> indicates the horizontal
|
|
and vertical <em>pixel sizes</em> for each of the strikes that are
|
|
present in the face.</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p>For a complete listing of all face properties and fields, please read
|
|
the <a href="#">FreeType 2 API Reference</a>.<p>
|
|
|
|
<hr>
|
|
|
|
<h3>
|
|
5. Setting the current pixel size
|
|
</h3>
|
|
|
|
<p>FreeType 2 uses <em>size objects</em> 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.</p>
|
|
|
|
<p>When the <tt>FT_New_Face()</tt> function is called (or one of its
|
|
cousins), it <em>automatically</em> creates a new size object for the
|
|
returned face. This size object is directly accessible as
|
|
<tt>face->size</tt>.</p>
|
|
|
|
<p><em>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 functions.</em></p>
|
|
|
|
<p>Before a glyph can be loaded, the size object must be set up. To do
|
|
that, simply call <tt>FT_Set_Char_Size()</tt>. Here is an example where
|
|
the character size is set to 16pt for a 300x300 dpi device:</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
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 */</pre>
|
|
</font>
|
|
|
|
<p>You will notice that</p>
|
|
|
|
<ul>
|
|
<li>
|
|
The character width and heights are specified in 1/64th of points.
|
|
A point is a <em>physical</em> distance, equaling 1/72th of an inch;
|
|
it is not a pixel.
|
|
</li>
|
|
<li>
|
|
Horizontal and vertical device resolutions are expressed in
|
|
<em>dots-per-inch</em>, or <em>dpi</em>. 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.
|
|
</li>
|
|
<li>
|
|
A value of 0 for the character width means <em>same as
|
|
character height</em>, a value of 0 for the character height
|
|
means <em>same as character width</em>. Otherwise, it is possible
|
|
to specify different char widths and heights.
|
|
</li>
|
|
<li>
|
|
Using a value of 0 for the horizontal or vertical resolution
|
|
means 72 dpi, which is the default.
|
|
</li>
|
|
<li>
|
|
The first argument is a handle to a face object, not a size object.
|
|
This behaviour must be seen as a convenience.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>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
|
|
<tt>FT_Set_Pixel_Sizes()</tt>, as in</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
error = FT_Set_Pixel_Sizes(
|
|
face, /* handle to face object */
|
|
0, /* pixel_width */
|
|
16 ); /* pixel_height */</pre>
|
|
</font>
|
|
|
|
<p>This example will set the character pixel sizes to 16x16 pixels.
|
|
As previously, a value of 0 for one of the dimensions means
|
|
<em>same as the other</em>.</p>
|
|
|
|
<p>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
|
|
<tt>face->fixed_sizes</tt> array.</p>
|
|
|
|
<hr>
|
|
|
|
<h3>
|
|
6. Loading a glyph image
|
|
</h3>
|
|
|
|
<h4>
|
|
a. Converting a character code into a glyph index
|
|
</h4>
|
|
|
|
<p>Usually, an application wants to load a glyph image based on its
|
|
<em>character code</em>, which is a unique value that defines the
|
|
character for a given <em>encoding</em>. For example, the character
|
|
code 65 in ASCII encoding represents letter `A'.</p>
|
|
|
|
<p>A face object contains one or more tables, called
|
|
<em>charmaps</em>, 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 usually). Note also that a given
|
|
charmap might not map to all the glyphs present in the font.</p>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>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 <tt>FT_New_Face()</tt>. To convert a
|
|
Unicode character code to a font glyph index, we use
|
|
<tt>FT_Get_Char_Index()</tt> as in</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
glyph_index = FT_Get_Char_Index( face, charcode );</pre>
|
|
</font>
|
|
|
|
<p>This will look up the glyph index corresponding to the given
|
|
<tt>charcode</tt> in the charmap that is currently selected for the
|
|
face.
|
|
|
|
<p>Note that this is one of the rare FreeType functions that do not
|
|
return an error code. If a given character code has no glyph image in
|
|
the face, the value 0 is returned. By convention, it always
|
|
corresponds to a special glyph image called the <em>missing
|
|
glyph</em>, which usually is represented as a box or a space.</p>
|
|
|
|
<h4>
|
|
b. Loading a glyph from the face
|
|
</h4>
|
|
|
|
<p>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 <em>outlines</em>, to describe each glyph. Some formats may have
|
|
even more exotic ways of representing glyphs (e.g. MetaFont).
|
|
Fortunately, FreeType 2 is flexible enough to support any kind of
|
|
glyph format through a simple API.</p>
|
|
|
|
<p>The glyph image is always stored in a special object called a
|
|
<em>glyph slot</em>. As its name suggests, a glyph slot is 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 <tt>face->glyph</tt>.</p>
|
|
|
|
<p>Loading a glyph image into the slot is performed by calling
|
|
<tt>FT_Load_Glyph()</tt> as in</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
error = FT_Load_Glyph(
|
|
face, /* handle to face object */
|
|
glyph_index, /* glyph index */
|
|
load_flags ); /* load flags, see below */</pre>
|
|
</font>
|
|
|
|
<p>The <tt>load_flags</tt> value is a set of bit flags used to
|
|
indicate some special operations. The default value
|
|
<tt>FT_LOAD_DEFAULT</tt> is 0.</p>
|
|
|
|
<p>This function will try to load the corresponding glyph image from
|
|
the face. Basically, this means that</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<p>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
|
|
changed by using the <tt>FT_LOAD_NO_BITMAP</tt> flag.</p>
|
|
</li>
|
|
<li>
|
|
<p>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 Type 1.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>The field <tt>glyph->format</tt> describes the format used to store
|
|
the glyph image in the slot. If it is not
|
|
<tt>ft_glyph_format_bitmap</tt>, it is possible to immedialy convert
|
|
it to a bitmap through <tt>FT_Render_Glyph()</tt>, as in</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
error = FT_Render_Glyph(
|
|
face->glyph, /* glyph slot */
|
|
render_mode ); /* render mode */</pre>
|
|
</font>
|
|
|
|
<p>The parameter <tt>render_mode</tt> specifies how to render the
|
|
glyph image. Set it <tt>ft_render_mode_normal</tt> to render a
|
|
high-quality anti-aliased (256 gray levels) bitmap. You can
|
|
alternatively use <tt>ft_render_mode_mono</tt> if you want to generate
|
|
a 1-bit monochrome bitmap.</p>
|
|
|
|
<p>Once you have a bitmapped glyph image, you can access it directly
|
|
through <tt>glyph->bitmap</tt> (a simple bitmap descriptor), and
|
|
position it with <tt>glyph->bitmap_left</tt> and
|
|
<tt>glyph->bitmap_top</tt>.</p>
|
|
|
|
<p>Note that <tt>bitmap_left</tt> is the horizontal distance from the
|
|
current pen position to the left-most border of the glyph bitmap,
|
|
while <tt>bitmap_top</tt> is the vertical distance from the pen
|
|
position (on the baseline) to the top-most border of the glyph bitmap.
|
|
<em>It is positive to indicate an upwards distance</em>.</p>
|
|
|
|
<p>The second part of the tutorial describes the contents of a glyph
|
|
slot and how to access specific glyph information (including
|
|
metrics).</p>
|
|
|
|
<h4>
|
|
c. Using other charmaps
|
|
</h4>
|
|
|
|
<p>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 <tt>face->charmap</tt>. This field
|
|
is <tt>NULL</tt> if no charmap is selected, which typically happens
|
|
when you create a new <tt>FT_Face</tt> object from a font file that
|
|
doesn't contain an ASCII, Latin-1, or Unicode charmap (rare
|
|
stuff).</p>
|
|
|
|
<p>There are two ways to select a different charmap with
|
|
FreeType 2. The easiest is if the encoding you need already has
|
|
a corresponding enumeration defined in <tt>freetype/freetype.h</tt>,
|
|
as <tt>ft_encoding_big5</tt>. In this case, you can simply call
|
|
<tt>FT_Select_CharMap()</tt> as in</p>
|
|
|
|
<font color="blue"><pre>
|
|
error = FT_Select_CharMap(
|
|
face, /* target face object */
|
|
ft_encoding_big5 ); /* encoding */</pre>
|
|
</font>
|
|
|
|
<p>Another way is to manually parse the list of charmaps for the face;
|
|
this is accessible through the fields <tt>num_charmaps</tt> and
|
|
<tt>charmaps</tt> (notice the final 's') of the face object. As
|
|
expected, the first is the number of charmaps in the face, while the
|
|
second is <em>a table of pointers to the charmaps</em> embedded in the
|
|
face.</p>
|
|
|
|
<p>Each charmap has a few visible fields used to describe it more
|
|
precisely. Mainly, one will look at <tt>charmap->platform_id</tt> and
|
|
<tt>charmap->encoding_id</tt> which define a pair of values that can
|
|
be used to describe the charmap in a rather generic way.</p>
|
|
|
|
<p>Each value pair corresponds to a given encoding. For example, the
|
|
pair (3,1) corresponds to Unicode (on the Windows platform). A list
|
|
of such pairs is defined in the TrueType specification, but you can
|
|
also use the file <tt><freetype/ttnameid.h></tt> which defines
|
|
several helpful constants to deal with them.</p>
|
|
|
|
<p>Note that some pid/eid pairs are <em>artificial</em>; such values
|
|
have been created by FreeType to identify platforms resp. encodings
|
|
not covered by the original TrueType specification.</p>
|
|
|
|
<p>To look up a specific encoding you need to find a corresponding
|
|
value pair in the specification, then look for it in the
|
|
<tt>charmaps</tt> list. Bear in mind that some encodings correspond
|
|
to several values pairs (yes, it's a real mess, but blame Apple and
|
|
Microsoft on such stupidity). Here some code to do it:</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
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 ) { ... }</pre>
|
|
</font>
|
|
|
|
<p>Once a charmap has been selected, either through
|
|
<tt>FT_Select_CharMap()</tt> or <tt>FT_Set_CharMap()</tt>, it is used
|
|
by all subsequent calls to <tt>FT_Get_Char_Index()</tt>.</p>
|
|
|
|
<h4>
|
|
d. Glyph transformations
|
|
</h4>
|
|
|
|
<p>It is possible to specify an affine transformation to be applied to
|
|
glyph images when they are loaded. Of course, this will only work for
|
|
scalable (vectorial) font formats.</p>
|
|
|
|
<p>To do that, simply call <tt>FT_Set_Transform()</tt>, as in</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
error = FT_Set_Transform(
|
|
face, /* target face object */
|
|
&matrix, /* pointer to 2x2 matrix */
|
|
&delta ); /* pointer to 2d vector */</pre>
|
|
</font>
|
|
|
|
<p>This function will set the current transformation for a given face
|
|
object. Its second parameter is a pointer to an <tt>FT_Matrix</tt>
|
|
structure that describes a 2x2 affine matrix. The third
|
|
parameter is a pointer to an <tt>FT_Vector</tt> structure that
|
|
describes a simple 2d vector that is used to translate the glyph
|
|
image <em>after</em> the 2x2 transformation.</p>
|
|
|
|
<p>Note that the matrix pointer can be set to <tt>NULL</tt>, in which
|
|
case the identity transformation will be used. Coefficients of the
|
|
matrix are otherwise in 16.16 fixed float units.</p>
|
|
|
|
<p>The vector pointer can also be set to <tt>NULL</tt> in which case a
|
|
delta vector of (0,0) will be used. The vector coordinates are
|
|
expressed in 1/64th of a pixel (also known as 26.6 fixed floats).</p>
|
|
|
|
<p><em>The transformation is applied to every glyph that is loaded
|
|
through <tt>FT_Load_Glyph()</tt> and is <b>completely independent of
|
|
any hinting process.</b> 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
|
|
transformation, because hints will have been computed differently
|
|
(unless hints have been disabled, of course).</em></p>
|
|
|
|
<p>If you ever need to use a non-orthogonal transformation with
|
|
optimal hints, you first need to decompose your transformation 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
|
|
<tt>FT_Set_Transform()</tt>. This is explained in details in a later
|
|
section of this tutorial.</p>
|
|
|
|
<p>Note also that loading a glyph bitmap with a non-identity
|
|
transformation will produce an error.</p>
|
|
|
|
<hr>
|
|
|
|
<h3>
|
|
7. Simple text rendering
|
|
</h3>
|
|
|
|
<p>We will now present a very simple example used to render a string of
|
|
8-bit Latin-1 text, assuming a face that contains a Unicode charmap</p>
|
|
|
|
<p>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.</p>
|
|
|
|
<h4>
|
|
a. basic code
|
|
</h4>
|
|
|
|
<p>The following code performs our simple text rendering with the
|
|
functions previously described.</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
FT_GlyphSlot slot = face->glyph; /* a small shortcut */
|
|
int pen_x, pen_y, n;
|
|
|
|
|
|
.. initialize 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; /* not useful for now */
|
|
}</pre>
|
|
</font>
|
|
|
|
<p>This code needs a few explanations:</p>
|
|
|
|
<ul>
|
|
<li>
|
|
We define a handle named <tt>slot</tt> that points to the face
|
|
object's glyph slot. (The type <tt>FT_GlyphSlot</tt> is a
|
|
pointer.) This is a convenience to avoid using
|
|
<tt>face->glyph->XXX</tt> every time.
|
|
</li>
|
|
<li>
|
|
We increment the pen position with the vector
|
|
<tt>slot->advance</tt>, which corresponds to the glyph's
|
|
<em>advance width</em> (also known as its <em>escapement</em>).
|
|
The advance vector is expressed in 1/64th of pixels, and is
|
|
truncated to integer pixels on each iteration.
|
|
</li>
|
|
<li>
|
|
The function <tt>my_draw_bitmap()</tt> 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 an
|
|
<tt>FT_Bitmap</tt> descriptor and the position of its top-left
|
|
corner as arguments.
|
|
</li>
|
|
<li>
|
|
The value of <tt>slot->bitmap_top</tt> is positive for an
|
|
<em>upwards</em> vertical distance. Assuming that the coordinates
|
|
taken by <tt>my_draw_bitmap()</tt> use the opposite convention
|
|
(increasing Y corresponds to downwards scanlines), we substract it
|
|
to <tt>pen_y</tt> instead of adding it.
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>b. refined code</h4>
|
|
|
|
<p>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 which will be explained below.</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
FT_GlyphSlot slot = face->glyph; /* a small shortcut */
|
|
FT_UInt glyph_index;
|
|
int pen_x, pen_y, n;
|
|
|
|
|
|
.. initialize 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;
|
|
}</pre>
|
|
</font>
|
|
|
|
<p>We have reduced the size of our code, but it does exactly the same
|
|
thing.</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<p>We use the function <tt>FT_Load_Char()</tt> instead of
|
|
<tt>FT_Load_Glyph()</tt>. As you probably imagine, it is
|
|
equivalent to calling <tt>FT_Get_Char_Index()</tt> followed by
|
|
<tt>FT_Get_Load_Glyph()</tt>.</p>
|
|
</li>
|
|
<li>
|
|
<p>We do not use <tt>FT_LOAD_DEFAULT</tt> for the loading mode but
|
|
the bit flag <tt>FT_LOAD_RENDER</tt>. It indicates that the glyph
|
|
image must be immediately converted to an anti-aliased bitmap.
|
|
This is of course a shortcut that avoids calling
|
|
<tt>FT_Render_Glyph()</tt> explicitly but is strictly
|
|
equivalent.</p>
|
|
|
|
<p>Note that you can also specify that you want a monochrome
|
|
bitmap by using the <tt>FT_LOAD_MONOCHROME</tt> load flag
|
|
instead.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>c. more advanced rendering</h4>
|
|
|
|
<p>We now render transformed text (for example through a rotation).
|
|
To do that we use <tt>FT_Set_Transform()</tt>:</p>
|
|
|
|
<font color="blue">
|
|
<pre>
|
|
FT_GlyphSlot slot = face->glyph; /* a small shortcut */
|
|
FT_Matrix matrix; /* transformation matrix */
|
|
FT_UInt glyph_index;
|
|
FT_Vector pen; /* untransformed origin */
|
|
int n;
|
|
|
|
|
|
.. initialize library ..
|
|
.. create face object ..
|
|
.. set character size ..
|
|
|
|
/* set up matrix */
|
|
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
|
|
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
|
|
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
|
|
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
|
|
|
|
/* 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 transformation */
|
|
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;
|
|
}</pre>
|
|
</font>
|
|
|
|
<p>Notes:</p>
|
|
|
|
<ul>
|
|
<li>
|
|
We now use a vector of type <tt>FT_Vector</tt> to store the pen
|
|
position, with coordinates expressed as 1/64th of pixels, hence a
|
|
multiplication. The position is expressed in cartesian space.
|
|
</li>
|
|
<li>
|
|
In FreeType, glyph images are always loaded, transformed, and
|
|
described in the cartesian coordinate system (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.
|
|
</li>
|
|
<li>
|
|
We apply the transformation matrix on each glyph to indicate
|
|
rotation as well as a delta vector that will move the transformed
|
|
image to the current pen position (in cartesian space, not bitmap
|
|
space).
|
|
</li>
|
|
<li>
|
|
The advance width is always returned transformed, which is why it
|
|
can be directly added to the current pen position. Note that it
|
|
is <em>not</em> rounded this time.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>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 transformation is the identity. Hence it can be used as a
|
|
replacement (but a more powerful one).</p>
|
|
|
|
<p>It has, however, a few shortcomings that we will explain, and
|
|
solve, in the next part of this tutorial.</p>
|
|
|
|
<hr>
|
|
|
|
<h3>
|
|
Conclusion
|
|
</h3>
|
|
|
|
<p>In this first section, you have learned the basics of FreeType 2
|
|
as well as sufficient knowledge how to render rotated text.</p>
|
|
|
|
<p>The next part will dive into more details of the API in order to let
|
|
you access glyph metrics and images directly, how to deal with scaling,
|
|
hinting, kerning, etc.</p>
|
|
|
|
<p>The third part will discuss issues like modules, caching, and a few
|
|
other advanced topics like how to use multiple size objects with a
|
|
single face.</p>
|
|
|
|
</td></tr>
|
|
</table>
|
|
</center>
|
|
|
|
</body>
|
|
</html>
|