1258 lines
45 KiB
HTML
1258 lines
45 KiB
HTML
<html>
|
|
<head>
|
|
<title>An introduction to glyphs</title>
|
|
|
|
<META name="description"
|
|
content="Glyphs in the FreeType engine">
|
|
<META name="keywords"
|
|
content="FreeType TrueType library engine glyphs baseline bearing
|
|
bounding box">
|
|
</head>
|
|
|
|
<body text="#000000"
|
|
bgcolor="#FFFFFF"
|
|
link="#0000EF"
|
|
vlink="#51188E"
|
|
alink="#FF0000">
|
|
|
|
|
|
<font size=1>http://www.freetype.org</font><p>
|
|
|
|
<center>
|
|
<font size="+2">Glyph Hell<p>
|
|
|
|
<font size="+1">An introduction to glyphs, as used and defined in
|
|
the FreeType engine<p>
|
|
</center>
|
|
|
|
<hr><p>
|
|
|
|
<font size="+2">Introduction<p>
|
|
|
|
<font size="+0">This article discusses in great detail the definition
|
|
of glyph metrics, per se the TrueType specification, and the way they
|
|
are managed and used by the FreeType engine. This information is
|
|
crucial when it comes to rendering text strings, either in a
|
|
conventional (i.e. Roman) layout, or with vertical or right-to-left
|
|
ones. Some aspects like glyph rotation and transformation are
|
|
explained too.<p>
|
|
|
|
Comments and corrections are highly welcome, and can be sent to the
|
|
<a href="mailto:devel@freetype.org">FreeType developers list</a>.<p>
|
|
|
|
<hr><p>
|
|
|
|
|
|
<font size="+2">I. An overview of font files<p>
|
|
|
|
<font size="+0">In TrueType, a single font file is used to contain
|
|
information related to classification, modeling and rendering of text
|
|
using a given typeface. This data is located in various independent
|
|
`tables', which can be sorted in four simple classes, as described
|
|
below:<p>
|
|
|
|
<ul>
|
|
|
|
<b><font size="+1"><li>Face Data</font></b><p>
|
|
|
|
We call <i>face data</i> the amount of information related to a
|
|
given typeface, independently of any particular scaling,
|
|
transformation, and/or glyph index. This usually means some
|
|
typeface-global metrics and attributes, like family and styles,
|
|
PANOSE number, typographic ascenders and descenders, as well as
|
|
some very TrueType specific items like the font `programs' found
|
|
in the <i>fpgm</i> and <i>prep</i> tables, the <i>gasp</i> table,
|
|
character mappings, etc.<p>
|
|
|
|
In FreeType, a <i>face object</i> is used to model a font file's
|
|
face data.<p>
|
|
|
|
<b><font size="+1"><li>Instance Data</font></b><p>
|
|
|
|
We call <i>instance</i> a given pointsize/transformation, at a
|
|
given device resolution (e.g. 8pt at 96x96dpi, or 12pt at
|
|
300x600dpi, etc). Some tables found in the font files are used to
|
|
produce instance-specific data, like the <i>cvt</i> table, or the
|
|
<i>prep</i> program. Though they are often part of the face data,
|
|
their processing results in information called <i>instance
|
|
data</i>.<p>
|
|
|
|
In FreeType, it is modeled through an <i>instance object</i>,
|
|
which is always created from an existing face object.<p>
|
|
|
|
<b><font size="+1"><li>Glyph Data</font></b><p>
|
|
|
|
We call <i>glyph data</i> the piece of information related to
|
|
specific glyphs. This includes the following things that are
|
|
described in more details in the next sections:<p>
|
|
|
|
<ul>
|
|
|
|
<li>The glyph's vectorial representation, also called its
|
|
<i>outline</i>.<p>
|
|
|
|
<li>Various metrics, like the glyph's <i>bounding box</i>, its
|
|
<i>bearings</i> and <i>advance</i> values.<p>
|
|
|
|
<li>TrueType specifies a specific instruction <i>bytecode</i>,
|
|
used to associate each glyph with a small <i>program</i>,
|
|
called the <i>glyph code</i>. Its purpose is to grid-fit the
|
|
outline to any target instance, in order to produce excellent
|
|
output at small pixel sizes.
|
|
|
|
</ul><p>
|
|
|
|
The FreeType engine doesn't map each glyph to a single structure,
|
|
as this would waste memory for no good reason. Rather, a <i>glyph
|
|
object</i> is a <i>container</i>, created from any active face,
|
|
which can be used to load and/or process any font glyph at any
|
|
instance (or even no instance at all). Of course, the glyph
|
|
properties (outline, metrics, bitmaps, etc.) can be extracted
|
|
independently from an object once it has been loaded or
|
|
processed.<p>
|
|
|
|
<b><font size="+1"><li>Text and Layout Data</font></b><p>
|
|
|
|
Finally, there is a last class of data that doesn't really fit in
|
|
all others, and that can be called <i>text</i> data. It comprises
|
|
information related to the grouping of glyphs together to form
|
|
text. Simple examples are the <i>kerning</i> table, which
|
|
controls the spacing between adjacent glyphs, as well as some of
|
|
the extensions introduced in <i>TrueType Open</i>,
|
|
<i>OpenType</i>, and <i>TrueType GX</i> like glyph substitution
|
|
(ligatures, vertical representations), baseline management,
|
|
justification, etc.<p>
|
|
|
|
This article focuses on the basic TrueType tables, and hence, will
|
|
only talk about kerning, as FreeType doesn't support OpenType nor
|
|
GX (yet). [Support for TrueType Open is already partially
|
|
available.]
|
|
|
|
</ul><p>
|
|
|
|
<hr><p>
|
|
|
|
|
|
<font size="+2">II. Glyph Outlines<p>
|
|
|
|
<font size="+0">TrueType is a scalable font format; it is thus
|
|
possible to render glyphs at any scale, and under any affine
|
|
transform, from a single source representation. However, simply
|
|
scaling vectorial shapes exhibits at small sizes (where `small' refers
|
|
here to anything smaller than at least 150 pixels) a collection
|
|
of un-harmonious artifacts, like widths and/or heights
|
|
degradations.<p>
|
|
|
|
Because of this, the format also provides a complete programming
|
|
language used to design small programs associated to each glyph. Its
|
|
role is to align the point positions on the pixel grid after the
|
|
scaling. This operation is hence called <i>grid-fitting</i>, or even
|
|
<i>hinting</i>.<p>
|
|
|
|
<ol>
|
|
|
|
<font size="+1"><li>Vectorial representation</font><p>
|
|
|
|
The source format of outlines is a collection of closed paths
|
|
called <i>contours</i>. Each contour delimits an outer or inner
|
|
region of the glyph, and can be made of either line segments
|
|
and/or second-order beziers (also called <i>conic beziers</i> or
|
|
<i>quadratics</i>).<p>
|
|
|
|
It is described internally as a series of successive points, with
|
|
each point having an associated flag indicating whether it is `on'
|
|
or `off' the curve. These rules are applied to decompose the
|
|
contour:<p>
|
|
|
|
<ul>
|
|
|
|
<li>Two successive `on' points indicate a line segment joining
|
|
them.<p>
|
|
|
|
<li>One `off' point amidst two `on' points indicates a conic
|
|
bezier, the `off' point being the control point, and the `on'
|
|
ones the start and end points.<p>
|
|
|
|
<li>Finally, two successive `off' points forces the rasterizer
|
|
to create (only during bitmap rendering) a virtual `on' point
|
|
amidst them, at their exact middle. This greatly facilitates
|
|
the definition of successive Bezier arcs.
|
|
|
|
</ul><p>
|
|
|
|
<pre>
|
|
* # on
|
|
* off
|
|
__---__
|
|
#-__ _-- -_
|
|
--__ _- -
|
|
--__ # \
|
|
--__ #
|
|
-#
|
|
Two `on' points
|
|
Two `on' points and one `off' point
|
|
between them
|
|
|
|
|
|
|
|
*
|
|
# __ Two `on' points with two `off'
|
|
\ - - points between them. The point
|
|
\ / \ marked `0' is the middle of the
|
|
- 0 \ `off' points, and is a `virtual
|
|
-_ _- # on' point where the curve passes.
|
|
-- It does not appear in the point
|
|
list.
|
|
*
|
|
</pre>
|
|
|
|
<img src="image/emsquare.gif" align="right" width=333 height=274>
|
|
|
|
Each glyph's original outline points are located on a grid of
|
|
indivisible units. The points are stored in the font file as
|
|
16-bit integer grid coordinates, with the grid origin's being at
|
|
(0,0); they thus range from -16384 to 16383.<p>
|
|
|
|
In creating the glyph outlines, a type designer uses an imaginary
|
|
square called the <i>EM square</i>. Typically, the EM square
|
|
encloses the capital letter `M' and most other letters of a
|
|
typical roman alphabet. The square's size, i.e., the number of
|
|
grid units on its sides, is very important for two reasons:<p>
|
|
|
|
<ul>
|
|
|
|
<li>It is the reference used to scale the outlines to a given
|
|
instance. For example, a size of 12pt at 300x300dpi
|
|
corresponds to 12*300/72 = 50 pixels. This is the
|
|
size the EM square would appear on the output device if it was
|
|
rendered directly. In other words, scaling from grid units to
|
|
pixels uses the formula<p>
|
|
|
|
<center>
|
|
pixel_size = point_size *
|
|
resolution / 72
|
|
</center><p>
|
|
|
|
<center>
|
|
pixel_coordinate = grid_coordinate *
|
|
pixel_size / EM_size
|
|
</center><p>
|
|
|
|
<li>The greater the EM size is, the larger resolution the
|
|
designer can use when digitizing outlines. For example, in
|
|
the extreme example of an EM size of 4 units, there are
|
|
only 25 point positions available within the EM square
|
|
which is clearly not enough. Typical TrueType fonts use an EM
|
|
size of 2048 units (note: with Type 1 PostScript
|
|
fonts, the EM size is fixed to 1000 grid units. However,
|
|
point coordinates can be expressed in floating values).
|
|
|
|
</ul><p>
|
|
|
|
Note that glyphs can freely extend beyond the EM square if the
|
|
font designer wants this. The EM is used as a convenience, and is
|
|
a valuable convenience from traditional typography.<p>
|
|
|
|
<center>
|
|
<font size="+1">
|
|
Grid units are very often called <i>font units</i> or <i>EM
|
|
units</i>.
|
|
</font>
|
|
</center><p>
|
|
|
|
<hr>
|
|
<i>IMPORTANT NOTE:</i><p>
|
|
|
|
Under FreeType, scaled pixel positions are all expressed in the
|
|
26.6 fixed float format (made of a 26-bit integer mantissa, and a
|
|
6-bit fractional part). In other words, all coordinates are
|
|
multiplied by 64. The grid lines along the integer pixel
|
|
positions, are multiples of 64, like (0,0), (64,0), (0,64),
|
|
(128,128), etc., while the pixel centers lie at middle coordinates
|
|
(32 modulo 64) like (32,32), (96,32), etc.
|
|
<hr><p>
|
|
|
|
<font size="+1"><li>Hinting and Bitmap rendering</font><p>
|
|
|
|
As said before, simply scaling outlines to a specific instance
|
|
always creates undesirable artifacts, like stems of different
|
|
widths or heights in letters like `E' or `H'. Proper glyph
|
|
rendering needs that the scaled points are aligned along the pixel
|
|
grid (hence the name <i>grid-fitting</i>), and that important
|
|
widths and heights are respected throughout the whole font (for
|
|
example, it is very often desirable that the letters `I' and `T'
|
|
have their central vertical line of the same pixel width).<p>
|
|
|
|
Type 1 PostScript font files include with each glyph a small
|
|
series of distances called <i>hints</i>, which are later used by
|
|
the type manager to try grid-fitting the outlines as cleverly as
|
|
possible. On one hand, it has the consequence that upgrading your
|
|
font engine can enhance the visual aspects of all fonts of your
|
|
system; on the other hand, the quality of even the best version of
|
|
Adobe's Type Manager isn't always very pleasing at small sizes
|
|
(notwithstanding font smoothing).<p>
|
|
|
|
TrueType takes a radically different approach: Each glyph has an
|
|
associated `program', designed in a specific geometrical language,
|
|
which is used to align explicitly each outline point to the pixel
|
|
grid, preserving important distances and metrics. A stack-based
|
|
low-level bytecode is used to store it in the font file, and is
|
|
interpreted later when rendering the scaled glyphs.<p>
|
|
|
|
This means that even very complex glyphs can be rendered perfectly
|
|
at very small sizes, as long as the corresponding glyph code is
|
|
designed correctly. Moreover, a glyph can loose some of its
|
|
details, like serifs, at small sizes to become more readable,
|
|
because the bytecode provides interesting features.<p>
|
|
|
|
However, this also have the sad implication that an ill-designed
|
|
glyph code will always render junk, whatever the font engine's
|
|
version, and that it's very difficult to produce quality glyph
|
|
code. There are about 200 TrueType opcodes, and no known
|
|
`high-level language' for it. Most type artists aren't
|
|
programmers at all and the only tools able to produce quality code
|
|
from vectorial representation have been distributed to only a few
|
|
font foundries, while tools available to the public, e.g.
|
|
Fontographer, are usually expensive though generating average to
|
|
mediocre glyph code.<p>
|
|
|
|
All this explains why an enormous number of broken or ugly `free'
|
|
fonts have appeared on the TrueType scene, and that this format is
|
|
now mistakenly thought as `crap' by many people. Funnily, these
|
|
are often the same who stare at the `beauty' of the classic `Times
|
|
New Roman' and `Arial/Helvetica' at 8 points.<p>
|
|
|
|
Once a glyph's code has been executed, the scan-line converter
|
|
converts the fitted outline into a bitmap (or a pixmap with
|
|
font-smoothing).
|
|
|
|
</ol><p>
|
|
|
|
|
|
<hr><p>
|
|
|
|
<font size="+2">III. Glyph metrics</font><p>
|
|
|
|
<ol>
|
|
|
|
<font size="+1"><li>Baseline, Pens and Layouts</font><p>
|
|
|
|
The baseline is an imaginary line that is used to `guide' glyphs
|
|
when rendering text. It can be horizontal (e.g. Roman, Cyrillic,
|
|
Arabic, etc.) or vertical (e.g. Chinese, Japanese, etc).
|
|
Moreover, to render text, a virtual point, located on the
|
|
baseline, called the <i>pen position</i>, is used to locate
|
|
glyphs.<p>
|
|
|
|
Each layout uses a different convention for glyph placement:<p>
|
|
|
|
<ul>
|
|
|
|
<li>With horizontal layout, glyphs simply `rest' on the
|
|
baseline. Text is rendered by incrementing the pen position,
|
|
either to the right or to the left.<p>
|
|
|
|
<center>
|
|
<img src="image/baseline.gif" width=458 height=179><p>
|
|
</center>
|
|
|
|
The distance between two successive pen positions is
|
|
glyph-specific and is called the <i>advance width</i>. Note
|
|
that its value is <b>always</b> positive, even for
|
|
right-to-left oriented alphabets, like Arabic. This
|
|
introduces some differences in the way text is rendered.<p>
|
|
|
|
<hr>
|
|
<i>IMPORTANT NOTE:</i><p>
|
|
|
|
The pen position is always placed on the baseline in
|
|
TrueType, unlike the convention used by some graphics
|
|
systems, like Windows, to always put the pen above the line,
|
|
at the ascender's position.
|
|
<hr><p>
|
|
|
|
<li>With vertical layout, glyphs are centered around the
|
|
baseline:<p>
|
|
|
|
<center>
|
|
<img src="image/baselin2.gif" width=162 height=275>
|
|
</center>
|
|
|
|
</ul><p>
|
|
|
|
<font size="+1"><li>Typographic metrics and bounding
|
|
boxes</font><p>
|
|
|
|
A various number of face metrics are defined for all glyphs in
|
|
a given font. Three of them have a rather curious status in
|
|
the TrueType specification; they only apply to horizontal
|
|
layouts:<p>
|
|
|
|
<ul>
|
|
|
|
<li>The <i>ascent</i><p>
|
|
|
|
This is the distance from the baseline to the highest/upper
|
|
grid coordinate used to place an outline point. It is a
|
|
positive value, due to the grid's orientation with the
|
|
y axis upwards.<p>
|
|
|
|
<li>The <i>descent</i><p>
|
|
|
|
The distance from the baseline to the lowest grid coordinate
|
|
used to place an outline point. This is a negative value,
|
|
due to the grid's orientation.<p>
|
|
|
|
<li>The <i>linegap</i><p>
|
|
|
|
The distance that must be placed between two lines of text.
|
|
The baseline-to-baseline distance should be computed as<p>
|
|
|
|
<center>
|
|
ascent - descent + linegap
|
|
</center><p>
|
|
|
|
if you use the typographic values.
|
|
|
|
</ul><p>
|
|
|
|
The problem with these metrics is that they appear three times
|
|
in a single font file, each version having a slightly different
|
|
meaning:<p>
|
|
|
|
<ol>
|
|
|
|
<li>The font's horizontal header provides the ascent, descent
|
|
and linegap fields, which are used to express the designer's
|
|
intents, rather than the real values that may be computed
|
|
from all glyphs in the outline. These are used by the
|
|
Macintosh font engine to perform font mapping (i.e. font
|
|
substitution).<p>
|
|
|
|
<li>The OS/2 table provides the <i>usWinAscent</i> and
|
|
<i>usWinDescent</i> fields. These values are computed for
|
|
glyphs of the Windows ANSI charset only, which means that
|
|
they are wrong for any other glyph. Note that
|
|
<i>usWinDescent</i> is always positive (i.e. looks like
|
|
`-descent').<p>
|
|
|
|
<li>The OS/2 table provides the <i>typoAscender</i>,
|
|
<i>typoDescender</i> and <i>typoLinegap</i> values, which
|
|
hopefully concern the whole font file. These are the
|
|
correct system-independent values!
|
|
|
|
</ol><p>
|
|
|
|
All metrics are expressed in font units. If you want to use any
|
|
of the two first versions of these metrics, the TrueType
|
|
specification contains some considerations and computing tips
|
|
that might help you.<p>
|
|
|
|
Other, simpler metrics are:<p>
|
|
|
|
<ul>
|
|
|
|
<li>The glyph's bounding box, also called <i>bbox</i><p>
|
|
|
|
This is an imaginary box that encloses any glyph (usually as
|
|
tightly as possible). It is represented by four fields,
|
|
namely <i>xMin</i>, <i>yMin</i>, <i>xMax</i>, and
|
|
<i>yMax</i>, that can be computed for any outline. In
|
|
FreeType, their values can be in font units (if measured in
|
|
the original outline) or in 26.6 pixel units (if
|
|
measured on scaled outlines).<p>
|
|
|
|
Note that if it wasn't for grid-fitting, you wouldn't need
|
|
to know a box's complete values, but only its dimensions to
|
|
know how big is a glyph outline/bitmapa. However, correct
|
|
rendering of hinted glyphs needs the preservation of
|
|
important grid alignment on each glyph translation/placement
|
|
on the baseline, which is why FreeType always returns the
|
|
complete glyph outline.<p>
|
|
|
|
Note also that the font's header contains a global font
|
|
bounding box in font units which should enclose all glyphs
|
|
in a font. This can be used to pre-compute the maximum
|
|
dimensions of any glyph at a given instance.<p>
|
|
|
|
<li>The <i>internal leading</i><p>
|
|
|
|
This concept comes directly from the world of traditional
|
|
typography. It represents the amount of space within the
|
|
`leading' which is reserved for glyph features that lay
|
|
outside of the EM square (like accentuation). It usually
|
|
can be computed as<p>
|
|
|
|
<center>
|
|
internal_leading = ascent - descent -
|
|
EM_size
|
|
</center><p>
|
|
|
|
<li>The <i>external leading</i><p>
|
|
|
|
This is another name for the linegap.
|
|
|
|
</ul><p>
|
|
|
|
<font size="+1"><li><i>Bearings</i> and <i>Advances</i></font><p>
|
|
|
|
Each glyph has also distances called <i>bearings</i> and
|
|
<i>advances</i>. Their definition is constant, but their values
|
|
depend on the layout, as the same glyph can be used to render
|
|
text either horizontally or vertically.<p>
|
|
|
|
<ol>
|
|
<li>The <i>left side bearing</i>: a.k.a. <i>bearingX</i><p>
|
|
|
|
This is the horizontal distance from the current pen
|
|
position to the glyph's left bounding box edge. It is
|
|
positive for horizontal layouts, and most generally negative
|
|
for vertical one.<p>
|
|
|
|
<li>The <i>top side bearing</i>: a.k.a. <i>bearingY</i><p>
|
|
|
|
This is the vertical distance from the baseline to the top
|
|
of the glyph's bounding box. It is usually positive for
|
|
horizontal layouts, and negative for vertical ones<p>
|
|
|
|
<li>The <i>advance width</i>: a.k.a. <i>advanceX</i><p>
|
|
|
|
This is the horizontal distance the pen position must be
|
|
incremented (for left-to-right writing) or decremented (for
|
|
right-to-left writing) by after each glyph is rendered when
|
|
processing text. It is always positive for horizontal
|
|
layouts, and null for vertical ones.<p>
|
|
|
|
<li>The <i>advance height</i>: a.k.a. <i>advanceY</i><p>
|
|
|
|
This is the vertical distance the pen position must be
|
|
decremented by after each glyph is rendered. It is always
|
|
null for horizontal layouts, and positive for vertical
|
|
layouts.<p>
|
|
|
|
<li>The <i>glyph width</i><p>
|
|
|
|
The glyph's horizontal extent. More simply, it is
|
|
(bbox.xMax - bbox.xMin) for unscaled font coordinates.
|
|
For scaled glyphs, its computation requests specific care,
|
|
described in the grid-fitting chapter below.<p>
|
|
|
|
<li>The <i>glyph height</i><p>
|
|
|
|
The glyph's vertical extent. More simply, it is
|
|
(bbox.yMax - bbox.yMin) for unscaled font coordinates.
|
|
For scaled glyphs, its computation requests specific care,
|
|
described in the grid-fitting chapter below.<p>
|
|
|
|
<li>The <i>right side bearing</i><p>
|
|
|
|
Only used for horizontal layouts to describe the distance
|
|
from the bbox's right edge to the advance width. It is in
|
|
most cases a non-negative number. The FreeType library
|
|
doesn't provide this metric directly, as it isn't really
|
|
part of the TrueType specification. It can be computed
|
|
simply as<p>
|
|
|
|
<center>
|
|
advance_width - left_side_bearing - (xMax-xMin)
|
|
</center>
|
|
|
|
</ol><p>
|
|
|
|
<center>
|
|
<img src="image/metrics.gif" width=388 height=253><p>
|
|
|
|
<img src="image/metrics2.gif" width=294 height=278>
|
|
</center><p>
|
|
|
|
Finally, if you use `ABC widths' under Windows and OS/2, the
|
|
following relations apply:
|
|
|
|
<pre>
|
|
A = left side bearing
|
|
B = width
|
|
C = right side bearing
|
|
|
|
A+B+C = advance width
|
|
</pre>
|
|
|
|
<font size="+1"><li>The effects of grid-fitting</font><p>
|
|
|
|
All these metrics are stored in font units in the font file.
|
|
They must be scaled and grid-fitted properly to be used at a
|
|
specific instance. This implies several things:<p>
|
|
|
|
<ul>
|
|
|
|
<li>First, a glyph program not only aligns the outline along
|
|
the grid pixel, it also processes the left side bearing and
|
|
the advance width. Other grid-fitted metrics are usually
|
|
available in optional TrueType tables if you need them.<p>
|
|
|
|
<li>A glyph program may decide to extend or stretch any of
|
|
these two metrics if it has a need for it. This means that
|
|
you cannot assume that the fitted metrics are simply equal
|
|
to the scaled one plus or minus a liberal distance
|
|
< 1 pixel (i.e., less than 64 fractional
|
|
pixel units). For example, it is often necessary to stretch
|
|
the letter `m' horizontally at small pixel sizes to make all
|
|
vertical stems visible, while the same glyph can be
|
|
perfectly `square' at larger sizes.<p>
|
|
|
|
<li>Querying the fitted metrics of all glyphs at a given
|
|
instance is very slow, as it needs to load and process each
|
|
glyph independently. For this reason, some optional
|
|
TrueType tables are defined in the specification, containing
|
|
pre-computed metrics for specific instances (the most
|
|
commonly used, like 8, 9, 10, 11, 12, and 14 points at
|
|
96dpi, for example). These tables aren't always present in
|
|
a TrueType font.<p>
|
|
|
|
If you don't need the exact fitted value, it's much faster
|
|
to query the metrics in font units, then scale them to the
|
|
instance's dimensions.
|
|
|
|
</ul><p>
|
|
|
|
<hr>
|
|
<i>IMPORTANT NOTE:</i><p>
|
|
|
|
Another very important consequence of grid-fitting is the fact
|
|
that moving a fitted outline by a non-integer pixel distance
|
|
will simply ruin the hinter's work, as alignments won't be
|
|
preserved. The translated glyph will then look `ugly' when
|
|
converted to a bitmap!<p>
|
|
|
|
In other words, each time you want to translate a fitted glyph
|
|
outline, you must take care of only using integer pixel
|
|
distances (the x and y offsets must be multiples
|
|
of 64, which equals to 1.0 in the 26.6 fixed float
|
|
format).
|
|
|
|
If you don't care about grid-fitting (typically when rendering
|
|
rotated text), you can use any offset you want and use sub-pixel
|
|
glyph placement.
|
|
<hr><p>
|
|
|
|
</ol>
|
|
|
|
<hr><p>
|
|
|
|
|
|
<font size="+2">IV. Text processing</font><p>
|
|
|
|
This section demonstrates how to use the concepts previously defined
|
|
to render text, whatever the layout you use.<p>
|
|
|
|
<ol>
|
|
|
|
<font size="+1"><li>Writing simple text strings</font><p>
|
|
|
|
We will start by generating a simple string with a Roman alphabet.
|
|
The layout is thus horizontal, left to right.<p>
|
|
|
|
For now, we will assume all glyphs are rendered in a single target
|
|
bitmap. The case of generating individual glyph bitmaps, then
|
|
placing them on demand on a device is presented in a later chapter
|
|
of this section.<p>
|
|
|
|
Rendering the string needs to place each glyph on the baseline;
|
|
this process looks like the following:<p>
|
|
|
|
<ol>
|
|
|
|
<li>Place the pen to the cursor position. The pen is always
|
|
located on the baseline. Its coordinates must be grid-fitted
|
|
(i.e. multiples of 64)!<p>
|
|
|
|
<pre>
|
|
pen_x = cursor_x;
|
|
pen_y = cursor_y;
|
|
</pre>
|
|
|
|
<li>Load the glyph outline and its metrics. Using the flag
|
|
TTLOAD_DEFAULT will scale and hint the glyph:
|
|
|
|
<pre>
|
|
TT_Load_Glyph( instance,
|
|
glyph,
|
|
glyph_index,
|
|
TTLOAD_DEFAULT );
|
|
|
|
TT_Get_Glyph_Metrics( glyph, &metrics );
|
|
TT_Get_Glyph_Outline( glyph, &outline );
|
|
</pre>
|
|
|
|
<li>The loader always places the glyph outline relative to the
|
|
imaginary pen position (0,0). You thus simply need to
|
|
translate the outline by the vector:
|
|
|
|
<pre>
|
|
( pen_x, pen_y )
|
|
</pre>
|
|
|
|
To place it on its correct position, you can use the call
|
|
|
|
<pre>
|
|
TT_Translate_Outline( outline, pen_x, pen_y );
|
|
</pre>
|
|
|
|
<li>Render the outline in the target bitmap, the glyph will be
|
|
surimposed on it with a binary `or' operation (FreeType never
|
|
creates glyph bitmaps by itself, it simply renders glyphs in
|
|
the arrays you pass to it. See the API reference for a
|
|
complete description of bitmaps and pixmaps).
|
|
|
|
<pre>
|
|
TT_Get_Outline_Bitmap( outline, &target_bitmap );
|
|
</pre>
|
|
|
|
<hr>
|
|
<i>IMPORTANT NOTE:</i><p>
|
|
|
|
If you don't want to access the outline in your code, you can
|
|
also use the API function TT_Get_Glyph_Bitmap() which does the
|
|
same as the previous lines:
|
|
|
|
<pre>
|
|
TT_Get_Glyph_Outline( glyph, &outline );
|
|
TT_Translate_Outline( outline, x_offset, y_offset );
|
|
TT_Get_Outline_Bitmap( outline, &target_bitmap );
|
|
TT_Translate_Outline( outline, -x_offset, -y_offset );
|
|
</pre>
|
|
|
|
is equivalent to:
|
|
|
|
<pre>
|
|
TT_Get_Glyph_Bitmap( glyph,
|
|
x_offset,
|
|
y_offset,
|
|
&target_bitmap );
|
|
</pre>
|
|
<hr><p>
|
|
|
|
<li>Now advance the pen to its next position. The advance is
|
|
always grid-fitted when the glyph was hinted:<p>
|
|
|
|
<pre>
|
|
pen_x += metrics.advance;
|
|
</pre>
|
|
|
|
The advance being grid-fitted, the pen position remains
|
|
aligned on the grid.<p>
|
|
|
|
<li>Start over on item 2 until string completion. That's
|
|
it!
|
|
|
|
</ol><p>
|
|
|
|
<font size="+1"><li>Writing right-to-left and vertical text</font><p>
|
|
|
|
Generating strings for different layouts is very similar. Here
|
|
are the most important differences.<p>
|
|
|
|
<ul>
|
|
|
|
<li>For right-to-left text (like Arabic)<p>
|
|
|
|
The main difference here is that, as the advance width and
|
|
left side bearings are oriented against the flow of text, the
|
|
pen position must be <i>decremented</i> by the advance width,
|
|
<i>before</i> placing and rendering the glyph. Other than
|
|
that, the rest is strictly similar.<p>
|
|
|
|
<li>For vertical text (like Chinese or Japanese)<p>
|
|
|
|
In this case, the baseline is vertical, which means that the
|
|
pen position must be shifted in the vertical direction. You
|
|
need the vertical glyph metrics to do that (using the
|
|
TT_Get_Big_Glyph_Metrics() function).<p>
|
|
|
|
Once you get these, the rest of the process is very similar.
|
|
The glyph outline is placed relative to an imaginary origin of
|
|
(0,0), and you should translate it to the pen position before
|
|
rendering it.<p>
|
|
|
|
The big difference is that you must decrement pen_y, rather
|
|
than increment pen_x (this is for the TrueType convention of y
|
|
oriented upwards).
|
|
|
|
<pre>
|
|
pen_y -= metrics.advance;
|
|
</pre>
|
|
|
|
</ul><p>
|
|
|
|
<font size="+1"><li>Generating individual glyph bitmaps and using
|
|
them to render text</font><p>
|
|
|
|
Loading each glyph when rendering text is slow, and it's much
|
|
more efficient to render each one in a standalone bitmap to place
|
|
it in a cache. Text can then be rendered fast by applying simple
|
|
blit operations on the target device.<p>
|
|
|
|
To be able to render text correctly with the bitmaps, you must
|
|
record and associate with them its fitted bearings and advances.
|
|
Hence the following process:<p>
|
|
|
|
<ol>
|
|
|
|
<li>Generate the bitmaps.<p>
|
|
|
|
<ul>
|
|
|
|
<li>Load the glyph and get its metrics.
|
|
|
|
<pre>
|
|
TT_Load_Glyph( instance,
|
|
glyph,
|
|
glyph_index,
|
|
TTLOAD_DEFAULT );
|
|
|
|
TT_Get_Glyph_Metrics( glyph, &metrics );
|
|
</pre>
|
|
|
|
The bbox is always fitted when calling
|
|
TT_Get_Glyph_Metrics() on a hinted glyph. You can then
|
|
easily compute the glyph's dimension in pixels as:
|
|
|
|
<pre>
|
|
width = (bbox.xMax - bbox.xMin) / 64;
|
|
height = (bbox.yMax - bbox.yMin) / 64;
|
|
</pre>
|
|
|
|
NOTE 1:<br>
|
|
The fitted bounding box always contains all the dropouts
|
|
that may be produced by the scan-line converter. This
|
|
width and height are thus valid for all kinds of
|
|
glyphs).<p>
|
|
|
|
NOTE 2:<br>
|
|
If you want to compute the dimensions of a rotated
|
|
outline's bitmap, compute its bounding box with
|
|
TT_Get_Outline_BBox(), then grid-fit the bbox manually:
|
|
|
|
<pre>
|
|
#define FLOOR(x) ((x) & -64)
|
|
#define CEILING(x) (((x)+63) & -64)
|
|
|
|
xMin = FLOOR(xMin);
|
|
yMin = FLOOR(yMin);
|
|
yMin = CEILING(xMax);
|
|
yMax = CEILING(yMax);
|
|
</pre>
|
|
|
|
then compute width and height as above.<p>
|
|
|
|
<li>Create a bitmap of the given dimension, e.g.:
|
|
|
|
<pre>
|
|
bitmap.width = width;
|
|
bitmap.cols = (width+7) & -8;
|
|
bitmap.rows = height;
|
|
bitmap.flow = TT_Flow_Up;
|
|
bitmap.size = bitmap.cols * bitmap.rows;
|
|
bitmap.buffer = malloc( bitmap.size );
|
|
</pre>
|
|
|
|
<li>Render the glyph into the bitmap.<p>
|
|
|
|
Don't forget to shift it by (-xMin, -yMin) to fit it in
|
|
the bitmap:
|
|
|
|
<pre>
|
|
/* Note that the offsets must be grid-fitted to */
|
|
/* preserve hinting! */
|
|
TT_Get_Glyph_Bitmap( glyph,
|
|
&bitmap,
|
|
-bbox.xMin,
|
|
-bbox.yMin );
|
|
</pre>
|
|
|
|
</ul>
|
|
|
|
<li>Store the bitmap with the following values:
|
|
|
|
<pre>
|
|
bearingX / 64 = left side bearing in pixels
|
|
advance / 64 = advance width/height in pixels
|
|
</pre>
|
|
|
|
When your cache is set up, you can then render text using a
|
|
scheme similar to the ones describe in 1. and 2.,
|
|
with the exception that now pen positions and metrics are
|
|
expressed in pixel values. We are done!
|
|
|
|
<pre>
|
|
pen_x = cursor_x;
|
|
pen_y = cursor_y;
|
|
|
|
while ( glyph_to_render )
|
|
{
|
|
access_cache( glyph_index, metrics, bitmap );
|
|
|
|
blit_bitmap_to_position
|
|
( pen_x + bearingX,
|
|
pen_y (+ bearingY depending on orientation ) );
|
|
|
|
pen_x += advance;
|
|
}
|
|
</pre>
|
|
|
|
</ol>
|
|
|
|
<font size="+1"><li>Device-independent text rendering</font><p>
|
|
|
|
The previously described rendering processes all align glyphs on
|
|
the baseline according to metrics fitted for the display's
|
|
distance. In some cases, the display isn't the final output, and
|
|
placing the glyphs in a device-independent way is more important
|
|
than anything.<p>
|
|
|
|
A typical case is a word processor which displays text as it
|
|
should appear on paper when printed. As you've probably noticed,
|
|
the glyphs aren't always spaced uniformly on the screen as you
|
|
type them, sometimes the space between an `m' and a `t' is too
|
|
small, some other it is too large, etc.<p>
|
|
|
|
These differences are simply due to the fact that the word
|
|
processor aligns glyphs in an device-independent way, using
|
|
original metrics in font units to do it, then scale them as it
|
|
can to display text on screen, usually at a very smaller
|
|
resolution than your printer's one.<p>
|
|
|
|
Device-independence is a crucial part of document portability,
|
|
and it is very saddening to see that most professional word
|
|
processors don't do it correctly. For example, MS Word uses
|
|
the fitted metrics of the printer's resolution, rather than the
|
|
originals in font units.<p>
|
|
|
|
This is great to get sure that your text prints very well on your
|
|
printer, but it also implies that someone printing the exact same
|
|
document on a device with different output resolutions (e.g.
|
|
bubble-jet vs. laser printers) may encounter trouble.<p>
|
|
|
|
As the differences in advances accumulate on one line, they can
|
|
sum to the width of one or more glyphs in extreme cases, which is
|
|
enough to `overflow' the automatic justification algorithm. This
|
|
may add additional lines of printed text, or even remove some.
|
|
Moreover, supplemental lines can produce unexpected page breaks
|
|
and `blank' pages. This can be extremely painful when working
|
|
with large documents, as this `feature' may require you to
|
|
redesign completely your formatting to re-print it.<p>
|
|
|
|
In conclusion, if you want portable document rendering, never
|
|
hesitate to use and apply device-independent terms! For example,
|
|
a simple way to produce text would be:<p>
|
|
|
|
<ol>
|
|
|
|
<li>Get a scale to convert from your device-independent units
|
|
to 26.6 pixels.<p>
|
|
|
|
<li>Get another scale to convert from original font units to
|
|
device-independent units.<p>
|
|
|
|
<li>Perform pen placement and advances in device-independent
|
|
units.<p>
|
|
|
|
<li>To render each glyph, compute the pen's rounded position,
|
|
as well as the rounded glyph left side bearing, both
|
|
expressed in 26.6 pixels (don't use the fitted metrics). You
|
|
will then be able to place the glyph and/or blit its bitmap.
|
|
|
|
</ol><p>
|
|
|
|
<font size="+1"><li>Kerning glyphs</font><p>
|
|
|
|
An interesting effect that most people appreciate is
|
|
<i>kerning</i>. It consists of modifying the spacing between two
|
|
successive glyphs according to their outlines. For example, the
|
|
letters `T' and a `y' can be easily moved closer, as the top of
|
|
the `y' fits nicely under the `T's upper right bar.<p>
|
|
|
|
To perform kerning, the TrueType specification provides a
|
|
specific table (its tag being `kern'), with several storage
|
|
formats. This section doesn't explain how to access this
|
|
information; however, you can have a look at the standard
|
|
extension called `ttkern.h' which comes with FreeType.<p>
|
|
|
|
The <i>kerning distance</i> between two glyphs is a value
|
|
expressed in font units which indicates whether their outline can
|
|
be moved together or apart when one follows the other. The
|
|
distance isn't reflexive, which means that the kerning for the
|
|
glyph pair (`T',`y') isn't the same as the one for (`y',`T').<p>
|
|
|
|
The value is positive when the glyphs must be moved apart, and
|
|
negative when they must be moved closer. You can implement
|
|
kerning simply by adding its scaled and rounded value to the
|
|
advance width when moving the pen position. Here an example for
|
|
horizontal kerning:
|
|
|
|
<pre>
|
|
#define ROUND( x ) ( (x + 32) & -64 )
|
|
|
|
scaled_kerning = kerning * imetrics.x_scale / 0x10000;
|
|
|
|
pen_x += metrics.advance + ROUND( scaled_kerning );
|
|
</pre>
|
|
|
|
<font size="+1"><li>Rotated and stretched/slanted text</font><p>
|
|
|
|
In order to produce rotated glyphs with FreeType, one must
|
|
understand a few things:<p>
|
|
|
|
<ul>
|
|
|
|
<li>The engine doesn't apply specific transformations to the
|
|
glyphs it loads and processes (other than the simpler
|
|
resolution-base scaling and grid-fitting). If you want to
|
|
rotate glyphs, you will have to load their outline, then apply
|
|
the geometric transformations that please you (a number of
|
|
APIs are there to help you to do it easily).<p>
|
|
|
|
<li>Even if the glyph loader hints `straight' glyphs, it is
|
|
possible to inform the font and glyph programs that you're
|
|
going to later transform the resulting outlines. Two flags
|
|
can be passed to the bytecode interpreter:<p>
|
|
|
|
<ul>
|
|
|
|
<li>The `rotated' flag indicates that you are going to
|
|
rotate the glyphs in a non-trivial direction (i.e., on
|
|
neither of the two coordinate axis). You are advised not
|
|
to set it when writing 90 degrees-rotated text for
|
|
example.<p>
|
|
|
|
<li>The `stretched' flag indicates that you are going to
|
|
apply a transformation that will distort distances. While
|
|
rotations and symmetries keep distances constant, slanting
|
|
and stretching do modify them.
|
|
|
|
</ul>
|
|
|
|
</ul><p>
|
|
|
|
These flags can be interpreted by the glyph code to toggle certain
|
|
processings which vary from one font to the other. However, most
|
|
of the TrueType fonts that were tested with FreeType, if not all
|
|
of them, simply change the dropout-mode when any of these flags is
|
|
set, and/or disable hinting when rotation is detected. We advise
|
|
you to never set these flags, even when rotating text. For what
|
|
it's worth, hinted rotated text is no uglier than un-hinted
|
|
one.<p>
|
|
|
|
You can use the function TT_Set_Instance_Transform_Flags() to set
|
|
them. Then, rendering can be done with the following calls:
|
|
|
|
<pre>
|
|
/* set the flags */
|
|
TT_Set_Instance_Transforms( instance,
|
|
rotated,
|
|
stretched );
|
|
|
|
/* load a given glyph */
|
|
TT_Get_Glyph_Outline( instance,
|
|
glyph,
|
|
index,
|
|
TTLOAD_DEFAULT );
|
|
|
|
/* access its outline */
|
|
TT_Get_Glyph_Outline( instance, &outline );
|
|
|
|
/* in order to transform it */
|
|
TT_Transform_Outline( outline, &matrix );
|
|
/* and/or */
|
|
TT_Translate_Outline( outline,
|
|
x_offset, y_offset );
|
|
|
|
/* to render it */
|
|
TT_Get_Outline_Bitmap( outline, &bitmap );
|
|
</pre>
|
|
|
|
Here is an example, assuming that the following variables
|
|
|
|
<pre>
|
|
TT_Matrix matrix; /* 2x2 matrix */
|
|
TT_Pos x_off, y_off; /* corrective offsets */
|
|
</pre>
|
|
|
|
define a transformation that can be correctly applied to a glyph
|
|
outline which have been previously placed relative to the
|
|
imaginary point position (0,0) with bearings preserved. Rendering
|
|
text can now be done as follows:<p>
|
|
|
|
<ol>
|
|
|
|
<li>Initialize the pen position; when rotating, it is extremely
|
|
well advised to use sub-pixel placement as you don't care
|
|
about hinting.
|
|
|
|
<pre>
|
|
pen_x = cursor_x;
|
|
pen_y = cursor_y;
|
|
</pre>
|
|
|
|
<li>Transform the glyph as needed, then translate it to the
|
|
current pen position:
|
|
|
|
<pre>
|
|
TT_Transform_Outline( outline, &matrix );
|
|
TT_Translate_Outline( outline,
|
|
pen_x + x_off,
|
|
pen_y + y_off );
|
|
</pre>
|
|
|
|
(Note that the transformation offsets have been included in
|
|
the translation.)<p>
|
|
|
|
<li>Render the bitmap, as it has now been placed correctly.<p>
|
|
|
|
<li>To change the pen position, transform the vector (0,advance)
|
|
with your matrix, and add it:
|
|
|
|
<pre>
|
|
vec_x = metrics.advance;
|
|
vec_y = 0;
|
|
TT_Transform_Vector( &vec_x, &vec_y, &matrix );
|
|
pen_x += vec_x;
|
|
pen_y += vec_y;
|
|
</pre>
|
|
|
|
<li>Start over at 2. until completion.
|
|
|
|
</ol><p>
|
|
|
|
<hr>
|
|
<i>IMPORTANT NOTE:</i><p>
|
|
|
|
Do not grid-fit the pen position before rendering your glyph when
|
|
rendering rotated text. If you do, your transformed baseline
|
|
won't be preserved on each glyph, and the text will look like it's
|
|
`hopping' randomly. This is particularly visible at small
|
|
sizes.<p>
|
|
|
|
Sub-pixel precision placement is <i>very</i> important for clean
|
|
rotated text.
|
|
<hr><p>
|
|
|
|
<font size="+1"><li>Font-smoothing, a.k.a. gray-levels
|
|
rendering</font><p>
|
|
|
|
The FreeType engine's scan-line converter (the component also
|
|
called the <i>rasterizer</i>) is able to convert a vectorial glyph
|
|
outline into either a normal bitmap, or an 8-bit pixmap (a.k.a.
|
|
<i>colored bitmaps</i> on some systems). This last feature is
|
|
called <i>gray-level rendering</i> or <i>font-smoothing</i>,
|
|
because it uses a user-supplied palette to produce anti-aliased
|
|
versions of the glyphs.<p>
|
|
|
|
Its principle is to render a bitmap which is twice as large than
|
|
the target pixmap, then simply filtering it using a 2x2
|
|
summation.<p>
|
|
|
|
<hr>
|
|
<i>NOTE:</i><p>
|
|
|
|
FreeType's scan-line converter doesn't use or need an intermediate
|
|
second bitmap. Rather, filtering is performed in a single pass
|
|
during the sweep (see the file `raster.txt' for more information
|
|
about it).
|
|
<hr><p>
|
|
|
|
You'll notice that, as with Windows 95, FreeType's rasterizer
|
|
only grays those parts of the glyph which need it, i.e., diagonals
|
|
and curves, while keeping horizontal and vertical stems straight
|
|
`black'. This greatly improves the legibility of text, while
|
|
avoiding the `blurry' look anti-aliased fonts typically found with
|
|
Adobe's Type Manager or Acrobat.<p>
|
|
|
|
There are thus five available gray-levels, ranging from 0
|
|
to 4, where level 0 and level 4 are the background
|
|
and foreground colors, respectively, and where levels 1,
|
|
2, 3 are intermediate. For example, to render black text on
|
|
a white background, one can use a palette like:<p>
|
|
|
|
<ul>
|
|
|
|
palette[0] = white (background) <br>
|
|
palette[1] = light gray <br>
|
|
palette[2] = medium gray <br>
|
|
palette[3] = dark gray <br>
|
|
palette[4] = black (foreground) <br>
|
|
|
|
</ul><p>
|
|
|
|
To set the engine's gray-level palette, simply use the API
|
|
function TT_Set_Raster_Palette() after initialization. It expects
|
|
an array of 5 chars which will be used to render the
|
|
pixmaps.<p>
|
|
|
|
Note that the rasterizer doesn't create bitmaps or pixmaps.
|
|
Rather, it simply renders glyphs in the arrays you pass to it.
|
|
The generated glyph bitmaps are simply `or'-ed to the target (with
|
|
0 being the background as a convention); in the case of pixmaps,
|
|
pixels are simply written to the buffer, in spans of four aligned
|
|
bytes.<p>
|
|
|
|
<hr>
|
|
<i>NOTE:</i><p>
|
|
|
|
The raster isn't able to superpose `transparent' glyphs on the
|
|
target pixmap. This means that you should always call the API
|
|
functions TT_Get_Glyph_Pixmap() and TT_Get_Outline_Pixmap() with
|
|
an empty map, and perform the superposition yourself.<p>
|
|
|
|
This can be more or less tricky, depending on the palette you are
|
|
using and your target graphics resolution. One of the components
|
|
found in the test directory, called `display.c', has large
|
|
comments on the way it implements it for the test programs. You
|
|
are encouraged to read the test program sources to understand how
|
|
one can take advantage of font smoothing.<p>
|
|
|
|
Pixmap surimposition is too system-specific a feature to be part
|
|
of the FreeType engine. Moreover, not everybody needs it!
|
|
<hr><p>
|
|
|
|
Finally, the question of sur-imposing anti-aliased colored text on
|
|
any texture, since being even more tricky, is left as an exercise
|
|
to the reader ;-) If this topic really interests you, the
|
|
FreeType mailing list may host some helpful enthusiasts ready to
|
|
answer your questions. Who knows :-)<p>
|
|
|
|
<font size="+1"><li>Other interesting text processes</font><p>
|
|
|
|
<ul>
|
|
|
|
<li>Glyph substitution<p>
|
|
|
|
Substitution is used to replace one glyph by another when some
|
|
specific condition is met in the text string. Its most common
|
|
examples are ligatures (like replacing the `f' followed by `i'
|
|
by the single glyph `fi' if available in the font), as well as
|
|
positional selection as performed in the Arabic script (for
|
|
those not aware of this, each letter of the Arabic alphabet
|
|
can be written differently according to its position on words:
|
|
starting, ending, intermediate, or isolated).<p>
|
|
|
|
The base TrueType format doesn't define any table for glyph
|
|
substitution. However, GX, TrueType Open, and OpenType
|
|
provide (incompatible) extensions to perform it. Of course,
|
|
it isn't supported by the engine, but an extension could be
|
|
easily written to access the required tables.<p>
|
|
|
|
[Support for TrueType Open is already partially available.]<p>
|
|
|
|
<li>Justification<p>
|
|
|
|
...
|
|
|
|
</ul>
|
|
|
|
</ol>
|
|
|
|
To be continued...
|
|
|
|
</body>
|
|
</html>
|