|
|
|
@ -1,12 +1,13 @@ |
|
|
|
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> |
|
|
|
|
<!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="blob"> |
|
|
|
|
<meta name="GENERATOR" content="Mozilla/4.5 [fr] (Win98; I) [Netscape]"> |
|
|
|
|
<title>FreeType Glyph Conventions</title> |
|
|
|
|
<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> |
|
|
|
|
|
|
|
|
|
<body text="#000000" |
|
|
|
|
bgcolor="#FFFFFF" |
|
|
|
@ -14,364 +15,415 @@ |
|
|
|
|
vlink="#51188E" |
|
|
|
|
alink="#FF0000"> |
|
|
|
|
|
|
|
|
|
<center><h1> |
|
|
|
|
FreeType Glyph Conventions |
|
|
|
|
</h1></center> |
|
|
|
|
|
|
|
|
|
<center><h2> |
|
|
|
|
version 2.1 |
|
|
|
|
</h2></center> |
|
|
|
|
|
|
|
|
|
<center><h3> |
|
|
|
|
Copyright 1998-2000 David Turner (<a href="mailto:david@freetype.org">david@freetype.org</a>)<br> |
|
|
|
|
Copyright 2000 The FreeType Development Team (<a href="devel@freetype.org">devel@freetype.org</a>) |
|
|
|
|
</h3></center> |
|
|
|
|
|
|
|
|
|
<center><table width=650><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> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<table width="100%"><tr valign=center bgcolor="#CCCCFF"><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> |
|
|
|
|
|
|
|
|
|
<h3><a name="section-1"> |
|
|
|
|
1. FreeType outline description and structure : |
|
|
|
|
</h3><blockquote> |
|
|
|
|
|
|
|
|
|
<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 bezier |
|
|
|
|
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 |
|
|
|
|
come from the TrueType format. The latter are called cubic arcs and mostly |
|
|
|
|
come from the Type1 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 wether 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> |
|
|
|
|
<p><b>FT_Curve_Tag_On </b></p> |
|
|
|
|
</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. one which isn't located on the contour itself, |
|
|
|
|
but serves as a control point for a bezier arc.</p> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
|
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<p><b>FT_Curve_Tag_Conic</b></p> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<p>Used for an "off" point used to control a conic bezier arc.</p> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
|
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<p><b>FT_Curve_Tag_Cubic</b></p> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<p>Used for an "off" point used to control a cubic bezier 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 bezier |
|
|
|
|
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 |
|
|
|
|
bezier 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 bezier arcs. Moreover, it's the way outlines are |
|
|
|
|
described in the TrueType specification. |
|
|
|
|
</li> |
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
<p><br>Note that it is possible to mix conic and cubic arcs in a single |
|
|
|
|
contour, even though no current font driver produces such outlines. |
|
|
|
|
<br> </ul> |
|
|
|
|
|
|
|
|
|
<center><table> |
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<blockquote><img SRC="points_segment.png" height=166 width=221></blockquote> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<blockquote><img SRC="points_conic.png" height=183 width=236></blockquote> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
|
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<blockquote><img SRC="points_cubic.png" height=162 width=214></blockquote> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<blockquote><img SRC="points_conic2.png" height=204 width=225></blockquote> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
</table></center> |
|
|
|
|
|
|
|
|
|
<h4> |
|
|
|
|
b. Outline descriptor :</h4> |
|
|
|
|
|
|
|
|
|
<p>A FreeType outline is described through a simple structure, |
|
|
|
|
called <tt>FT_Outline</tt>, which fields are :</p> |
|
|
|
|
|
|
|
|
|
<center><table CELLSPACING=3 CELLPADDING=3 BGCOLOR="#CCCCCC"> |
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<p><b><tt>n_points</tt></b></p> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<p>the number of points in the outline</p> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
|
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<p><b><tt>n_contours</tt></b></p> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<p>the number of contours in the outline</p> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
|
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<p><b><tt>points</tt></b></p> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<p>array of point coordinates</p> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
|
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<p><b><tt>contours</tt></b></p> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<p>array of contour end indices</p> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
|
|
|
|
|
<tr> |
|
|
|
|
<td> |
|
|
|
|
<p><b><tt>tags</tt></b></p> |
|
|
|
|
</td> |
|
|
|
|
|
|
|
|
|
<td> |
|
|
|
|
<p>array of point flags</p> |
|
|
|
|
</td> |
|
|
|
|
</tr> |
|
|
|
|
</table></center> |
|
|
|
|
|
|
|
|
|
<p>Here, <b><tt>points</tt></b> 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 <i>26.6 fixed float format</i>. |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p><b><tt>contours</tt></b> 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 a point <b><tt>contours[0]</tt></b>. The second contour |
|
|
|
|
starts at point "<b><tt>contours[0]+1</tt></b>" and ends at |
|
|
|
|
<b><tt>contours[1]</tt></b>, etc.. |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p>Note that each contour is closed, and that <b><tt>n_points</tt></b> |
|
|
|
|
should be equal to "<b><tt>contours[n_contours-1]+1</tt></b>" for a valid |
|
|
|
|
outline. |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p>Finally, <b><tt>tags</tt></b> is an array of bytes, used to store each |
|
|
|
|
outline point's tag. |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</blockquote><h3><a name="section-2"> |
|
|
|
|
2. Bounding and control box computations : |
|
|
|
|
</h3><blockquote> |
|
|
|
|
|
|
|
|
|
<p>A <b>bounding box</b> (also called "<b>bbox</b>") is simply |
|
|
|
|
the smallest possible rectangle that encloses the shape of a given outline. |
|
|
|
|
Because of the way arcs are defined, bezier control points are not |
|
|
|
|
necessarily contained within an outline's bounding box. |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p>This situation happens when one bezier 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 <b>control box</b> (a.k.a. the "<b>cbox</b>") 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 also much faster to compute.</p> |
|
|
|
|
|
|
|
|
|
<center><table> |
|
|
|
|
<tr> |
|
|
|
|
<td><img SRC="bbox1.png" height=264 width=228></td> |
|
|
|
|
|
|
|
|
|
<td><img SRC="bbox2.png" height=229 width=217></td> |
|
|
|
|
</tr> |
|
|
|
|
</table></center> |
|
|
|
|
|
|
|
|
|
<p>Control and bounding boxes can be computed automatically through the |
|
|
|
|
functions <b><tt>FT_Get_Outline_CBox</tt></b> and <b><tt>FT_Get_Outline_BBox</tt></b>. |
|
|
|
|
The former function is always very fast, while the latter <i>may</i> 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's 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 |
|
|
|
|
transform like rotation is applied to them. |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
</blockquote><h3><a name="section-3"> |
|
|
|
|
3. Coordinates, scaling and grid-fitting : |
|
|
|
|
</h3><blockquote> |
|
|
|
|
|
|
|
|
|
<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> |
|
|
|
|
<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> |
|
|
|
|
<p><tt>round(x) == (x+32) & -64</tt> |
|
|
|
|
<br><tt>floor(x) == x & |
|
|
|
|
-64</tt> |
|
|
|
|
<br><tt>ceiling(x) == (x+63) & -64</tt></center> |
|
|
|
|
|
|
|
|
|
<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>The scan-line converter draws all the pixels whose <i>centers</i> fall |
|
|
|
|
inside the glyph shape. It can also detect "<b><i>drop-outs</i></b>", 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 one cannot predict easily where they'll appear |
|
|
|
|
before rendering. |
|
|
|
|
<p>This leads to the following computations : |
|
|
|
|
<br> |
|
|
|
|
<ul> |
|
|
|
|
<li> |
|
|
|
|
compute the bbox</li> |
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
<ul> |
|
|
|
|
<li> |
|
|
|
|
grid-fit the bounding box with the following :</li> |
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
<ul><p> |
|
|
|
|
<ul><tt>xmin = floor( bbox.xMin )</tt> |
|
|
|
|
<br><tt>xmax = ceiling( bbox.xMax )</tt> |
|
|
|
|
<br><tt>ymin = floor( bbox.yMin )</tt> |
|
|
|
|
<br><tt>ymax = ceiling( bbox.yMax )</tt> |
|
|
|
|
</p></ul> |
|
|
|
|
|
|
|
|
|
<li> |
|
|
|
|
return pixel dimensions, i.e. |
|
|
|
|
<tt>width = (xmax - xmin)/64</tt> and <tt>height = (ymax - ymin)/64</tt> |
|
|
|
|
</li> |
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
<p><br>By grid-fitting the bounding box, one guarantees that all the pixel |
|
|
|
|
centers that are to be drawn, <b><i>including those coming from drop-out |
|
|
|
|
control</i></b>, will be <b><i>within</i></b> the adjusted box. Then the |
|
|
|
|
box's dimensions in pixels can be computed. |
|
|
|
|
<p>Note also that, when <i>translating</i> a <i>grid-fitted outline</i>, |
|
|
|
|
one should <b><i>always</i></b> use <b><i>integer distances</i></b> 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 |
|
|
|
|
<b><i>very |
|
|
|
|
low quality </i></b>bitmaps and pixmaps..</blockquote> |
|
|
|
|
</blockquote> |
|
|
|
|
|
|
|
|
|
<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> |
|
|
|
|
<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, called |
|
|
|
|
<tt>FT_Outline</tt>, which fields are:</p> |
|
|
|
|
|
|
|
|
|
<center> |
|
|
|
|
<table cellspacing=3 |
|
|
|
|
cellpadding=3> |
|
|
|
|
<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"> |
|
|
|
|
<hr3> |
|
|
|
|
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> |
|
|
|
|