276 lines
12 KiB
HTML
276 lines
12 KiB
HTML
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||
|
<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>
|
||
|
</head>
|
||
|
<body>
|
||
|
|
||
|
<body text="#000000"
|
||
|
bgcolor="#FFFFFF"
|
||
|
link="#0000EF"
|
||
|
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-4.html">Previous</a>
|
||
|
</td>
|
||
|
<td align=center width="30%">
|
||
|
<a href="index.html">Contents</a>
|
||
|
</td>
|
||
|
<td align=center width="30%">
|
||
|
<a href="glyphs-6.html">Next</a>
|
||
|
</td>
|
||
|
</tr></table></center>
|
||
|
|
||
|
<table width="100%"><tr valign=center bgcolor="#CCCCFF"><td><h2>
|
||
|
V. Text processing
|
||
|
</h2></td></tr></table>
|
||
|
|
||
|
<p>This section demonstrates how to use the concepts previously
|
||
|
defined to render text, whatever the layout you use.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3><a name="section-1">
|
||
|
1. Writing simple text strings :
|
||
|
</h3><blockquote>
|
||
|
|
||
|
<p>In this first example, we'll generate a simple string of Roman
|
||
|
text, i.e. with a horizontal left-to-right layout. Using exclusively pixel
|
||
|
metrics, the process looks like :
|
||
|
<blockquote><tt>1) convert the character string into a series of glyph
|
||
|
indexes.</tt>
|
||
|
<br><tt>2) place the pen to the cursor position.</tt>
|
||
|
<br><tt>3) get or load the glyph image.</tt>
|
||
|
<br><tt>4) translate the glyph so that its 'origin' matches the pen position</tt>
|
||
|
<br><tt>5) render the glyph to the target device</tt>
|
||
|
<br><tt>6) increment the pen position by the glyph's advance width in pixels</tt>
|
||
|
<br><tt>7) start over at step 3 for each of the remaining glyphs</tt>
|
||
|
<br><tt>8) when all glyphs are done, set the text cursor to the new pen
|
||
|
position</tt></blockquote>
|
||
|
Note that kerning isn't part of this algorithm.</blockquote>
|
||
|
|
||
|
<h3><a name="section-2">
|
||
|
2. Sub-pixel positioning :</h3>
|
||
|
|
||
|
<blockquote>It is somewhat useful to use sub-pixel positioning when rendering
|
||
|
text. This is crucial, for example, to provide semi-WYSIWYG text layouts.
|
||
|
Text rendering is very similar to the algorithm described in sub-section
|
||
|
1, with the following few differences :
|
||
|
<ul>
|
||
|
<li>
|
||
|
The pen position is expressed in fractional pixels.</li>
|
||
|
|
||
|
<li>
|
||
|
Because translating a hinted outline by a non-integer distance will ruin
|
||
|
its grid-fitting, the position of the glyph origin must be rounded before
|
||
|
rendering the character image.</li>
|
||
|
|
||
|
<li>
|
||
|
The advance width is expressed in fractional pixels, and isn't necessarily
|
||
|
an integer.</li>
|
||
|
</ul>
|
||
|
|
||
|
<p><br>Which finally looks like :
|
||
|
<blockquote><tt>1. convert the character string into a series of glyph
|
||
|
indexes.</tt>
|
||
|
<br><tt>2. place the pen to the cursor position. This can be a non-integer
|
||
|
point.</tt>
|
||
|
<br><tt>3. get or load the glyph image.</tt>
|
||
|
<br><tt>4. translate the glyph so that its 'origin' matches the rounded
|
||
|
pen position.</tt>
|
||
|
<br><tt>5. render the glyph to the target device</tt>
|
||
|
<br><tt>6. increment the pen position by the glyph's advance width in fractional
|
||
|
pixels.</tt>
|
||
|
<br><tt>7. start over at step 3 for each of the remaining glyphs</tt>
|
||
|
<br><tt>8. when all glyphs are done, set the text cursor to the new pen
|
||
|
position</tt></blockquote>
|
||
|
Note that with fractional pixel positioning, the space between two given
|
||
|
letters isn't fixed, but determined by the accumulation of previous rounding
|
||
|
errors in glyph positioning.</blockquote>
|
||
|
|
||
|
<h3><a name="section-3">
|
||
|
3. Simple kerning :</h3>
|
||
|
|
||
|
<blockquote>Adding kerning to the basic text rendering algorithm is easy
|
||
|
: when a kerning pair is found, simply add the scaled kerning distance
|
||
|
to the pen position before step 4. Of course, the distance should be rounded
|
||
|
in the case of algorithm 1, though it doesn't need to for algorithm 2.
|
||
|
This gives us :
|
||
|
<p>Algorithm 1 with kerning:
|
||
|
<blockquote><tt>3) get or load the glyph image.</tt>
|
||
|
<br><tt>4) Add the rounded scaled kerning distance, if any, to the pen
|
||
|
position</tt>
|
||
|
<br><tt>5) translate the glyph so that its 'origin' matches the pen position</tt>
|
||
|
<br><tt>6) render the glyph to the target device</tt>
|
||
|
<br><tt>7) increment the pen position by the glyph's advance width in pixels</tt>
|
||
|
<br><tt>8) start over at step 3 for each of the remaining glyphs</tt></blockquote>
|
||
|
|
||
|
<p><br>Algorithm 2 with kerning:
|
||
|
<blockquote><tt>3) get or load the glyph image.</tt>
|
||
|
<br><tt>4) Add the scaled unrounded kerning distance, if any, to the pen
|
||
|
position.</tt>
|
||
|
<br><tt>5) translate the glyph so that its 'origin' matches the rounded
|
||
|
pen position.</tt>
|
||
|
<br><tt>6) render the glyph to the target device</tt>
|
||
|
<br><tt>7) increment the pen position by the glyph's advance width in fractional
|
||
|
pixels.</tt>
|
||
|
<br><tt>8) start over at step 3 for each of the remaining glyphs</tt></blockquote>
|
||
|
Of course, the algorithm described in section IV can also be applied to
|
||
|
prevent the sliding dot problem if one wants to..</blockquote>
|
||
|
|
||
|
<h3><a name="section-4">
|
||
|
4. Right-To-Left Layout :</h3>
|
||
|
|
||
|
<blockquote>The process of laying out arabic or hebrew text is extremely
|
||
|
similar. The only difference is that the pen position must be decremented
|
||
|
before the glyph rendering (remember : the advance width is always positive,
|
||
|
even for arabic glyphs). Thus, algorithm 1 becomes :
|
||
|
<p>Right-to-left Algorithm 1:
|
||
|
<blockquote><tt>3) get or load the glyph image.</tt>
|
||
|
<br><tt>4) Decrement the pen position by the glyph's advance width in pixels</tt>
|
||
|
<br><tt>5) translate the glyph so that its 'origin' matches the pen position</tt>
|
||
|
<br><tt>6) render the glyph to the target device</tt>
|
||
|
<br><tt>7) start over at step 3 for each of the remaining glyphs</tt></blockquote>
|
||
|
|
||
|
<p><br>The changes to Algorithm 2, as well as the inclusion of kerning
|
||
|
are left as an exercise to the reader.
|
||
|
<br>
|
||
|
<br> </blockquote>
|
||
|
|
||
|
<h3><a name="section-5">
|
||
|
5. Vertical layouts :</h3>
|
||
|
|
||
|
<blockquote>Laying out vertical text uses exactly the same processes, with
|
||
|
the following significant differences :
|
||
|
<br>
|
||
|
<blockquote>
|
||
|
<li>
|
||
|
The baseline is vertical, and the vertical metrics must be used instead
|
||
|
of the horizontal one.</li>
|
||
|
|
||
|
<li>
|
||
|
The left bearing is usually negative, but this doesn't change the fact
|
||
|
that the glyph origin must be located on the baseline.</li>
|
||
|
|
||
|
<li>
|
||
|
The advance height is always positive, so the pen position must be decremented
|
||
|
if one wants to write top to bottom (assuming the Y axis is oriented upwards).</li>
|
||
|
</blockquote>
|
||
|
Through the following algorithm :
|
||
|
<blockquote><tt>1) convert the character string into a series of glyph
|
||
|
indexes.</tt>
|
||
|
<br><tt>2) place the pen to the cursor position.</tt>
|
||
|
<br><tt>3) get or load the glyph image.</tt>
|
||
|
<br><tt>4) translate the glyph so that its 'origin' matches the pen position</tt>
|
||
|
<br><tt>5) render the glyph to the target device</tt>
|
||
|
<br><tt>6) decrement the vertical pen position by the glyph's advance height
|
||
|
in pixels</tt>
|
||
|
<br><tt>7) start over at step 3 for each of the remaining glyphs</tt>
|
||
|
<br><tt>8) when all glyphs are done, set the text cursor to the new pen
|
||
|
position</tt></blockquote>
|
||
|
</blockquote>
|
||
|
|
||
|
<h3><a name="section-6">
|
||
|
6. WYSIWYG text layouts :</h3>
|
||
|
|
||
|
<blockquote>As you probably know, the acronym WYSIWYG stands for '<i>What
|
||
|
You See Is What You Get</i>'. Basically, this means that the output of
|
||
|
a document on the screen should match "perfectly" its printed version.
|
||
|
A <b><i>true</i></b> wysiwyg system requires two things :
|
||
|
<p><b>device-independent text layout</b>
|
||
|
<blockquote>Which means that the document's formatting is the same on the
|
||
|
screen than on any printed output, including line breaks, justification,
|
||
|
ligatures, fonts, position of inline images, etc..</blockquote>
|
||
|
|
||
|
<p><br><b>matching display and print character sizes</b>
|
||
|
<blockquote>Which means that the displayed size of a given character should
|
||
|
match its dimensions when printed. For example, a text string which is
|
||
|
exactly 1 inch tall when printed should also appear 1 inch tall on the
|
||
|
screen (when using a scale of 100%).</blockquote>
|
||
|
|
||
|
<p><br>It is clear that matching sizes cannot be possible if the computer
|
||
|
has no knowledge of the physical resolutions of the display device(s) it
|
||
|
is using. And of course, this is the most common case ! That's not too
|
||
|
unfortunate, however because most users really don't care about this
|
||
|
feature. Legibility is much more important.
|
||
|
<p>When the Mac appeared, Apple decided to choose a resolution of 72 dpi
|
||
|
to describe the Macintosh screen to the font sub-system (whatever the monitor
|
||
|
used). This choice was most probably driven by the fact that, at this resolution,
|
||
|
1 point = 1 pixel. However; it neglected one crucial fact : as most users
|
||
|
tend to choose a document character size between 10 and 14 points, the
|
||
|
resultant displayed text was rather small and not too legible without scaling.
|
||
|
Microsoft engineers took notice of this problem and chose a resolution
|
||
|
of 96 dpi on Windows, which resulted in slightly larger, and more legible,
|
||
|
displayed characters (for the same printed text size).
|
||
|
<p>These distinct resolutions explain some differences when displaying
|
||
|
text at the same character size on a Mac and a Windows machine. Moreover,
|
||
|
it is not unusual to find some TrueType fonts with enhanced hinting (tech
|
||
|
note: through delta-hinting) for the sizes of 10, 12, 14 and 16 points
|
||
|
at 96 dpi.
|
||
|
<br>
|
||
|
<p>As for device-independent text, it is a notion that is, unfortunately,
|
||
|
often abused. For example, many word processors, including MS Word, do
|
||
|
not really use device-independent glyph positioning algorithms when laying
|
||
|
out text. Rather, they use the target printer's resolution to compute <i>hinted</i>
|
||
|
glyph metrics for the layout. Though it guarantees that the printed version
|
||
|
is always the "nicest" it can be, especially for very low resolution printers
|
||
|
(like dot-matrix), it has a very sad effect : changing the printer can
|
||
|
have dramatic effects on the <i>whole</i> document layout, especially if
|
||
|
it makes strong use of justification, uses few page breaks, etc..
|
||
|
<p>Because the glyph metrics vary slightly when the resolution changes
|
||
|
(due to hinting), line breaks can change enormously, when these differences
|
||
|
accumulate over long runs of text. Try for example printing a very long
|
||
|
document (with no page breaks) on a 300 dpi ink-jet printer, then the same
|
||
|
one on a 3000 dpi laser printer : you'll be extremely lucky if your final
|
||
|
page count didn't change between the prints ! Of course, we can still call
|
||
|
this WYSIWYG, as long as the printer resolution is fixed !!
|
||
|
<p>Some applications, like Adobe Acrobat, which targeted device-independent
|
||
|
placement from the start, do not suffer from this problem. There are two
|
||
|
ways to achieve this : either use the scaled and unhinted glyph metrics
|
||
|
when laying out text both in the rendering and printing processes, or simply
|
||
|
use wathever metrics you want and store them with the text in order to
|
||
|
get sure they're printed the same on all devices (the latter being probably
|
||
|
the best solution, as it also enables font substitution without breaking
|
||
|
text layouts).
|
||
|
<p>Just like matching sizes, device-independent placement isn't necessarily
|
||
|
a feature that most users want. However, it is pretty clear that for any
|
||
|
kind of professional document processing work, it <b><i>is</i></b> a requirement.</blockquote>
|
||
|
</blockquote>
|
||
|
|
||
|
<center><table width="100%" border=0 cellpadding=5><tr bgcolor="#CCFFCC" valign=center>
|
||
|
<td align=center width="30%">
|
||
|
<a href="glyphs-4.html">Previous</a>
|
||
|
</td>
|
||
|
<td align=center width="30%">
|
||
|
<a href="index.html">Contents</a>
|
||
|
</td>
|
||
|
<td align=center width="30%">
|
||
|
<a href="glyphs-6.html">Next</a>
|
||
|
</td>
|
||
|
</tr></table></center>
|
||
|
|
||
|
</td></tr></table></center>
|
||
|
|
||
|
</body>
|
||
|
</html>
|