Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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