2
How FreeType's rasterizer work
9
This file is an attempt to explain the internals of the FreeType
10
rasterizer. The rasterizer is of quite general purpose and could
11
easily be integrated into other programs.
16
II. Rendering Technology
20
b. Decomposing Outlines into Profiles
22
d. Computing Profiles Extents
23
e. Computing Profiles Coordinates
24
f. Sweeping and Sorting the Spans
30
A rasterizer is a library in charge of converting a vectorial
31
representation of a shape into a bitmap. The FreeType rasterizer
32
has been originally developed to render the glyphs found in
33
TrueType files, made up of segments and second-order B�ziers.
34
Meanwhile it has been extended to render third-order B�zier curves
35
also. This document is an explanation of its design and
38
While these explanations start from the basics, a knowledge of
39
common rasterization techniques is assumed.
42
II. Rendering Technology
43
========================
48
We assume that all scaling, rotating, hinting, etc., has been
49
already done. The glyph is thus described by a list of points in
52
- All point coordinates are in the 26.6 fixed float format. The
57
| reference orientation
63
`26.6' means that 26 bits are used for the integer part of a
64
value and 6 bits are used for the fractional part.
65
Consequently, the `distance' between two neighbouring pixels is
66
64 `units' (1 unit = 1/64th of a pixel).
68
Note that, for the rasterizer, pixel centers are located at
69
integer coordinates. The TrueType bytecode interpreter,
70
however, assumes that the lower left edge of a pixel (which is
71
taken to be a square with a length of 1 unit) has integer
78
+-----------+ +-----+-----+
84
o-----------+-----> x +-----------+
87
TrueType bytecode interpreter FreeType rasterizer
90
A pixel line in the target bitmap is called a `scanline'.
92
- A glyph is usually made of several contours, also called
93
`outlines'. A contour is simply a closed curve that delimits an
94
outer or inner region of the glyph. It is described by a series
95
of successive points of the points table.
97
Each point of the glyph has an associated flag that indicates
98
whether it is `on' or `off' the curve. Two successive `on'
99
points indicate a line segment joining the two points.
101
One `off' point amidst two `on' points indicates a second-degree
102
(conic) B�zier parametric arc, defined by these three points
103
(the `off' point being the control point, and the `on' ones the
104
start and end points). Similarly, a third-degree (cubic) B�zier
105
curve is described by four points (two `off' control points
106
between two `on' points).
108
Finally, for second-order curves only, two successive `off'
109
points forces the rasterizer to create, during rendering, an
110
`on' point amidst them, at their exact middle. This greatly
111
facilitates the definition of successive B�zier arcs.
113
The parametric form of a second-order B�zier curve is:
115
P(t) = (1-t)^2*P1 + 2*t*(1-t)*P2 + t^2*P3
117
(P1 and P3 are the end points, P2 the control point.)
119
The parametric form of a third-order B�zier curve is:
121
P(t) = (1-t)^3*P1 + 3*t*(1-t)^2*P2 + 3*t^2*(1-t)*P3 + t^3*P4
123
(P1 and P4 are the end points, P2 and P3 the control points.)
125
For both formulae, t is a real number in the range [0..1].
127
Note that the rasterizer does not use these formulae directly.
128
They exhibit, however, one very useful property of B�zier arcs:
129
Each point of the curve is a weighted average of the control
132
As all weights are positive and always sum up to 1, whatever the
133
value of t, each arc point lies within the triangle (polygon)
134
defined by the arc's three (four) control points.
136
In the following, only second-order curves are discussed since
137
rasterization of third-order curves is completely identical.
139
Here some samples for second-order curves.
151
Two `on' points and one `off' point
155
# __ Two `on' points with two `off'
156
\ - - points between them. The point
157
\ / \ marked `0' is the middle of the
158
- 0 \ `off' points, and is a `virtual
159
-_ _- # on' point where the curve passes.
160
-- It does not appear in the point
164
2. Profiles and Spans
165
---------------------
167
The following is a basic explanation of the _kind_ of computations
168
made by the rasterizer to build a bitmap from a vector
169
representation. Note that the actual implementation is slightly
170
different, due to performance tuning and other factors.
172
However, the following ideas remain in the same category, and are
173
more convenient to understand.
176
a. Sweeping the Shape
178
The best way to fill a shape is to decompose it into a number of
179
simple horizontal segments, then turn them on in the target
180
bitmap. These segments are called `spans'.
190
__---__ Example: filling a shape
191
_----------_ with spans.
194
/-----------------\ This is typically done from the top
195
/ \ to the bottom of the shape, in a
196
| | \ movement called a `sweep'.
204
/-------------------\
205
|---------------------\
208
In order to draw a span, the rasterizer must compute its
209
coordinates, which are simply the x coordinates of the shape's
210
contours, taken on the y scanlines.
213
/---/ |---| Note that there are usually
214
/---/ |---| several spans per scanline.
216
| /---/_______|---| When rendering this shape to the
217
V /----------------| current scanline y, we must
218
/-----------------| compute the x values of the
219
a /----| |---| points a, b, c, and d.
220
- - - * * - - - - * * - - y -
225
/---/ |---| And then turn on the spans a-b
231
- - - ####### - - - - ##### - - y -
235
b. Decomposing Outlines into Profiles
237
For each scanline during the sweep, we need the following
240
o The number of spans on the current scanline, given by the
241
number of shape points intersecting the scanline (these are
242
the points a, b, c, and d in the above example).
244
o The x coordinates of these points.
246
x coordinates are computed before the sweep, in a phase called
247
`decomposition' which converts the glyph into *profiles*.
249
Put it simply, a `profile' is a contour's portion that can only
250
be either ascending or descending, i.e., it is monotonic in the
251
vertical direction (we also say y-monotonic). There is no such
252
thing as a horizontal profile, as we shall see.
254
Here are a few examples:
259
---->---- is made of two
274
|\ is made of two | \
276
| | \ \ profiles | \ |
286
A more general contour can be made of more than two profiles:
293
^ | |___| | | ^ + | + | + v
296
|___________| | down |
301
Successive profiles are always joined by horizontal segments
302
that are not part of the profiles themselves.
304
For the rasterizer, a profile is simply an *array* that
305
associates one horizontal *pixel* coordinate to each bitmap
306
*scanline* crossed by the contour's section containing the
307
profile. Note that profiles are *oriented* up or down along the
308
glyph's original flow orientation.
310
In other graphics libraries, profiles are also called `edges' or
316
FreeType has been designed to be able to run well on _very_
317
light systems, including embedded systems with very few memory.
319
A render pool will be allocated once; the rasterizer uses this
320
pool for all its needs by managing this memory directly in it.
321
The algorithms that are used for profile computation make it
322
possible to use the pool as a simple growing heap. This means
323
that this memory management is actually quite easy and faster
324
than any kind of malloc()/free() combination.
326
Moreover, we'll see later that the rasterizer is able, when
327
dealing with profiles too large and numerous to lie all at once
328
in the render pool, to immediately decompose recursively the
329
rendering process into independent sub-tasks, each taking less
330
memory to be performed (see `sub-banding' below).
332
The render pool doesn't need to be large. A 4KByte pool is
333
enough for nearly all renditions, though nearly 100% slower than
334
a more confortable 16KByte or 32KByte pool (that was tested with
335
complex glyphs at sizes over 500 pixels).
338
d. Computing Profiles Extents
340
Remember that a profile is an array, associating a _scanline_ to
341
the x pixel coordinate of its intersection with a contour.
343
Though it's not exactly how the FreeType rasterizer works, it is
344
convenient to think that we need a profile's height before
345
allocating it in the pool and computing its coordinates.
347
The profile's height is the number of scanlines crossed by the
348
y-monotonic section of a contour. We thus need to compute these
349
sections from the vectorial description. In order to do that,
350
we are obliged to compute all (local and global) y extrema of
351
the glyph (minima and maxima).
354
P2 For instance, this triangle has only
355
two y-extrema, which are simply
357
| \ P2.y as a vertical maximum
358
| \ P3.y as a vertical minimum
360
| \ P1.y is not a vertical extremum (though
361
| \ it is a horizontal minimum, which we
362
P1 ---___ \ don't need).
367
Note that the extrema are expressed in pixel units, not in
368
scanlines. The triangle's height is certainly (P3.y-P2.y+1)
369
pixel units, but its profiles' heights are computed in
370
scanlines. The exact conversion is simple:
372
- min scanline = FLOOR ( min y )
373
- max scanline = CEILING( max y )
375
A problem arises with B�zier Arcs. While a segment is always
376
necessarily y-monotonic (i.e., flat, ascending, or descending),
377
which makes extrema computations easy, the ascent of an arc can
378
vary between its control points.
387
P1 _- - A non y-monotonic B�zier arc.
389
- The arc goes from P1 to P3.
395
We first need to be able to easily detect non-monotonic arcs,
396
according to their control points. I will state here, without
397
proof, that the monotony condition can be expressed as:
399
P1.y <= P2.y <= P3.y for an ever-ascending arc
401
P1.y >= P2.y >= P3.y for an ever-descending arc
403
with the special case of
405
P1.y = P2.y = P3.y where the arc is said to be `flat'.
407
As you can see, these conditions can be very easily tested.
408
They are, however, extremely important, as any arc that does not
409
satisfy them necessarily contains an extremum.
411
Note also that a monotonic arc can contain an extremum too,
412
which is then one of its `on' points:
416
#---__ * P1P2P3 is ever-descending, but P1
425
Let's go back to our previous example:
434
P1 _- - A non-y-monotonic B�zier arc.
438
\ P3 P2.y >= P3.y (!)
442
We need to compute the vertical maximum of this arc to be able
443
to compute a profile's height (the point marked by an `x'). The
444
arc's equation indicates that a direct computation is possible,
445
but we rely on a different technique, which use will become
448
B�zier arcs have the special property of being very easily
449
decomposed into two sub-arcs, which are themselves B�zier arcs.
450
Moreover, it is easy to prove that there is at most one vertical
451
extremum on each B�zier arc (for second-degree curves; similar
452
conditions can be found for third-order arcs).
454
For instance, the following arc P1P2P3 can be decomposed into
455
two sub-arcs Q1Q2Q3 and R1R2R3:
464
original B�zier arc P1P2P3.
481
Q3 Decomposed into two subarcs
482
Q2 R2 Q1Q2Q3 and R1R2R3
485
_- R1 -_ Q1 = P1 R3 = P3
486
- - Q2 = (P1+P2)/2 R2 = (P2+P3)/2
488
/ \ Q3 = R1 = (Q2+R2)/2
490
Q1 R3 Note that Q2, R2, and Q3=R1
491
are on a single line which is
492
tangent to the curve.
495
We have then decomposed a non-y-monotonic B�zier curve into two
496
smaller sub-arcs. Note that in the above drawing, both sub-arcs
497
are monotonic, and that the extremum is then Q3=R1. However, in
498
a more general case, only one sub-arc is guaranteed to be
499
monotonic. Getting back to our former example:
515
Here, we see that, though Q1Q2Q3 is still non-monotonic, R1R2R3
516
is ever descending: We thus know that it doesn't contain the
517
extremum. We can then re-subdivide Q1Q2Q3 into two sub-arcs and
518
go on recursively, stopping when we encounter two monotonic
519
subarcs, or when the subarcs become simply too small.
521
We will finally find the vertical extremum. Note that the
522
iterative process of finding an extremum is called `flattening'.
525
e. Computing Profiles Coordinates
527
Once we have the height of each profile, we are able to allocate
528
it in the render pool. The next task is to compute coordinates
531
In the case of segments, the computation is straightforward,
532
using the Euclidian algorithm (also known as Bresenham).
533
However, for B�zier arcs, the job is a little more complicated.
535
We assume that all B�ziers that are part of a profile are the
536
result of flattening the curve, which means that they are all
537
y-monotonic (ascending or descending, and never flat). We now
538
have to compute the intersections of arcs with the profile's
539
scanlines. One way is to use a similar scheme to flattening
543
Consider this arc, going from P1 to
544
--------------------- P3. Suppose that we need to
545
compute its intersections with the
546
drawn scanlines. As already
547
--------------------- mentioned this can be done
548
directly, but the involed algorithm
549
* P2 _---# P3 is far too slow.
552
_/ Instead, it is still possible to
553
---------/----------- use the decomposition property in
554
/ the same recursive way, i.e.,
555
| subdivide the arc into subarcs
556
------|-------------- until these get too small to cross
557
| more than one scanline!
559
-----|--------------- This is very easily done using a
560
| rasterizer-managed stack of
565
f. Sweeping and Sorting the Spans
567
Once all our profiles have been computed, we begin the sweep to
568
build (and fill) the spans.
570
As both the TrueType and Type 1 specifications use the winding
571
fill rule (but with opposite directions), we place, on each
572
scanline, the present profiles in two separate lists.
574
One list, called the `left' one, only contains ascending
575
profiles, while the other `right' list contains the descending
578
As each glyph is made of closed curves, a simple geometric
579
property ensures that the two lists contain the same number of
582
Creating spans is thus straightforward:
584
1. We sort each list in increasing horizontal order.
586
2. We pair each value of the left list with its corresponding
587
value in the right list.
590
/ / | | For example, we have here
591
/ / | | four profiles. Two of
592
>/ / | | | them are ascending (1 &
593
1// / ^ | | | 2 3), while the two others
594
// // 3| | | v are descending (2 & 4).
595
/ //4 | | | On the given scanline,
596
a / /< | | the left list is (1,3),
597
- - - *-----* - - - - *---* - - y - and the right one is
598
/ / b c| |d (4,2) (sorted).
600
There are then two spans, joining
601
1 to 4 (i.e. a-b) and 3 to 2
605
Sorting doesn't necessarily take much time, as in 99 cases out
606
of 100, the lists' order is kept from one scanline to the next.
607
We can thus implement it with two simple singly-linked lists,
608
sorted by a classic bubble-sort, which takes a minimum amount of
609
time when the lists are already sorted.
611
A previous version of the rasterizer used more elaborate
612
structures, like arrays to perform `faster' sorting. It turned
613
out that this old scheme is not faster than the one described
616
Once the spans have been `created', we can simply draw them in
620
--- end of raster.txt ---