bitmaps.txt   [plain text]



             Bitmap and Pixmap generation with FreeType
             ------------------------------------------

                         Table of Contents


                Introduction
                
                I.   The rasterizer component
                
                II.  Bitmap & pixmap descriptors
                    
                III. Rendering an outline

                IV.  Anti-aliasing palette and other concerns
                
                Conclusion

                

Introduction
------------

  This  document describes  the steps  that are  needed to  render a
  glyph outline into a bitmap or a pixmap with the FreeType library.
  It contains  several important details needed  to generate bitmaps
  correctly  in all  situations, including  if an  outline  has been
  transformed or translated.


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


I. The rasterizer component
---------------------------

  In  FreeType, the  component in  charge of  performing  bitmap and
  pixmap  rendering  is  called  the  `rasterizer'.   Generation  is
  performed   through  a   traditional  process   called  `scan-line
  conversion', but exhibits certain properties:

  - The rasterizer doesn't allocate bitmaps:
  
    In fact, it  is only able to render an  outline into an existing
    bitmap  or pixmap,  which  is  passed to  one  of its  rendering
    functions.  This means that the target bitmap/pixmap must be set
    up correctly by the  caller to achieve desired results.  Setting
    up bitmap and pixmap descriptors is explained in section II.

  - It is able to render anti-aliased pixmaps directly:
  
    This  is  unlike other  graphics  packages,  which  render to  a
    `large'  bitmap  which  is  then  filtered  down.   Putting  the
    anti-aliasing logic  within the rasterizer  improves performance
    and  reduces  memory  usage,  as  well as  lets  us  use  better
    algorithms which couldn't work in a `two-phase' process.

  The  rasterizer   is  located   in  the  files   `ttraster.h'  and
  `ttraster.c'  (or   `ttraster.pas'  for  the   Pascal  version  --
  unfortunately, this is severely out of date).

  The  format of outlines  isn't important  for most  developers and
  won't  be discussed  here.   However, a  few  conventions must  be
  explained regarding the vector outlines:


  1. Units

    All  point coordinates within  an outline  are stored  in 32-bit
    fractional  pixel  values, using  the  26.6  fixed float  format
    (which uses  26 bits for  the integer part,  and 6 bits  for the
    fractional part).   The following  table gives some  examples of
    real versus 26.6 coordinates:

    -----------------------------------------
      real        real coord     26.6 coord
     coord.         * 2^6
    ----------------------------------------- 
         0       0*64 =    0.0         0
       2.4     2.4*64 =  153.6       154
         3       3*64 =  192.0       192
      -1.7    -1.7*64 = -108.8      -109

   As you  can see, conversion  is relatively simple --  basically a
   multiplication by 64.

   In order  to differentiate coordinates expressed in  real or 26.6
   systems, we'll use in the  following lines brackets (`[' and `]')
   for real  coordinates, and simple  parentheses (`(' and  `)') for
   fractional coordinates so that

                   [1.0,2.5] equals (64,160)

                       [0,0] equals (0,0)

                      [-2,3] equals (-128,192)


  2. Orientation

    The  rasterizer uses  the traditional  convention of  an  X axis
    oriented  from left  to right,  and of  a Y  axis  oriented from
    bottom to top.

         ^ Y
         |
         |
         |
        -*-----> X
         |

    You've probably already used it at school when doing math :-)
    
    Though  the  orientation  of   bitmap  lines  has  the  opposite
    direction on nearly all  graphics systems, the former convention
    is the _right_ one when it comes to vector graphics.  The reason
    is  simply that  for managing  angles and  vector cross-products
    resp. orientations  in complex algorithms,  a single convention,
    used in math as well as computing alike solves many headaches.
    
    And due to  education, most people expect a  45 degrees angle to
    be in the top right quadrant, at coordinate (1,1).


  3. Pixels and the grid

    In a  vector outline, a point  is immaterial and has  no size or
    width, just like in usual  geometry.  A `pixel' is an element of
    a computer image called a `map' (like a bitmap or a pixmap).

    The FreeType  rasterizer follows  the convention defined  by the
    TrueType specification regarding pixel placement:

    - The map  can be seen as  a `grid' placed in  the vector plane.
      The grid lines  are set on integer real  coordinates (i.e., on
      multiples of 64 in 26.6 fractional notation).

      Each pixel  is one `cell' of  the grid, and can  be `lit' with
      any  color.  Hence, each  pixel has  a width  and a  height of
      [1.0] units, (i.e., 64 fixed float units).

                     ^ Y
                     |
                     |                      The pixel grid with two
                     |                      points (not pixels!)
         +-----+-----+-----+-----+-----+    at coordinates [0,0]
         |     |     |     |     |     |    and [2,2].
         |     |     |     |     |     |
         |     |     |     |     |[2,2]|
         +-----+-----+-----+-----@-----+    The pixels are the
         |     |     |11111|22222|     |    grid's cells, and this
         |     |     |11111|22222|     |    example show the four
         |     |     |11111|22222|     |    pixels enclosed within
         +-----+-----+-----+-----+-----+    the rectangle delimited
         |     |     |33333|44444|     |    by these two points.
         |     |     |33333|44444|     |
         |     |     |33333|44444|     |
       --+-----+-----@-----+-----+-----+----> X
         |     |     |[0,0]|     |     |
         |     |     |     |     |     |    Note that the numbering
         |     |     |     |     |     |    of pixels isn't
         +-----+-----+-----+-----+-----+    meaningful here, it's
         |     |     |     |     |     |    only used to distinguish
         |     |     |     |     |     |    them.
         |     |     |     |     |     |
         +-----+-----+-----+-----+-----+
                     |
                     |

    - The   `center'  of  each   pixel  is   always  located   on  a
      `half-integer' coordinate, i.e., at -1.5, -0.5, 0.5, 1.5, etc.

    - When drawing a shape, the  rasterizer only `lits' a pixel when
      its center  is placed _within_  the shape.  This  is important
      because an outline  point may not be necessarily  be on a grid
      line.

    - When a pixel center falls on the shape, the pixel is lit too.

      For  example, the  following  graphics show  the `lit'  pixels
      corresponding to the rectangle enclosed by the points:

             [-0.2, 0] and [2.4, 2.7]


                     ^ Y                        As one can see, the
                     |                          newest pixels `1'
                     |                          and `2' are now lit,
                     |                          because its centers
         +-----+-----+-----+-----+--[2.4,2.7]   are located at
         |     |     |11111|22222| @   |        coordinates
         |  .  |  .  |11.11|22.22|  .  |        [0.5,2.5] and
         |     |     |11111|22222|     |        [1.5,2.5],
         +-----+-----+-----+-----+-----+        respectively.
         |     |     |33333|44444|     |
         |  .  |  .  |33.33|44.44|  .  |        Note that pixel
         |     |     |33333|44444|     |        centers are
         +-----+-----+-----+-----+-----+        represented with a
         |     |     |55555|66666|     |        dot in the graphics.
         |  .  |  .  |55.55|66.66|  .  |
         |     |     |55555|66666|     |
       --+-----+----@+-----+-----+-----+----> X
         |     | [-0.2,0]  |     |     |
         |  .  |  .  |  .  |  .  |  .  |
         |     |     |     |     |     |        Note also that pixel
         +-----+-----+-----+-----+-----+        numbering is still
         |     |     |     |     |     |        meaningless there.
         |  .  |  .  |  .  |  .  |  .  |
         |     |     |     |     |     |
         +-----+-----+-----+-----+-----+
                     |
                     |


  4. Drop-out control

    Sometimes, a stroke  is too thin to even  contain a single pixel
    center.   This results  in  `lost continuity'  in the  resulting
    bitmap,  i.e.,  some  unpleasant  `holes'  or  `breaks'  in  the
    rendered shape, which are called a `drop-out'.

    Because a  glyph representation uses curves  (Bezier arcs), this
    case is  not easily controllable  during the `hinting'  of glyph
    outlines  by the font  driver, which  means that  the rasterizer
    must be able to correct these `artefacts'.

    This  processing  is  called  `drop-out  control',  and  can  be
    performed   in   several   modes,   defined  by   the   TrueType
    specification, and which details do not belong to this document.
    However, the  important idea is  that, in _some_ cases,  a pixel
    may be lit even if its center isn't part of the shape.

    This case  is relatively rare,  but is mentioned because  it has
    consequences of  the rendering of maps.  More  precisely, in the
    way an outline's extent is computed (see below).


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


