~kalon33/corsix-th/master

« back to all changes in this revision

Viewing changes to agg/include/agg_scanline_boolean_algebra.h

  • Committer: corsixth.bot at gmail
  • Date: 2014-03-31 23:30:23 UTC
  • Revision ID: svn-v4:c39591fa-788f-11de-a72b-d90af8dea425:trunk:2687
Remove trailing whitespaces in .h, .cpp, .c and .lua files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
// Anti-Grain Geometry - Version 2.4
3
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4
4
//
5
 
// Permission to copy, use, modify, sell and distribute this software 
6
 
// is granted provided this copyright notice appears in all copies. 
 
5
// Permission to copy, use, modify, sell and distribute this software
 
6
// is granted provided this copyright notice appears in all copies.
7
7
// This software is provided "as is" without express or implied
8
8
// warranty, and with no claim as to its suitability for any purpose.
9
9
//
30
30
    // anti-aliasing information, but only X and Length. The function
31
31
    // is compatible with any type of scanlines.
32
32
    //----------------
33
 
    template<class Scanline1, 
34
 
             class Scanline2, 
35
 
             class Scanline> 
 
33
    template<class Scanline1,
 
34
             class Scanline2,
 
35
             class Scanline>
36
36
    struct sbool_combine_spans_bin
37
37
    {
38
 
        void operator () (const typename Scanline1::const_iterator&, 
39
 
                          const typename Scanline2::const_iterator&, 
40
 
                          int x, unsigned len, 
 
38
        void operator () (const typename Scanline1::const_iterator&,
 
39
                          const typename Scanline2::const_iterator&,
 
40
                          int x, unsigned len,
41
41
                          Scanline& sl) const
42
42
        {
43
43
            sl.add_span(x, len, cover_full);
51
51
    // Combine two spans as empty ones. The functor does nothing
52
52
    // and is used to XOR binary spans.
53
53
    //----------------
54
 
    template<class Scanline1, 
55
 
             class Scanline2, 
56
 
             class Scanline> 
 
54
    template<class Scanline1,
 
55
             class Scanline2,
 
56
             class Scanline>
57
57
    struct sbool_combine_spans_empty
58
58
    {
59
 
        void operator () (const typename Scanline1::const_iterator&, 
60
 
                          const typename Scanline2::const_iterator&, 
61
 
                          int, unsigned, 
 
59
        void operator () (const typename Scanline1::const_iterator&,
 
60
                          const typename Scanline2::const_iterator&,
 
61
                          int, unsigned,
62
62
                          Scanline&) const
63
63
        {}
64
64
    };
69
69
    // Functor.
70
70
    // Add nothing. Used in conbine_shapes_sub
71
71
    //----------------
72
 
    template<class Scanline1, 
73
 
             class Scanline> 
 
72
    template<class Scanline1,
 
73
             class Scanline>
74
74
    struct sbool_add_span_empty
75
75
    {
76
 
        void operator () (const typename Scanline1::const_iterator&, 
77
 
                          int, unsigned, 
 
76
        void operator () (const typename Scanline1::const_iterator&,
 
77
                          int, unsigned,
78
78
                          Scanline&) const
79
79
        {}
80
80
    };
84
84
    // Functor.
85
85
    // Add a binary span
86
86
    //----------------
87
 
    template<class Scanline1, 
88
 
             class Scanline> 
 
87
    template<class Scanline1,
 
88
             class Scanline>
89
89
    struct sbool_add_span_bin
90
90
    {
91
 
        void operator () (const typename Scanline1::const_iterator&, 
92
 
                          int x, unsigned len, 
 
91
        void operator () (const typename Scanline1::const_iterator&,
 
92
                          int x, unsigned len,
93
93
                          Scanline& sl) const
94
94
        {
95
95
            sl.add_span(x, len, cover_full);
96
96
        }
97
97
    };
98
98
 
99
 
    
 
99
 
100
100
 
101
101
 
102
102
    //-----------------------------------------------------sbool_add_span_aa
105
105
    // anti-aliasing information, but only X and Length. The function
106
106
    // is compatible with any type of scanlines.
107
107
    //----------------
108
 
    template<class Scanline1, 
109
 
             class Scanline> 
 
108
    template<class Scanline1,
 
109
             class Scanline>
110
110
    struct sbool_add_span_aa
111
111
    {
112
 
        void operator () (const typename Scanline1::const_iterator& span, 
113
 
                          int x, unsigned len, 
 
112
        void operator () (const typename Scanline1::const_iterator& span,
 
113
                          int x, unsigned len,
114
114
                          Scanline& sl) const
115
115
        {
116
116
            if(span->len < 0)
135
135
    // Intersect two spans preserving the anti-aliasing information.
136
136
    // The result is added to the "sl" scanline.
137
137
    //------------------
138
 
    template<class Scanline1, 
139
 
             class Scanline2, 
140
 
             class Scanline, 
141
 
             unsigned CoverShift = cover_shift> 
 
138
    template<class Scanline1,
 
139
             class Scanline2,
 
140
             class Scanline,
 
141
             unsigned CoverShift = cover_shift>
142
142
    struct sbool_intersect_spans_aa
143
143
    {
144
144
        enum cover_scale_e
148
148
            cover_mask  = cover_size - 1,
149
149
            cover_full  = cover_mask
150
150
        };
151
 
        
152
 
 
153
 
        void operator () (const typename Scanline1::const_iterator& span1, 
154
 
                          const typename Scanline2::const_iterator& span2, 
155
 
                          int x, unsigned len, 
 
151
 
 
152
 
 
153
        void operator () (const typename Scanline1::const_iterator& span1,
 
154
                          const typename Scanline2::const_iterator& span2,
 
155
                          int x, unsigned len,
156
156
                          Scanline& sl) const
157
157
        {
158
158
            unsigned cover;
159
159
            const typename Scanline1::cover_type* covers1;
160
160
            const typename Scanline2::cover_type* covers2;
161
161
 
162
 
            // Calculate the operation code and choose the 
 
162
            // Calculate the operation code and choose the
163
163
            // proper combination algorithm.
164
164
            // 0 = Both spans are of AA type
165
165
            // 1 = span1 is solid, span2 is AA
176
176
                do
177
177
                {
178
178
                    cover = *covers1++ * *covers2++;
179
 
                    sl.add_cell(x++, 
 
179
                    sl.add_cell(x++,
180
180
                                (cover == cover_full * cover_full) ?
181
 
                                cover_full : 
 
181
                                cover_full :
182
182
                                (cover >> cover_shift));
183
183
                }
184
184
                while(--len);
196
196
                    do
197
197
                    {
198
198
                        cover = *(span1->covers) * *covers2++;
199
 
                        sl.add_cell(x++, 
 
199
                        sl.add_cell(x++,
200
200
                                    (cover == cover_full * cover_full) ?
201
 
                                    cover_full : 
 
201
                                    cover_full :
202
202
                                    (cover >> cover_shift));
203
203
                    }
204
204
                    while(--len);
217
217
                    do
218
218
                    {
219
219
                        cover = *covers1++ * *(span2->covers);
220
 
                        sl.add_cell(x++, 
 
220
                        sl.add_cell(x++,
221
221
                                    (cover == cover_full * cover_full) ?
222
 
                                    cover_full : 
 
222
                                    cover_full :
223
223
                                    (cover >> cover_shift));
224
224
                    }
225
225
                    while(--len);
228
228
 
229
229
            case 3:      // Both are solid spans
230
230
                cover = *(span1->covers) * *(span2->covers);
231
 
                sl.add_span(x, len, 
 
231
                sl.add_span(x, len,
232
232
                            (cover == cover_full * cover_full) ?
233
 
                            cover_full : 
 
233
                            cover_full :
234
234
                            (cover >> cover_shift));
235
235
                break;
236
236
            }
247
247
    // Unite two spans preserving the anti-aliasing information.
248
248
    // The result is added to the "sl" scanline.
249
249
    //------------------
250
 
    template<class Scanline1, 
251
 
             class Scanline2, 
252
 
             class Scanline, 
253
 
             unsigned CoverShift = cover_shift> 
 
250
    template<class Scanline1,
 
251
             class Scanline2,
 
252
             class Scanline,
 
253
             unsigned CoverShift = cover_shift>
254
254
    struct sbool_unite_spans_aa
255
255
    {
256
256
        enum cover_scale_e
260
260
            cover_mask  = cover_size - 1,
261
261
            cover_full  = cover_mask
262
262
        };
263
 
        
264
 
 
265
 
        void operator () (const typename Scanline1::const_iterator& span1, 
266
 
                          const typename Scanline2::const_iterator& span2, 
267
 
                          int x, unsigned len, 
 
263
 
 
264
 
 
265
        void operator () (const typename Scanline1::const_iterator& span1,
 
266
                          const typename Scanline2::const_iterator& span2,
 
267
                          int x, unsigned len,
268
268
                          Scanline& sl) const
269
269
        {
270
270
            unsigned cover;
271
271
            const typename Scanline1::cover_type* covers1;
272
272
            const typename Scanline2::cover_type* covers2;
273
273
 
274
 
            // Calculate the operation code and choose the 
 
274
            // Calculate the operation code and choose the
275
275
            // proper combination algorithm.
276
276
            // 0 = Both spans are of AA type
277
277
            // 1 = span1 is solid, span2 is AA
287
287
                if(span2->x < x) covers2 += x - span2->x;
288
288
                do
289
289
                {
290
 
                    cover = cover_mask * cover_mask - 
291
 
                                (cover_mask - *covers1++) * 
 
290
                    cover = cover_mask * cover_mask -
 
291
                                (cover_mask - *covers1++) *
292
292
                                (cover_mask - *covers2++);
293
 
                    sl.add_cell(x++, 
 
293
                    sl.add_cell(x++,
294
294
                                (cover == cover_full * cover_full) ?
295
 
                                cover_full : 
 
295
                                cover_full :
296
296
                                (cover >> cover_shift));
297
297
                }
298
298
                while(--len);
309
309
                {
310
310
                    do
311
311
                    {
312
 
                        cover = cover_mask * cover_mask - 
313
 
                                    (cover_mask - *(span1->covers)) * 
 
312
                        cover = cover_mask * cover_mask -
 
313
                                    (cover_mask - *(span1->covers)) *
314
314
                                    (cover_mask - *covers2++);
315
 
                        sl.add_cell(x++, 
 
315
                        sl.add_cell(x++,
316
316
                                    (cover == cover_full * cover_full) ?
317
 
                                    cover_full : 
 
317
                                    cover_full :
318
318
                                    (cover >> cover_shift));
319
319
                    }
320
320
                    while(--len);
332
332
                {
333
333
                    do
334
334
                    {
335
 
                        cover = cover_mask * cover_mask - 
336
 
                                    (cover_mask - *covers1++) * 
 
335
                        cover = cover_mask * cover_mask -
 
336
                                    (cover_mask - *covers1++) *
337
337
                                    (cover_mask - *(span2->covers));
338
 
                        sl.add_cell(x++, 
 
338
                        sl.add_cell(x++,
339
339
                                    (cover == cover_full * cover_full) ?
340
 
                                    cover_full : 
 
340
                                    cover_full :
341
341
                                    (cover >> cover_shift));
342
342
                    }
343
343
                    while(--len);
345
345
                break;
346
346
 
347
347
            case 3:      // Both are solid spans
348
 
                cover = cover_mask * cover_mask - 
349
 
                            (cover_mask - *(span1->covers)) * 
 
348
                cover = cover_mask * cover_mask -
 
349
                            (cover_mask - *(span1->covers)) *
350
350
                            (cover_mask - *(span2->covers));
351
 
                sl.add_span(x, len, 
 
351
                sl.add_span(x, len,
352
352
                            (cover == cover_full * cover_full) ?
353
 
                            cover_full : 
 
353
                            cover_full :
354
354
                            (cover >> cover_shift));
355
355
                break;
356
356
            }
359
359
 
360
360
 
361
361
    //---------------------------------------------sbool_xor_formula_linear
362
 
    template<unsigned CoverShift = cover_shift> 
 
362
    template<unsigned CoverShift = cover_shift>
363
363
    struct sbool_xor_formula_linear
364
364
    {
365
365
        enum cover_scale_e
379
379
 
380
380
 
381
381
    //---------------------------------------------sbool_xor_formula_saddle
382
 
    template<unsigned CoverShift = cover_shift> 
 
382
    template<unsigned CoverShift = cover_shift>
383
383
    struct sbool_xor_formula_saddle
384
384
    {
385
385
        enum cover_scale_e
417
417
    // XOR two spans preserving the anti-aliasing information.
418
418
    // The result is added to the "sl" scanline.
419
419
    //------------------
420
 
    template<class Scanline1, 
421
 
             class Scanline2, 
422
 
             class Scanline, 
 
420
    template<class Scanline1,
 
421
             class Scanline2,
 
422
             class Scanline,
423
423
             class XorFormula,
424
 
             unsigned CoverShift = cover_shift> 
 
424
             unsigned CoverShift = cover_shift>
425
425
    struct sbool_xor_spans_aa
426
426
    {
427
427
        enum cover_scale_e
431
431
            cover_mask  = cover_size - 1,
432
432
            cover_full  = cover_mask
433
433
        };
434
 
        
435
 
 
436
 
        void operator () (const typename Scanline1::const_iterator& span1, 
437
 
                          const typename Scanline2::const_iterator& span2, 
438
 
                          int x, unsigned len, 
 
434
 
 
435
 
 
436
        void operator () (const typename Scanline1::const_iterator& span1,
 
437
                          const typename Scanline2::const_iterator& span2,
 
438
                          int x, unsigned len,
439
439
                          Scanline& sl) const
440
440
        {
441
441
            unsigned cover;
442
442
            const typename Scanline1::cover_type* covers1;
443
443
            const typename Scanline2::cover_type* covers2;
444
444
 
445
 
            // Calculate the operation code and choose the 
 
445
            // Calculate the operation code and choose the
446
446
            // proper combination algorithm.
447
447
            // 0 = Both spans are of AA type
448
448
            // 1 = span1 is solid, span2 is AA
507
507
    // Unite two spans preserving the anti-aliasing information.
508
508
    // The result is added to the "sl" scanline.
509
509
    //------------------
510
 
    template<class Scanline1, 
511
 
             class Scanline2, 
512
 
             class Scanline, 
513
 
             unsigned CoverShift = cover_shift> 
 
510
    template<class Scanline1,
 
511
             class Scanline2,
 
512
             class Scanline,
 
513
             unsigned CoverShift = cover_shift>
514
514
    struct sbool_subtract_spans_aa
515
515
    {
516
516
        enum cover_scale_e
520
520
            cover_mask  = cover_size - 1,
521
521
            cover_full  = cover_mask
522
522
        };
523
 
        
524
 
 
525
 
        void operator () (const typename Scanline1::const_iterator& span1, 
526
 
                          const typename Scanline2::const_iterator& span2, 
527
 
                          int x, unsigned len, 
 
523
 
 
524
 
 
525
        void operator () (const typename Scanline1::const_iterator& span1,
 
526
                          const typename Scanline2::const_iterator& span2,
 
527
                          int x, unsigned len,
528
528
                          Scanline& sl) const
529
529
        {
530
530
            unsigned cover;
531
531
            const typename Scanline1::cover_type* covers1;
532
532
            const typename Scanline2::cover_type* covers2;
533
533
 
534
 
            // Calculate the operation code and choose the 
 
534
            // Calculate the operation code and choose the
535
535
            // proper combination algorithm.
536
536
            // 0 = Both spans are of AA type
537
537
            // 1 = span1 is solid, span2 is AA
550
550
                    cover = *covers1++ * (cover_mask - *covers2++);
551
551
                    if(cover)
552
552
                    {
553
 
                        sl.add_cell(x, 
 
553
                        sl.add_cell(x,
554
554
                                    (cover == cover_full * cover_full) ?
555
 
                                    cover_full : 
 
555
                                    cover_full :
556
556
                                    (cover >> cover_shift));
557
557
                    }
558
558
                    ++x;
568
568
                    cover = *(span1->covers) * (cover_mask - *covers2++);
569
569
                    if(cover)
570
570
                    {
571
 
                        sl.add_cell(x, 
 
571
                        sl.add_cell(x,
572
572
                                    (cover == cover_full * cover_full) ?
573
 
                                    cover_full : 
 
573
                                    cover_full :
574
574
                                    (cover >> cover_shift));
575
575
                    }
576
576
                    ++x;
588
588
                        cover = *covers1++ * (cover_mask - *(span2->covers));
589
589
                        if(cover)
590
590
                        {
591
 
                            sl.add_cell(x, 
 
591
                            sl.add_cell(x,
592
592
                                        (cover == cover_full * cover_full) ?
593
 
                                        cover_full : 
 
593
                                        cover_full :
594
594
                                        (cover >> cover_shift));
595
595
                        }
596
596
                        ++x;
603
603
                cover = *(span1->covers) * (cover_mask - *(span2->covers));
604
604
                if(cover)
605
605
                {
606
 
                    sl.add_span(x, len, 
 
606
                    sl.add_span(x, len,
607
607
                                (cover == cover_full * cover_full) ?
608
 
                                cover_full : 
 
608
                                cover_full :
609
609
                                (cover >> cover_shift));
610
610
                }
611
611
                break;
619
619
 
620
620
 
621
621
    //--------------------------------------------sbool_add_spans_and_render
622
 
    template<class Scanline1, 
623
 
             class Scanline, 
624
 
             class Renderer, 
 
622
    template<class Scanline1,
 
623
             class Scanline,
 
624
             class Renderer,
625
625
             class AddSpanFunctor>
626
 
    void sbool_add_spans_and_render(const Scanline1& sl1, 
627
 
                                    Scanline& sl, 
628
 
                                    Renderer& ren, 
 
626
    void sbool_add_spans_and_render(const Scanline1& sl1,
 
627
                                    Scanline& sl,
 
628
                                    Renderer& ren,
629
629
                                    AddSpanFunctor add_span)
630
630
    {
631
631
        sl.reset_spans();
654
654
    // two spans without Anti-Aliasing, the second preserves the AA
655
655
    // information, but works slower
656
656
    //
657
 
    template<class Scanline1, 
658
 
             class Scanline2, 
659
 
             class Scanline, 
 
657
    template<class Scanline1,
 
658
             class Scanline2,
 
659
             class Scanline,
660
660
             class CombineSpansFunctor>
661
 
    void sbool_intersect_scanlines(const Scanline1& sl1, 
662
 
                                   const Scanline2& sl2, 
663
 
                                   Scanline& sl, 
 
661
    void sbool_intersect_scanlines(const Scanline1& sl1,
 
662
                                   const Scanline2& sl2,
 
663
                                   Scanline& sl,
664
664
                                   CombineSpansFunctor combine_spans)
665
665
    {
666
666
        sl.reset_spans();
683
683
 
684
684
            // Determine what spans we should advance in the next step
685
685
            // The span with the least ending X should be advanced
686
 
            // advance_both is just an optimization when we ending 
 
686
            // advance_both is just an optimization when we ending
687
687
            // coordinates are the same and we can advance both
688
688
            //--------------
689
689
            bool advance_span1 = xe1 <  xe2;
732
732
 
733
733
 
734
734
    //------------------------------------------------sbool_intersect_shapes
735
 
    // Intersect the scanline shapes. Here the "Scanline Generator" 
736
 
    // abstraction is used. ScanlineGen1 and ScanlineGen2 are 
 
735
    // Intersect the scanline shapes. Here the "Scanline Generator"
 
736
    // abstraction is used. ScanlineGen1 and ScanlineGen2 are
737
737
    // the generators, and can be of type rasterizer_scanline_aa<>.
738
738
    // There function requires three scanline containers that can be of
739
739
    // different types.
741
741
    // "sl" is ised as the resulting scanline to render it.
742
742
    // The external "sl1" and "sl2" are used only for the sake of
743
743
    // optimization and reusing of the scanline objects.
744
 
    // the function calls sbool_intersect_scanlines with CombineSpansFunctor 
 
744
    // the function calls sbool_intersect_scanlines with CombineSpansFunctor
745
745
    // as the last argument. See sbool_intersect_scanlines for details.
746
746
    //----------
747
 
    template<class ScanlineGen1, 
748
 
             class ScanlineGen2, 
749
 
             class Scanline1, 
750
 
             class Scanline2, 
751
 
             class Scanline, 
 
747
    template<class ScanlineGen1,
 
748
             class ScanlineGen2,
 
749
             class Scanline1,
 
750
             class Scanline2,
 
751
             class Scanline,
752
752
             class Renderer,
753
753
             class CombineSpansFunctor>
754
754
    void sbool_intersect_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2,
755
755
                                Scanline1& sl1, Scanline2& sl2,
756
 
                                Scanline& sl, Renderer& ren, 
 
756
                                Scanline& sl, Renderer& ren,
757
757
                                CombineSpansFunctor combine_spans)
758
758
    {
759
759
        // Prepare the scanline generators.
760
 
        // If anyone of them doesn't contain 
 
760
        // If anyone of them doesn't contain
761
761
        // any scanlines, then return.
762
762
        //-----------------
763
763
        if(!sg1.rewind_scanlines()) return;
768
768
        rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
769
769
        rect_i r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
770
770
 
771
 
        // Calculate the intersection of the bounding 
 
771
        // Calculate the intersection of the bounding
772
772
        // boxes and return if they don't intersect.
773
773
        //-----------------
774
774
        rect_i ir = intersect_rectangles(r1, r2);
785
785
        ren.prepare();
786
786
 
787
787
        // The main loop
788
 
        // Here we synchronize the scanlines with 
 
788
        // Here we synchronize the scanlines with
789
789
        // the same Y coordinate, ignoring all other ones.
790
 
        // Only scanlines having the same Y-coordinate 
 
790
        // Only scanlines having the same Y-coordinate
791
791
        // are to be combined.
792
792
        //-----------------
793
793
        for(;;)
832
832
    // two spans without Anti-Aliasing, the second preserves the AA
833
833
    // information, but works slower
834
834
    //
835
 
    template<class Scanline1, 
836
 
             class Scanline2, 
837
 
             class Scanline, 
 
835
    template<class Scanline1,
 
836
             class Scanline2,
 
837
             class Scanline,
838
838
             class AddSpanFunctor1,
839
839
             class AddSpanFunctor2,
840
840
             class CombineSpansFunctor>
841
 
    void sbool_unite_scanlines(const Scanline1& sl1, 
842
 
                               const Scanline2& sl2, 
843
 
                               Scanline& sl, 
 
841
    void sbool_unite_scanlines(const Scanline1& sl1,
 
842
                               const Scanline2& sl2,
 
843
                               Scanline& sl,
844
844
                               AddSpanFunctor1 add_span1,
845
845
                               AddSpanFunctor2 add_span2,
846
846
                               CombineSpansFunctor combine_spans)
853
853
        typename Scanline1::const_iterator span1;// = sl1.begin();
854
854
        typename Scanline2::const_iterator span2;// = sl2.begin();
855
855
 
856
 
        enum invalidation_e 
857
 
        { 
858
 
            invalid_b = 0xFFFFFFF, 
859
 
            invalid_e = invalid_b - 1 
 
856
        enum invalidation_e
 
857
        {
 
858
            invalid_b = 0xFFFFFFF,
 
859
            invalid_e = invalid_b - 1
860
860
        };
861
861
 
862
862
        // Initialize the spans as invalid
891
891
        {
892
892
            // Retrieve a new span1 if it's invalid
893
893
            //----------------
894
 
            if(num1 && xb1 > xe1) 
 
894
            if(num1 && xb1 > xe1)
895
895
            {
896
896
                --num1;
897
897
                ++span1;
901
901
 
902
902
            // Retrieve a new span2 if it's invalid
903
903
            //----------------
904
 
            if(num2 && xb2 > xe2) 
 
904
            if(num2 && xb2 > xe2)
905
905
            {
906
906
                --num2;
907
907
                ++span2;
947
947
                    // Invalidate span1 and eat
948
948
                    // the processed part of span2
949
949
                    //--------------
950
 
                    xb1 = invalid_b;    
 
950
                    xb1 = invalid_b;
951
951
                    xe1 = invalid_e;
952
952
                    xb2 += len;
953
953
                }
957
957
                    // Invalidate span2 and eat
958
958
                    // the processed part of span1
959
959
                    //--------------
960
 
                    xb2 = invalid_b;  
 
960
                    xb2 = invalid_b;
961
961
                    xe2 = invalid_e;
962
962
                    xb1 += len;
963
963
                }
973
973
            {
974
974
                // The spans do not intersect
975
975
                //--------------
976
 
                if(xb1 < xb2) 
 
976
                if(xb1 < xb2)
977
977
                {
978
978
                    // Advance span1
979
979
                    //---------------
1003
1003
 
1004
1004
 
1005
1005
    //----------------------------------------------------sbool_unite_shapes
1006
 
    // Unite the scanline shapes. Here the "Scanline Generator" 
1007
 
    // abstraction is used. ScanlineGen1 and ScanlineGen2 are 
 
1006
    // Unite the scanline shapes. Here the "Scanline Generator"
 
1007
    // abstraction is used. ScanlineGen1 and ScanlineGen2 are
1008
1008
    // the generators, and can be of type rasterizer_scanline_aa<>.
1009
 
    // There function requires three scanline containers that can be 
 
1009
    // There function requires three scanline containers that can be
1010
1010
    // of different type.
1011
1011
    // "sl1" and "sl2" are used to retrieve scanlines from the generators,
1012
1012
    // "sl" is ised as the resulting scanline to render it.
1013
1013
    // The external "sl1" and "sl2" are used only for the sake of
1014
1014
    // optimization and reusing of the scanline objects.
1015
 
    // the function calls sbool_unite_scanlines with CombineSpansFunctor 
 
1015
    // the function calls sbool_unite_scanlines with CombineSpansFunctor
1016
1016
    // as the last argument. See sbool_unite_scanlines for details.
1017
1017
    //----------
1018
 
    template<class ScanlineGen1, 
1019
 
             class ScanlineGen2, 
1020
 
             class Scanline1, 
1021
 
             class Scanline2, 
1022
 
             class Scanline, 
 
1018
    template<class ScanlineGen1,
 
1019
             class ScanlineGen2,
 
1020
             class Scanline1,
 
1021
             class Scanline2,
 
1022
             class Scanline,
1023
1023
             class Renderer,
1024
1024
             class AddSpanFunctor1,
1025
1025
             class AddSpanFunctor2,
1026
1026
             class CombineSpansFunctor>
1027
1027
    void sbool_unite_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2,
1028
1028
                            Scanline1& sl1, Scanline2& sl2,
1029
 
                            Scanline& sl, Renderer& ren, 
 
1029
                            Scanline& sl, Renderer& ren,
1030
1030
                            AddSpanFunctor1 add_span1,
1031
1031
                            AddSpanFunctor2 add_span2,
1032
1032
                            CombineSpansFunctor combine_spans)
1033
1033
    {
1034
1034
        // Prepare the scanline generators.
1035
 
        // If anyone of them doesn't contain 
 
1035
        // If anyone of them doesn't contain
1036
1036
        // any scanlines, then return.
1037
1037
        //-----------------
1038
1038
        bool flag1 = sg1.rewind_scanlines();
1058
1058
        // Reset the scanlines and get two first ones
1059
1059
        //-----------------
1060
1060
        sl.reset(ur.x1, ur.x2);
1061
 
        if(flag1) 
 
1061
        if(flag1)
1062
1062
        {
1063
1063
            sl1.reset(sg1.min_x(), sg1.max_x());
1064
1064
            flag1 = sg1.sweep_scanline(sl1);
1065
1065
        }
1066
1066
 
1067
 
        if(flag2) 
 
1067
        if(flag2)
1068
1068
        {
1069
1069
            sl2.reset(sg2.min_x(), sg2.max_x());
1070
1070
            flag2 = sg2.sweep_scanline(sl2);
1071
1071
        }
1072
1072
 
1073
1073
        // The main loop
1074
 
        // Here we synchronize the scanlines with 
 
1074
        // Here we synchronize the scanlines with
1075
1075
        // the same Y coordinate.
1076
1076
        //-----------------
1077
1077
        while(flag1 || flag2)
1084
1084
                    // Combine the scanlines, render if they contain any spans,
1085
1085
                    // and advance both generators to the next scanlines
1086
1086
                    //----------------------
1087
 
                    sbool_unite_scanlines(sl1, sl2, sl, 
 
1087
                    sbool_unite_scanlines(sl1, sl2, sl,
1088
1088
                                          add_span1, add_span2, combine_spans);
1089
1089
                    if(sl.num_spans())
1090
1090
                    {
1132
1132
 
1133
1133
 
1134
1134
    //-------------------------------------------------sbool_subtract_shapes
1135
 
    // Subtract the scanline shapes, "sg1-sg2". Here the "Scanline Generator" 
1136
 
    // abstraction is used. ScanlineGen1 and ScanlineGen2 are 
 
1135
    // Subtract the scanline shapes, "sg1-sg2". Here the "Scanline Generator"
 
1136
    // abstraction is used. ScanlineGen1 and ScanlineGen2 are
1137
1137
    // the generators, and can be of type rasterizer_scanline_aa<>.
1138
1138
    // There function requires three scanline containers that can be of
1139
1139
    // different types.
1141
1141
    // "sl" is ised as the resulting scanline to render it.
1142
1142
    // The external "sl1" and "sl2" are used only for the sake of
1143
1143
    // optimization and reusing of the scanline objects.
1144
 
    // the function calls sbool_intersect_scanlines with CombineSpansFunctor 
 
1144
    // the function calls sbool_intersect_scanlines with CombineSpansFunctor
1145
1145
    // as the last argument. See combine_scanlines_sub for details.
1146
1146
    //----------
1147
 
    template<class ScanlineGen1, 
1148
 
             class ScanlineGen2, 
1149
 
             class Scanline1, 
1150
 
             class Scanline2, 
1151
 
             class Scanline, 
 
1147
    template<class ScanlineGen1,
 
1148
             class ScanlineGen2,
 
1149
             class Scanline1,
 
1150
             class Scanline2,
 
1151
             class Scanline,
1152
1152
             class Renderer,
1153
1153
             class AddSpanFunctor1,
1154
1154
             class CombineSpansFunctor>
1155
1155
    void sbool_subtract_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2,
1156
1156
                               Scanline1& sl1, Scanline2& sl2,
1157
 
                               Scanline& sl, Renderer& ren, 
 
1157
                               Scanline& sl, Renderer& ren,
1158
1158
                               AddSpanFunctor1 add_span1,
1159
1159
                               CombineSpansFunctor combine_spans)
1160
1160
    {
1183
1183
        sbool_add_span_empty<Scanline2, Scanline> add_span2;
1184
1184
 
1185
1185
        // The main loop
1186
 
        // Here we synchronize the scanlines with 
 
1186
        // Here we synchronize the scanlines with
1187
1187
        // the same Y coordinate, ignoring all other ones.
1188
 
        // Only scanlines having the same Y-coordinate 
 
1188
        // Only scanlines having the same Y-coordinate
1189
1189
        // are to be combined.
1190
1190
        //-----------------
1191
1191
        bool flag1 = true;
1229
1229
 
1230
1230
 
1231
1231
    //---------------------------------------------sbool_intersect_shapes_aa
1232
 
    // Intersect two anti-aliased scanline shapes. 
1233
 
    // Here the "Scanline Generator" abstraction is used. 
1234
 
    // ScanlineGen1 and ScanlineGen2 are the generators, and can be of 
1235
 
    // type rasterizer_scanline_aa<>. There function requires three 
 
1232
    // Intersect two anti-aliased scanline shapes.
 
1233
    // Here the "Scanline Generator" abstraction is used.
 
1234
    // ScanlineGen1 and ScanlineGen2 are the generators, and can be of
 
1235
    // type rasterizer_scanline_aa<>. There function requires three
1236
1236
    // scanline containers that can be of different types.
1237
1237
    // "sl1" and "sl2" are used to retrieve scanlines from the generators,
1238
1238
    // "sl" is ised as the resulting scanline to render it.
1239
1239
    // The external "sl1" and "sl2" are used only for the sake of
1240
1240
    // optimization and reusing of the scanline objects.
1241
1241
    //----------
1242
 
    template<class ScanlineGen1, 
1243
 
             class ScanlineGen2, 
1244
 
             class Scanline1, 
1245
 
             class Scanline2, 
1246
 
             class Scanline, 
 
1242
    template<class ScanlineGen1,
 
1243
             class ScanlineGen2,
 
1244
             class Scanline1,
 
1245
             class Scanline2,
 
1246
             class Scanline,
1247
1247
             class Renderer>
1248
1248
    void sbool_intersect_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1249
1249
                                   Scanline1& sl1, Scanline2& sl2,
1258
1258
 
1259
1259
 
1260
1260
    //--------------------------------------------sbool_intersect_shapes_bin
1261
 
    // Intersect two binary scanline shapes (without anti-aliasing). 
 
1261
    // Intersect two binary scanline shapes (without anti-aliasing).
1262
1262
    // See intersect_shapes_aa for more comments
1263
1263
    //----------
1264
 
    template<class ScanlineGen1, 
1265
 
             class ScanlineGen2, 
1266
 
             class Scanline1, 
1267
 
             class Scanline2, 
1268
 
             class Scanline, 
 
1264
    template<class ScanlineGen1,
 
1265
             class ScanlineGen2,
 
1266
             class Scanline1,
 
1267
             class Scanline2,
 
1268
             class Scanline,
1269
1269
             class Renderer>
1270
1270
    void sbool_intersect_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
1271
1271
                                    Scanline1& sl1, Scanline2& sl2,
1280
1280
 
1281
1281
 
1282
1282
    //-------------------------------------------------sbool_unite_shapes_aa
1283
 
    // Unite two anti-aliased scanline shapes 
 
1283
    // Unite two anti-aliased scanline shapes
1284
1284
    // See intersect_shapes_aa for more comments
1285
1285
    //----------
1286
 
    template<class ScanlineGen1, 
1287
 
             class ScanlineGen2, 
1288
 
             class Scanline1, 
1289
 
             class Scanline2, 
1290
 
             class Scanline, 
 
1286
    template<class ScanlineGen1,
 
1287
             class ScanlineGen2,
 
1288
             class Scanline1,
 
1289
             class Scanline2,
 
1290
             class Scanline,
1291
1291
             class Renderer>
1292
1292
    void sbool_unite_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1293
1293
                               Scanline1& sl1, Scanline2& sl2,
1296
1296
        sbool_add_span_aa<Scanline1, Scanline> add_functor1;
1297
1297
        sbool_add_span_aa<Scanline2, Scanline> add_functor2;
1298
1298
        sbool_unite_spans_aa<Scanline1, Scanline2, Scanline> combine_functor;
1299
 
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, 
 
1299
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
1300
1300
                           add_functor1, add_functor2, combine_functor);
1301
1301
    }
1302
1302
 
1305
1305
 
1306
1306
 
1307
1307
    //------------------------------------------------sbool_unite_shapes_bin
1308
 
    // Unite two binary scanline shapes (without anti-aliasing). 
 
1308
    // Unite two binary scanline shapes (without anti-aliasing).
1309
1309
    // See intersect_shapes_aa for more comments
1310
1310
    //----------
1311
 
    template<class ScanlineGen1, 
1312
 
             class ScanlineGen2, 
1313
 
             class Scanline1, 
1314
 
             class Scanline2, 
1315
 
             class Scanline, 
 
1311
    template<class ScanlineGen1,
 
1312
             class ScanlineGen2,
 
1313
             class Scanline1,
 
1314
             class Scanline2,
 
1315
             class Scanline,
1316
1316
             class Renderer>
1317
1317
    void sbool_unite_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
1318
1318
                                Scanline1& sl1, Scanline2& sl2,
1321
1321
        sbool_add_span_bin<Scanline1, Scanline> add_functor1;
1322
1322
        sbool_add_span_bin<Scanline2, Scanline> add_functor2;
1323
1323
        sbool_combine_spans_bin<Scanline1, Scanline2, Scanline> combine_functor;
1324
 
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, 
 
1324
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
1325
1325
                           add_functor1, add_functor2, combine_functor);
1326
1326
    }
1327
1327
 
1334
1334
 
1335
1335
 
1336
1336
    //---------------------------------------------------sbool_xor_shapes_aa
1337
 
    // Apply eXclusive OR to two anti-aliased scanline shapes. There's 
 
1337
    // Apply eXclusive OR to two anti-aliased scanline shapes. There's
1338
1338
    // a modified "Linear" XOR used instead of classical "Saddle" one.
1339
1339
    // The reason is to have the result absolutely conststent with what
1340
1340
    // the scanline rasterizer produces.
1341
1341
    // See intersect_shapes_aa for more comments
1342
1342
    //----------
1343
 
    template<class ScanlineGen1, 
1344
 
             class ScanlineGen2, 
1345
 
             class Scanline1, 
1346
 
             class Scanline2, 
1347
 
             class Scanline, 
 
1343
    template<class ScanlineGen1,
 
1344
             class ScanlineGen2,
 
1345
             class Scanline1,
 
1346
             class Scanline2,
 
1347
             class Scanline,
1348
1348
             class Renderer>
1349
1349
    void sbool_xor_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1350
1350
                             Scanline1& sl1, Scanline2& sl2,
1352
1352
    {
1353
1353
        sbool_add_span_aa<Scanline1, Scanline> add_functor1;
1354
1354
        sbool_add_span_aa<Scanline2, Scanline> add_functor2;
1355
 
        sbool_xor_spans_aa<Scanline1, Scanline2, Scanline, 
 
1355
        sbool_xor_spans_aa<Scanline1, Scanline2, Scanline,
1356
1356
                           sbool_xor_formula_linear<> > combine_functor;
1357
 
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, 
 
1357
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
1358
1358
                           add_functor1, add_functor2, combine_functor);
1359
1359
    }
1360
1360
 
1361
1361
 
1362
1362
 
1363
1363
    //------------------------------------------sbool_xor_shapes_saddle_aa
1364
 
    // Apply eXclusive OR to two anti-aliased scanline shapes. 
1365
 
    // There's the classical "Saddle" used to calculate the 
 
1364
    // Apply eXclusive OR to two anti-aliased scanline shapes.
 
1365
    // There's the classical "Saddle" used to calculate the
1366
1366
    // Anti-Aliasing values, that is:
1367
1367
    // a XOR b : 1-((1-a+a*b)*(1-b+a*b))
1368
1368
    // See intersect_shapes_aa for more comments
1369
1369
    //----------
1370
 
    template<class ScanlineGen1, 
1371
 
             class ScanlineGen2, 
1372
 
             class Scanline1, 
1373
 
             class Scanline2, 
1374
 
             class Scanline, 
 
1370
    template<class ScanlineGen1,
 
1371
             class ScanlineGen2,
 
1372
             class Scanline1,
 
1373
             class Scanline2,
 
1374
             class Scanline,
1375
1375
             class Renderer>
1376
1376
    void sbool_xor_shapes_saddle_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1377
1377
                                    Scanline1& sl1, Scanline2& sl2,
1379
1379
    {
1380
1380
        sbool_add_span_aa<Scanline1, Scanline> add_functor1;
1381
1381
        sbool_add_span_aa<Scanline2, Scanline> add_functor2;
1382
 
        sbool_xor_spans_aa<Scanline1, 
1383
 
                           Scanline2, 
1384
 
                           Scanline, 
 
1382
        sbool_xor_spans_aa<Scanline1,
 
1383
                           Scanline2,
 
1384
                           Scanline,
1385
1385
                           sbool_xor_formula_saddle<> > combine_functor;
1386
 
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, 
 
1386
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
1387
1387
                           add_functor1, add_functor2, combine_functor);
1388
1388
    }
1389
1389
 
1390
1390
 
1391
1391
    //--------------------------------------sbool_xor_shapes_abs_diff_aa
1392
 
    // Apply eXclusive OR to two anti-aliased scanline shapes. 
1393
 
    // There's the absolute difference used to calculate 
 
1392
    // Apply eXclusive OR to two anti-aliased scanline shapes.
 
1393
    // There's the absolute difference used to calculate
1394
1394
    // Anti-Aliasing values, that is:
1395
1395
    // a XOR b : abs(a-b)
1396
1396
    // See intersect_shapes_aa for more comments
1397
1397
    //----------
1398
 
    template<class ScanlineGen1, 
1399
 
             class ScanlineGen2, 
1400
 
             class Scanline1, 
1401
 
             class Scanline2, 
1402
 
             class Scanline, 
 
1398
    template<class ScanlineGen1,
 
1399
             class ScanlineGen2,
 
1400
             class Scanline1,
 
1401
             class Scanline2,
 
1402
             class Scanline,
1403
1403
             class Renderer>
1404
1404
    void sbool_xor_shapes_abs_diff_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1405
1405
                                      Scanline1& sl1, Scanline2& sl2,
1407
1407
    {
1408
1408
        sbool_add_span_aa<Scanline1, Scanline> add_functor1;
1409
1409
        sbool_add_span_aa<Scanline2, Scanline> add_functor2;
1410
 
        sbool_xor_spans_aa<Scanline1, 
1411
 
                           Scanline2, 
1412
 
                           Scanline, 
 
1410
        sbool_xor_spans_aa<Scanline1,
 
1411
                           Scanline2,
 
1412
                           Scanline,
1413
1413
                           sbool_xor_formula_abs_diff> combine_functor;
1414
 
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, 
 
1414
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
1415
1415
                           add_functor1, add_functor2, combine_functor);
1416
1416
    }
1417
1417
 
1418
1418
 
1419
1419
 
1420
1420
    //--------------------------------------------------sbool_xor_shapes_bin
1421
 
    // Apply eXclusive OR to two binary scanline shapes (without anti-aliasing). 
 
1421
    // Apply eXclusive OR to two binary scanline shapes (without anti-aliasing).
1422
1422
    // See intersect_shapes_aa for more comments
1423
1423
    //----------
1424
 
    template<class ScanlineGen1, 
1425
 
             class ScanlineGen2, 
1426
 
             class Scanline1, 
1427
 
             class Scanline2, 
1428
 
             class Scanline, 
 
1424
    template<class ScanlineGen1,
 
1425
             class ScanlineGen2,
 
1426
             class Scanline1,
 
1427
             class Scanline2,
 
1428
             class Scanline,
1429
1429
             class Renderer>
1430
1430
    void sbool_xor_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
1431
1431
                              Scanline1& sl1, Scanline2& sl2,
1434
1434
        sbool_add_span_bin<Scanline1, Scanline> add_functor1;
1435
1435
        sbool_add_span_bin<Scanline2, Scanline> add_functor2;
1436
1436
        sbool_combine_spans_empty<Scanline1, Scanline2, Scanline> combine_functor;
1437
 
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, 
 
1437
        sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
1438
1438
                           add_functor1, add_functor2, combine_functor);
1439
1439
    }
1440
1440
 
1447
1447
    // Subtract shapes "sg1-sg2" with anti-aliasing
1448
1448
    // See intersect_shapes_aa for more comments
1449
1449
    //----------
1450
 
    template<class ScanlineGen1, 
1451
 
             class ScanlineGen2, 
1452
 
             class Scanline1, 
1453
 
             class Scanline2, 
1454
 
             class Scanline, 
 
1450
    template<class ScanlineGen1,
 
1451
             class ScanlineGen2,
 
1452
             class Scanline1,
 
1453
             class Scanline2,
 
1454
             class Scanline,
1455
1455
             class Renderer>
1456
1456
    void sbool_subtract_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1457
1457
                                  Scanline1& sl1, Scanline2& sl2,
1459
1459
    {
1460
1460
        sbool_add_span_aa<Scanline1, Scanline> add_functor;
1461
1461
        sbool_subtract_spans_aa<Scanline1, Scanline2, Scanline> combine_functor;
1462
 
        sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren, 
 
1462
        sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren,
1463
1463
                              add_functor, combine_functor);
1464
1464
    }
1465
1465
 
1471
1471
    // Subtract binary shapes "sg1-sg2" without anti-aliasing
1472
1472
    // See intersect_shapes_aa for more comments
1473
1473
    //----------
1474
 
    template<class ScanlineGen1, 
1475
 
             class ScanlineGen2, 
1476
 
             class Scanline1, 
1477
 
             class Scanline2, 
1478
 
             class Scanline, 
 
1474
    template<class ScanlineGen1,
 
1475
             class ScanlineGen2,
 
1476
             class Scanline1,
 
1477
             class Scanline2,
 
1478
             class Scanline,
1479
1479
             class Renderer>
1480
1480
    void sbool_subtract_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
1481
1481
                                   Scanline1& sl1, Scanline2& sl2,
1483
1483
    {
1484
1484
        sbool_add_span_bin<Scanline1, Scanline> add_functor;
1485
1485
        sbool_combine_spans_empty<Scanline1, Scanline2, Scanline> combine_functor;
1486
 
        sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren, 
 
1486
        sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren,
1487
1487
                              add_functor, combine_functor);
1488
1488
    }
1489
1489
 
1510
1510
 
1511
1511
 
1512
1512
    //----------------------------------------------sbool_combine_shapes_bin
1513
 
    template<class ScanlineGen1, 
1514
 
             class ScanlineGen2, 
1515
 
             class Scanline1, 
1516
 
             class Scanline2, 
1517
 
             class Scanline, 
 
1513
    template<class ScanlineGen1,
 
1514
             class ScanlineGen2,
 
1515
             class Scanline1,
 
1516
             class Scanline2,
 
1517
             class Scanline,
1518
1518
             class Renderer>
1519
1519
    void sbool_combine_shapes_bin(sbool_op_e op,
1520
1520
                                  ScanlineGen1& sg1, ScanlineGen2& sg2,
1526
1526
        case sbool_or          : sbool_unite_shapes_bin    (sg1, sg2, sl1, sl2, sl, ren); break;
1527
1527
        case sbool_and         : sbool_intersect_shapes_bin(sg1, sg2, sl1, sl2, sl, ren); break;
1528
1528
        case sbool_xor         :
1529
 
        case sbool_xor_saddle  : 
 
1529
        case sbool_xor_saddle  :
1530
1530
        case sbool_xor_abs_diff: sbool_xor_shapes_bin      (sg1, sg2, sl1, sl2, sl, ren); break;
1531
1531
        case sbool_a_minus_b   : sbool_subtract_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
1532
1532
        case sbool_b_minus_a   : sbool_subtract_shapes_bin (sg2, sg1, sl2, sl1, sl, ren); break;
1537
1537
 
1538
1538
 
1539
1539
    //-----------------------------------------------sbool_combine_shapes_aa
1540
 
    template<class ScanlineGen1, 
1541
 
             class ScanlineGen2, 
1542
 
             class Scanline1, 
1543
 
             class Scanline2, 
1544
 
             class Scanline, 
 
1540
    template<class ScanlineGen1,
 
1541
             class ScanlineGen2,
 
1542
             class Scanline1,
 
1543
             class Scanline2,
 
1544
             class Scanline,
1545
1545
             class Renderer>
1546
1546
    void sbool_combine_shapes_aa(sbool_op_e op,
1547
1547
                                 ScanlineGen1& sg1, ScanlineGen2& sg2,