| <!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="David Turner"> |
| <title>FreeType Glyph Conventions</title> |
| </head> |
| |
| <body text="#000000" |
| bgcolor="#FFFFFF" |
| link="#0000EF" |
| vlink="#51188E" |
| alink="#FF0000"> |
| |
| <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> |