
			The FreeType Engine

		      Core Library User Guide

				 or

    How to use the engine in your applications and font servers
			  by David Turner

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

			    Introduction


			 I. Basic Concepts:
  
                       1. Concepts
                       2. Handles
                       3. Conventions of use
                       4. Object classes

			  II. Extensions:

                     1. What is an extension?
                     2. Where to find them
                     3. Writing your own extension

                             Conclusion

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

Introduction:

This file has  been written to present the  FreeType core library to
would-be  writers  of  applications  and  font  servers.   It  first
describes the concepts on which the engine is based, then how to use
it to obtain glyph metrics, outlines and bitmaps.

The last part discusses the ability to add and use extensions to the
core library to get access to supplemental TrueType tables which are
not currently  provided by  the core engine.   If you would  like to
write your own extensions, read also the FreeType developer's guide.



I. Basic Concepts:


1. Concepts:

    FreeType defines several  kinds of structures, called "objects",
    that  are used to  manage the  various abstractions  required to
    access and display fonts.

    In a care of good  encapsulation, these objects are not directly
    accessible from a client application.  Rather, the user receives
    a 'handle'  for each object it  queries and wants  to use.  This
    handle  is a  stand-alone reference,  it cannot  be used  like a
    pointer to access directly the object's data.

2. Properties:

    It  is however  possible  to obtain  and  set object  properties
    through  several  functions of  the  API.   For  example, it  is
    possible to query a face  object's properties with only a handle
    for it, using the function TT_Get_Face_Properties().

    Note  that  the  data  will  be  returned  in  a  user-allocated
    structure,  but will also  contain pointers  addressing directly
    some data found within the object.

    A client application should  never modify the data through these
    pointers!  In order to set new properties' values, the user must
    always call  a specific  API to  do so, as  a certain  number of
    other related  data might not  appear in the  returned structure
    and imply various non-visible coherency and coercion rules.

    NOTE:

    A notable  exception to this rule  is the ability  to move point
    coordinates in a glyph  container's outline through the pointers
    returned by TT_Get_Glyph_Outline.  However, this operation isn't
    necessary for most programs.


3. Conventions of use:

     o All API functions have their label prefixed by 'TT_', as well
       as all external (i.e. client-side) types.


     o To allow  the  use  of  FreeType's  core  engine in  threaded
       environments, nearly all API  functions return an error code,
       which is always set to 0 in case of success.

       The error codes'  type is TT_Error, and a  listing of them is
       given in the API reference (see "apiref.txt").

       Some functions do not return  an error code.  Their result is
       usually a value that takes  a negative value in case of error
       (this is used for functions  where only one kind of error can
       be reported, like an invalid glyph index).

       An important note  is that the engine should  not leak memory
       when  returning an error,  e.g. querying  the creation  of an
       object  will allocate  several internal  tables that  will be
       freed if a disk error occurs during a load.


     o A handle is acquired through API functions labelled along the
       names:

          TT_Open_xxxx(), TT_New_xxxx()

          where xxxx is the object's class (Face, Instance, etc.)

          examples:

             TT_Open_Face(), TT_Open_Collection(),
             TT_New_Instance(), TT_New_Glyph()


     o A handle is closed through an API labelled

          TT_Close_xxxx() or TT_Done_xxxx()

          where xxxx is the object's class (Face, Instance, etc.)

          examples:
             TT_Close_Face(), TT_Done_Instance(), TT_Done_Glyph()


     o Properties are obtained through an API labelled

          TT_Get_xxxx_yyyy()

          where xxxx is the object's class, and yyyy its property

          examples:

             TT_Get_Face_Properties(), TT_Get_Instance_Metrics()
             TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap()


     o Properties are set through an API labelled

          TT_Set_xxxx_yyyy()
          
          where xxxx is the object's class, and yyyy its property

          examples:

             TT_Set_Instance_Resolution(),
             TT_Set_Instance_Pointsize()


