2000-11-10 06:45:07 +01:00
|
|
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en"
|
|
|
|
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
2000-11-09 01:01:38 +01:00
|
|
|
<html>
|
|
|
|
<head>
|
2000-11-10 06:45:07 +01:00
|
|
|
<meta http-equiv="Content-Type"
|
|
|
|
content="text/html; charset=iso-8859-1">
|
|
|
|
<meta name="Author"
|
|
|
|
content="David Turner">
|
|
|
|
<title>FreeType Glyph Conventions</title>
|
2000-11-09 01:01:38 +01:00
|
|
|
</head>
|
|
|
|
|
|
|
|
<body text="#000000"
|
|
|
|
bgcolor="#FFFFFF"
|
|
|
|
link="#0000EF"
|
|
|
|
vlink="#51188E"
|
|
|
|
alink="#FF0000">
|
|
|
|
|
2000-11-10 06:45:07 +01:00
|
|
|
<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>
|
2000-11-09 01:01:38 +01:00
|
|
|
|
|
|
|
<center>
|
2000-11-10 06:45:07 +01:00
|
|
|
<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
|
2000-11-10 23:39:21 +01:00
|
|
|
quadratic or conic arcs, and they are used in the TrueType format.
|
2000-11-10 06:45:07 +01:00
|
|
|
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>
|
|
|
|
|
2000-11-10 18:10:14 +01:00
|
|
|
<p>A FreeType outline is described through a simple structure:</p>
|
2000-11-10 06:45:07 +01:00
|
|
|
|
|
|
|
<center>
|
|
|
|
<table cellspacing=3
|
|
|
|
cellpadding=3>
|
2000-11-10 18:10:14 +01:00
|
|
|
<caption>
|
|
|
|
<b><tt>FT_Outline</tt></b>
|
|
|
|
</caption>
|
|
|
|
|
2000-11-10 06:45:07 +01:00
|
|
|
<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">
|
2000-11-10 18:10:14 +01:00
|
|
|
<h3>
|
2000-11-10 06:45:07 +01:00
|
|
|
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
|
2001-01-19 04:33:30 +01:00
|
|
|
26.6 format, i.e. in 1/64th of a pixel, hence the coordinates
|
|
|
|
(1.0,-2.5) are stored as the integer pair (x:64,y:-192).</p>
|
2000-11-10 06:45:07 +01:00
|
|
|
|
|
|
|
<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>
|
2000-11-09 01:01:38 +01:00
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|