

                           Welcome to the
          
                  F R E E T Y P E    P R O J E C T
      

                   The FREE TrueType Font Engine

                     Copyright 1996 David Turner



This document is an introduction to the  FreeType  project,  a  very
efficient  and fast, though portable, TrueType font rendering engine
*freely available*.  The reader's good  knowledge  of  the  TrueType
Font  specification  is  not  required,  though  being  a indeniable
"plus".

---------------------------------------------------------------------

TABLE OF CONTENTS :

   Introduction :

I. Engine Design Goals :

  1. Easy Maintenance
  2. System Independance
  3. Reliability
  4. High Quality
  5. Speed !

II. Engine Architecture :

  1. Component Hierarchy
  2. Runtime Execution

II. Internals :

  1. Engine Memory Management.
  2. Rasterizer mechanics.
  3. Interpreting TrueType opcodes.

III. Engine Characteristics :

  1. Differences found between TrueType specs and real-world
     font files.

  2. Engine's behaviour with incorrect font files or glyphs.

IV. What to do now ? :

  1. Debug the whole interpreter..

  2. Add more character-oriented functions.

  3. Porting considerations ( IMPORTANT ).

--------------------------------------------------------------------

Introduction :
--------------

Managing fonts can be a serious task !

    In these good old days when all we had were dot-matrix printers,
it was common practice to  use  bitmap files to print and/or display
text.  This could lead to the use of a lot of disk  space,  as  each
pointsize of a same typeface had to be bitmapped in a separate file.
Moreover,  it  made  creating  new  typefaces  incredibly  slow  and
painful, as the file for each size had to be generated.

    The  first  system  which  included automaticaly-computed bitmap
files from a description  was  undoubtly  Metafonts, part of the TeX
package from Donald Knuth, which is still widely  used  in  academia
and  research nowadays !  Metafonts is a font specification language
and bitmap generator.  It produces  the bitmaps that the TeX program
uses to generate its 'DVI' ( DeVice-Independent ) files.
    Unlike modern systems, it's a stand-alone product  that  is  not
integrated into TeX, and does not  work "on-demand".  It must be run
by the user before any TeX processing to generate the bitmap  files.

    Metafonts  was a masterpiece at the time it was invented, and in
many ways, it still  is,  with  features  that  have  yet to come to
modern systems ( like family-generation :  give him the  description
of  an  A,  and  it will generate all others letters of the alphabet
with the same style !!  ).

    Metafonts  did  not  resolve  the  disk  space  problem, it just
automated the bitmap generation and made it fairly easy.  Meanwhile,
the advent of laser  printers  and  graphical environments urged the
need  for  a  suitable  'on-demand'  font  rendering  system.    Not
surprisingly,   Adobe  which  led  the  laser  revolution  with  its
Postcript printing language, proposed the  Type 1 Font Format.  This
format is based on a vector specification of each glyph as  well  as
the  presence  of  small  instructions,  called  'hinting',  to help
preserve some aesthetics properties  of  the fonts when rendering to
small sizes ( like keeping the width of the two vertical bars of a H
the same, for example ).  As Type  1  was  one  of  Postcript's  key
points,  laser printers became the choice of quality of many, as the
quality of the printed texts out-performed by far dot-matrix.

    A  Type 1 font was typically downloaded into the laser printer's
memory, where all rendering  calculations  took  place; there was no
need for extra work from the computer.  This is why early  windowing
systems  started  to  allow  printing with Type 1 fonts on Postcript
printers,  while  keeping  their  weak  bitmap  files  for  display.
Moreover, Adobe refused to license the font rendering code to  Apple
and  Microsoft.   The two software giants decided then to team up to
create a new font technology,  today known as 'TrueType'.  Few weeks
after they had agreed, Adobe announced ATM ( Adobe Type Manager ), a
product  that  allowed  (  and still does !  ) Macintosh and Windows
owner to display Type 1  fonts  and  (at last) do some real WYSIWYG.
What is funny is that neither products were even written on paper at
that time.

   Adobe benefited from the vast momentum of already available  Type
1  fonts,  most  Typeface  designers  having been converted to their
format.  It is still widely  used  in corporations where the quality
of the fonts used is important (  Publishing,  Advertising,  ..   ),
while  TrueType,  which finally came out and became part of System 7
and Windows 3.0, is a source of  free or cheap low-level fonts for a
lot of every-day jobs.  Though, more and more new fonts are proposed
in both formats today.

   So the question is :   why  make  a TrueType engine rather than a
Type 1 one ?

   Well, few years ago, if  someone  wanted some good quality fonts,
one had  to  purchase  them  in  Type  1  format  from  professional
designers.   This  seems not to be so true today, after we bought so
many of  these  troublesome  but  cheap  Windows  PCs. Moreover, the
TrueType specification includes a much  better  hinting  facility  :
you can actually *read* TrueType fonts at 12 pts on  a  VGA  screen,
while  this  is  unlikely with ATM whose rendering of small sizes is
jerky, to say the least (  just  ask  any OS/2 user out there !!  ).

   Finally, there *is* already a freely available Type  1  renderer,