4. Object Classes:

    The following object classes are  defined in this release of the
    engine:

    * The Face objects:

        A  face contains  the  data  that is  specific  to a  single
        TrueType font  file.  It presents information  common to all
        glyphs and  all point  sizes like font-specific  metrics and
        properties.

        You can  open a face object  by simply giving  a pathname to
        the TrueType  file.  You can later close  (i.e. discard) the
        face object.

        You  can also  open a  single  face embedded  in a  TrueType
        collection.

        See also:

           TT_Open_Face(), TT_Open_Collection(), TT_Close_Face(),
           TT_Get_face_Properties()


     * The Instance objects:

        An instance is also called  a 'pointsize' or a 'fontsize' in
        some windowing  systems.  An instance  holds the information
        used to render glyphs on  a specific device at a given point
        size; it is always related to an opened face object.

        For instance, if  you want to generate glyphs  for text from
        the same  typeface at 'sizes' of  10 and 12  points, all you
        need  is  one face  object,  from  which  you'll create  two
        distinct instances.
        
        A  device   is  defined  by  its   horizontal  and  vertical
        resolution,  usually specified  in dots  per inch  (dpi).  A
        point size  is a scaling number, given  as _absolute_ values
        in points, where 1 point = 1/72 inch.

        The 'pixel' size, also known as the 'ppem' value (for Points
        Per EM  square) is computed from both  the device resolution
        and the point size.  It determines the size of the resulting
        glyph bitmaps on your screen or sheet of paper.

        The default device resolution  for any new instance is 96dpi
        in both  directions, which corresponds to  VGA screens.  The
        default point  size is 10pt.  The high-level  API allows you
        to  change this  whenever you  want for  any  given instance
        object.

        Note that  closing a face object  will automatically destroy
        all its  child instances (even  though you can  release them
        yourself to free memory).

        See also:

          TT_New_Instance(), TT_Done_Instance(),
          TT_Get_Instance_Metrics(), TT_Set_Instance_Resolution(),
          TT_Set_Instance_Pointsize()


     * The Glyph objects:

        A Glyph object is a  _container_ for the data that describes
        any glyph  of a  given font.  This  means that  it typically
        holds:

         - glyph metrics  information, like bounding  box or advance
           width.

         - outline arrays, sized large enough to hold any glyph from
           the  face.   This  size  is  extracted  from  the  face's
           internal 'maxProfile' table to optimize memory costs.

         - other   important  parameters   related  to   the  'fine'
           rendering of  the glyphs.  This includes  things like the
           dropout-control mode used at low sizes.

         - and it doesn't contain a bitmap or a pixmap!

        A glyph object is used  to load, hint and rasterize a single
        glyph, as taken from the font file.

        See also:

          TT_New_Glyph(), TT_Done_Glyph(), TT_Get_Glyph_Metrics(),
          TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap(),
          TT_Get_Glyph_Pixmap()


     * The Character Map (CharMap) handle:

        Glyphs  can be  indexed in  a  TrueType file  in any  order,
        independent of  any standard character  encoding, like ASCII
        or Unicode.   For this reason,  each file comes with  one or
        more character  mapping tables,  used to translate  from one
        specific encoding's charcodes to font glyph indexes.

        There  are  many  encoding  formats,  and each  one  can  be
        distinguished by two values:

           - its platform ID
           - its platform-specific encoding ID

        Their values  are defined in the  TrueType specification and
        won't be commented there.

        It  is possible  to  enumerate the  charmaps  provided by  a
        TrueType  font   and  to  use   any  of  these   to  perform
        translations.

        The charmaps are loaded in memory only on demand to save the
        space taken by the maps  that are not needed on your system.
        They are part of the face object, however.

        This  means  that even  though  a  charmap  can be  accessed
        through  a  handle  (obtained through  the  TT_Get_CharMap()
        function), it isn't a  stand-alone object.  For example, you
        never need to de-allocate  it; this is done automatically by
        the engine when its face object expires.

        See also:

          TT_Get_CharMap_Count(), TT_Get_CharMap_ID(),
          TT_Get_CharMap(), TT_Char_Index().


