| <!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 Glyph Conventions</title> |
| </head> |
| |
| <body text="#000000" |
| bgcolor="#FFFFFF" |
| link="#0000EF" |
| vlink="#51188E" |
| alink="#FF0000"> |
| |
| <h1 align=center> |
| FreeType Glyph Conventions |
| </h1> |
| |
| <h2 align=center> |
| Version 2.1 |
| </h2> |
| |
| <h3 align=center> |
| Copyright 1998-2000 David Turner (<a |
| href="mailto:david@freetype.org">david@freetype.org</a>)<br> |
| Copyright 2000 The FreeType Development Team (<a |
| href="mailto:devel@freetype.org">devel@freetype.org</a>) |
| </h3> |
| |
| <center> |
| <table width="65%"> |
| <tr><td> |
| |
| <center> |
| <table width="100%" |
| border=0 |
| cellpadding=5> |
| <tr bgcolor="#CCFFCC" |
| valign=center> |
| <td align=center |
| width="30%"> |
| <a href="glyphs-5.html">Previous</a> |
| </td> |
| <td align=center |
| width="30%"> |
| <a href="index.html">Contents</a> |
| </td> |
| <td align=center |
| width="30%"> |
| <a href="glyphs-7.html">Next</a> |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <p><hr></p> |
| |
| <table width="100%"> |
| <tr bgcolor="#CCCCFF" |
| valign=center><td> |
| <h2> |
| VI. FreeType outlines |
| </h2> |
| </td></tr> |
| </table> |
| |
| <p>The purpose of this section is to present the way FreeType manages |
| vectorial outlines, as well as the most common operations that can be |
| applied on them.</p> |
| |
| <a name="section-1"> |
| <h3> |
| 1. FreeType outline description and structure |
| </h3> |
| |
| <h4> |
| a. Outline curve decomposition |
| </h4> |
| |
| <p>An outline is described as a series of closed contours in the 2D |
| plane. Each contour is made of a series of line segments and |
| Bézier arcs. Depending on the file format, these can be |
| second-order or third-order polynomials. The former are also called |
| quadratic or conic arcs, and they are used in the TrueType format. |
| The latter are called cubic arcs and are mostly used in the |
| Type 1 format.</p> |
| |
| <p>Each arc is described through a series of start, end, and control |
| points. Each point of the outline has a specific tag which indicates |
| whether it is used to describe a line segment or an arc. The tags can |
| take the following values:</p> |
| |
| <center> |
| <table cellspacing=5 |
| cellpadding=5 |
| width="80%"> |
| <tr VALIGN=TOP> |
| <td valign=top> |
| <tt>FT_Curve_Tag_On</tt> |
| </td> |
| <td valign=top> |
| <p>Used when the point is "on" the curve. This corresponds to |
| start and end points of segments and arcs. The other tags specify |
| what is called an "off" point, i.e. a point which isn't located on |
| the contour itself, but serves as a control point for a |
| Bézier arc.</p> |
| </td> |
| </tr> |
| |
| <tr> |
| <td valign=top> |
| <tt>FT_Curve_Tag_Conic</tt> |
| </td> |
| <td valign=top> |
| <p>Used for an "off" point used to control a conic Bézier |
| arc.</p> |
| </td> |
| </tr> |
| |
| <tr> |
| <td valign=top> |
| <tt>FT_Curve_Tag_Cubic</tt> |
| </td> |
| <td valign=top> |
| <p>Used for an "off" point used to control a cubic Bézier |
| arc.</p> |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <p>The following rules are applied to decompose the contour's points |
| into segments and arcs:</p> |
| |
| <ul> |
| <li> |
| Two successive "on" points indicate a line segment joining them. |
| </li> |
| <li> |
| One conic "off" point amidst two "on" points indicates a conic |
| Bézier arc, the "off" point being the control point, and |
| the "on" ones the start and end points. |
| </li> |
| <li> |
| Two successive cubic "off" points amidst two "on" points indicate |
| a cubic Bézier arc. There must be exactly two cubic |
| control points and two "on" points for each cubic arc (using a |
| single cubic "off" point between two "on" points is forbidden, for |
| example). |
| </li> |
| <li> |
| Finally, two successive conic "off" points forces the rasterizer |
| to create (during the scan-line conversion process exclusively) a |
| virtual "on" point amidst them, at their exact middle. This |
| greatly facilitates the definition of successive conic |
| Bézier arcs. Moreover, it is the way outlines are |
| described in the TrueType specification. |
| </li> |
| </ul> |
| |
| <p>Note that it is possible to mix conic and cubic arcs in a single |
| contour, even though no current font driver produces such |
| outlines.</p> |
| |
| <center> |
| <table> |
| <tr> |
| <td> |
| <img src="points_segment.png" |
| height=166 width=221 |
| alt="segment example"> |
| </td> |
| <td> |
| <img src="points_conic.png" |
| height=183 width=236 |
| alt="conic arc example"> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <img src="points_cubic.png" |
| height=162 width=214 |
| alt="cubic arc example"> |
| </td> |
| <td> |
| <img src="points_conic2.png" |
| height=204 width=225 |
| alt="cubic arc with virtual 'on' point"> |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| |
| <h4> |
| b. Outline descriptor |
| </h4> |
| |
| <p>A FreeType outline is described through a simple structure:</p> |
| |
| <center> |
| <table cellspacing=3 |
| cellpadding=3> |
| <caption> |
| <b><tt>FT_Outline</tt></b> |
| </caption> |
| |
| <tr> |
| <td> |
| <tt>n_points</tt> |
| </td> |
| <td> |
| the number of points in the outline |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <tt>n_contours</tt> |
| </td> |
| <td> |
| the number of contours in the outline |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <tt>points</tt> |
| </td> |
| <td> |
| array of point coordinates |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <tt>contours</tt> |
| </td> |
| <td> |
| array of contour end indices |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <tt>tags</tt> |
| </td> |
| <td> |
| array of point flags |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <p>Here, <tt>points</tt> is a pointer to an array of |
| <tt>FT_Vector</tt> records, used to store the vectorial coordinates of |
| each outline point. These are expressed in 1/64th of a pixel, which |
| is also known as the <em>26.6 fixed float format</em>.</p> |
| |
| <p><tt>contours</tt> is an array of point indices used to delimit |
| contours in the outline. For example, the first contour always starts |
| at point 0, and ends at point <tt>contours[0]</tt>. The second |
| contour starts at point <tt>contours[0]+1</tt> and ends at |
| <tt>contours[1]</tt>, etc.</p> |
| |
| <p>Note that each contour is closed, and that <tt>n_points</tt> should |
| be equal to <tt>contours[n_contours-1]+1</tt> for a valid outline.</p> |
| |
| <p>Finally, <tt>tags</tt> is an array of bytes, used to store each |
| outline point's tag.</p> |
| |
| |
| <a name="section-2"> |
| <h3> |
| 2. Bounding and control box computations |
| </h3> |
| |
| <p>A <em>bounding box</em> (also called <em>bbox</em>) is simply a |
| rectangle that completely encloses the shape of a given outline. The |
| interesting case is the smallest bounding box possible, and in the |
| following we subsume this under the term "bounding box". Because of the |
| way arcs are defined, Bézier control points are not necessarily |
| contained within an outline's (smallest) bounding box.</p> |
| |
| <p>This situation happens when one Bézier arc is, for example, |
| the upper edge of an outline and an "off" point happens to be above the |
| bbox. However, it is very rare in the case of character outlines |
| because most font designers and creation tools always place "on" points |
| at the extrema of each curved edges, as it makes hinting much |
| easier.</p> |
| |
| <p>We thus define the <em>control box</em> (also called <em>cbox</em>) |
| as the smallest possible rectangle that encloses all points of a given |
| outline (including its "off" points). Clearly, it always includes the |
| bbox, and equates it in most cases.</p> |
| |
| <p>Unlike the bbox, the cbox is much faster to compute.</p> |
| |
| <center> |
| <table> |
| <tr> |
| <td> |
| <img src="bbox1.png" |
| height=264 width=228 |
| alt="a glyph with different bbox and cbox"> |
| </td> |
| <td> |
| <img src="bbox2.png" |
| height=229 width=217 |
| alt="a glyph with identical bbox and cbox"> |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| <p>Control and bounding boxes can be computed automatically through the |
| functions <tt>FT_Get_Outline_CBox()</tt> and |
| <tt>FT_Get_Outline_BBox()</tt>. The former function is always very |
| fast, while the latter <em>may</em> be slow in the case of "outside" |
| control points (as it needs to find the extreme of conic and cubic arcs |
| for "perfect" computations). If this isn't the case, it is as fast as |
| computing the control box. |
| |
| <p>Note also that even though most glyph outlines have equal cbox and |
| bbox to ease hinting, this is not necessary the case anymore when a |
| transformation like rotation is applied to them.</p> |
| |
| |
| <a name="section-3"> |
| <h3> |
| 3. Coordinates, scaling and grid-fitting |
| </h3> |
| |
| <p>An outline point's vectorial coordinates are expressed in the |
| 26.6 format, i.e. in 1/64th of a pixel, hence coordinates |
| (1.0,-2.5) is stored as the integer pair (x:64,y:-192).</p> |
| |
| <p>After a master glyph outline is scaled from the EM grid to the |
| current character dimensions, the hinter or grid-fitter is in charge of |
| aligning important outline points (mainly edge delimiters) to the pixel |
| grid. Even though this process is much too complex to be described in a |
| few lines, its purpose is mainly to round point positions, while trying |
| to preserve important properties like widths, stems, etc.</p> |
| |
| <p>The following operations can be used to round vectorial distances in |
| the 26.6 format to the grid:</p> |
| |
| <pre> |
| round( x ) == ( x + 32 ) & -64 |
| floor( x ) == x & -64 |
| ceiling( x ) == ( x + 63 ) & -64</pre> |
| |
| <p>Once a glyph outline is grid-fitted or transformed, it often is |
| interesting to compute the glyph image's pixel dimensions before |
| rendering it. To do so, one has to consider the following:</p> |
| |
| <p>The scan-line converter draws all the pixels whose <em>centers</em> |
| fall inside the glyph shape. It can also detect <em>drop-outs</em>, |
| i.e. discontinuities coming from extremely thin shape fragments, in |
| order to draw the "missing" pixels. These new pixels are always located |
| at a distance less than half of a pixel but it is not easy to predict |
| where they will appear before rendering.</p> |
| |
| <p>This leads to the following computations:</p> |
| |
| <ul> |
| <li> |
| <p>compute the bbox</p> |
| </li> |
| <li> |
| <p>grid-fit the bounding box with the following:</p> |
| |
| <pre> |
| xmin = floor( bbox.xMin ) |
| xmax = ceiling( bbox.xMax ) |
| ymin = floor( bbox.yMin ) |
| ymax = ceiling( bbox.yMax )</pre> |
| </li> |
| <li> |
| return pixel dimensions, i.e. |
| |
| <pre> |
| width = (xmax - xmin)/64</pre> |
| |
| and |
| |
| <pre> |
| height = (ymax - ymin)/64</pre> |
| </li> |
| </ul> |
| |
| <p>By grid-fitting the bounding box, it is guaranteed that all the pixel |
| centers that are to be drawn, <em>including those coming from drop-out |
| control</em>, will be <em>within</em> the adjusted box. Then the box's |
| dimensions in pixels can be computed.</p> |
| |
| <p>Note also that, when translating a grid-fitted outline, one should |
| <em>always use integer distances</em> to move an outline in the 2D |
| plane. Otherwise, glyph edges won't be aligned on the pixel grid |
| anymore, and the hinter's work will be lost, producing <em>very low |
| quality </em>bitmaps and pixmaps.</p> |
| |
| |
| <p><hr></p> |
| |
| <center> |
| <table width="100%" |
| border=0 |
| cellpadding=5> |
| <tr bgcolor="#CCFFCC" |
| valign=center> |
| <td align=center |
| width="30%"> |
| <a href="glyphs-5.html">Previous</a> |
| </td> |
| <td align=center |
| width="30%"> |
| <a href="index.html">Contents</a> |
| </td> |
| <td align=center |
| width="30%"> |
| <a href="glyphs-7.html">Next</a> |
| </td> |
| </tr> |
| </table> |
| </center> |
| |
| </td></tr> |
| </table> |
| </center> |
| |
| </body> |
| </html> |