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