II. Step-by-step Example:

  Here  is  an  example  to  show,  step by  step,  how  one  client
  application can  open a font  file, set one or  several instances,
  load any glyph, then render it to a bitmap.

  a. Initialize the engine:

    This  is the  first thing  to do.   You need  to  initialize the
    engine through a call to TT_Init_FreeType().  This function will
    set up a various number of structures needed by the library.

    This allocates about 68kByte,  of which 64kByte are dedicated to
    the scan-line  converter's "render  pool", a workspace  used for
    bitmap generation.  Note that even though this space is bounded,
    the raster is able to render a glyph to any size or bitmap.

    NOTE: You  can reduce  the size  of this  pool by  modifying the
          constant  RASTER_RENDER_POOL  in  the  file  'ttraster.c'.
          Take care  of never assigning a value  smaller than 4kByte
          however.  A  smaller pool will result  in slower rendering
          at large sizes.

  b. Open the font file:

    There are  two ways to open  a font face, depending  on its file
    format:

     - If it's  a TrueType  file (ttf), you  can simply use  the API
       named  TT_Open_Face(),  which takes  the  file's pathname  as
       argument, as well as the address of the returned face handle.

       Check the  returned error  code to see  if the file  could be
       opened and accessed successfully.

         TT_Face  face;  /* face handle */

         error = TT_Open_Face( "c:\work\ttf\wingding.ttf", &face );
         if ( error )
         {
           printf( "could not open the file\n" );
           ...
         }


     - If the font  is embedded in a TrueType  collection (ttc), you
       can use the API  named TT_Open_Collection(), which takes also
       the font's index within the collection's directory.

         TT_Face  face;  /* face handle */

         /* Load the collection's second face (index=1) */
         error = TT_Open_Collection( "c:\work\ttf\whatever.ttc",
                                     1, &face );
         if ( error )
         {
           printf( "could not open the file\n" );
           ...
         }


     - Finally, when you do not know the number of faces embedded in
       a TrueType collection, the following technique can be used:

        o call  TT_Open_Face() with the  collection file's pathname.
          This API  recognizes collections automatically  and always
          return a handle for its first embedded font.

        o get       the       face's        properties       through
          TT_Get_Face_Properties().   These   contain,  among  other
          things, the maximum font collection index that can be used
          in a  call to the  API TT_Open_Collection(), in  its field
          'max_Faces'.


             TT_Face             face;  /* face handle     */
             TT_Face_Properties  props; /* face properties */
    
             /* open the first collection font */
             error = TT_Open_Face( "c:\work\ttf\collection.ttc",
                                   &face );
             if ( error )
             {
               printf( "could not open the file\n" );
               ...
             }
    
             /* Get the face properties */
             TT_Get_Face_Properties( face, &props );
    
             /* Now print the number of faces */
             printf( "there are %d faces in this collection file\n",
                     props->max_Faces + 1 );


  c. Create an instance from the face object:

     You must create an  instance (a.k.a a pointsize) which contains
     information relative to  the target output device's resolutions
     and a given point size.

     o The instance object is created through TT_New_Instance():

           TT_Instance  instance;

           error = TT_New_Instance( face, &instance );
           if ( error )
           {
             printf( "could not create instance\n" );
             ...
           }

       TECHNICAL NOTE:
       Creating a new instance  executes its font program.  This can
       fail if the font is broken.  Never assume that the error code
       returned here is always 0.

     o You  must set the  instance's properties to suit  your needs.
       They   are  simply  its   device  resolutions,   set  through
       TT_Set_Instance_Resolution(), and its point size, set through
       TT_Set_Instance_Pointsize():

         /* set the target horizontal and vertical resolution to */
         /* 300dpi in each direction (typically for a printer)   */
         /* A fresh instance's default resolutions are 96dpi in  */
         /* both directions.                                     */
         error = TT_Set_Instance_Resolution( instance, 300, 300 );
         if ( error )
         {
            printf( "could not set resolution" );
            ...
         }

         /* Now set the point size. Default is 10pt. */
         error = TT_Set_Instance_Pointsize( instance, 12 );
         if ( error )
         {
           printf( "could not set point size" );
           ...
         }

         TECH NOTE:
         These calls may execute  the font's prep program, which can
         fail when the font is  broken.  Never assume that the error
         codes returned there are always successful.


     o You can also set  the instance's transformation flags to tell
       the  glyph loading function  that you're  going to  perform a
       transformation  (like  rotation or  slanting)  on the  glyph.
       Note   that   the    glyph   loader   doesn't   perform   the
       transformation.    It  only   informs  the   glyphs'  hinting
       instruction  streams about these  flags which  may use  it to
       disable  or enable  various features  (grid-fitting, drop-out
       control etc).


           TT_Set_Instance_Transforms( FALSE, TRUE );

           to indicate that you're going to stretch, but not rotate,
           this  instance's  glyphs.  Default  is, of  course,  both
           FALSE.


  d. Create a glyph container:

     You need a glyph object to  serve as a container for the glyphs
     you want to load from the face.  This is done simply by

           TT_Glyph  glyph;  /* glyph object handle */

           error = TT_New_Glyph( face, &glyph );
           if ( error )
           {
             printf( "could not create glyph\n" );
             ...
           }

     Note that in  spite of the fact that a  glyph is always related
     to a given face, the glyph isn't destroyed when its parent face
     object is discarded, unlike instances.


  e. Load the glyph:

     The  glyph loader  is easily  queried  through TT_Load_Glyph().
     This API function takes several arguments:

      o an  instance  handle, to  specify  at which  point size  and
        resolution   the   loaded  glyph   should   be  scaled   and
        grid-fitted.

      o a glyph container, used  to hold the glyph's data in memory.
        Note  that the  instance and  the glyph  must relate  to the
        _same_ font  file.  An  error would be  produced immediately
        otherwise.

      o a glyph  index, used to reference the  glyph within the font
        file.  This index is not a platform specific character code.
        Charmap objects are provided  to translate from charcodes to
        glyph  indexes.  All  you need  is to  know  your platform's
        encoding IDs  according to the  TrueType specification, then
        to obtain a charmap for it  (if the font comes with it), and
        finally  to use it  through TT_Char_Index()  to get  a glyph
        index.   We  strongly recommend  using  the Unicode  charmap
        whenever possible.

      o a  load mode, indicating  what kind of operations  you need.
        There are only two defined:

           TTLOAD_SCALE_GLYPH:

              When set,  this flag  indicates that the  loaded glyph
              will be scaled to fractional pixel coordinates (26.6).
              If  not, the coordinates  will remain  integer FUnits.
              Please  refer to  the TrueType  specification  and the
              FreeType  header files  for more  details on  the 26.6
              format and other data types.

           TTLOAD_HINT_GLYPH:

              This    flag   is    only   in    effect    when   the
              TTLOAD_SCALE_GLYPH flag is set.  It indicates that the
              glyph  must  also be  'hinted',  or 'grid-fitted'  for
              better display results.

        You can  'or' the flags  simply.  As most  applications will
        require both flags to be set, the constant TTLOAD_DEFAULT is
        defined as:

           #define TTLOAD_DEFAULT  (TTLOAD_SCALE_GLYPH | \
                                    TTLOAD_HINT_GLYPH )


    example:

      error = TT_Load_Glyph( instance, glyph, 65, TTLOAD_DEFAULT );
      if ( error )
      {
        printf("could not load the glyph\n");
        ...
      }


  f. Query glyph properties:

     You're then able to query various glyph properties:

     o The    glyph     metrics    can    be     obtained    through
       TT_Get_Glyph_Metrics().   The data  returned  in the  metrics
       structure is:

         - the glyph's left side bearing
         - the glyph's advance width
         - the glyph's bounding box
         - its drop out control mode for better rendering

       These values are expressed in 26.6 pixel units when the glyph
       was loaded with scaling, or in FUnits if not.

     o The     glyph    outline     can    be     queried    through
       TT_Get_Glyph_Outline().   This can be  useful to  process the
       points  coordinates (e.g.   applying stretching  or rotation)
       with    functions   like    TT_Apply_Outline_Transform()   or
       TT_Apply_Outline_Translation().  Note that these functions do
       not recompute a glyph's metrics after the transformation!

       The  outline's  structure   is  described  in  the  reference
       "apiref.txt".

       A bitmap or pixmap for the glyph can be queried with the APIs
       TT_Get_Glyph_Bitmap()   and   TT_Get_Glyph_Pixmap().    These
       functions take  a glyph handle as  an argument, as  well as a
       bitmap/pixmap description block and two offsets.

       The target  map is described through  a TT_Raster_Map object,
       which   structure   is   defined   in  the   reference   (see
       "apiref.txt").  The  offsets are given  in the same  units as
       the points  coordinates and  glyph metrics: 26.6  pixel units
       for a scaled glyph, and FUnits for an unscaled one.

       IMPORTANT TECH NOTE: **
       ***********************

       When the glyph has been scaled and hinted, the offsets _must_
       be multiples of 64  (i.e. integer pixel offsets).  Otherwise,
       you would simply ruin the grid fitting (which usually results
       in ugly glyphs).

   examples:

       TT_Glyph_Metrics   metrics;
       TT_Glyph_Outline   outline;
       TT_Raster_Map      bitmap;

       TT_Get_Glyph_Metrics( glyph, &metrics );
       TT_Get_Glyph_Outline( glyph, &outline );

       /* set up the bitmap */
       ...
       TT_Get_Glyph_Bitmap( glyph, &bitmap, 0, 0 );


  g. When you're done:

     o You  can  close any  font face  object  with TT_Close_Face().
       This call will automatically  discard its child instances and
       charmaps.  However,  the related glyph will  remain in memory
       and  it is  the user's  responsibility  not to  use them  for
       further loads.

     o You  can  also  close  the  engine  with  a  single  call  to
       TT_Done_FreeType().  This  will simply release  _all_ objects
       that were previously allocated, and close all font files.


