| <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <meta name="Author" content="David Turner"> |
| <meta name="GENERATOR" content="Mozilla/4.5 [fr] (Win98; I) [Netscape]"> |
| <title>FreeType 2 Tutorial</title> |
| </head> |
| <body> |
| |
| <body text="#000000" |
| bgcolor="#FFFFFF" |
| link="#0000EF" |
| vlink="#51188E" |
| alink="#FF0000"> |
| |
| <center> |
| <h1> |
| FreeType 2.0 Tutorial</h1></center> |
| |
| <center> |
| <h3> |
| © 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> |
| |
| <center> |
| <table width=650><tr><td> |
| |
| <p><br> |
| <hr WIDTH="100%"> |
| <br> |
| <h2>Introduction:</h2> |
| <ul> |
| This simple tutorial will teach you how to use the FreeType 2 library |
| in your own applications. |
| </ul> |
| |
| <p><hr><p> |
| |
| <h3>1. Header files :</h3> |
| <ul> |
| To include the main FreeType header file, simply use:<p> |
| <ul><font color="blue"><tt> |
| #include <freetype/freetype.h><p> |
| </tt></font></ul> |
| 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>. They will be described later in this tutorial. |
| </ul> |
| |
| <p><hr><p> |
| |
| <h3>2. Initialise the library:</h3> |
| <ul> |
| 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: |
| |
| <font color="blue"><pre> |
| #include <freetype/freetype.h> |
| |
| FT_Library library; |
| |
| .... |
| |
| { |
| .. |
| error = FT_Init_FreeType( &library ); |
| if (error) { .. an error occured during library initialisation .. } |
| } |
| </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. |
| <p> |
| |
| <li>Load each font driver that FreeType knows about in the library. |
| This means that by default, your new <tt>library</tt> object is |
| able to handle TrueType and Type 1 fonts gracefully. |
| <p> |
| </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 succesful; otherwise, the value describes the error, and <tt>library</tt> |
| is set to NULL. |
| </ul> |
| |
| <p><hr><p> |
| |
| <h3>3. Load a font face:</h3> |
| <ul> |
| <h4>a. From a font file:</h4> |
| <ul> |
| 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, read or simply that it is broken.. |
| } |
| </pre></font> |
| <p> |
| As you certainly imagine, <tt>FT_New_Face</tt> opens a font file then |
| tries to extract one face from it. Its parameters are :<p> |
| <ul> |
| <table cellpadding=5> |
| <tr valign="top"><td><tt><b>library</b></tt> |
| <td>handle to the FreeType library instance where the face object is |
| created |
| |
| <tr valign="top"><td><tt><b>filepathname</b></tt> |
| <td>the font file pathname (standard C string). |
| |
| <tr valign="top"><td><tt><b>face_index</b></tt> |
| <td>Certain font formats allow several font faces to be embedded in |
| a single file.<br> |
| This index tells which face you want to load. An |
| error will be returned if its value is too large.<br> |
| Index 0 always work though. |
| |
| <tr><td><tt><b>face</b></tt> |
| <td>A <em>pointer</em> to the handle that will be set to |
| describe the new face object.<br> |
| It is set to NULL in case of error. |
| </table> |
| </ul> |
| <p> |
| To known how many faces a given font file contains, simply load its |
| first face (use <tt>face_index</tt>=0), then see the value of |
| <tt>face->num_faces</tt> which indicates how many faces are embedded in |
| the font file. |
| </ul> |
| <p> |
| |
| <h4>b. From memory:</h4> |
| <ul> |
| 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> 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 |
| <tt>FT_New_Face</tt>. |
| </ul> |
| <p> |
| |
| <h4>c. From other sources: (compressed files, network, etc..)</h4> |
| <ul> |
| There are cases where using a filepathname 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. |
| <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 |
| Reference in order to learn how to use it. |
| <p> |
| </ul> |
| <p> |
| </ul> |
| |
| <p><hr><p> |
| |
| <h3>4. Accessing face content:</h3> |
| <ul> |
| 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><b>face−>num_glyphs</b></tt> |
| <td>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. |
| |
| <tr valign="top"> |
| <td><tt><b>face−>flags</b></tt> |
| <td>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 API |
| Reference</a> |
| |
| <tr valign="top"> |
| <td><tt><b>face−>units_per_EM</b></tt> |
| <td>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. |
| |
| <tr valign="top"> |
| <td><tt><b>face−>num_fixed_sizes</b></tt> |
| <td>this field gives the number of embedded bitmap <em>strikes</em> in |
| the current face. A <em>strike</em> 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 embedded bitmap strikes ! |
| |
| <tr valign="top"> |
| <td><tt><b>face−>fixed_sizes</b></tt> |
| <td>this is a pointer to an array of <tt>FT_Bitmap_Size</tt> element. |
| 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. |
| |
| </table> |
| <p> |
| For a complete listing of all face properties and fields, please read |
| the <a href="#">FreeType 2 API Reference</a>. |
| <p> |
| </ul> |
| |
| <p><hr><p> |
| <h3>5. Setting the current pixel size:</h3> |
| <ul> |
| A face object also holds a handle to a <em>size object</em> in its |
| <tt>face->size</tt> field. The <em>size</em> object is used to model |
| all information for the face that is relative to a given character |
| size. |
| <p> |
| 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. |
| <p> |
| To do that, simply call <tt>FT_Set_Char_Size</tt>. Here's an example |
| where the character size is set to 16 pts 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'll notice that:<p> |
| <ul> |
| <li>The character width and heights are specified in 1/64th of points.<p> |
| |
| <li>The 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.<p> |
| |
| <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 width and height.<p> |
| |
| <li>Using a value of 0 for the horizontal or vertical resolution means |
| 72 dpi, which is the default. |
| <p> |
| </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> |
| 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><b>face->fixed_sizes</b></tt> array. |
| </ul> |
| |
| <p><hr><p> |
| |
| <h3>6. Loading a glyph image:</h3> |
| <ul> |
| <h4>a. Converting a character code into a glyph index:</h4> |
| <ul> |
| 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 represents the 'A' in the ASCII encoding. |
| <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, bwerk..). Note also that a given charmap might not map to all |
| the glyphs present in the font. |
| <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> |
| 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 <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 the glyph index corresponding to the given <tt>charcode</tt> |
| in the charmap that is currently selected for the face. If charmap is |
| selected, the function simply returns the charcode. |
| <p> |
| 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 <b>missing glyph</b>, which usually is |
| represented as a box or a space. |
| <p> |
| </ul> |
| <p> |
| |
| <h4>b. Loading a glyph from the face:</h4> |
| <ul> |
| 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. |
| <p> |
| The glyph image is always stored in a special object called a |
| <em>glyph slot</em>. 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 <b><tt>face−>glyph</tt></b>. |
| <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. The function performs the following :<p> |
| <ul> |
| <li>if there is a bitmap for the corresponding glyph and size, load |
| it in the glyph slot, unless the <tt>FT_LOAD_NO_BITMAP</tt> flag |
| is set. This is even <em>true</em> for scalable formats (embedded |
| bitmaps are favored over outlines as they usually correspond to |
| higher-quality images of the same glyph). |
| <p> |
| |
| <li>if there is an outline for the corresponding glyph, load it |
| unless <tt>FT_LOAD_NO_OUTLINE</tt> is set. Otherwise, scale it |
| to the current size, unless the <tt>FT_LOAD_NO_SCALE</tt> flag |
| is set. |
| <p> |
| |
| <li>if the outline was loaded and scaled, try to grid-fit it (which |
| dramatically improves its quality) unless the flag |
| <tt>FT_LOAD_NO_HINTING</tt> is set. |
| </ul> |
| <p> |
| There are a few others <tt>FT_LOAD_xxx</tt> flags defined. For more |
| details see the <a href="#">FreeType 2 API Reference</a>. |
| </ul> |
| <p> |
| |
| <h4>c. Using other charmaps:</h4> |
| <ul> |
| 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 <b><tt>face−>charmap</tt></b>. This |
| field is NULL when no charmap is selected, which typically happen 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> |
| The fields <b><tt>face−>num_charmaps</tt></b> and |
| <b><tt>face−>charmaps</tt></b> (notice the 's') can be used by |
| client applications to look at what charmaps are available in a given |
| face. |
| <p> |
| <b><tt>face−>charmaps</tt></b> is an array of <em>pointers</em> |
| to the <tt><b>face−>num_charmaps</b></tt> charmaps contained in the |
| font face. |
| <p> |
| Each charmap has a few visible fields used to describe it in more details. |
| For example, <tt><b>charmap->encoding</b></tt> is an enumeration type |
| that describes the charmap with FreeType codes. One can also look at |
| <tt><b>charmap->platform_id</b></tt> and |
| <tt><b>charmap->encoding_id</b></tt> for more exotic needs. |
| <p> |
| Here's an example code that looks for a chinese Big5 charmap then |
| selects it via <tt>FT_Set_CharMap</tt>: |
| <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->encoding == ft_encoding_big5) |
| { |
| found = charmap; |
| break; |
| } |
| } |
| |
| if (!found) { ... } |
| |
| /* now, select the charmap for the face object */ |
| error = FT_Set_CharMap( face, found ); |
| if (error) { .... } |
| </pre></font> |
| <p> |
| One might now call <tt>FT_Get_Char_Index</tt> with Big5 character codes |
| to retrieve glyph indices. |
| <p> |
| </ul> |
| <p> |
| </ul> |
| |
| <p><hr><p> |
| |
| <h3>7. Accessing glyph image data:</h3> |
| <ul> |
| Glyph image data is accessible through <tt><b>face−>glyph</b></tt>. |
| See the definition of the <tt>FT_GlyphSlot</tt> type for more details. As |
| stated previously, each face has a single glyph slot, where <em>one</em> glyph |
| image <em>at a time</em> can be loaded. Each time you call |
| <tt>FT_Load_Glyph</tt>, you erase the content of the glyph slot with a new |
| glyph image. |
| <p> |
| 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: |
| <p> |
| <font color="blue"><pre> |
| { |
| FT_GlyphSlot glyph = face->glyph; /* shortcut to glyph slot */ |
| |
| for ( n = 0; n < face->num_glyphs; n++ ) |
| { |
| .... load glyph n... |
| .... access glyph data as glyph->xxxx |
| } |
| } |
| </pre></font> |
| <p> |
| The <tt>glyph</tt> variable will be valid until its parent <tt>face</tt> |
| is destroyed. Here are a few important fields of the glyph slot: |
| <p> |
| <table cellpadding=10> |
| <tr valign="top"> |
| <td><tt><b>glyph−>format</b></tt> |
| <td>Indicates the type of the loaded glyph image. Can be either |
| <tt>ft_glyph_format_bitmap</tt>, <tt>ft_glyph_format_outline</tt> |
| or other values. |
| |
| <tr valign="top"> |
| <td><tt><b>glyph−>metrics</b></tt> |
| <td>A simple structure used to hold the glyph image's metrics. Note |
| that <em>most distances are expressed in 1/64th of pixels !</em> |
| See the API reference or User Guide for a description of the |
| <tt>FT_Glyph_Metrics</tt> structure. |
| |
| <tr valign="top"> |
| <td><tt><b>glyph−>bitmap</b></tt> |
| <td>When the glyph slot contains a bitmap, a simple <tt>FT_Bitmap</tt> |
| that describes it. See the API reference or user guide for a |
| description of the <tt>FT_Bitmap</tt> structure. |
| |
| <tr valign="top"> |
| <td><tt><b>glyph−>outline</b></tt> |
| <td>When the glyph slot contains a scalable outline, this structure |
| describes it. See the definition of the <tt>FT_Outline</tt> |
| structure. |
| </table> |
| <p> |
| </ul> |
| |
| <h3>8. Rendering glyph outlines into bitmaps:</h3> |
| <ul> |
| You can easily test the format of the glyph image by inspecting the |
| <tt>face->glyph->format</tt> variable. If its value is |
| <tt>ft_glyph_format_bitmap</tt>, 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 :-) |
| <p> |
| On the other hand, when the format if <tt>ft_glyph_format_outline</tt> |
| or something else, the library provides a means to convert such glyph |
| images to bitmaps through what are called <b>rasters</b>. |
| <p> |
| |
| |
| |
| 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 |
| <tt>FT_Get_Glyph_Bitmap</tt>. Here's a <em>simple</em> example code |
| that renders an outline into a <b>monochrome</b> bitmap : |
| <p> |
| <font color="blue"><pre> |
| { |
| FT_GlyphSlot glyph; |
| |
| .... load glyph ... |
| |
| glyph = face->glyph; /* shortcut to glyph data */ |
| if (glyph->format == ft_glyph_format_outline ) |
| { |
| FT_Bitmap bit; |
| |
| /* set-up a bitmap descriptor for our target bitmap */ |
| bit.rows = bitmap_height; |
| bit.width = bitmap_width; |
| bit.pitch = bitmap_row_bytes; |
| bit.pixel_mode = ft_pixel_mode_mono; /* render into a mono bitmap */ |
| bit.buffer = bitmap_buffer; |
| |
| /* render the outline directly into the bitmap */ |
| error = FT_Get_Glyph_Bitmap( face, &bit ); |
| if (error) { ... } |
| } |
| } |
| </pre></font> |
| <p> |
| You should note that <b><em><tt>FT_Get_Glyph_Bitmap</tt> doesn't create the |
| bitmap.</em></b> It only needs a descriptor, of type <tt>FT_Bitmap</tt>, |
| and writes directly into it. |
| <p> |
| 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: |
| <p> |
| <font color="blue"><pre> |
| { |
| FT_GlyphSlot glyph; |
| |
| .... load glyph ... |
| |
| glyph = face->glyph; /* shortcut to glyph data */ |
| if (glyph->format == ft_glyph_format_outline ) |
| { |
| FT_Bitmap bit; |
| |
| /* set-up a bitmap descriptor for our target bitmap */ |
| bit.rows = bitmap_height; |
| bit.width = bitmap_width; |
| bit.pitch = bitmap_row_bytes; |
| bit.pixel_mode = ft_pixel_mode_gray; /* 8-bit gray-level bitmap */ |
| bit.grays = 128; /* MUST be 128 for now */ |
| bit.buffer = bitmap_buffer; |
| |
| /* clean the bitmap - IMPORTANT */ |
| memset( bit.buffer, 0, bit.rows*bit.pitch ); |
| |
| /* render the outline directly into the bitmap */ |
| error = FT_Get_Glyph_Bitmap( face, &bit ); |
| if (error) { ... } |
| } |
| } |
| </pre></font> |
| <p> |
| You'll notice that :<p> |
| <ul> |
| <li>As previously, <tt>FT_Get_Glyph_Bitmap</tt> doesn't generate the |
| bitmap, it simply renders to it.<p> |
| |
| <li>The target bitmap must be cleaned before calling the function. This |
| is a limitation of our current anti-aliasing algorithm and is |
| EXTREMELY important.<p> |
| |
| <li>The anti-aliaser uses 128 levels of grays exclusively for now (this |
| will probably change in a near future). This means that you <b>must</b> |
| set <tt>bit.grays</tt> to 128. The generated image uses values from |
| 0 (back color) to 127 (foreground color). |
| <p> |
| |
| <li>It is <b>not</b> possible to render directly an anti-aliased outline into |
| a pre-existing gray-level bitmap, or even any colored-format one |
| (like RGB16 or paletted 8-bits). We will not discuss this issue in |
| great details here, but the reason is that we do not want to deal |
| with graphics composition (or alpha-blending) within FreeType. |
| </ul> |
| <p> |
| </ul> |
| </ul> |
| |
| </td></tr></table> |
| </center> |
| <p><hr> |
| |