donated  by  IBM to the X Consortium.  Look for source distributions
of X11r6 for it !  It works, the source isn't really readable ( IMHO
) and suffers from a  "weird"  implementation  ( still IMHO ), to be
polite !

   The FreeType project aims the development of  a  TrueType  engine
that can be  easily  ported  across  platforms,  while  being  fast,
accurate and stable. Simply.




I. Engine Design Goals :
------------------------

This  section  describes  the  several  goals  the  engine  has been
developped for :


  - Easy maintenance :

      In an age where all 'serious' programming is done in C or C++,
      the author decided to code the engine in PASCAL  !   This  may
      seem  rather  weird,  but  this  language comes on the PC with
      high-quality programming environments  (  namely Borland's for
      DOS, and Virtual Pascal  on  OS/2  )  that  allow  light-speed
      compilation,  real  module  separation and easy debugging.
      
      The  drawback  of  these  compilers  ( i.e. a poorly, if ever,
      optimised generated  code  )  forced  development  to focus on
      algorithm  fine-tuning,  rather  than clever macro tricks, and
      the  tendency  to  optimize  'on   the  run'  so  usual  of  C
      programmers ( a practice that easily leads to weird and hardly
      maintainable code ).

      This approach, though quite constraining at first,  paid  back
      faster than expected.  The project is now a well crafted piece
      of software, and runs *fast*  even under Borland Pascal.  This
      is unoptimized code, and one could expect a great  performance
      increase  by  translating  to  C  and  using a good optimizing
      compiler like GCC, or even to assembly.

      The  current version has been compiled and tested on Borland's
      16 bits Pascal  Compilers  ( Turbo-Pascal, Borland-Pascal Real
      Mode, and Borland-Pascal DPMI ) as well as  the  32  bit  OS/2
      Virtual  Pascal  compiler  (  a  *must-have*  ).   The 32-bits
      version is  about  2.5  to  3  times  faster  than  its 16-bit
      counterpart.  This is mainly due to the fact that most of  the
      data processed by the  engine  is  32-bit,  a painful task for
      16-bit programs..

      There exist  some  small  differences  between  the 16-bit and
      32-bit engines, coming from very short buit-in assembly  lines
      embedded  in  functions,  for  convenience rather than speed..
      See the section on Porting to locate these..

      As a whole,  the  Engine  proved  several  times  to be highly
      readable and maintainable.   It  takes  about  12  K-lines  of
      commented and airy Pascal code,  which  is  a small for such a
      software.


  - System Independence *and* Portability:

      The Engine has been developped with portability in mind.  This
      means that  we  don't  rely  on  any  specific  feature of the
      Pascal runtime  libraries.   It  thus  manages  resources in a
      specific way.


          a. Memory management :

             A client application should first allocate a block of
             memory  and  pass it to the engine at elaboration.  The
             engine  has no interface to any external memory manager
             to allocate or  release  chunks  of memory.  Rather, it
             will use the  passed  memory  block,  called  the  Font
             Storage Pool, for all its needs.  Deallocation of the
             pool is left to the client application.

             This  approach  garantees   that  the  engine's  memory
             requirements  during  execution  are  limited  to those
             defined by the client  application.  Should the pool be
             too small, the engine should fail to initialize, or  to
             load  a  font file, in a gentle way ( typically with an
             error message ).


          b. File operations :

             A  simple  unit  called  'File'  provides  a  basic I/O
             layer using the  simple  Pascal  FILE type ( unbuffered
             file access ).  New instances of 'File' can be  written
             to  take care of buffered or memory-mapped files access
             when possible, or other systems I/O.


          c. Endianess :

             TrueType  is  built on little-endianess, used typically
             on Motorola processors,  where  the  high order byte is
             always in the first memory position, while  the  lowest
             is in the last.

             Endianess  plays a role when reading data from the font
             file, and  when  extracting  constant  values  from the
             instruction  stream.   In  the   modules  where  it  is
             important  (  'Tables'  and 'Ins' ), the short/long int
             access has been well defined, and porting to a platform
             with a different endianess should not be a big problem.


  - Reliability and  Predictable Behaviour :

      This means that in the event of a corrupt font file processed
      by the Engine, the latter should react gently by delivering an
      error  message, rather than puking garbage at the screen or at
      the application's  memory  space.   This  is  important if one
      wants to make the Engine part of a  windowing  system  (  it's
      author  is  considering seriously writing a TrueType SubSystem
      for OS/2, and maybe X11/Linux ), and keep it stable.


  - High Quality :

      The quality of the rendered glyphs should equal those found on
      the Windows and Macintosh platforms.  This implies an accurate
      rasterizer ( did you say *smooth*  splines ?  ;), as well as a
      real TrueType bytecode interpreter ( did you say good  hinting
      ?  ).

      Most  shareware/commercial  TrueType  libraries do not include
      both   components.    Their   overall   rendering  quality  is
      consequently  poor  to  disastrous,  especially   with   small
      characters.

      The Free TrueType Engine is to date the first freely available
      source code for such a library.


      NOTE :  Win95's  style   anti-aliasing   technology   is   not
              considered seriously right now..   This being a matter
              of time, not of competence :-) It doesn't seem to be
              a difficult issue though..

  - Speed :

      This may surprise the many programmers who think that portable
      code is forced to  be  inefficient.   The idea is to fine-tune
      every piece of algorithm found in this engine, as long  as  it
      stays  on  touch  with  its  goals  (  accuracy,  portability,
      maintainability ).

      For example, appropriate research led the rasterizer to become
      faster,  more  accurate,  and  less  memory-consuming  as time
      passed.   This  is  Pascal  code,  with  zero,  nilch,   nada,
      optimisation; though, it flies .. test it !



II. Engine Architecture :

  1. Component hierarchy :
  ------------------------

  A component is simply a Pascal unit ( a simple module  made  of  a
  spec  and  a body ).  We'll give for each component its name which
  can be used to  get  its  unit  name.   The  unit name is found by
  prefixing "TT" to the component name; hence, the 'Types' component
  is in file 'TTTypes.Pas' !

    a. Base Components :

      - 'Types'
      - 'Error'
      - 'Vars'

      - 'Calc'
      - 'File'
      - 'Disp'

    b. Advanced Components :

      - 'Raster'
      - 'Tables'
      - 'Ins'

    c. Test programes :

      - 'TestTime'
      - 'TTZoom'
      - 'TTDebug'


   2. Runtime execution :
   ----------------------

    a. The Storage Pool :

       Though written in Pascal, the Engine has been  developped  to
       be  as platform, language and system independent as possible.
       This simply means two things :

       The features, like File I/O,  dependent on a specific runtime
       library or system, have been moved to  well  chosen  modules,
       which  are  the  only  ones that shall be touched to port the
       engine.

       Moreover,  the  Engine  provides  its  own  memory management
       routines.  A client  application  should  allocate  a  memory
       block  with  its own implementation of 'malloc', 'GetMem', or
       wathever similar function, and pass a pointer and its size at
       Egine elaboration.

       This block is called the Storage Pool, as all Engine routines
       will allocate the blocks they need in it.


    b. The Interpreter :

      - code ranges

    c. The Rasterizer :










      - pixel coordinates :

          According  to  the   TrueType  specifications,  all  pixel
          coordinates managed by the rasterizer are in 6 bits  fixed
          float format coded on 32 bits ( the famous F26dot6 type ).

      - contours :

          A  contour  is a closed, oriented curve giving the borders
          of the regions to be filled when rasterizing a glyph.  One
          glyph is commonly described using several contours.

          According to the TrueType specs, contours must be oriented
          so that the filled region  is  to the right of the contour
          orientation.  Unfortunately, many freely  available  fonts
          do not respect this simple rule !

          Contours  are  given to the rasterizer as sets of segments
          and simple  arcs  (  second-degree  Bzier  polynomials ).

          They are first converted to sets of "Profiles".

      - profiles :

          Put it simply, a "profile" is  a contour's portion of a
          contour that can only be either ascending  or  descending,
          i.e. it is monotonous in the vertical direction.  There is
          no such thing as a horizontal profile, as we shall see.

          Here are a few examples :

            A Square
                                            1         2
           ---->----     is made of two
          |         |                       |         |
          |         |       profiles        |         |
          ^         v                       ^    +    v
          |         |                       |         |
          |         |                       |         |
           ----<----

                                          up         down
             A Triangle

              P2                             1          2

              |\        is made of two       |         \
           ^  | \  \                         |          \
           | |   \  \      profiles         |            \      |
          |  |    \  v                  ^   |             \     |
            |      \                    |  |         +     \    v
            |       \                   |  |                \
         P1 ---___   \                     ---___            \
                  ---_\                          ---_         \
              <--__     P3                   up           down


          A more general contour can be made of more than
                           two profiles :

             __     ^
            /  |   /  ___          /    |
           /   |     /   |        /     |       /     |
          |    |    /   /    =>  |      v      /     /
          |    |   |   |         |      |     ^     |
       ^  |    |___|   |  |      ^   +  |  +  |  +  v
       |  |           |   v      |                 |
          |           |          |           up    |
          |___________|          |    down         |

               <--               up              down


          Each profile is  an  array  that associates one horizontal
          *pixel coordinate* to each bitmap *scanline* crossed by  the
          contour's section represented by the profile.

          They are stored in the Storage Pool



      - table overflow and sub-banding