III. Extensions:

1. What is an extension?

  FreeType allows you to access a various number of TrueType tables,
  as well as to render individual glyphs. However:

  1 - it doesn't perform some high-level operations, like generating
      a string text from many individual glyphs.

  2 - it doesn't perform kerning (which can be needed by topic 1).

  3 - it doesn't  give  access to  all the defined  TrueType tables,
      especially the optional ones.


  While point 1 is a feature that will never go into FreeType's core
  engine,  which goal is  to provide  easy access  to font  data and
  rendering _individual_ glyphs,  point 2 and 3 can  be added to the
  engine's features through extensions.

  An  extension is simply  a small  piece of  code that  extends the
  engine's abilities and APIs.  It  is possible to extend the engine
  without  touching the  core's source  code, this  is  described in
  chapter 3 below.


2. The two kinds of extensions:

  There  are  basically  two  kinds  of  extensions,  which  require
  different implementations.

  a. API extensions:

    An API extension is a  set of functions that extend the FreeType
    core API to give access to tables that are already loaded by the
    engine, but not  provided for now.  An example  of such data can
    be:

      - the horizontal metrics table (HMTX)
      - the gasp table

    This kind of extension is made of:

     o an API extension  header file, following the usage convention
       introduced here  (all labels prefixed with  'TT_'), and which
       will  be  included by  the  clients  which  want to  use  the
       extension.  By convention, such header names begin with 'ftx'
       (for FreeType eXtension).

       examples: ftxgasp.h, ftxhtmx.h
  
     o One or more functions used  to give access to the tables that
       are already  loaded and managed by the  engine.  They usually
       only  copy pointers  to  the target  structure  given by  the
       client application since  these structures are not accessible
       through the 'normal' API.


  b. engine extensions:

    It can  be sometimes  useful to load  and manage  several tables
    that are  not considered by  the core engine.   These extensions
    need  to provide  additional  functions to  fit into  FreeType's
    internal  object management  model, and  are  more sophisticated
    than API extensions.

    An  example is  given in  this distribution  to  provide kerning
    support  (or  more technically  spoken,  access  to the  kerning
    tables found within the TrueType files). It is made of:

    o An  API  extension  providing  new  interfaces  to the  client
      applications that need it. See the file "ftxkern.h".

    o A specific implementation,  providing services to create, load
      and  manage  kerning tables  as  additional  parts  of a  face
      object.  In  the case of  kerning, the directory of  tables is
      loaded  when the  face is  opened, and  tables  themselves are
      fetched from the file on demand.  This implies several 'hooks'
      in the  core engine. See the files  "ttkern.h" and "ttkern.c".
      These are called 'engine extensions'.


