+ // now that this is done, too, we can also finally free this segment
+ segment_destroy(seg);
+ seg = next;
+ }
+ status->ending_segments = 0;
+}
+
+static void recalculate_windings(status_t*status, segrange_t*range)
+{
+#ifdef DEBUG
+ fprintf(stderr, "range: [%d]..[%d]\n", SEGNR(range->segmin), SEGNR(range->segmax));
+#endif
+ segrange_adjust_endpoints(range, status->y);
+
+ segment_t*s = range->segmin;
+ segment_t*end = range->segmax;
+ segment_t*last = 0;
+
+#ifdef DEBUG
+ s = actlist_leftmost(status->actlist);
+ while(s) {
+ fprintf(stderr, "[%d]%d%s ", s->nr, s->changed,
+ s == range->segmin?"S":(
+ s == range->segmax?"E":""));
+ s = s->right;
+ }
+ fprintf(stderr, "\n");
+ s = range->segmin;
+#endif
+#ifdef CHECKS
+ /* test sanity: check that we don't have changed segments
+ outside of the given range */
+ s = actlist_leftmost(status->actlist);
+ while(s && s!=range->segmin) {
+ assert(!s->changed);
+ s = s->right;
+ }
+ s = actlist_rightmost(status->actlist);
+ while(s && s!=range->segmax) {
+ assert(!s->changed);
+ s = s->left;
+ }
+ /* in check mode, go through the whole interval so we can test
+ that all polygons where the fillstyle changed also have seg->changed=1 */
+ s = actlist_leftmost(status->actlist);
+ end = 0;
+#endif
+
+ if(end)
+ end = actlist_right(status->actlist, end);
+ while(s!=end) {
+#ifndef CHECKS
+ if(s->changed)
+#endif
+ {
+ segment_t* left = actlist_left(status->actlist, s);
+ windstate_t wind = left?left->wind:status->windrule->start(status->context);
+ s->wind = status->windrule->add(status->context, wind, s->fs, s->dir, s->polygon_nr);
+ fillstyle_t*fs_old = s->fs_out;
+ s->fs_out = status->windrule->diff(&wind, &s->wind);
+
+ assert(!(!s->changed && fs_old!=s->fs_out));
+ s->changed = 0;
+
+#ifdef CHECKS
+ s->fs_out_ok = 1;
+#endif
+#ifdef DEBUG
+ fprintf(stderr, "[%d] %s/%d/%s/%s %s\n", s->nr, s->dir==DIR_UP?"up":"down", s->wind.wind_nr, s->wind.is_filled?"fill":"nofill", s->fs_out?"draw":"omit",
+ fs_old!=s->fs_out?"CHANGED":"");
+#endif
+ }
+ s = s->right;
+ }
+}
+
+/* we need to handle horizontal lines in order to add points to segments
+ we otherwise would miss during the windrule re-evaluation */
+static void intersect_with_horizontal(status_t*status, segment_t*h)
+{
+ segment_t* left = actlist_find(status->actlist, h->a, h->a);
+ segment_t* right = actlist_find(status->actlist, h->b, h->b);
+
+ /* not strictly necessary, also done by the event */
+ xrow_add(status->xrow, h->a.x);
+ point_t o = h->a;
+
+ if(!right) {
+ assert(!left);
+ return;
+ }
+
+ left = actlist_right(status->actlist, left); //first seg to the right of h->a
+ right = right->right; //first seg to the right of h->b
+ segment_t* s = left;
+
+ while(s!=right) {
+ assert(s);
+ int32_t x = XPOS_INT(s, status->y);
+#ifdef DEBUG
+ fprintf(stderr, "...into [%d] (%d,%d) -> (%d,%d) at (%d,%d)\n", s->nr,
+ s->a.x, s->a.y,
+ s->b.x, s->b.y,
+ x, status->y
+ );
+#endif
+ assert(x >= h->a.x);
+ assert(x <= h->b.x);
+ assert(s->delta.x > 0 && x >= s->a.x || s->delta.x <= 0 && x <= s->a.x);
+ assert(s->delta.x > 0 && x <= s->b.x || s->delta.x <= 0 && x >= s->b.x);
+ xrow_add(status->xrow, x);
+
+ s = s->right;