modules/freetype2/docs/raster.txt

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial