db9290523b8391ecfc2000503921a89680c55f5a
[swftools.git] / lib / gfxpoly / wind.c
1 #include "wind.h"
2
3 fillstyle_t fillstyle_default;
4
5 windstate_t windstate_nonfilled = {
6     is_filled: 0,
7     wind_nr: 0,
8 };
9
10 // -------------------- even/odd ----------------------
11
12 windstate_t evenodd_start(windcontext_t*context)
13 {
14     return windstate_nonfilled;
15 }
16 windstate_t evenodd_add(windcontext_t*context, windstate_t left, fillstyle_t*edge, segment_dir_t dir, int master)
17 {
18     left.is_filled ^= 1;
19     return left;
20 }
21 fillstyle_t* evenodd_diff(windstate_t*left, windstate_t*right)
22 {
23     if(left->is_filled==right->is_filled)
24         return 0;
25     else
26         return &fillstyle_default;
27 }
28
29 windrule_t windrule_evenodd = {
30     start: evenodd_start,
31     add: evenodd_add,
32     diff: evenodd_diff,
33 };
34
35 // -------------------- circular ----------------------
36
37 windstate_t circular_start(windcontext_t*context)
38 {
39     return windstate_nonfilled;
40 }
41
42 windstate_t circular_add(windcontext_t*context, windstate_t left, fillstyle_t*edge, segment_dir_t dir, int master)
43 {
44     /* which one is + and which one - doesn't actually make any difference */
45     if(dir == DIR_DOWN)
46         left.wind_nr++;
47     else
48         left.wind_nr--;
49
50     left.is_filled = left.wind_nr != 0;
51     return left;
52 }
53
54 fillstyle_t* circular_diff(windstate_t*left, windstate_t*right)
55 {
56     if(left->is_filled==right->is_filled)
57         return 0;
58     else
59         return &fillstyle_default;
60 }
61
62 windrule_t windrule_circular = {
63     start: circular_start,
64     add: circular_add,
65     diff: circular_diff,
66 };
67
68 // -------------------- intersect ----------------------
69
70 windstate_t intersect_start(windcontext_t*context)
71 {
72     return windstate_nonfilled;
73 }
74
75 windstate_t intersect_add(windcontext_t*context, windstate_t left, fillstyle_t*edge, segment_dir_t dir, int master)
76 {
77     assert(master < context->num_polygons);
78
79     left.wind_nr ^= 1<<master;
80     left.is_filled = (left.wind_nr == (1<<context->num_polygons)-1);
81     return left;
82 }
83
84 fillstyle_t* intersect_diff(windstate_t*left, windstate_t*right)
85 {
86     if(left->is_filled==right->is_filled)
87         return 0;
88     else
89         return &fillstyle_default;
90 }
91
92 windrule_t windrule_intersect = {
93     start: intersect_start,
94     add: intersect_add,
95     diff: intersect_diff,
96 };
97
98 // -------------------- union ----------------------
99
100 windstate_t union_start(windcontext_t*context)
101 {
102     return windstate_nonfilled;
103 }
104
105 windstate_t union_add(windcontext_t*context, windstate_t left, fillstyle_t*edge, segment_dir_t dir, int master)
106 {
107     assert(master<sizeof(left.wind_nr)*8); //up to 32/64 polygons max
108     left.wind_nr ^= 1<<master;
109     left.is_filled = (left.wind_nr!=0);
110     return left;
111 }
112
113 fillstyle_t* union_diff(windstate_t*left, windstate_t*right)
114 {
115     if(left->is_filled==right->is_filled)
116         return 0;
117     else
118         return &fillstyle_default;
119 }
120
121 windrule_t windrule_union = {
122     start: union_start,
123     add: union_add,
124     diff: union_diff,
125 };
126
127
128 /* 
129  } else if (rule == WIND_NONZERO) {
130      fill = wind!=0;
131  } else if (rule == WIND_ODDEVEN) {
132      fill = wind&1;
133  } else { // rule == WIND_POSITIVE
134      fill = wind>=1;
135  }
136  */