3. Writing your own extensions:

    As it was  suggested earlier, writing an engine  extensions is a
    delicate process,  as the additional code must  follow a certain
    number  of design  rules,  presented in  the FreeType  developer
    guide.  There  is also an  extension writer's guide in  the file
    "extend.txt".

    ** NOTE **: The developer  and  extension writer guides  are not
                present in this beta.   These documents will be part
                of FreeType 1.0, however.

    By writing your  own extensions, it will be  possible to support
    more advanced TrueType formats like TrueType GX or OpenType in a
    near future, without having to torture the engine core source at
    each iteration.

    If you  encounter some difficulties  when trying to  create your
    own extension,  please read the core source  file carefully, and
    in the  event that you may  need changes that are  not fitted to
    the current extension mechanism,  do not hesitate to contact the
    authors at 'freetype-devel@lists.lrz-muenchen.de'

    
Conclusion:

   This  is  the  first   version  of  this  document,  released  in
   FreeType's first public  beta.  We consider it as  a "real" beta,
   i.e., a functional  version with a complete API,  released to the
   public to help us find bugs.

   We invite  you to  read the test  programs' source code  to learn
   more about the high-level interface.

   The API is now considered  frozen, and won't evolve in the future
   unless we encounter important  incoherencies which must be fixed.
   Unlike the four previous alphas,  we invite you to test and start
   development of your own tools based on this API.

   The engine's internals may still vary during this last phase, and
   we may  decide to make some  of the provided  extensions parts of
   the core engine, but this  should not affect the already existing
   APIs.

   We hope you have success and fun in using this engine.  Much time
   has been taken to make it one of the best in its genre.  Remember
   that it  is not  intended to  be a complete  font server  or text
   rendering library,  but a  pretty solid base  for these  kinds of
   applications, as well as others.

   We would  like you to report  the bugs you  find, _after_ reading
   the current bug report at our web page:

      http://www.physiol.med.tu-muenchen.de/~robert/freetype.html

   We have already many  volunteers for the current projects, though
   additional help can still be useful:

      - an OS/2 font server based on FreeType

      - an X11 font server based on FreeType

      - TrueType support for the Wine Windows emulator

      - ttf2bdf, a  conversion tool  for producing bitmaps  from TTF
        files


   We also welcome volunteers to the following ideas:


      - a text rendering library based on FreeType.

          To  provide  various  features  that are  not  covered  by
          FreeType's core library,  like string text rendering (with
          or  without  kerning, with  or  without gray-scaling  like
          Win95), rotation, stretching, blitting, etc.

          This library would be  of great help for many environments
          which cannot  access a TrueType renderer.  It  can also be
          the base  of some extended font servers  for some specific
          systems.


      - a font server for  any graphical system that doesn't support
        TrueType properly.

          OS/2  and  BeOS  come  to  mind as  systems  that  provide
          mediocre  TrueType support, which  is not  surprising when
          one sees  the fuzzy  quality of the  specs.  Note  that we
          already have an OS/2 renderer on its way.

          Some systems, like the AmigaOS  or RISC OS, do not support
          TrueType even though  they provide scalable font services.
          Adapting  a  font server  from  the  FreeType source  code
          should be a relatively easy task.

          There  are many other  systems that  could benefit  from a
          royalty-free  TrueType  engine,  and  we  encourage  their
          implementors to contact us and experiment with our engine.
          

      - TrueType GX support (the font part of GX, of course)

          Provided  through  extensions.  We  have  no  idea of  the
          difficulty of such support.


      - OpenType support

          Also  through  extensions.  It  would  need  a real  Type1
          engine!

          Note from the author:

            By the way, anyone wanting to rewrite the horrible Type1
            renderer found in X11R5 would be MORE than welcomed!

            This code is probably the worst design I've ever seen in
            my life!  It's  slow, eats a lot of  memory, uses stupid
            algorithms, and the auto-hinter is a shame!
            
            We're used to it because it 'works' more or less.

            
      ISN'T IT TIME TO RAISE THE STANDARD OF FREE SOFTWARE ?!?
      ********************************************************

		  Resist bloat! Resist free junk!

            PS:

              I  wouldn't like  to offend  mrz, author  of  T1lib, a
              better derivative to the original renderer.  I admit I
              couldn't have done  what he did, as bad  code makes me
              sick... but  he uses the original  engine, which still
              requires about  150kByte to do much less  that what we
              do in about 55kByte, and renders poorly...

          End of note


      - Java / Java2D support

        There are two possibilities:

            - One could  rewrite the engine entirely  in Java.  This
              would be a hard task, and probably won't run on a JVM.
              However, a native Java  compiler could do wonders with
              this code.

            - A more practical thing would be to embed the engine in
              a native  Java class and integrate it  to Java2D. This
              would give excellent  performance and good portability
              (the engine is written in ANSI C).

            - Alternatively, only  the scan-line converter  could be
              kept in  C for obvious performance  reasons, while the
              rest of the engine would be translated to Java.  There
              are delicate technical issues explaining why it is not
              possible to  use Java2D's current  scan-line converter
              to do this work.


      - conversions and  dumping tools for all kinds  of formats and
        platforms.



    We thank you for your time and consideration.

                        David Turner, Robert Wilhelm, Werner Lemberg,
                                  and all the FreeType enthusiasts...


--- End of user.txt ---
