Revised.
This commit is contained in:
parent
361d9b8a7c
commit
6f36900589
@ -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>
|
||||
<h1 align=center>
|
||||
FreeType Glyph Conventions
|
||||
</h1>
|
||||
|
||||
<center><h2>
|
||||
version 2.1
|
||||
</h2></center>
|
||||
<h2 align=center>
|
||||
Version 2.1
|
||||
</h2>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<table width="65%">
|
||||
<tr><td>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
grid-fit the bounding box with the following :</li>
|
||||
</ul>
|
||||
<p><hr></p>
|
||||
|
||||
<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>
|
||||
<table width="100%">
|
||||
<tr bgcolor="#CCCCFF"
|
||||
valign=center><td>
|
||||
<h2>
|
||||
VI. FreeType outlines
|
||||
</h2>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
<li>
|
||||
return pixel dimensions, i.e.
|
||||
<tt>width = (xmax - xmin)/64</tt> and <tt>height = (ymax - ymin)/64</tt>
|
||||
</li>
|
||||
</ul>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<a name="section-1">
|
||||
<h3>
|
||||
1. FreeType outline description and structure
|
||||
</h3>
|
||||
|
||||
<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>
|
||||
<h4>
|
||||
a. Outline curve decomposition
|
||||
</h4>
|
||||
|
||||
</td></tr></table></center>
|
||||
<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>
|
||||
|
Loading…
Reference in New Issue
Block a user