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