| <!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 2 -- managing glyphs |
| </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 second part of the FreeType 2 tutorial. It will teach |
| you the following:</p> |
| |
| <ul> |
| <li>how to retrieve glyph metrics</li> |
| <li>how to easily manage glyph images</li> |
| <li>how to retrieve global metrics (including kerning)</li> |
| <li>how to render a simple string of text, with kerning</li> |
| <li>how to render a centered string of text (with kerning)</li> |
| <li>how to render a transformed string of text (with centering)</li> |
| <li>finally, how to access metrics in design font units if needed, |
| and how to scale them to device space</li> |
| </ul> |
| |
| <hr> |
| |
| <h3> |
| 1. Glyph metrics |
| </h3> |
| |
| <p>Glyph metrics are, as their name suggests, certain distances |
| associated to each glyph in order to describe how to use it to layout |
| text.</p> |
| |
| <p>There are usually two sets of metrics for a single glyph: those used |
| to layout the glyph in horizontal text layouts (like Latin, Cyrillic, |
| Arabic, Hebrew, etc.), and those used to layout the glyph in vertical |
| text layouts (like some layouts of Chinese, Japanese, Korean, and |
| others).</p> |
| |
| <p>Note that only a few font formats provide vertical metrics. You can |
| test wether a given face object contains them by using the macro |
| <tt>FT_HAS_VERTICAL(face)</tt>, which is true if vertical metrics are |
| available.</p> |
| |
| <p>Individual glyph metrics can be accessed by first loading the glyph |
| in a face's glyph slot, then using the <tt>face->glyph->metrics</tt> |
| structure. This will be described later; for now, we observe that it |
| contains the following fields:</p> |
| |
| <center> |
| <table width="90%" cellpadding=5> |
| <tr valign=top> |
| <td> |
| <tt>width</tt> |
| </td> |
| <td> |
| This is the width of the glyph image's bounding box. It is |
| independent of the layout direction. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>height</tt> |
| </td> |
| <td> |
| This is the height of the glyph image's bounding box. It is |
| independent of the layout direction. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>horiBearingX</tt> |
| </td> |
| <td> |
| For <em>horizontal text layouts</em>, this is the horizontal |
| distance from the current cursor position to the left-most border of |
| the glyph image's bounding box. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>horiBearingY</tt> |
| </td> |
| <td> |
| For <em>horizontal text layouts</em>, this is the vertical distance |
| from the current cursor position (on the baseline) to the top-most |
| border of the glyph image's bounding box. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>horiAdvance</tt> |
| </td> |
| <td> |
| For <em>horizontal text layouts</em>, this is the horizontal |
| distance used to increment the pen position when the glyph is drawn |
| as part of a string of text. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>vertBearingX</tt> |
| </td> |
| <td> |
| For <em>vertical text layouts</em>, this is the horizontal distance |
| from the current cursor position to the left-most border of the |
| glyph image's bounding box. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>vertBearingY</tt> |
| </td> |
| <td> |
| For <em>vertical text layouts</em>, this is the vertical distance |
| from the current cursor position (on the baseline) to the top-most |
| border of the glyph image's bounding box. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>vertAdvance</tt> |
| </td> |
| <td> |
| For <em>vertical text layouts</em>, this is the vertical distance |
| used to increment the pen position when the glyph is drawn as part |
| of a string of text. |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <p><em>As not all fonts do contain vertical metrics, the values of |
| <tt>vertBearingX</tt>, <tt>vertBearingY</tt>, and <tt>vertAdvance</tt> |
| should not be considered reliable if <tt>FT_HAS_VERTICAL(face)</tt> is |
| false.</em></p> |
| |
| <p>The following graphics illustrate the metrics more clearly. First |
| horizontal metrics, where the baseline is the horizontal axis:</p> |
| |
| <center> |
| <img src="metrics.png" |
| alt="horizontal metrics layout" |
| width=388 height=253> |
| </center> |
| |
| <p>For vertical text layouts, the baseline is vertical and is the |
| vertical axis:</p> |
| |
| <center> |
| <img src="metrics2.png" |
| alt="vertical metrics layout" |
| width=294 height=278> |
| </center> |
| |
| <p>The metrics found in <tt>face->glyph->metrics</tt> are normally |
| expressed in 26.6 pixel format (i.e 1/64th of pixels), unless you use |
| the <tt>FT_LOAD_NO_SCALE</tt> flag when calling <tt>FT_Load_Glyph()</tt> |
| or <tt>FT_Load_Char()</tt>. In that case, the metrics will be expressed |
| in original font units.</p> |
| |
| <p>The glyph slot object has a few other interesting fields that will |
| ease a developer's work. You can access them through |
| <tt>face->glyph->???</tt>:</p> |
| |
| <center> |
| <table width="90%" cellpadding=5> |
| <tr valign=top> |
| <td> |
| <tt>advance</tt> |
| </td> |
| <td> |
| This field is an <tt>FT_Vector</tt> which holds the transformed |
| advance value for the glyph. This is useful if you are using a |
| transformation through <tt>FT_Set_Transform()</tt>, as shown in the |
| rotated text example of the previous part. Other than that, its |
| value is by default (metrics.horiAdvance,0), unless you specify |
| <tt>FT_LOAD_VERTICAL</tt> when loading the glyph image; it will then |
| be (0,metrics.vertAdvance). |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>linearHoriAdvance</tt> |
| </td> |
| <td> |
| This field contains the linearly-scaled value of the glyph's |
| horizontal advance width. Indeed, the value of |
| <tt>metrics.horiAdvance</tt> that is returned in the glyph slot is |
| normally rounded to integer pixel coordinates (i.e., it will be a |
| multiple of 64) by the font driver used to load the glyph |
| image. <tt>linearHoriAdvance</tt> is a 16.16 fixed float number |
| that gives the value of the original glyph advance width in |
| 1/65536th of pixels. It can be used to perform pseudo |
| device-independent text layouts. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>linearVertAdvance</tt> |
| </td> |
| <td> |
| This is the same thing as <tt>linearHoriAdvance</tt> for the glyph's |
| vertical advance height. Its value is only reliable if the font |
| face contains vertical metrics. |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <hr> |
| |
| <h3> |
| 2. Managing glyph images |
| </h3> |
| |
| <p>The glyph image that is loaded in a glyph slot can be converted into |
| a bitmap, either by using <tt>FT_LOAD_RENDER</tt> when loading it, or by |
| calling <tt>FT_Render_Glyph()</tt> afterwards. Each time you load a new |
| glyph image, the previous one is erased from the glyph slot.</p> |
| |
| <p>There are times, however, where you may need to extract this image |
| from the glyph slot. For example, you want to cache images within your |
| application, or you want to apply additional transformations and |
| measures on it before converting it to a bitmap.</p> |
| |
| <p>The FreeType 2 API has a specific extension which is capable of |
| dealing with glyph images in a flexible and generic way. To use it, you |
| first need to include the <tt>ftglyph.h</tt> header file:</p> |
| |
| <font color="blue"> |
| <pre> |
| #include <freetype/ftglyph.h></pre> |
| </font> |
| |
| <p>We will now explain how to use the functions defined in this |
| file.</p> |
| |
| <h4> |
| a. Extracting the glyph image |
| </h4> |
| |
| <p>You can extract a single glyph image very easily. Here some code |
| that shows how to do it.</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_Glyph glyph; /* handle to glyph image */ |
| |
| |
| ... |
| error = FT_Load_Glyph( face, glyph, FT_LOAD_NORMAL ); |
| if ( error ) { .... } |
| |
| error = FT_Get_Glyph( face->glyph, &glyph ); |
| if ( error ) { .... }</pre> |
| </font> |
| |
| <p>As can be seen, we have</p> |
| |
| <ul> |
| <li> |
| created a variable, named <tt>glyph</tt>, of type |
| <tt>FT_Glyph</tt>. This is a handle (pointer) to an individual |
| glyph image, |
| </li> |
| <li> |
| loaded the glyph image normally in the face's glyph slot. We did |
| not use <tt>FT_LOAD_RENDER</tt> because we want to grab a scalable |
| glyph image in order to transform it later, |
| </li> |
| <li> |
| copied the glyph image from the slot into a new <tt>FT_Glyph</tt> |
| object by calling <tt>FT_Get_Glyph()</tt>. This function returns |
| an error code and sets <tt>glyph</tt>. |
| </li> |
| </ul> |
| |
| <p>It is important to note that the extracted glyph is in the same |
| format as the original one that is still in the slot. For example, if |
| we are loading a glyph from a TrueType font file, the glyph image will |
| really be a scalable vector outline.</p> |
| |
| <p>You can access the field <tt>glyph->format</tt> if you want to know |
| exactly how the glyph is modeled and stored. A new glyph object can |
| be destroyed with a call to <tt>FT_Done_Glyph()</tt>.</p> |
| |
| <p>The glyph object contains exactly one glyph image and a |
| 2d vector representing the glyph's advance in 16.16 fixed float |
| coordinates. The latter can be accessed directly as |
| <tt>glyph->advance</tt>.</p> |
| |
| <p><em>Note that unlike other FreeType objects, the library doesn't |
| keep a list of all allocated glyph objects. This means you will need |
| to destroy them yourself, instead of relying on |
| <tt>FT_Done_FreeType()</tt> to do all the clean-up.</em></p> |
| |
| <h4> |
| b. Transforming & copying the glyph image |
| </h4> |
| |
| <p>If the glyph image is scalable (i.e., if <tt>glyph->format</tt> is |
| not <tt>ft_glyph_format_bitmap</tt>), it is possible to transform the |
| image anytime by a call to <tt>FT_Glyph_Transform()</tt>.</p> |
| |
| <p>You can also copy a single glyph image with |
| <tt>FT_Glyph_Copy()</tt>. Here some example code:</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_Glyph glyph, glyph2; |
| FT_Matrix matrix; |
| FT_Vector delta; |
| |
| |
| ... |
| .. load glyph image in "glyph" .. |
| |
| /* copy glyph to glyph2 */ |
| error = FT_Glyph_Copy( glyph, &glyph2 ); |
| if ( error ) { ... could not copy (out of memory) } |
| |
| /* translate "glyph" */ |
| delta.x = -100 * 64; /* coordinates are in 26.6 pixels */ |
| delta.y = 50 * 64; |
| |
| FT_Glyph_Transform( glyph, 0, &delta ); |
| |
| /* transform glyph2 (horizontal shear) */ |
| matrix.xx = 0x10000L; |
| matrix.xy = 0; |
| matrix.yx = 0.12 * 0x10000L; |
| matrix.yy = 0x10000L; |
| |
| FT_Glyph_Transform( glyph2, &matrix, 0 );</pre> |
| </font> |
| |
| <p>Note that the 2x2 transformation matrix is always applied to |
| the 16.16 advance vector in the glyph; you thus don't need to |
| recompute it.</p> |
| |
| <h4> |
| c. Measuring the glyph image |
| </h4> |
| |
| <p>You can also retrieve the control (bounding) box of any glyph image |
| (scalable or not), using the <tt>FT_Glyph_Get_CBox()</tt> |
| function:</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_BBox bbox; |
| |
| |
| ... |
| FT_Glyph_Get_CBox( glyph, <em>bbox_mode</em>, &bbox );</pre> |
| </font> |
| |
| <p>Coordinates are relative to the glyph origin, i.e. (0,0), using the |
| Y upwards convention. This function takes a special argument, |
| <tt>bbox_mode</tt>, to indicate how box coordinates are expressed. If |
| <tt>bbox_mode</tt> is set to <tt>ft_glyph_bbox_subpixels</tt>, the |
| coordinates are returned in 26.6 pixels (i.e. 1/64th of pixels). |
| |
| <p>Note that the box's maximum coordinates are exclusive, which means |
| that you can always compute the width and height of the glyph image, |
| be it in integer or 26.6 pixels with</p> |
| |
| <font color="blue"> |
| <pre> |
| width = bbox.xMax - bbox.xMin; |
| height = bbox.yMax - bbox.yMin;</pre> |
| </font> |
| |
| <p>Note also that for 26.6 coordinates, if |
| <tt>ft_glyph_bbox_gridfit</tt> is set in <tt>bbox_mode</tt>, the |
| coordinates will also be grid-fitted, which corresponds to</p> |
| |
| <font color="blue"> |
| <pre> |
| bbox.xMin = FLOOR(bbox.xMin) |
| bbox.yMin = FLOOR(bbox.yMin) |
| bbox.xMax = CEILING(bbox.xMax) |
| bbox.yMax = CEILING(bbox.yMax)</pre> |
| </font> |
| |
| <p>The default value for <tt>bbox_mode</tt> is |
| <tt>ft_glyph_bbox_pixels</tt> (i.e. integer, grid-fitted pixel |
| coordinates). Please check the API reference of |
| <tt>FT_Glyph_Get_CBox()</tt> for other possible values.</p> |
| |
| <h4> |
| d. Converting the glyph image to a bitmap |
| </h4> |
| |
| <p>You may need to convert the glyph object to a bitmap once you have |
| conveniently cached or transformed it. This can be done easily with |
| the <tt>FT_Glyph_To_Bitmap()</tt> function:</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_Vector origin; |
| |
| |
| origin.x = 32; /* 1/2 pixel in 26.6 format */ |
| origin.y = 0; |
| |
| error = FT_Glyph_To_Bitmap( &glyph, |
| <em>render_mode</em>, |
| &origin, |
| 1 ); /* destroy orig. image == true */</pre> |
| </font> |
| |
| <p>Some details on this function's parameters:</p> |
| |
| <ul> |
| <li> |
| The first parameter is <em>the address of the source glyph's |
| handle</em>. When the function is called, it reads it to access |
| the source glyph object. After the call, the handle will point to |
| a <em>new</em> glyph object that contains the rendered bitmap. |
| </li> |
| <li> |
| The second parameter is a standard render mode that is used to |
| specify what kind of bitmap we want. It can be |
| <tt>ft_render_mode_default</tt> for an 8-bit anti-aliased pixmap, |
| or <tt>ft_render_mode_mono</tt> for a 1-bit monochrome bitmap. |
| </li> |
| <li> |
| The third parameter is a pointer to a 2d vector that is used |
| to translate the source glyph image before the conversion. Note |
| that the source image will be translated back to its original |
| position (and will thus be left unchanged) after the call. If you |
| do not need to translate the source glyph before rendering, set |
| this pointer to 0. |
| </li> |
| <li> |
| The last parameter is a Boolean to indicate whether the source |
| glyph object should be destroyed by the function. By default, the |
| original glyph object is never destroyed, even if its handle is |
| lost (it's up to client applications to keep it). |
| </li> |
| </ul> |
| |
| <p>The new glyph object always contains a bitmap (when no error is |
| returned), and you must <em>typecast</em> its handle to the |
| <tt>FT_BitmapGlyph</tt> type in order to access its contents. This |
| type is a sort of <em>subclass</em> of <tt>FT_Glyph</tt> that contains |
| additional fields:</p> |
| |
| <center> |
| <table width="90%" cellpadding=5> |
| <tr valign=top> |
| <td> |
| <tt>left</tt> |
| </td> |
| <td> |
| Just like the <tt>bitmap_left</tt> field of a glyph slot, this is |
| the horizontal distance from the glyph origin (0,0) to the |
| left-most pixel of the glyph bitmap. It is expressed in integer |
| pixels. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>top</tt> |
| </td> |
| <td> |
| Just like the <tt>bitmap_top</tt> field of a glyph slot, this is |
| the vertical distance from the glyph origin (0,0) to the top-most |
| pixel of the glyph bitmap (more exactly, to the pixel just above |
| the bitmap). This distance is expressed in integer pixels, and is |
| positive for upwards Y. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>bitmap</tt> |
| </td> |
| <td> |
| This is a bitmap descriptor for the glyph object, just like the |
| <tt>bitmap</tt> field in a glyph slot. |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <hr> |
| |
| <h3> |
| 3. Global glyph metrics |
| </h3> |
| |
| <p>Unlike glyph metrics, global ones are used to describe distances and |
| features of a whole font face. They can be expressed either in 26.6 |
| pixel format or in design <em>font units</em> for scalable formats.</p> |
| |
| <h4> |
| a. Design global metrics |
| </h4> |
| |
| <p>For scalable formats, all global metrics are expressed in font |
| units in order to be later scaled to device space, according to the |
| rules described in the last chapter of this part of the tutorial. You |
| can access them directly as fields of an <tt>FT_Face</tt> handle.</p> |
| |
| <p>However, you need to check that the font face's format is scalable |
| before using them. This can be done with the macro |
| <tt>FT_IS_SCALABLE(face)</tt> which returns true if we have a scalable |
| format.</p> |
| |
| <p>In this case, you can access the global design metrics as</p> |
| |
| <center> |
| <table width="90%" cellpadding=5> |
| <tr valign=top> |
| <td> |
| <tt>units_per_EM</tt> |
| </td> |
| <td> |
| This is the size of the EM square for the font face. It is used |
| by scalable formats to scale design coordinates to device pixels, |
| as described by the last chapter of this part. Its value usually |
| is 2048 (for TrueType) or 1000 (for Type 1), but |
| other values are possible too. It is set to 1 for fixed-size |
| formats like FNT/FON/PCF/BDF. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>global_bbox</tt> |
| </td> |
| <td> |
| The global bounding box is defined as the largest rectangle that |
| can enclose all the glyphs in a font face. It is defined for |
| horizontal layouts only. This is not necessarily the smallest |
| bounding box which is possible. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>ascender</tt> |
| </td> |
| <td> |
| The ascender is the vertical distance from the horizontal baseline |
| to the height of the highest character in a font face. |
| <em>Unfortunately, font formats define the ascender |
| differently</em>. For some, it represents the ascent of all |
| capital Latin characters, without accents, for others it is the |
| ascent of the highest accented character, and finally, other |
| formats define it as being equal to <tt>global_bbox.yMax</tt>. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>descender</tt> |
| </td> |
| <td> |
| The descender is the vertical distance from the horizontal |
| baseline to the depth of the lowest character in a font face. |
| <em>Unfortunately, font formats define the descender |
| differently</em>. For some, it represents the descent of all |
| capital Latin characters, without accents, for others it is the |
| ascent of the lowest accented character, and finally, other |
| formats define it as being equal to <tt>global_bbox.yMin</tt>. |
| <em>This field is usually negative.</em> |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>text_height</tt> |
| </td> |
| <td> |
| This field is used to compute a default line spacing (i.e. the |
| baseline-to-baseline distance) when writing text with this font. |
| Note that it usually is larger than the sum of the ascender and |
| descender taken as absolute values. There is also no guarantee |
| that no glyphs can extend above or below subsequent baselines when |
| using this distance. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>max_advance_width</tt> |
| </td> |
| <td> |
| This field gives the maximum horizontal cursor advance for all |
| glyphs in the font. It can be used to quickly compute the maximum |
| advance width of a string of text. <em>It doesn't correspond to |
| the maximum glyph image width!</em> |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>max_advance_height</tt> |
| </td> |
| <td> |
| Same as <tt>max_advance_width</tt> but for vertical text layout. |
| It is only available in fonts providing vertical glyph metrics. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>underline_position</tt> |
| </td> |
| <td> |
| When displaying or rendering underlined text, this value |
| corresponds to the vertical position, relative to the baseline, of |
| the underline bar. It normally is negative (as it is below the |
| baseline). |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>underline_thickness</tt> |
| </td> |
| <td> |
| When displaying or rendering underlined text, this value |
| corresponds to the vertical thickness of the underline. |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <p>Notice how, unfortunately, the values of the ascender and the |
| descender are not reliable (due to various discrepancies in font |
| formats).</p> |
| |
| <h4> |
| b. Scaled global metrics |
| </h4> |
| |
| <p>Each size object also contains scaled versions of some of the |
| global metrics described above. They can be accessed directly through |
| the <tt>face->size->metrics</tt> structure.</p> |
| |
| <p>Note that these values correspond to scaled versions of the design |
| global metrics, <em>with no rounding/grid-fitting performed</em>. They |
| are also completely independent of any hinting process. In other |
| words, don't rely on them to get exact metrics at the pixel level. |
| They are expressed in 26.6 pixel format.</p> |
| |
| <center> |
| <table width="90%" cellpadding=5> |
| <tr valign=top> |
| <td> |
| <tt>ascender</tt> |
| </td> |
| <td> |
| This is the scaled version of the original design ascender. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>descender</tt> |
| </td> |
| <td> |
| This is the scaled version of the original design descender. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>height</tt> |
| </td> |
| <td> |
| The scaled version of the original design text height. This is |
| probably the only field you should really use in this structure. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>max_advance</tt> |
| </td> |
| <td> |
| This is the scaled version of the original design max advance. |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <p>Note that the <tt>face->size->metrics</tt> structure contains other |
| fields that are used to scale design coordinates to device space. |
| They are described below.</p> |
| |
| <h4> |
| c. Kerning |
| </h4> |
| |
| <p>Kerning is the process of adjusting the position of two subsequent |
| glyph images in a string of text, in order to improve the general |
| appearance of text. Basically, it means that when the glyph for an |
| "A" is followed by the glyph for a "V", the space between them can be |
| slightly reduced to avoid extra "diagonal whitespace".</p> |
| |
| <p>Note that in theory, kerning can happen both in the horizontal and |
| vertical direction between two glyphs; however, it only happens in the |
| horizontal direction in nearly all cases except really extreme |
| ones.</p> |
| |
| <p>Not all font formats contain kerning information. Instead, they |
| sometimes rely on an additional file that contains various glyph |
| metrics, including kerning, but no glyph images. A good example would |
| be the Type 1 format, where glyph images are stored in a file |
| with extension <tt>.pfa</tt> or <tt>.pfb</tt>, and where kerning |
| metrics can be found in an additional file with extension |
| <tt>.afm</tt> or <tt>.pfm</tt>.</p> |
| |
| <p>FreeType 2 allows you to deal with this by providing the |
| <tt>FT_Attach_File()</tt> and <tt>FT_Attach_Stream()</tt> APIs. Both |
| functions are used to load additional metrics into a face object, by |
| reading them from an additional format-specific file. For example, |
| you could open a Type 1 font by doing the following:</p> |
| |
| <font color="blue"> |
| <pre> |
| error = FT_New_Face( library, |
| "/usr/shared/fonts/cour.pfb", |
| 0, |
| &face ); |
| if ( error ) { ... } |
| |
| error = FT_Attach_File( face, "/usr/shared/fonts/cour.afm" ); |
| if ( error ) |
| { |
| .. could not read kerning and additional metrics .. |
| }</pre> |
| </font> |
| |
| <p>Note that <tt>FT_Attach_Stream()</tt> is similar to |
| <tt>FT_Attach_File()</tt> except that it doesn't take a C string |
| to name the extra file, but a <tt>FT_Stream</tt> handle. Also, |
| <em>reading a metrics file is in no way mandatory</em>.</p> |
| |
| <p>Finally, the file attachment APIs are very generic and can be used |
| to load any kind of extra information for a given face. The nature of |
| the additional data is entirely font format specific.</p> |
| |
| <p>FreeType 2 allows you to retrieve the kerning information |
| between two glyphs through the <tt>FT_Get_Kerning()</tt> function, |
| whose interface looks like</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_Vector kerning; |
| |
| |
| ... |
| error = FT_Get_Kerning( |
| face, /* handle to face object */ |
| left, /* left glyph index */ |
| right, /* right glyph index */ |
| <em>kerning_mode</em>, /* kerning mode */ |
| &kerning ); /* target vector */</pre> |
| </font> |
| |
| <p>As can be seen, the function takes a handle to a face object, the |
| indices of the left and right glyphs for which the kerning value is |
| desired, as well as an integer, called the <em>kerning mode</em>, and |
| a pointer to a destination vector that receives the corresponding |
| distances.</p> |
| |
| <p>The kerning mode is very similar to <tt>bbox_mode</tt> described in |
| a previous part. It is an enumeration value that indicates how the |
| kerning distances are expressed in the target vector.</p> |
| |
| <p>The default value <tt>ft_kerning_mode_default</tt> (which has |
| value 0) corresponds to kerning distances expressed in 26.6 |
| grid-fitted pixels (which means that the values are multiples |
| of 64). For scalable formats, this means that the design kerning |
| distance is scaled, then rounded.</p> |
| |
| <p>The value <tt>ft_kerning_mode_unfitted</tt> corresponds to kerning |
| distances expressed in 26.6 unfitted pixels (i.e. that do not |
| correspond to integer coordinates). It is the design kerning distance |
| that is scaled without rounding.</p> |
| |
| <p>Finally, the value <tt>ft_kerning_mode_unscaled</tt> is used to |
| return the design kerning distance, expressed in font units. You can |
| later scale it to device space using the computations explained in the |
| last chapter of this part.</p> |
| |
| <p>Note that the "left" and "right" positions correspond to the |
| <em>visual order</em> of the glyphs in the string of text. This is |
| important for bidirectional text, or when writing right-to-left |
| text.</p> |
| |
| <hr> |
| |
| <h3> |
| 4. Simple text rendering: kerning + centering |
| </h3> |
| |
| <p>In order to show off what we have just learned, we will now modify |
| the example code that was provided in the first part to render a string |
| of text, and enhance it to support kerning and delayed rendering.</p> |
| |
| <h4> |
| a. Kerning support |
| </h4> |
| |
| <p>Adding support for kerning to our code is trivial, as long as we |
| consider that we are still dealing with a left-to-right script like |
| Latin. We need to retrieve the kerning distance between two glyphs in |
| order to alter the pen position appropriately. The code looks |
| like</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_GlyphSlot slot = face->glyph; /* a small shortcut */ |
| FT_UInt glyph_index; |
| FT_Bool use_kerning; |
| FT_UInt previous; |
| int pen_x, pen_y, n; |
| |
| |
| .. initialize library .. |
| .. create face object .. |
| .. set character size .. |
| |
| pen_x = 300; |
| pen_y = 200; |
| |
| use_kerning = FT_HAS_KERNING( face ); |
| previous = 0; |
| |
| for ( n = 0; n < num_chars; n++ ) |
| { |
| /* convert character code to glyph index */ |
| glyph_index = FT_Get_Char_Index( face, text[n] ); |
| |
| /* retrieve kerning distance and move pen position */ |
| if ( use_kerning && previous && glyph_index ) |
| { |
| FT_Vector delta; |
| |
| |
| FT_Get_Kerning( face, previous, glyph_index, |
| ft_kerning_mode_default, &delta ); |
| |
| pen_x += delta.x >> 6; |
| } |
| |
| /* load glyph image into the slot (erase previous one) */ |
| error = FT_Load_Glyph( face, glyph_index, 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; |
| |
| /* record current glyph index */ |
| previous = glyph_index; |
| }</pre> |
| </font> |
| |
| <p>We are done. Notice that</p> |
| |
| <ul> |
| <li> |
| As kerning is determined from glyph indices, we need to |
| explicitly convert our character code into a glyph index, then |
| later call <tt>FT_Load_Glyph()</tt> instead of |
| <tt>FT_Load_Char()</tt>. |
| </li> |
| <li> |
| We use a Boolean named <tt>use_kerning</tt> which is set with the |
| result of the macro <tt>FT_HAS_KERNING(face)</tt>. It is |
| certainly faster not to call <tt>FT_Get_Kerning()</tt> if we |
| know that the font face does not contain kerning information. |
| </li> |
| <li> |
| We move the position of the pen <em>before</em> a new glyph is |
| drawn. |
| </li> |
| <li> |
| We did initialize the variable <tt>previous</tt> with the |
| value 0, which always correspond to the <em>missing |
| glyph</em> (also called <tt>.notdef</tt> in the PostScript world). |
| There is never any kerning distance associated with this glyph. |
| </li> |
| <li> |
| We do not check the error code returned by |
| <tt>FT_Get_Kerning()</tt>. This is because the function always |
| set <tt>delta</tt> to (0,0) when an error occurs. |
| </li> |
| </ul> |
| |
| <h4> |
| b. Centering |
| </h4> |
| |
| <p>Our code becomes more interesting but it is still a bit too simple |
| for normal uses. For example, the position of the pen is determined |
| before we do the rendering if in a real-life situation; you would want |
| to layout the text and measure it before computing its final position |
| (e.g. centering) or perform things like word-wrapping.</p> |
| |
| <p>As a consequence we are now going to decompose our text rendering |
| function into two distinct but successive parts: The first one will |
| position individual glyph images on the baseline, while the second one |
| will render the glyphs. As will be shown, this has many |
| advantages.</p> |
| |
| <p>We start by storing individual glyph images, as well as their |
| position on the baseline. This can be done with code like</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_GlyphSlot slot = face->glyph; /* a small shortcut */ |
| FT_UInt glyph_index; |
| FT_Bool use_kerning; |
| FT_UInt previous; |
| int pen_x, pen_y, n; |
| |
| FT_Glyph glyphs[MAX_GLYPHS]; /* glyph image */ |
| FT_Vector pos [MAX_GLYPHS]; /* glyph position */ |
| FT_UInt num_glyphs; |
| |
| |
| .. initialize library .. |
| .. create face object .. |
| .. set character size .. |
| |
| pen_x = 0; /* start at (0,0)! */ |
| pen_y = 0; |
| |
| num_glyphs = 0; |
| use_kerning = FT_HAS_KERNING( face ); |
| previous = 0; |
| |
| for ( n = 0; n < num_chars; n++ ) |
| { |
| /* convert character code to glyph index */ |
| glyph_index = FT_Get_Char_Index( face, text[n] ); |
| |
| /* retrieve kerning distance and move pen position */ |
| if ( use_kerning && previous && glyph_index ) |
| { |
| FT_Vector delta; |
| |
| |
| FT_Get_Kerning( face, previous, glyph_index, |
| ft_kerning_mode_default, &delta ); |
| |
| pen_x += delta.x >> 6; |
| } |
| |
| /* store current pen position */ |
| pos[num_glyphs].x = pen_x; |
| pos[num_glyphs].y = pen_y; |
| |
| /* load glyph image into the slot. DO NOT RENDER IT! */ |
| error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); |
| if ( error ) continue; /* ignore errors, jump to next glyph */ |
| |
| /* extract glyph image and store it in our table */ |
| error = FT_Get_Glyph( face->glyph, &glyphs[num_glyphs] ); |
| if ( error ) continue; /* ignore errors, jump to next glyph */ |
| |
| /* increment pen position */ |
| pen_x += slot->advance.x >> 6; |
| |
| /* record current glyph index */ |
| previous = glyph_index; |
| |
| /* increment number of glyphs */ |
| num_glyphs++; |
| }</pre> |
| </font> |
| |
| <p>As you see, this is a very slight variation of our previous code |
| where we extract each glyph image from the slot, and store it, along |
| with the corresponding position, in our tables.</p> |
| |
| <p>Note also that <tt>pen_x</tt> contains the total advance for the |
| string of text. We can now compute the bounding box of the text |
| string with a simple function like</p> |
| |
| <font color="blue"> |
| <pre> |
| void compute_string_bbox( FT_BBox* abbox ) |
| { |
| FT_BBox bbox; |
| |
| |
| /* initialize string bbox to "empty" values */ |
| bbox.xMin = bbox.yMin = 32000; |
| bbox.xMax = bbox.yMax = -32000; |
| |
| /* for each glyph image, compute its bounding box, */ |
| /* translate it, and grow the string bbox */ |
| for ( n = 0; n < num_glyphs; n++ ) |
| { |
| FT_BBox glyph_bbox; |
| |
| |
| FT_Glyph_Get_CBox( glyphs[n], &glyph_bbox ); |
| |
| glyph_bbox.xMin += pos[n].x; |
| glyph_bbox.xMax += pos[n].x; |
| glyph_bbox.yMin += pos[n].y; |
| glyph_bbox.yMax += pos[n].y; |
| |
| if ( glyph_bbox.xMin < bbox.xMin ) |
| bbox.xMin = glyph_bbox.xMin; |
| |
| if ( glyph_bbox.yMin < bbox.yMin ) |
| bbox.yMin = glyph_bbox.yMin; |
| |
| if ( glyph_bbox.xMax > bbox.xMax ) |
| bbox.xMax = glyph_bbox.xMax; |
| |
| if ( glyph_bbox.yMax &gy; bbox.yMax ) |
| bbox.yMax = glyph_bbox.yMax; |
| } |
| |
| /* check that we really grew the string bbox */ |
| if ( bbox.xMin > bbox.xMax ) |
| { |
| bbox.xMin = 0; |
| bbox.yMin = 0; |
| bbox.xMax = 0; |
| bbox.yMax = 0; |
| } |
| |
| /* return string bbox */ |
| *abbox = bbox; |
| }</pre> |
| </font> |
| |
| <p>The resulting bounding box dimensions can then be used to compute |
| the final pen position before rendering the string as in:</p> |
| |
| <font color="blue"> |
| <pre> |
| /* compute string dimensions in integer pixels */ |
| string_width = ( string_bbox.xMax - string_bbox.xMin ) / 64; |
| string_height = ( string_bbox.yMax - string_bbox.yMin ) / 64; |
| |
| /* compute start pen position in 26.6 cartesian pixels */ |
| start_x = ( ( my_target_width - string_width ) / 2 ) * 64; |
| start_y = ( ( my_target_height - string_height ) / 2 ) * 64; |
| |
| for ( n = 0; n < num_glyphs; n++ ) |
| { |
| FT_Glyph image; |
| FT_Vector pen; |
| |
| |
| image = glyphs[n]; |
| |
| pen.x = start_x + pos[n].x; |
| pen.y = start_y + pos[n].y; |
| |
| error = FT_Glyph_To_Bitmap( &image, ft_render_mode_normal, |
| &pen.x, 0 ); |
| if ( !error ) |
| { |
| FT_BitmapGlyph bit = (FT_BitmapGlyph)image; |
| |
| |
| my_draw_bitmap( bitmap->bitmap, |
| bitmap->left, |
| my_target_height - bitmap->top ); |
| |
| FT_Done_Glyph( image ); |
| } |
| }</pre> |
| </font> |
| |
| <p>Some remarks:</p> |
| |
| <ul> |
| <li> |
| The pen position is expressed in the cartesian space (i.e. |
| Y upwards). |
| </li> |
| <li> |
| We call <tt>FT_Glyph_To_Bitmap()</tt> with the <tt>destroy</tt> |
| parameter set to 0 (false), in order to avoid destroying the |
| original glyph image. The new glyph bitmap is accessed through |
| <tt>image</tt> after the call and is typecast to an |
| <tt>FT_BitmapGlyph</tt>. |
| </li> |
| <li> |
| We use translation when calling <tt>FT_Glyph_To_Bitmap()</tt>. |
| This ensures that the <tt>left</tt> and <tt>top</tt> fields of the |
| bitmap glyph object are already set to the correct pixel |
| coordinates in the cartesian space. |
| </li> |
| <li> |
| Of course, we still need to convert pixel coordinates from |
| cartesian to device space before rendering, hence the |
| <tt>my_target_height - bitmap->top</tt> in the call to |
| <tt>my_draw_bitmap()</tt>. |
| </li> |
| </ul> |
| |
| <p>The same loop can be used to render the string anywhere on our |
| display surface, without the need to reload our glyph images each |
| time.</p> |
| |
| <hr> |
| |
| <h3> |
| 5. Advanced text rendering: transformation + centering + kerning |
| </h3> |
| |
| <p>We are now going to modify our code in order to be able to easily |
| transform the rendered string, for example to rotate it. We will start |
| by performing a few minor improvements:</p> |
| |
| <h4> |
| a. packing & translating glyphs |
| </h4> |
| |
| <p>We start by packing the information related to a single glyph image |
| into a single structure instead of parallel arrays. We thus define |
| the following structure type:</p> |
| |
| <font color="blue"> |
| <pre> |
| typedef struct TGlyph_ |
| { |
| FT_UInt index; /* glyph index */ |
| FT_Vector pos; /* glyph origin on the baseline */ |
| FT_Glyph image; /* glyph image */ |
| |
| } TGlyph, *PGlyph;</pre> |
| </font> |
| |
| <p>We will also translate each glyph image directly after it is loaded |
| to its position on the baseline at load time, which has several |
| advantages. Our glyph sequence loader thus becomes:</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_GlyphSlot slot = face->glyph; /* a small shortcut */ |
| FT_UInt glyph_index; |
| FT_Bool use_kerning; |
| FT_UInt previous; |
| int pen_x, pen_y, n; |
| |
| TGlyph glyphs[MAX_GLYPHS]; /* glyphs table */ |
| PGlyph glyph; /* current glyph in table */ |
| FT_UInt num_glyphs; |
| |
| |
| .. initialize library .. |
| .. create face object .. |
| .. set character size .. |
| |
| pen_x = 0; /* start at (0,0)! */ |
| pen_y = 0; |
| |
| num_glyphs = 0; |
| use_kerning = FT_HAS_KERNING( face ); |
| previous = 0; |
| |
| glyph = glyphs; |
| for ( n = 0; n < num_chars; n++ ) |
| { |
| glyph->index = FT_Get_Char_Index( face, text[n] ); |
| |
| if ( use_kerning && previous && glyph->index ) |
| { |
| FT_Vector delta; |
| |
| |
| FT_Get_Kerning( face, previous, glyph->index, |
| ft_kerning_mode_default, &delta ); |
| |
| pen_x += delta.x >> 6; |
| } |
| |
| /* store current pen position */ |
| glyph->pos.x = pen_x; |
| glyph->pos.y = pen_y; |
| |
| error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); |
| if ( error ) continue; |
| |
| error = FT_Get_Glyph( face->glyph, &glyph->image ); |
| if ( error ) continue; |
| |
| /* translate the glyph image now */ |
| FT_Glyph_Transform( glyph->image, 0, &glyph->pos ); |
| |
| pen_x += slot->advance.x >> 6; |
| previous = glyph->index |
| |
| /* increment number of glyphs */ |
| glyph++; |
| } |
| |
| /* count number of glyphs loaded */ |
| num_glyphs = glyph - glyphs;</pre> |
| </font> |
| |
| <p>Translating glyphs now has several advantages, as mentioned |
| earlier. The first one is that we don't need to translate the glyph |
| bounding box when we compute the string's bounding box. The code |
| becomes:</p> |
| |
| <font color="blue"> |
| <pre> |
| void compute_string_bbox( FT_BBox* abbox ) |
| { |
| FT_BBox bbox; |
| |
| |
| bbox.xMin = bbox.yMin = 32000; |
| bbox.xMax = bbox.yMax = -32000; |
| |
| for ( n = 0; n < num_glyphs; n++ ) |
| { |
| FT_BBox glyph_bbox; |
| |
| |
| FT_Glyph_Get_CBox( glyphs[n], &glyph_bbox ); |
| |
| if ( glyph_bbox.xMin < bbox.xMin ) |
| bbox.xMin = glyph_bbox.xMin; |
| |
| if ( glyph_bbox.yMin < bbox.yMin ) |
| bbox.yMin = glyph_bbox.yMin; |
| |
| if ( glyph_bbox.xMax > bbox.xMax ) |
| bbox.xMax = glyph_bbox.xMax; |
| |
| if ( glyph_bbox.yMax &gy; bbox.yMax ) |
| bbox.yMax = glyph_bbox.yMax; |
| } |
| |
| if ( bbox.xMin > bbox.xMax ) |
| { |
| bbox.xMin = 0; |
| bbox.yMin = 0; |
| bbox.xMax = 0; |
| bbox.yMax = 0; |
| } |
| |
| *abbox = bbox; |
| }</pre> |
| </font> |
| |
| <p><tt>compute_string_bbox()</tt> can now compute the bounding box of |
| a transformed glyph string. For example, we can do something |
| like</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_BBox bbox; |
| FT_Matrix matrix; |
| FT_Vector delta; |
| |
| |
| ... load glyph sequence |
| |
| ... setup "matrix" and "delta" |
| |
| /* transform glyphs */ |
| for ( n = 0; n < num_glyphs; n++ ) |
| FT_Glyph_Transform( glyphs[n].image, &matrix, &delta ); |
| |
| /* compute bounding box of transformed glyphs */ |
| compute_string_bbox( &bbox );</pre> |
| </font> |
| |
| <h4> |
| b. Rendering a transformed glyph sequence |
| </h4> |
| |
| <p>However, directly transforming the glyphs in our sequence is not a |
| useful idea if we want to reuse them in order to draw the text string |
| with various angles or transforms. It is better to perform the affine |
| transformation just before the glyph is rendered, as in the following |
| code:</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_Vector start; |
| FT_Matrix transform; |
| |
| |
| /* get bbox of original glyph sequence */ |
| compute_string_bbox( &string_bbox ); |
| |
| /* compute string dimensions in integer pixels */ |
| string_width = ( string_bbox.xMax - string_bbox.xMin ) / 64; |
| string_height = ( string_bbox.yMax - string_bbox.yMin ) / 64; |
| |
| /* set up start position in 26.6 cartesian space */ |
| start.x = ( ( my_target_width - string_width ) / 2 ) * 64; |
| start.y = ( ( my_target_height - string_height ) / 2 ) * 64; |
| |
| /* set up transformation (a rotation here) */ |
| 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 ); |
| |
| for ( n = 0; n < num_glyphs; n++ ) |
| { |
| FT_Glyph image; |
| FT_Vector pen; |
| FT_BBox bbox; |
| |
| |
| /* create a copy of the original glyph */ |
| error = FT_Glyph_Copy( glyphs[n].image, &image ); |
| if ( error ) continue; |
| |
| /* transform copy (this will also translate it to the */ |
| /* correct position */ |
| FT_Glyph_Transform( image, &matrix, &start ); |
| |
| /* check bounding box -- if the transformed glyph image */ |
| /* is not in our target surface, we can avoid rendering */ |
| FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox ); |
| if ( bbox.xMax <= 0 || bbox.xMin >= my_target_width || |
| bbox.yMax <= 0 || bbox.yMin >= my_target_height ) |
| continue; |
| |
| /* convert glyph image to bitmap (destroy the glyph */ |
| /* copy!) */ |
| error = FT_Glyph_To_Bitmap( |
| &image, |
| ft_render_mode_normal, |
| 0, /* no additional translation */ |
| 1 ); /* destroy copy in "image" */ |
| if ( !error ) |
| { |
| FT_BitmapGlyph bit = (FT_BitmapGlyph)image; |
| |
| |
| my_draw_bitmap( bitmap->bitmap, |
| bitmap->left, |
| my_target_height - bitmap->top ); |
| |
| FT_Done_Glyph( image ); |
| } |
| }</pre> |
| </font> |
| |
| <p>There are a few changes compared to the previous version of this |
| code:</p> |
| |
| <ul> |
| <li> |
| We keep the original glyph images untouched, by transforming a |
| copy. |
| </li> |
| <li> |
| We perform clipping computations in order to avoid rendering & |
| drawing glyphs that are not within our target surface. |
| </li> |
| <li> |
| We always destroy the copy when calling |
| <tt>FT_Glyph_To_Bitmap()</tt> in order to get rid of the |
| transformed scalable image. Note that the image is destroyed even |
| when the function returns an error code (which is why |
| <tt>FT_Done_Glyph()</tt> is only called within the compound |
| statement). |
| </li> |
| <li> |
| The translation of the glyph sequence to the start pen position is |
| integrated in the call to <tt>FT_Glyph_Transform()</tt> intead of |
| <tt>FT_Glyph_To_Bitmap()</tt>. |
| </li> |
| </ul> |
| |
| <p>It is possible to call this function several times to render the |
| string with different angles, or even change the way <tt>start</tt> |
| is computed in order to move it to a different place.</p> |
| |
| <p>This code is the basis of the FreeType 2 demonstration program |
| named <tt>ftstring.c</tt>. It could be easily extended to perform |
| advanced text layout or word-wrapping in the first part, without |
| changing the second one.</p> |
| |
| <p>Note however that a normal implementation would use a glyph cache |
| in order to reduce memory consumption. For example, let us assume |
| that our text string to render is "FreeType". We would store three |
| identical glyph images in our table for the letter "e", which isn't |
| optimal (especially when you consider longer lines of text, or even |
| whole pages).</p> |
| |
| <hr> |
| |
| <h3> |
| 6. Accessing metrics in design font units and scaling them |
| </h3> |
| |
| <p>Scalable font formats usually store a single vectorial image, called |
| an <em>outline</em>, for each glyph in a face. Each outline is defined |
| in an abstract grid called the <em>design space</em>, with coordinates |
| expressed in nominal <em>font units</em>. When a glyph image is loaded, |
| the font driver usually scales the outline to device space according to |
| the current character pixel size found in a <tt>FT_Size</tt> object. |
| The driver may also modify the scaled outline in order to significantly |
| improve its appearance on a pixel-based surface (a process known as |
| <em>hinting</em> or <em>grid-fitting</em>).</p> |
| |
| <p>This section describes how design coordinates are scaled to device |
| space, and how to read glyph outlines and metrics in font units. This |
| is important for a number of things:</p> |
| |
| <ul> |
| <li> |
| <p>to perform "true" WYSIWYG text layout.</p> |
| </li> |
| <li> |
| <p>to access font data for conversion or analysis purposes</p> |
| </li> |
| </ul> |
| |
| <h4> |
| a. Scaling distances to device space |
| </h4> |
| |
| <p>Design coordinates are scaled to device space using a simple |
| scaling transformation whose coefficients are computed with the help |
| of the <em>character pixel size</em>:</p> |
| |
| <font color="purple"> |
| <pre> |
| device_x = design_x * x_scale |
| device_y = design_y * y_scale |
| |
| x_scale = pixel_size_x / EM_size |
| y_scale = pixel_size_y / EM_size</pre> |
| </font> |
| |
| <p>Here, the value <tt>EM_size</tt> is font-specific and corresponds |
| to the size of an abstract square of the design space (called the |
| "EM"), which is used by font designers to create glyph images. It is |
| thus expressed in font units. It is also accessible directly for |
| scalable font formats as <tt>face->units_per_EM</tt>. You should |
| check that a font face contains scalable glyph images by using the |
| <tt>FT_IS_SCALABLE(face)</tt> macro, which returns true when the font |
| is scalable.</p> |
| |
| <p>When you call the function <tt>FT_Set_Pixel_Sizes()</tt>, you are |
| specifying the value of <tt>pixel_size_x</tt> and |
| <tt>pixel_size_y</tt>; FreeType will then immediately compute the |
| values of <tt>x_scale</tt> and <tt>y_scale</tt>.</p> |
| |
| <p>When you call the function <tt>FT_Set_Char_Size()</tt>, you are |
| specifying the character size in physical "points", which is used, |
| along with the device's resolutions, to compute the character pixel |
| size, then the scaling factors.</p> |
| |
| <p>Note that after calling any of these two functions, you can access |
| the values of the character pixel size and scaling factors as fields |
| of the <tt>face->size->metrics</tt> structure. These fields are:</p> |
| |
| <center> |
| <table width="90%" cellpadding="5"> |
| <tr valign=top> |
| <td> |
| <tt>x_ppem</t> |
| </td> |
| <td> |
| This is the size in integer pixels of the EM square, which also is |
| the <em>horizontal character pixel size</em>, called |
| <tt>pixel_size_x</tt> in the above example. <tt>x_ppem</tt> means |
| "x pixels per EM". |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>y_ppem</tt> |
| </td> |
| <td> |
| This is the size in integer pixels of the EM square, which also is |
| the <em>vertical character pixel size</em>, called |
| <tt>pixel_size_y</tt> in the above example. <tt>y_ppem</tt> means |
| "y pixels per EM". |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>x_scale</tt> |
| </td> |
| <td> |
| This is a 16.16 fixed float scale that is used to directly scale |
| horizontal distances from design space to 1/64th of device pixels. |
| </td> |
| </tr> |
| <tr valign=top> |
| <td> |
| <tt>y_scale</tt> |
| </td> |
| <td> |
| This is a 16.16 fixed float scale that is used to directly scale |
| vertical distances from design space to 1/64th of device pixels. |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <p>You can scale a distance expressed in font units to 26.6 pixels |
| directly with the help of the <tt>FT_MulFix()</tt> function, as |
| in:</p> |
| |
| <font color="blue"> |
| <pre> |
| /* convert design distances to 1/64th of pixels */ |
| pixels_x = FT_MulFix( design_x, face->size->metrics.x_scale ); |
| pixels_y = FT_MulFix( design_y, face->size->metrics.y_scale );</pre> |
| </font> |
| |
| <p>However, you can also scale the value directly with more accuracy |
| by using doubles and the equations:</p> |
| |
| <font color="blue"> |
| <pre> |
| FT_Size_Metrics* metrics = &face->size->metrics; /* shortcut */ |
| double pixels_x, pixels_y; |
| double em_size, x_scale, y_scale; |
| |
| |
| /* compute floating point scale factors */ |
| em_size = 1.0 * face->units_per_EM; |
| x_scale = metrics->x_ppem / em_size; |
| y_scale = metrics->y_ppem / em_size; |
| |
| /* convert design distances to floating point pixels */ |
| pixels_x = design_x * x_scale; |
| pixels_y = design_y * y_scale;</pre> |
| </font> |
| |
| <h4> |
| b. Accessing design metrics (glyph & global) |
| </h4> |
| |
| <p>You can access glyph metrics in font units by specifying the |
| <tt>FT_LOAD_NO_SCALE</tt> bit flag in <tt>FT_Load_Glyph()</tt> or |
| <tt>FT_Load_Char()</tt>. The metrics returned in |
| <tt>face->glyph->metrics</tt> will then all be in font units.</p> |
| |
| <p>Unscaled kerning data can be retrieved using the |
| <tt>ft_kerning_mode_unscaled</tt> mode.</p> |
| |
| <p>Finally, a few global metrics are available directly in font units |
| as fields of the <tt>FT_Face</tt> handle, as described in |
| section 3 of this tutorial part.</p> |
| |
| <hr> |
| |
| <h3> |
| Conclusion |
| </h3> |
| |
| <p>This is the end of the second part of the FreeType 2 tutorial; |
| you are now able to access glyph metrics, manage glyph images, and |
| render text much more intelligently (kerning, measuring, transforming |
| & caching).</p> |
| |
| <p>With this knowledge you can build a pretty decent text service on top |
| of FreeType 2, and you could possibly stop there if you want.</p> |
| |
| <p>The next section will deal with FreeType 2 internals (like |
| modules, vector outlines, font drivers, renderers), as well as a few |
| font format specific issues (mainly, how to access certain TrueType or |
| Type 1 tables).</p> |
| </td></tr> |
| </table> |
| </center> |
| |
| </body> |
| </html> |