home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / ft-beta.zip / freetype / docs / raster.doc < prev    next >
Text File  |  1997-10-06  |  23KB  |  591 lines

  1. This  file is an attempt at explaining the internals of the FreeType
  2. rasterizer.  This  component  is  quite  general  purpose  and could
  3. easily be  integrated into  other  programs  (but  still  under  the
  4. current license).
  5.  
  6. --------------------------------------------------------------------
  7.  
  8.               HOWs and WHYs of the FreeType rasterizer
  9.  
  10.                           by David Turner
  11.  
  12.  
  13.   I. Introduction
  14.  
  15.  II. Rendering Technology
  16.  
  17. III. Implementation Details
  18.  
  19.  IV. Gray-Level Support
  20.  
  21.  
  22.  
  23. I. Introduction:
  24.  
  25.   A rasterizer is  a  library  in  charge  of converting a vectorial
  26.   representation of a shape into a bitmap.  The FreeType  rasterizer
  27.   has  been  developed to render the glyphs found in TrueType files,
  28.   made up  of  segments  and  second-order  Beziers.   This document
  29.   is an explanation of its design and implementation.
  30.  
  31.   Though these explanations start  from  the  basics, a knowledge of
  32.   common rasterization techniques is assumed.
  33.  
  34.  
  35. II. Rendering Technology:
  36.  
  37.  1. Requirements:
  38.  
  39.   We will  assume that  all  scaling/rotating/hinting/wathever  have
  40.   been already done. The glyph is thus described, as in the TrueType
  41.   spec, by a list  of points. Each point has an  x and y coordinate,
  42.   as well as a flag that indicates wether the point is _on_ or _off_
  43.   the curve.
  44.   
  45.   More precisely:
  46.  
  47.    - All  point  coordinates  are  in the 26.6 fixed float format as
  48.      defined by the specification. The orientation used is:
  49.  
  50.        ^ y
  51.        |         reference orientation
  52.        |
  53.        *----> x
  54.      0
  55.  
  56.      This means that the  'distance' between two neighbouring pixels
  57.      is 64 pixel 'units' (1 unit = 1/64th of a pixel).
  58.  
  59.      Note that, for the rasterizer, pixel  centers  are  located  at
  60.      integer coordinates, i.e.  (0.0, 0.0) is  the coordinate of the
  61.      origin's  center   (unlike  what  happens   with  the  TrueType
  62.      bytecode interpreter).
  63.  
  64.      A pixel line in the target bitmap is called a 'scanline'.
  65.  
  66.  
  67.    - A  glyph  is  usually  made  of  several  contours, also called
  68.      outlines.  A contour is simply a closed curve that delimits  an
  69.      outer  or  inner  region  of  the  glyph.  It is described by a
  70.      series of successive points of the points table.
  71.  
  72.      Each point of the glyph  has  an associated flag that indicates
  73.      whether it is "on" or "off"  the  curve.  Two  successive  "on"
  74.      points indicate a line segment joining the two points.
  75.  
  76.      One  "off"  point  amidst  two "on" points indicates one second
  77.      degree  Bezier parametric  arc, defined  by these  three points
  78.      (the "off" point being the control point, and the "on" ones the
  79.      start and end points).
  80.      
  81.      Finally, two successive "off"  points  forces the rasterizer to
  82.      create, during  rendering, an  "on" point amidst them, at their
  83.      exact  middle.   This  greatly facilitates   the  definition of
  84.      successive Bezier arcs.
  85.  
  86.                                         *            # on
  87.                                                      * off
  88.                                      __---__
  89.         #-__                      _--       -_
  90.             --__                _-            -
  91.                 --__           #               \ 
  92.                     --__                        #
  93.                         -#
  94.                                  Two "on" points
  95.          Two "on" points       and one "off" point
  96.                                   between them
  97.  
  98.                       *
  99.         #            __      Two "on" points with two "off"
  100.          \          -  -     points between them. The point
  101.           \        /    \    marked '0' is the middle of the
  102.            -      0      \   "off" points, and is a 'virtual'
  103.             -_  _-       #   "on" point where the curve passes.
  104.               --             It does not appear in the point
  105.               *              list.
  106.  
  107.  
  108.      The FreeType rasterizer, as intended to render TrueType glyphs,
  109.      does not support third order  Beziers,  usually found in Type 1
  110.      fonts. Type 1 support may lead to further development of the
  111.      engine.
  112.  
  113.      The parametric form of a second-order Bezier is :
  114.  
  115.         P(t) = (1-t)^2*P1 + 2*t*(1-t)*P2 + t^2*P3
  116.  
  117.            with t a real number in the range [0..1]
  118.  
  119.      P1 and P3 are the endpoints, P2 the control point.
  120.  
  121.      Note  that  the  rasterizer  does  not  use  this  formula.  It
  122.      exhibits,  however,  one very  useful property  of Bezier arcs:
  123.      each point of  the curve is  a weighted average of  the control
  124.      points.
  125.  
  126.      As all weights are positive  and  always sum to 1, whatever the
  127.      value of t, each arc point lies within the triangle defined  by
  128.      the arc's three control points.
  129.  
  130.  
  131.  
  132.   2. Profiles and Spans:
  133.  
  134.  
  135.    The  following  is  a  basic  explanation  of   the   _kind_   of
  136.    computations  made  by  the  rasterizer  to build a bitmap from a
  137.    vector representation.  Note  that  the  actual implementation is
  138.    slightly different, due to performance tuning and other  factors.
  139.  
  140.    However, the following ideas remain in the same category, and are
  141.    more convenient to understand.
  142.  
  143.  
  144.    a. Sweeping the shape:
  145.  
  146.      The  best way to  fill a shape is to decompose it into a number
  147.      of simple horizontal segments, then turn  them on in the target
  148.      bitmap.   These  segments  are  called  'spans'.
  149.  
  150.                 __---__
  151.              _--       -_
  152.            _-            -
  153.           -               \
  154.          /                 \
  155.         /                   \
  156.        |                     \
  157.  
  158.                 __---__         Example: filling a shape
  159.              _----------_                with spans.
  160.            _--------------
  161.           ----------------\ 
  162.          /-----------------\    This is typically done from the top
  163.         /                   \   to the bottom of the shape, in a
  164.        |           |         \  movement called the "sweep".
  165.                    V
  166.  
  167.                 __---__
  168.              _----------_
  169.            _--------------
  170.           ----------------\ 
  171.          /-----------------\
  172.         /-------------------\
  173.        |---------------------\
  174.                     
  175.      
  176.      In  order  to  draw  a  span,  the  rasterizer must compute its
  177.      coordinates,   which   are   simply   the   shape's   contours'
  178.      x-coordinates taken on the y scanlines.
  179.  
  180.  
  181.              /---/    |---|   Note that there are usually several
  182.             /---/     |---|   spans per scanline.
  183.   |        /---/      |---|
  184.   |       /---/_______|---|  When rendering this shape to the current
  185.   V      /----------------|      scanline y, we must compute the x of
  186.         /-----------------|      points a, b, c and d.
  187.      a /----|         |---| 
  188. - - - *     * - - - - *   * - - y -   
  189.      /     / b       c|   |d      
  190.  
  191.  
  192.              /---/    |---|   
  193.             /---/     |---|  And then turn on the spans a-b and c-d. 
  194.            /---/      |---|
  195.           /---/_______|---|  
  196.          /----------------|  
  197.         /-----------------|  
  198.      a /----|         |---| 
  199. - - - ####### - - - - ##### - - y -
  200.      /     / b       c|   |d       
  201.  
  202.  
  203.  
  204.    b. Decomposing outlines into profiles:
  205.  
  206.  
  207.      For each scanline during  the  sweep,  we  need  the  following
  208.      information:
  209.  
  210.          the number of spans on the current scanline, given  by  the
  211.          number  of  shape  points intersecting  the scanline (these
  212.          are the points a, b, c, and d in the above example).
  213.  
  214.          the x coordinates of these points
  215.  
  216.      These  are  computed  before  the  sweep,  in  a  phase  called
  217.      'decomposition' which converts the glyph into *profiles*.
  218.  
  219.      Put it simply, a "profile" is a contour's portion that can only
  220.      be either ascending or descending, i.e. it is monotonous in the
  221.      vertical direction (we will also say Y-monotonous). There is no
  222.      such thing as a horizontal profile, as we shall see.
  223.  
  224.      Here are a few examples:
  225.  
  226.  
  227.      this square
  228.                                        1         2
  229.       ---->----     is made of two
  230.      |         |                       |         |
  231.      |         |       profiles        |         |
  232.      ^         v                       ^    +    v
  233.      |         |                       |         |
  234.      |         |                       |         |
  235.       ----<----
  236.  
  237.                                      up         down
  238.  
  239.     this triangle
  240.  
  241.          P2                             1          2
  242.  
  243.          |\        is made of two       |         \
  244.       ^  | \  \                         |          \
  245.       | |   \  \      profiles         |            \      |
  246.      |  |    \  v                  ^   |             \     |
  247.        |      \                    |  |         +     \    v
  248.        |       \                   |  |                \
  249.     P1 ---___   \                     ---___            \
  250.              ---_\                          ---_         \
  251.          <--__     P3                   up           down
  252.  
  253.  
  254.  
  255.      A more general contour can be made of more than
  256.                       two profiles :
  257.  
  258.         __     ^
  259.        /  |   /  ___          /    |
  260.       /   |     /   |        /     |       /     |
  261.      |    |    /   /    =>  |      v      /     /
  262.      |    |   |   |         |      |     ^     |
  263.   ^  |    |___|   |  |      ^   +  |  +  |  +  v
  264.   |  |           |   v      |                 |
  265.      |           |          |           up    |
  266.      |___________|          |    down         |
  267.  
  268.           <--               up              down
  269.  
  270.  
  271.      Successive  profiles  are always joined by horizontal segments,
  272.      that  are  not  part  of  the  profiles  themselves.
  273.      
  274.      Note that for the  rasterizer,  a  profile is simply an _array_
  275.      that associates  one  horizontal  *pixel*  coordinate  to  each
  276.      bitmap  *scanline*  crossed by the contour's section containing
  277.      the profile.  Note also that profiles are *oriented* up or down
  278.      along the glyph's original flow orientation.
  279.  
  280.      In other graphics libraries,  profiles  are also called 'edges'
  281.      or 'edgelists'.
  282.  
  283.  
  284.   c. The Render Pool:
  285.  
  286.  
  287.      FreeType has been designed  to  be  able  to run well on _very_
  288.      light systems, including embedded systems with very few memory.
  289.      As a consequence, the rasterizer does not rely on a  user  heap
  290.      accessible  through  malloc  and  free.   Rather,  it takes, as
  291.      initialisation arguments,  the  address  and  size  of a memory
  292.      block that must be allocated by the client application (or font
  293.      server) called the "Render Pool".
  294.  
  295.      The  rasterizer  uses  the  render  pool  for  all its needs by
  296.      managing memory directly in  it.   The algorithms that are used
  297.      for profile computation make it possible to use the pool  as  a
  298.      simple growing heap.  This means that this memory management is
  299.      actually  easy,  and  faster   than  any  kind  of  malloc/free
  300.      combination.
  301.      
  302.      Moreover, we'll see later that the  rasterizer  is  able,  when
  303.      dealing with profiles too large and numerous to lie all at once
  304.      in  the  render  pool, to immediately decompose recursively the
  305.      rendering process in  independent  sub-tasks,  each taking less
  306.      memory to be performed (see "sub-banding" below).
  307.  
  308.      The  render pool, which is allocated by the client application,
  309.      must be freed by  it.   The  rasterizer  has thus absolutely no
  310.      knowledge of the memory  manager  used  by  the  system  it  is
  311.      running on.
  312.  
  313.      And  finally, the render pool doesn't need to be large.  A 4 Kb
  314.      pool  is  enough  for nearly all renditions, though nearly 100%
  315.      slower than a  more  confortable  16  or  32  Kb pool (that was
  316.      tested with complex glyphs at sizes over 500 pixels).
  317.  
  318.  
  319.   d. Computing Profiles Extents:
  320.  
  321.      
  322.      Remember that a  profile  is  an  array,  that  associates to a
  323.      _scanline_  the  x  pixel coordinate of its intersection with a
  324.      contour.
  325.  
  326.      Though it's not exactly  how  the  FreeType  rasterizer  works,
  327.      it is convenient  to  think  that  we  need  a profile's height
  328.      before allocating it in the pool and computing its coordinates.
  329.  
  330.      The profile's height is the  number of scanlines crossed by the
  331.      Y-monotonous section of  a  contour.   We  thus need to compute
  332.      these sections from the vectorial description.  In order to  do
  333.      that,  we  are  obliged  to  compute  all  (local  and  global)
  334.      Y-extrema of the glyph (minima and maxima).
  335.  
  336.      
  337.          P2             For instance, this triangle has only
  338.                         two Y-extrema, which are simply
  339.          |\       
  340.          | \               P2.y  as an Y-maximum
  341.         |   \              P3.y  as an Y-minimum
  342.         |    \    
  343.        |      \            P1.y is not an Y-extremum (though it is
  344.        |       \           a X-minimum, which we don't need).
  345.     P1 ---___   \    
  346.              ---_\      
  347.                    P3   
  348.  
  349.      Note that the extrema are expressed  in  pixel  units,  not  in
  350.      scanlines.   The  triangle's  height is certainly (P3.y-P2.y+1)
  351.      pixel  units,  but  its  profiles'  heights  are  computed   in
  352.      scanlines.   The  exact  conversion  is simply :                
  353.  
  354.           - min scanline = FLOOR  ( min y )
  355.           - max scanline = CEILING( max y )
  356.  
  357.      A problem arises with Bezier  Arcs.   While a segment is always
  358.      necessarily Y-monotonous (i.e.  flat, ascending or descending),
  359.      which  makes extrema  computations  easy, the ascent of  a  arc
  360.      can vary between its control points.
  361.  
  362.                           P2
  363.                          *
  364.                                    # on
  365.                                    * off
  366.                    __-x--_
  367.                 _--       -_
  368.           P1  _-            -       A non Y-monotonous Bezier arc.
  369.              #               \ 
  370.                               -        The arc goes from P1 to P3
  371.                                \
  372.                                 \  P3
  373.                                  #
  374.  
  375.      We first need to be able to easily detect non-monotonous  arcs,
  376.      according to their  control points.  I will state here, without
  377.      proof, that the monotony condition can be expressed as:
  378.  
  379.        P1.y <= P2.y <= P3.y   for an ever-ascending arc
  380.  
  381.        P1.y >= P2.y >= P3.y   for an ever_descending arc
  382.  
  383.      with the special case of
  384.  
  385.        P1.y = P2.y = P3.y     where the arc is said to be 'flat'.
  386.  
  387.      As you can see,  these  conditions  can  be very easily tested.
  388.      They are, however, extremely important, as any  arc  that  does
  389.      not satisfies them necessarily contains an extremum.
  390.  
  391.      Note also that a  monotonous  arc  can contain an extremum too,
  392.      which is then one of its 'on' points:
  393.  
  394.         P1           P2
  395.           #---__   *         P1P2P3 if ever-descending, but P1
  396.                 -_           is an Y-extremum.
  397.                   -
  398.            ---_    \
  399.                ->   \
  400.                      \  P3
  401.                       #
  402.  
  403.  
  404.      Let's go back to our previous example:
  405.  
  406.                           P2
  407.                          *
  408.                                    # on
  409.                                    * off
  410.                    __-x--_
  411.                 _--       -_
  412.           P1  _-            -       A non Y-montonous Bezier arc.
  413.              #               \ 
  414.                               -        here we have
  415.                                \              P2.y >= P1.y &&
  416.                                 \  P3         P2.y >= P3.y      (!)
  417.                                  #
  418.  
  419.      We  need  to  compute  the  y-maximum of this arc to be able to
  420.      compute  a  profile's  height (the point  marked  by  an  'x').
  421.      The arc's  equation  indicates  that  a  direct  computation is
  422.      possible, but only if  we  care  about  performing at least one
  423.      square  root  extraction,  with  sufficient   accuracy.    This
  424.      computation being  much too  slow for us, we use an alternative
  425.      method that will become very handy in the following chapters:
  426.  
  427.      Bezier arcs have a magnificent property of  being  very  easily
  428.      decomposed  into  two  other  sub-arcs,  which  are  themselves
  429.      Beziers.  Moreover, it is easy  to  prove that there is at most
  430.      one Y-extremum on each Bezier arc (for second degree ones).
  431.  
  432.      For instance, the following arc  P1P2P3 can be decomposed into
  433.      two sub-arcs Q1Q2Q3 and R1R2R3 that look like:
  434.  
  435.                     P2
  436.                    *
  437.                                # on  curve
  438.                                * off curve
  439.  
  440.  
  441.                                     Original Bezier Arc P1P2P3
  442.                 __---__
  443.              _--       --_
  444.            _-             -_
  445.           -                 -
  446.          /                   \
  447.         /                     \
  448.        #                       #
  449.      P1                         P3
  450.                     P2
  451.                    * 
  452.  
  453.  
  454.  
  455.                    Q3               Decomposed into two subarcs
  456.           Q2                R2
  457.             *   __-#-__   *           Q1Q2Q3 and R1R2R3 with
  458.              _--       --_
  459.            _-       R1    -_       Q1 = P1          R3 = P3
  460.           -                 -      Q2 = (P1+P2)/2   R2 = (P2+P3)/2
  461.          /                   \                 
  462.         /                     \        Q3 = R1 = (Q2+R2)/2
  463.        #                       #
  464.      Q1                         R3    Note that Q2, R2 and Q3=R1 are
  465.                                       on  a  single  line  which  is
  466.                                       tangent to the curve.
  467.  
  468.     We have  then  decomposed  a  non-Y-monotonous  bezier  into two
  469.     smaller  sub-arcs. Note that in the above drawing, both sub-arcs
  470.     are monotonous, and that the extremum is then  Q3=R1.   However,
  471.     in  a  more  general  case, only one sub-arc is guaranteed to be
  472.     monotonous. Getting back to our former example:
  473.  
  474.                     Q2    
  475.                    *                   
  476.                                           
  477.                    __-x--_ R1
  478.                 _--       #_
  479.           Q1  _-        Q3  -   R2  
  480.              #               \ *
  481.                               -     
  482.                                \    
  483.                                 \  R3
  484.                                  #
  485.  
  486.  
  487.     Here, we see that, though Q1Q2Q3 is still non-monotonous, R1R2R3
  488.     is ever descending: we  thus  know  that  it doesn't contain the
  489.     extremum.  We can then re-subdivide Q1Q2Q3  into  two  sub-arcs,
  490.     and go on recursively, stopping when we encounter two monotonous
  491.     subarcs, or when the subarcs become simply too small.
  492.  
  493.     We  will  finally find the y-extremum.  Note that the iterative
  494.     process of finding an extremum is called 'flattening'.
  495.     
  496.  
  497.   e. Computing Profiles coordinates:
  498.  
  499.     Once we have the height of  each profile, we're able to allocate
  500.     it  in  the  render pool.  We now have to compute its coordinate
  501.     for each scanline.
  502.  
  503.     In the case of segments, the computation is straightforward, and
  504.     uses  good  old  Euclide (also known as Bresenham ;-).  However,
  505.     for Bezier arcs, things get a little more complicated.
  506.  
  507.     We  assume  that  all Beziers that are part of a profile are the
  508.     result of 'flattening' the  curve,  which means that they're all
  509.     y-monotonous  (ascending  or  descending, and never  flat).   We
  510.     now  have  to compute the arcs' intersections with the profile's
  511.     scanlines.  One way is to  use a similar scheme to 'flattening',
  512.     called 'stepping'.
  513.  
  514.                                  Consider this arc, going from P1 to
  515.       --------------------       P3. Suppose that we need to compute
  516.                                  its  intersections with  the  drawn
  517.                                  scanlines.  Again, this is feasible
  518.       ---------------------      directly, if  we  dare  compute one
  519.                                  square   root  per   scanline  (how
  520.           * P2         _---# P3  great!). 
  521.       ------------- _--  --
  522.                   _-
  523.                 _/               Rather, it is still possible to use
  524.       ---------/-----------      the  decomposition property in  the
  525.               /                  same recursive way,  i.e. subdivise
  526.              |                   the  arc into  subarcs until  these
  527.       ------|--------------      get  too small  to cross more  than 
  528.             |                    one scanline!
  529.            |                     
  530.       -----|---------------      This  is  very easily  done using a
  531.           |                      rasterizer-managed stack of subarcs
  532.           |                      
  533.           # P1
  534.  
  535.  
  536.   f. Sweeping and Sorting the spans:
  537.  
  538.     Once all our profiles have been  computed,  we  begin  the sweep
  539.     to build (and fill) the spans.
  540.  
  541.     As  the  TrueType  specs uses the winding fill rule, we place on
  542.     each scanline the profiles present in two separate lists.
  543.  
  544.     One  list,  called  the  'left' one,  only  contains ascending
  545.     profiles, while the other 'right' list contains  the  descending
  546.     profiles.
  547.  
  548.     As  each  glyph  is  made  of  closed curves, a simple geometric
  549.     property is that the two  lists  necessarily contain the same number
  550.     of elements.
  551.  
  552.     Creating  spans  is there straightforward :
  553.     
  554.     1. We sort each list in increasing X order
  555.  
  556.     2. We pair each value of the left list, with its corresponding
  557.        value in the right one.
  558.     
  559.  
  560.              /     /  |   |        For exemple, we have here four
  561.             /     /   |   |        profiles. Two of them are ascending
  562.           >/     /    |   |  |     (1 & 3), while the two others are    
  563.         1//     /   ^ |   |  | 2   descending (2 & 4)  
  564.         //     //  3| |   |  v           
  565.         /     //4   | |   |          On the given scanline, the left   
  566.      a /     /<       |   |          list is (1,3) and the right one
  567. - - - *-----* - - - - *---* - - y -  is (4,2) (sorted).
  568.      /     / b       c|   |d               
  569.                                   There are then two spans, joining
  570.                                   1 to 4 (i.e. a-b) and 3 to 2 
  571.                                   (i.e. c-d) !
  572.  
  573.     Sorting doesn't necessarily take much time, as in 99  cases  out
  574.     of 100, the lists's order is kept from one scanline to the next.
  575.     We  can  thus  implement it with two simple singly-linked lists,
  576.     sorted by a classic bubble-sort, which takes a minimum amount of
  577.     time when the lists are already sorted.
  578.  
  579.     A  previous  version  of  the  rasterizer  used  more  elaborate
  580.     structures, like arrays to perform 'faster' sorting.  It  turned
  581.     up  that this scheme was far more faster, and clearly not faster
  582.     than the one described above, which is currently implemented.
  583.  
  584.     Once the spans have been  'created',  we can simply draw them in
  585.     the target bitmap.
  586.  
  587.  
  588.   g. Drop-out control :
  589.  
  590.  
  591.