2
2
// Anti-Grain Geometry - Version 2.4
3
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
30
30
// anti-aliasing information, but only X and Length. The function
31
31
// is compatible with any type of scanlines.
33
template<class Scanline1,
33
template<class Scanline1,
36
36
struct sbool_combine_spans_bin
38
void operator () (const typename Scanline1::const_iterator&,
39
const typename Scanline2::const_iterator&,
38
void operator () (const typename Scanline1::const_iterator&,
39
const typename Scanline2::const_iterator&,
41
41
Scanline& sl) const
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.
54
template<class Scanline1,
54
template<class Scanline1,
57
57
struct sbool_combine_spans_empty
59
void operator () (const typename Scanline1::const_iterator&,
60
const typename Scanline2::const_iterator&,
59
void operator () (const typename Scanline1::const_iterator&,
60
const typename Scanline2::const_iterator&,
70
70
// Add nothing. Used in conbine_shapes_sub
72
template<class Scanline1,
72
template<class Scanline1,
74
74
struct sbool_add_span_empty
76
void operator () (const typename Scanline1::const_iterator&,
76
void operator () (const typename Scanline1::const_iterator&,
85
85
// Add a binary span
87
template<class Scanline1,
87
template<class Scanline1,
89
89
struct sbool_add_span_bin
91
void operator () (const typename Scanline1::const_iterator&,
91
void operator () (const typename Scanline1::const_iterator&,
93
93
Scanline& sl) const
95
95
sl.add_span(x, len, cover_full);
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,
108
template<class Scanline1,
110
110
struct sbool_add_span_aa
112
void operator () (const typename Scanline1::const_iterator& span,
112
void operator () (const typename Scanline1::const_iterator& span,
114
114
Scanline& sl) const
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,
141
unsigned CoverShift = cover_shift>
138
template<class Scanline1,
141
unsigned CoverShift = cover_shift>
142
142
struct sbool_intersect_spans_aa
144
144
enum cover_scale_e
148
148
cover_mask = cover_size - 1,
149
149
cover_full = cover_mask
153
void operator () (const typename Scanline1::const_iterator& span1,
154
const typename Scanline2::const_iterator& span2,
153
void operator () (const typename Scanline1::const_iterator& span1,
154
const typename Scanline2::const_iterator& span2,
156
156
Scanline& sl) const
159
159
const typename Scanline1::cover_type* covers1;
160
160
const typename Scanline2::cover_type* covers2;
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
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,
253
unsigned CoverShift = cover_shift>
250
template<class Scanline1,
253
unsigned CoverShift = cover_shift>
254
254
struct sbool_unite_spans_aa
256
256
enum cover_scale_e
260
260
cover_mask = cover_size - 1,
261
261
cover_full = cover_mask
265
void operator () (const typename Scanline1::const_iterator& span1,
266
const typename Scanline2::const_iterator& span2,
265
void operator () (const typename Scanline1::const_iterator& span1,
266
const typename Scanline2::const_iterator& span2,
268
268
Scanline& sl) const
271
271
const typename Scanline1::cover_type* covers1;
272
272
const typename Scanline2::cover_type* covers2;
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;
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++);
294
294
(cover == cover_full * cover_full) ?
296
296
(cover >> cover_shift));
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++);
316
316
(cover == cover_full * cover_full) ?
318
318
(cover >> cover_shift));
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));
339
339
(cover == cover_full * cover_full) ?
341
341
(cover >> cover_shift));
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));
352
352
(cover == cover_full * cover_full) ?
354
354
(cover >> cover_shift));
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,
420
template<class Scanline1,
423
423
class XorFormula,
424
unsigned CoverShift = cover_shift>
424
unsigned CoverShift = cover_shift>
425
425
struct sbool_xor_spans_aa
427
427
enum cover_scale_e
431
431
cover_mask = cover_size - 1,
432
432
cover_full = cover_mask
436
void operator () (const typename Scanline1::const_iterator& span1,
437
const typename Scanline2::const_iterator& span2,
436
void operator () (const typename Scanline1::const_iterator& span1,
437
const typename Scanline2::const_iterator& span2,
439
439
Scanline& sl) const
442
442
const typename Scanline1::cover_type* covers1;
443
443
const typename Scanline2::cover_type* covers2;
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,
513
unsigned CoverShift = cover_shift>
510
template<class Scanline1,
513
unsigned CoverShift = cover_shift>
514
514
struct sbool_subtract_spans_aa
516
516
enum cover_scale_e
520
520
cover_mask = cover_size - 1,
521
521
cover_full = cover_mask
525
void operator () (const typename Scanline1::const_iterator& span1,
526
const typename Scanline2::const_iterator& span2,
525
void operator () (const typename Scanline1::const_iterator& span1,
526
const typename Scanline2::const_iterator& span2,
528
528
Scanline& sl) const
531
531
const typename Scanline1::cover_type* covers1;
532
532
const typename Scanline2::cover_type* covers2;
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
621
621
//--------------------------------------------sbool_add_spans_and_render
622
template<class Scanline1,
622
template<class Scanline1,
625
625
class AddSpanFunctor>
626
void sbool_add_spans_and_render(const Scanline1& sl1,
626
void sbool_add_spans_and_render(const Scanline1& sl1,
629
629
AddSpanFunctor add_span)
631
631
sl.reset_spans();
654
654
// two spans without Anti-Aliasing, the second preserves the AA
655
655
// information, but works slower
657
template<class Scanline1,
657
template<class Scanline1,
660
660
class CombineSpansFunctor>
661
void sbool_intersect_scanlines(const Scanline1& sl1,
662
const Scanline2& sl2,
661
void sbool_intersect_scanlines(const Scanline1& sl1,
662
const Scanline2& sl2,
664
664
CombineSpansFunctor combine_spans)
666
666
sl.reset_spans();
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
689
689
bool advance_span1 = xe1 < xe2;
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.
747
template<class ScanlineGen1,
747
template<class ScanlineGen1,
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)
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());
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);
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
//-----------------
832
832
// two spans without Anti-Aliasing, the second preserves the AA
833
833
// information, but works slower
835
template<class Scanline1,
835
template<class Scanline1,
838
838
class AddSpanFunctor1,
839
839
class AddSpanFunctor2,
840
840
class CombineSpansFunctor>
841
void sbool_unite_scanlines(const Scanline1& sl1,
842
const Scanline2& sl2,
841
void sbool_unite_scanlines(const Scanline1& sl1,
842
const Scanline2& sl2,
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();
858
invalid_b = 0xFFFFFFF,
859
invalid_e = invalid_b - 1
858
invalid_b = 0xFFFFFFF,
859
invalid_e = invalid_b - 1
862
862
// Initialize the spans as invalid
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.
1018
template<class ScanlineGen1,
1018
template<class ScanlineGen1,
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)
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);
1063
1063
sl1.reset(sg1.min_x(), sg1.max_x());
1064
1064
flag1 = sg1.sweep_scanline(sl1);
1069
1069
sl2.reset(sg2.min_x(), sg2.max_x());
1070
1070
flag2 = sg2.sweep_scanline(sl2);
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())
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.
1147
template<class ScanlineGen1,
1147
template<class ScanlineGen1,
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)
1183
1183
sbool_add_span_empty<Scanline2, Scanline> add_span2;
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;
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.
1242
template<class ScanlineGen1,
1242
template<class ScanlineGen1,
1247
1247
class Renderer>
1248
1248
void sbool_intersect_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1249
1249
Scanline1& sl1, Scanline2& sl2,
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
1264
template<class ScanlineGen1,
1264
template<class ScanlineGen1,
1269
1269
class Renderer>
1270
1270
void sbool_intersect_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
1271
1271
Scanline1& sl1, Scanline2& sl2,
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
1286
template<class ScanlineGen1,
1286
template<class ScanlineGen1,
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);
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
1311
template<class ScanlineGen1,
1311
template<class ScanlineGen1,
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);
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
1343
template<class ScanlineGen1,
1343
template<class ScanlineGen1,
1348
1348
class Renderer>
1349
1349
void sbool_xor_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1350
1350
Scanline1& sl1, Scanline2& sl2,
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);
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
1370
template<class ScanlineGen1,
1370
template<class ScanlineGen1,
1375
1375
class Renderer>
1376
1376
void sbool_xor_shapes_saddle_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1377
1377
Scanline1& sl1, Scanline2& sl2,
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,
1382
sbool_xor_spans_aa<Scanline1,
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);
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
1398
template<class ScanlineGen1,
1398
template<class ScanlineGen1,
1403
1403
class Renderer>
1404
1404
void sbool_xor_shapes_abs_diff_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1405
1405
Scanline1& sl1, Scanline2& sl2,
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,
1410
sbool_xor_spans_aa<Scanline1,
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);
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
1424
template<class ScanlineGen1,
1424
template<class ScanlineGen1,
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);
1447
1447
// Subtract shapes "sg1-sg2" with anti-aliasing
1448
1448
// See intersect_shapes_aa for more comments
1450
template<class ScanlineGen1,
1450
template<class ScanlineGen1,
1455
1455
class Renderer>
1456
1456
void sbool_subtract_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
1457
1457
Scanline1& sl1, Scanline2& sl2,
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);
1471
1471
// Subtract binary shapes "sg1-sg2" without anti-aliasing
1472
1472
// See intersect_shapes_aa for more comments
1474
template<class ScanlineGen1,
1474
template<class ScanlineGen1,
1479
1479
class Renderer>
1480
1480
void sbool_subtract_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
1481
1481
Scanline1& sl1, Scanline2& sl2,
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);
1512
1512
//----------------------------------------------sbool_combine_shapes_bin
1513
template<class ScanlineGen1,
1513
template<class ScanlineGen1,
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;
1539
1539
//-----------------------------------------------sbool_combine_shapes_aa
1540
template<class ScanlineGen1,
1540
template<class ScanlineGen1,
1545
1545
class Renderer>
1546
1546
void sbool_combine_shapes_aa(sbool_op_e op,
1547
1547
ScanlineGen1& sg1, ScanlineGen2& sg2,