|
|
|
@ -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,262 +15,470 @@ |
|
|
|
|
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> |
|
|
|
|
<h1 align=center> |
|
|
|
|
FreeType Glyph Conventions |
|
|
|
|
</h1> |
|
|
|
|
|
|
|
|
|
<h2 align=center> |
|
|
|
|
Version 2.1 |
|
|
|
|
</h2> |
|
|
|
|
|
|
|
|
|
<h3 align=center> |
|
|
|
|
Copyright 1998-2000 David Turner (<a |
|
|
|
|
href="mailto:david@freetype.org">david@freetype.org</a>)<br> |
|
|
|
|
Copyright 2000 The FreeType Development Team (<a |
|
|
|
|
href="mailto:devel@freetype.org">devel@freetype.org</a>) |
|
|
|
|
</h3> |
|
|
|
|
|
|
|
|
|
<center> |
|
|
|
|
<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-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> |
|
|
|
|
|
|
|
|
|
<p><hr></p> |
|
|
|
|
|
|
|
|
|
<table width="100%"> |
|
|
|
|
<tr bgcolor="#CCCCFF" |
|
|
|
|
valign=center><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> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="section-1"> |
|
|
|
|
<h3> |
|
|
|
|
1. Writing simple text strings |
|
|
|
|
</h3> |
|
|
|
|
|
|
|
|
|
<p>In this first example, we will generate a simple string of Roman |
|
|
|
|
text, i.e. with a horizontal left-to-right layout. Using exclusively |
|
|
|
|
pixel metrics, the process looks like: |
|
|
|
|
|
|
|
|
|
<tt> |
|
|
|
|
<ol> |
|
|
|
|
<li> |
|
|
|
|
Convert the character string into a series of glyph |
|
|
|
|
indices. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Place the pen to the cursor position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Get or load the glyph image. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Translate the glyph so that its 'origin' matches the pen position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Render the glyph to the target device. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Increment the pen position by the glyph's advance width in pixels. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Start over at step 3 for each of the remaining glyphs. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
When all glyphs are done, set the text cursor to the new pen |
|
|
|
|
position. |
|
|
|
|
</li> |
|
|
|
|
</ol> |
|
|
|
|
</tt> |
|
|
|
|
|
|
|
|
|
<p>Note that kerning isn't part of this algorithm.</p> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="section-2"> |
|
|
|
|
<h3> |
|
|
|
|
2. Sub-pixel positioning |
|
|
|
|
</h3> |
|
|
|
|
|
|
|
|
|
<p>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 |
|
|
|
|
subsection 1, with the following few differences:</p> |
|
|
|
|
|
|
|
|
|
<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> |
|
|
|
|
</ol> |
|
|
|
|
|
|
|
|
|
<p>Here an improved version of the algorithm:</p> |
|
|
|
|
|
|
|
|
|
<tt> |
|
|
|
|
<ol> |
|
|
|
|
<li> |
|
|
|
|
Convert the character string into a series of glyph |
|
|
|
|
indices. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Place the pen to the cursor position. This can be a non-integer |
|
|
|
|
point. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Get or load the glyph image. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Translate the glyph so that its "origin" matches the rounded pen |
|
|
|
|
position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Render the glyph to the target device. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Increment the pen position by the glyph's advance width in |
|
|
|
|
fractional pixels. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Start over at step 3 for each of the remaining glyphs. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
When all glyphs are done, set the text cursor to the new pen |
|
|
|
|
position. |
|
|
|
|
</li> |
|
|
|
|
</ol> |
|
|
|
|
</tt> |
|
|
|
|
|
|
|
|
|
<p>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.</p> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="section-3"> |
|
|
|
|
<h3> |
|
|
|
|
3. Simple kerning |
|
|
|
|
</h3> |
|
|
|
|
|
|
|
|
|
<p>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> |
|
|
|
|
|
|
|
|
|
<p>Algorithm 1 with kerning:</p> |
|
|
|
|
|
|
|
|
|
<tt> |
|
|
|
|
<ol> |
|
|
|
|
<li> |
|
|
|
|
Convert the character string into a series of glyph |
|
|
|
|
indices. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Place the pen to the cursor position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Get or load the glyph image. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Add the rounded scaled kerning distance, if any, to the pen |
|
|
|
|
position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Translate the glyph so that its "origin" matches the pen position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Render the glyph to the target device. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Increment the pen position by the glyph's advance width in pixels. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Start over at step 3 for each of the remaining glyphs. |
|
|
|
|
</li> |
|
|
|
|
</ol> |
|
|
|
|
</tt> |
|
|
|
|
|
|
|
|
|
<p>Algorithm 2 with kerning:</p> |
|
|
|
|
|
|
|
|
|
<tt> |
|
|
|
|
<ol> |
|
|
|
|
<li> |
|
|
|
|
Convert the character string into a series of glyph |
|
|
|
|
indices. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Place the pen to the cursor position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Get or load the glyph image. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Add the scaled unrounded kerning distance, if any, to the pen |
|
|
|
|
position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Translate the glyph so that its "origin" matches the rounded pen |
|
|
|
|
position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Render the glyph to the target device. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Increment the pen position by the glyph's advance width in |
|
|
|
|
fractional pixels. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Start over at step 3 for each of the remaining glyphs. |
|
|
|
|
</li> |
|
|
|
|
</ol> |
|
|
|
|
</tt> |
|
|
|
|
|
|
|
|
|
Of course, the algorithm described in section IV can also be |
|
|
|
|
applied to prevent the sliding dot problem if one wants to. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="section-4"> |
|
|
|
|
<h3> |
|
|
|
|
4. Right-to-left layout |
|
|
|
|
</h3> |
|
|
|
|
|
|
|
|
|
<p>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).</p> |
|
|
|
|
|
|
|
|
|
<p>Right-to-left algorithm 1:</p> |
|
|
|
|
|
|
|
|
|
<tt> |
|
|
|
|
<ol> |
|
|
|
|
<li> |
|
|
|
|
Convert the character string into a series of glyph |
|
|
|
|
indices. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Place the pen to the cursor position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Get or load the glyph image. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Decrement the pen position by the glyph's advance width in pixels. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Translate the glyph so that its "origin" matches the pen position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Render the glyph to the target device. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Start over at step 3 for each of the remaining glyphs. |
|
|
|
|
</li> |
|
|
|
|
</ol> |
|
|
|
|
</tt> |
|
|
|
|
|
|
|
|
|
<p>The changes to algorithm 2, as well as the inclusion of kerning |
|
|
|
|
are left as an exercise to the reader.</p> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="section-5"> |
|
|
|
|
<h3> |
|
|
|
|
5. Vertical layouts |
|
|
|
|
</h3> |
|
|
|
|
|
|
|
|
|
<p>Laying out vertical text uses exactly the same processes, with the |
|
|
|
|
following significant differences:</p> |
|
|
|
|
|
|
|
|
|
<ul> |
|
|
|
|
<li> |
|
|
|
|
<p>The baseline is vertical, and the vertical metrics must be used |
|
|
|
|
instead of the horizontal one.</p> |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
<p>The left bearing is usually negative, but this doesn't change the |
|
|
|
|
fact that the glyph origin must be located on the baseline.</p> |
|
|
|
|
</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 |
|
|
|
|
<i>Y</i> axis is oriented upwards). |
|
|
|
|
</li> |
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
<p>Here the algorithm:</p> |
|
|
|
|
|
|
|
|
|
<tt> |
|
|
|
|
<ol> |
|
|
|
|
<li> |
|
|
|
|
Convert the character string into a series of glyph |
|
|
|
|
indices. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Place the pen to the cursor position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Get or load the glyph image. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Translate the glyph so that its "origin" matches the pen position. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Render the glyph to the target device. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Decrement the vertical pen position by the glyph's advance height |
|
|
|
|
in pixels. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Start over at step 3 for each of the remaining glyphs. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
When all glyphs are done, set the text cursor to the new pen |
|
|
|
|
position. |
|
|
|
|
</li> |
|
|
|
|
</ol> |
|
|
|
|
</tt> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="section-6"> |
|
|
|
|
<h3> |
|
|
|
|
6. WYSIWYG text layouts |
|
|
|
|
</h3> |
|
|
|
|
|
|
|
|
|
<p>As you probably know, the acronym WYSIWYG stands for "What You See Is |
|
|
|
|
What You Get". Basically, this means that the output of a document on |
|
|
|
|
the screen should match "perfectly" its printed version. A |
|
|
|
|
<em>true</em> WYSIWYG system requires two things:</p> |
|
|
|
|
|
|
|
|
|
<ul> |
|
|
|
|
<li> |
|
|
|
|
<p><em>device-independent text layout</em></p> |
|
|
|
|
|
|
|
|
|
<p>This 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.</p> |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
<p><em>matching display and print character sizes</em></p> |
|
|
|
|
|
|
|
|
|
<p>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%).</p> |
|
|
|
|
</li> |
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
<p>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 is not too |
|
|
|
|
unfortunate, however, because most users really don't care about this |
|
|
|
|
feature. Legibility is much more important.</p> |
|
|
|
|
|
|
|
|
|
<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 equals exactly |
|
|
|
|
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> |
|
|
|
|
|
|
|
|
|
<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 (technical note: through delta-hinting) for the sizes of 10, 12, |
|
|
|
|
14 and 16 points at 96 dpi.</p> |
|
|
|
|
|
|
|
|
|
<p>The term <em>device-independent text</em> 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 <em>hinted</em> 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 |
|
|
|
|
<em>whole</em> document layout, especially if it makes strong use of |
|
|
|
|
justification, uses few page breaks, etc.</p> |
|
|
|
|
|
|
|
|
|
<p>Because 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 will 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> |
|
|
|
|
|
|
|
|
|
<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 whatever metrics you want and store |
|
|
|
|
them with the text in order to get sure they are printed the same on all |
|
|
|
|
devices (the latter being probably the best solution, as it also enables |
|
|
|
|
font substitution without breaking text layouts).</p> |
|
|
|
|
|
|
|
|
|
<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 |
|
|
|
|
<em>is</em> a requirement.</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-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> |
|
|
|
|