II. Bitmap and pixmap descriptors
---------------------------------

  The Freetype  rasterizer only supports bitmaps  and 8-bit pixmaps.
  In order  to render an outline,  a map descriptor must  be sent to
  its rendering functions, along with a vectorial outline.


  1. Bitmap properties

    This section explains how to set up a bitmap descriptor, and how
    vector  coordinates  in  the   outline  plane  relate  to  pixel
    positions within the bitmap buffer.

    A bitmap's `raw data' is made  of a simple bit buffer where each
    bit  corresponds  to  a  monochrome  pixel.   For  the  sake  of
    simplicity,   the  FreeType   rasterizer   uses  the   following
    conventions to store bitmaps in a buffer:

    - The  value   0  is  used  for  `unlit'   pixels,  usually  the
      `background' when rendering text.  Hence 1 is used for `lit'.

    - Lines are  padded to  8 bits, i.e.  bytes.  A bitmap  row thus
      takes an integral  number of bytes in its  buffer.  No further
      alignment is required.

      (Some systems  compress bitmaps by  _not_ padding bit  rows to
      byte boundaries.   It is  not possible to  render into  such a
      bitmap buffer with FreeType.)

    - In a bitmap buffer byte, the left-most pixel is represented by
      the most significant bit (i.e., 0x80).
      
      The  opposite  convention is  not  supported  by the  FreeType
      rasterizer, though it may  possibly be implemented too if this
      ever comes useful (ask the developers -- for now, nobody did).

    - Increasing  offsets  within  a  row correspond  to  right-most
      positions   in  the   bitmap  (i.e.,   byte  1   contains  the
      8 bits/pixels   that  are   located  on   the  right   of  the
      8 bits/pixels of byte 0).

    - A bitmap can be oriented in two ways:

      o If increasing row  addresses within the buffer correspond to
        lower vertical lines, the bitmap is said to go `down'.  This
        is, for example, the case of nearly all video RAMs.

      o If increasing row  addresses within the buffer correspond to
        higher vertical lines, the bitmap  is said to go `up'.  This
        is the case, for example, for OS/2 bitmaps.

      The  `direction' of  a bitmap  is called  `flow' to  avoid any
      confusion.  In  both cases, the rasterizer  ALWAYS matches the
      vector  coordinate (0,0)  with  the lower-left  corner of  the
      *lower-left* pixel in the bitmap.

      The following graphics illustrate these ideas:



         Y ^
           |                                  A `down-flow' bitmap.
           +--+--+--+--+--+--+--+--+          On the left is each
           |  |  |  |  |  |  |  |  |          row's number and its
  0:  0    |  |  |  |  |  |  |  |  |          offset in the bitmap
           +--+--+--+--+--+--+--+--+          buffer (where `w' is
           |  |  |  |  |  |  |  |  |          the width, in bytes,
  1:  w    |  |  |  |  |  |  |  |  |          of a single bitmap
           +--+--+--+--+--+--+--+--+          row).  Note that the
           |  |  |  |  |  |  |  |  |          origin is located at
  2:  2*w  |  |  |  |  |  |  |  |  |          the lower left, i.e.,
           +--+--+--+--+--+--+--+--+          near the leftmost bit
           |  |  |  |  |  |  |  |  |          of the last bitmap
  3:  3*w  |  |  |  |  |  |  |  |  |          row.
          -@--+--+--+--+--+--+--+-----> X
           |[0,0]                          
      


         Y ^
           |                                  An `up-flow' bitmap.
           +--+--+--+--+--+--+--+--+          On the left is each
           |  |  |  |  |  |  |  |  |          row's number and its
  3:  3*w  |  |  |  |  |  |  |  |  |          offset in the bitmap
           +--+--+--+--+--+--+--+--+          buffer (where `w' is
           |  |  |  |  |  |  |  |  |          the width, in bytes,
  2:  2*w  |  |  |  |  |  |  |  |  |          of a single bitmap
           +--+--+--+--+--+--+--+--+          row).  Note that the
           |  |  |  |  |  |  |  |  |          origin is located at
  1:  w    |  |  |  |  |  |  |  |  |          the lower left, i.e.,
           +--+--+--+--+--+--+--+--+          near the first bit in
           |  |  |  |  |  |  |  |  |          the buffer.
  0:  0    |  |  |  |  |  |  |  |  |          The first buffer bit
          -@--+--+--+--+--+--+--+-----> X     corresponds to the
           |[0,0]                             rectangle [0,0]-[1,1]
                                              in the vector plane.

      
  2. Bitmap descriptors

    Now  that you  understand all  these  details, a  bitmap can  be
    described  to  the  rasterizer   engine  through  a  map,  which
    structure must be set up by client application:

      struct  TT_Raster_Map_
      {
        int    rows;    /* number of rows                    */
        int    cols;    /* number of columns (bytes) per row */
        int    width;   /* number of pixels per line         */
        int    flow;    /* bitmap orientation                */
    
        void*  bitmap;  /* bit/pixmap buffer                 */
        long   size;    /* bit/pixmap size in bytes          */
      };
      typedef struct TT_Raster_Map_  TT_Raster_Map;

    where the fields stand for:

      rows:
        The number of rows within the bitmap buffer.

      cols:
        The  number  of columns,  i.e.   bytes  per  row within  the
        buffer.  It corresponds  to the `w' value used  in the above
        graphics.

      width:
        The number of pixels (i.e. bits) per row in the buffer.  The
        rasterizer  always  clips its  rendering  to  the bit  width
        specified  in   this  field,  even  if   the  `cols'  fields
        corresponds to a larger width.

      flow:
        The   bitmap  flow.   Use   the  constants   TT_Flow_Up  and
        TT_Flow_Down exclusively for this field.

      bitmap:
        A typeless pointer to the bit buffer.

      size:
        The total size of the bit buffer in bytes.  This is not used
        directly by the rasterizer, so applications can use it.

    Note  that the  `cols' field  should always  be bigger  than the
    value  of `width'  multiplied by  8.  The  rasterizer  clips the
    generated bitmap to the `width' first bits in a row.

    Note also that it is of course allowed to create, for example, a
    Windows or X11 bitmap through a normal system-specific API call,
    using a  TT_Raster_Map that describes it to  the rasterizer.  It
    is  thus  possible  to  draw  directly  into  such  OS  specific
    structures.


    IMPORTANT: *****************************************************

    When rendering  a bitmap, the rasterizer always  OR-es the shape
    on  the target  bitmap.  It  is  thus possible  to draw  several
    shapes  into a  single  surface which  successive  calls to  the
    render functions.

    ****************************************************************


  3. Pixmap properties

    The rasterizer  only supports 8-bit pixmaps, where  one pixel is
    represented  by  a  single  byte.   They  must  conform  to  the
    following rules:

    - A 5-entries palette is used to generate an outline's pixmap in
      the buffer.  They correspond to:

          palette[0]  -> background
          palette[1]  -> `light'
          palette[2]  -> `medium'
          palette[3]  -> `dark'
          palette[4]  -> foreground

      where the  terms `light',  `medium', and `dark'  correspond to
      intermediate  values between the  first (background)  and last
      (foreground) entry.

      The   upcoming  FreeType  2.0   will  feature   an  additional
      anti-aliasing logic with a 17-entries palette.

    - Lines are padded to 32 bits,  i.e. 4 bytes.  A pixmap row thus
      takes a multiple of 4 bytes in its buffer.

    - Increasing  offsets  within  a  row correspond  to  right-most
      positions in the bitmap (i.e., byte/pixel 1 is to the right of
      byte/pixel 0).

    - A pixmap can be oriented in two ways, following the same rules
      as a bitmap regarding its flow.


    IMPORTANT: *****************************************************

    In order  to improve  performance when rendering  large outlines
    with  anti-aliasing,  the rasterizer  draws  pixels  in runs  of
    4-bytes  ONLY  when at  least  one  of  their `colour'  isn't  0
    (background).

    This means that you should ALWAYS CLEAR the pixmap buffer before
    calling  the rendering  function, you  may  otherwise experience
    ugly  artefacts,  which  are   possibly  left  from  a  previous
    rendering!

    In general, it is not possible to do colour compositing with the
    FreeType rasterizer  (compositing is if you want  to superpose a
    transparent coloured layer on top  of an image).  This is mainly
    due to the fact that:

    - There are too many pixel formats to support.

    - There is not a single portable way to do it anyway.

    - It  really is  a graphics  processing question,  not  one that
      should be solved by a text rendering engine.

    ****************************************************************


  4. Pixmap descriptors

    Pixmaps use the same descriptor structure as bitmaps, with a few
    differences in interpretation:

    - The `cols' field is used  to indicate the number of _bytes_ in
      a pixmap row.  It must thus be a multiple of 4!

    - The  rasterizer  clips  the   outline  to  the  first  `width'
      pixels/width within each buffer row.

    As usual, it should be  possible to use a system-specific pixmap
    and render directly into it, as  long as you set up a descriptor
    for it.


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


III. Rendering an outline
-------------------------

  Now that you understand how the rasterizer sees the target bitmaps
  and  pixmaps it  renders to,  this  section will  explain how  the
  rendering eventually happen.


  1. Outline coordinates and extents

    Let's  first  consider  the  case  where  we're  rendering  text
    directly  into a  huge single  bitmap.   To do  that, we  simply
    translate  each  glyph outline  before  calling the  rasterizer.
    Here the roadmap:

    - Vectorial  coordinates  [0,0] are  mapped  to  the lower  left
      `corner' (in the  grid) of the lower left  pixel in the bitmap
      (whatever its flow is).

    - When the glyph loader returns an outline, the latter is placed
      so that the coordinate [0,0] corresponds to the current cursor
      position.

    This means that:

    - If we use our own cursor (cx,cy) within the bitmap during text
      rendering,  we  must translate  the  outline  to its  position
      before rendering it, e.g. with
      
        TT_Translate_Outline( outline, cx, cy )

      (and the  cursor position must be  incremented after rendering
       each glyph).

    - Before  translation (i.e., when  it is  returned by  the glyph
      loader), the  glyph outline doesn't necessarily lie  on any of
      the coordinate axes,  nor is it limited to  the first quadrant
      (i.e., x>0 and y>0 is not true in general).

      Its    extent   can    be   computed    with    the   function
      TT_Get_Outline_BBox(), which  returns the minimum  and maximum
      values of  its X and Y  point coordinates (in  26.6 format, of
      course).


  2. Computing an outline's dimensions in pixels

    In many cases,  however, it is much better  to render individual
    glyph bitmaps, then cache them with appropriate metrics in order
    to render text much more quickly at a given point size.

    To be  able to  render the smallest  possible bitmap,  the exact
    outline's  extent dimensions  in  pixel are  required.  Again  a
    roadmap:

    - Get the outline's bounding box in vector coordinates:

      Simply  call  the  TT_Get_Outline_BBox() function  which  will
      return  the values  of xMin,  yMin, xMax,  and yMax  in vector
      (i.e. fractional) coordinates.

    - Grid-fit the bounding box:

      Because of the  way pixels are lit in  the bitmaps relative to
      the  position  of  their   `centers'  within  the  shape  (see
      section I), it is necessary to align the values of xMin, xMax,
      yMin, and yMax to the pixel grid in order to compute the width
      and height of the resulting bitmap.  This can be done with:

        xMin = FLOOR  ( xMin );   with FLOOR(x)   == (x & -64)
        xMax = CEILING( xMax );        CEILING(x) == ((x+63) & -64)
        yMin = FLOOR  ( yMin );
        yMax = CEILING( yMax );

      The extents in pixels can then be simply computed as:

        pixel_width  = (xMax - xMin) / 64;
        pixel_height = (yMax - yMin) / 64;

      Note  that  because  of  drop-out  control,  and  because  the
      bounding  box computed currently  includes all  Bezier control
      points  from the outline,  the bitmap  may be  slightly larger
      than necessary in some cases.

      Some improvements  are planned for FreeType 2.0;  for now, you
      should consider  that finding the `exact'  bitmap bounding box
      requires to scan all `borders' to detect null columns or rows.
      However, the values are right in most cases.

      NOTE: It seems  that in  some  *rare*  cases, which  relate to
            weird drop-out control  situations, the above dimensions
            are not enough to store all bits from the outline (there
            are one or more bits `cut' on the edge).

            This being hard to study (it only appears in very poorly
            hinted fonts), we leave this problem to FreeType 2.0.

    - Create/setup  a bitmap  with the  computed  dimensions.  DON'T
      FORGET TO CLEAR ITS BUFFER TOO!

    - Translate the outline to  stick within the bitmap space.  This
      is done  easily by translating it by  (-xMin,-yMin), where you
      should ALWAYS  USE THE  GRID-FITTED VALUES computed  above for
      xMin and yMin:

          TT_Translate_Outline( outline, -xMin, -yMin );


      IMPORTANT: ***************************************************

      For  technical reasons,  you should  never translate  a HINTED
      outline  by  a  non-integer   vector  (i.e.,  a  vector  which
      coordinates  aren't multiples  of 64)!   This  would CERTAINLY
      completely RUIN  the delicate HINTING  of the glyph,  and will
      result probably in pure GARBAGE at small point sizes.

      Of  course, if  you're not  interested in  hinting,  like when
      displaying  rotated  text,  you   can  ignore  this  rule  and
      translate to any position freely.

      **************************************************************

    - Render the bitmap (or pixmap).

      DON'T FORGET TO  STORE THE GRID-FITTED xMin and  yMin WITH THE
      BITMAP!   This will  allow  you later  to  place it  correctly
      relative to your cursor position.


    Here's some example pseudo code:

      {
        ... load the glyph ...

        TT_Outline     outline;
        TT_BBox        bbox;
        TT_Raster_Map  bitmap;


        /* get the outline */
        TT_Get_Glyph_Outline( glyph, &outline );

        /* compute its extent */
        TT_Get_Outline_BBox( &outline, &bbox );

        /* Grid-fit it */
        bbox.xMin &= -64;
        bbox.xMax  = ( bbox.xMax + 63 ) & -64;
        bbox.yMin &= -64;
        bbox.yMax  = ( bbox.yMax + 63 ) & -64;

        /* compute pixel dimensions */
        width  = (bbox.xMax - bbox.xMin) / 64;
        height = (bbox.yMax - bbox.yMin) / 64;

        /* set up bitmap */
        bitmap.rows   = height;
        bitmap.width  = width;
        bitmap.cols   = (width + 7) / 8;
        bitmap.size   = bitmap.rows * bitmap.cols;
        bitmap.bitmap = malloc( bitmap.size );
        if ( !bitmap.bitmap )
          return error_memory...

        /* clear the bitmap buffer! */
        memset( bitmap.bitmap, 0, bitmap.size );

        /* translate outline */
        TT_Translate_Outline( &outline, -bbox.xMin, -bbox.yMin );

        /* render it within the bitmap */
        TT_Get_Outline_Bitmap( engine, &outline, &bitmap );
            
        /* We're done; don't forget to save bbox.xMin and */
        /* bbox.yMin to adjust the bitmap position when   */
        /* rendering text with it                         */

         ...
       }


  3. The case of transformed/rotated glyphs:

    You may want to apply  a transformation other than a translation
    to your  glyph outlines before  rendering them.  For  example, a
    simple slant to synthesize italics, or a slight rotation.

    In all cases, it is possible to render individual glyph bitmaps.
    Just  make  sure to  follow  the  same  process AFTER  you  have
    transformed you outline!

    DON'T FORGET  THAT YOU  NEED TO RE-COMPUTE  THE BBOX TO  GET THE
    CORRECT PIXEL DIMENSIONS AFTER A TRANSFORMATION.


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


IV. Anti-aliasing palette and other concerns

  When  rendering  pixmaps,  using  the  TT_Get_Outline_Pixmap()  or
  TT_Get_Glyph_Pixmap() functions,  the rasterizer uses  a 5-entries
  palette of 8-bit deep `colors'.

  By default, this palette is set to  ( 0, 1, 2, 3, 4 ), but one can
  change it to suit your needs with TT_Set_Raster_Palette().

  While  in bitmap mode,  it simply  OR-es the  pixel values  to the
  target  bitmap that  has been  passed  to TT_Get_Outline_Bitmap().

  For  pixmaps  it  simply   writes  directly  the  palette  entries
  corresponding to the `color' of  the `lit' pixels it has computed.
  This means  that it  is NOT  POSSIBLE to render  text in  a single
  pixmap with multiple  calls to TT_Get_Outline_Pixmaps() within the
  same target!

  The reason is that `gray'  pixels of two distinct outlines are not
  `added' when they overlap (the operation called 'compositing'), as
  it could be expected by applications.

  The  following  graphic  shows  this  effect  when  rendering  two
  overlapping anti-aliased shapes:


                ***                              ***
               .**                              .**
               **        **.               **.  **
              .*.         .*..              .*..*.
             .*.    +        .*.   =    --->  ..*.
            .*.                **      |     .*. **
            **                         |     **
           **.                         |    **.
          ***                          |   ***
                                       |

                                    missing black pixel after second
                                    rendering...


  There  is  no simple  way  to  perform  a composition  within  the
  rasterizer.   This would not  be portable;  moreover, it  would be
  extremely slow if it is  too general.  This operation is thus left
  to client applications which can use their own system-specific API
  for  transparently blitting the  glyph pixmaps  into a  surface to
  form text.

  NOTE:

  If your  system doesn't  support transparent/alpha blits,  you can
  still have  a look  at the source  file `freetype/test/display.c'.
  It uses a large pixmap, with a special palette trick to render all
  text  quickly,  then  convert  everything  to  `real'  colors  for
  display.


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


Conclusion
----------

  We've  seen  how  the  FreeType rasterizer  sees  bitmaps  through
  descriptors,  as well  as  the mapping  which  exists between  the
  vector coordinate space and the pixel position space.

  You should now be able to render outlines into bitmaps and pixmaps
  while  applying  transformations  like translation,  slanting,  or
  rotation.  Don't forget a few rules, however:

  - Always clear  the bitmap/pixmap buffer  before rendering (unless
    you want to render several glyphs in a single _bitmap_; it won't
    work on a pixmap).

  - A pixmap `cols' field, i.e. the size in bytes of each rows, must
    be a multiple of 4.

  - Never translate a hinted outline  by a non-integer vector if you
    want to preserve the  hints (i.e., the vector's coordinates must
    be multiples of 64).

  - Finally,  don't expect the  rasterizer to  composite transparent
    `grays'  for you  in  a single  target  pixmap through  multiple
    calls.


--- end of bitmaps.txt ---