static gfxpoly_t*current_polygon = 0;
void gfxpoly_fail(char*expr, char*file, int line, const char*function)
{
- if(!current_polygon) {fprintf(stderr, "error outside polygon\n");exit(1);}
+ if(!current_polygon) {
+ fprintf(stderr, "assert(%s) failed in %s in line %d: %s\n", expr, file, line, function);
+ exit(1);
+ }
void*md5 = init_md5();
/* we need to schedule end after intersect (so that a segment about
to end has a chance to tear up a few other segs first) and start
events after end (in order not to confuse the intersection check, which
- assumes there's an actual y overlap between active segments)).
+ assumes there's an actual y overlap between active segments, and
+ because ending segments in the active list make it difficult to insert
+ starting segments at the right position)).
Horizontal lines come last, because the only purpose
they have is to create snapping coordinates for the segments (still)
existing in this scanline.
*/
d = b->type - a->type;
if(d) return d;
- d = b->p.x - a->p.x;
- return d;
+ return 0;
+
+ /* I don't see any reason why we would need to order by x- at least as long
+ as we do horizontal lines in a seperate pass */
+ //d = b->p.x - a->p.x;
+ //return d;
}
gfxpoly_t* gfxpoly_new(double gridsize)
{
edge_t* s = poly->edges;
double g = poly->gridsize;
+ fprintf(stderr, "polyon %08x (gridsize: %f)\n", poly, poly->gridsize);
while(s) {
fprintf(stderr, "(%f,%f) -> (%f,%f)\n", s->a.x*g, s->a.y*g, s->b.x*g, s->b.y*g);
s = s->next;
/* the code that's required (and the checks you can perform) before
it can be said with 100% certainty that we indeed have a valid crossing
amazes me every time. -mk */
-
#ifdef CHECKS
assert(s1!=s2);
assert(s1->right == s2);
/* we need to calculate the xpos anew (and can't use start coordinate or
intersection coordinate), because we need the xpos exactly at the end of
this scanline.
- TODO: might be faster to use XPOS_COMPARE here (see also _max)
*/
double x = XPOS(seg, y);
if(!range->segmin || x<range->xmin) {
//break;
}
}
- seg = actlist_right(status->actlist, seg);
+ seg = seg->right;
}
}
segrange_test_segment_min(range, first, y);
//break;
}
}
- seg = actlist_left(status->actlist, seg);
+ seg = seg->left;
}
}
segrange_test_segment_min(range, last, y);
if(status->xrow->num == 1) {
// shortcut
+ assert(seg->b.x == status->xrow->x[0]);
point_t p = {status->xrow->x[0], y};
insert_point_into_segment(status, seg, p);
} else {
#endif
if(end)
- end = actlist_right(status->actlist, end);
+ end = end->right;
while(s!=end) {
#ifndef CHECKS
if(s->changed)
assert(!dict_contains(status->intersecting_segs, s));
assert(!dict_contains(status->segs_with_point, s));
#endif
- segment_t*left = actlist_left(status->actlist, s);
- segment_t*right = actlist_right(status->actlist, s);
+ segment_t*left = s->left;
+ segment_t*right = s->right;
actlist_delete(status->actlist, s);
if(left && right)
schedule_crossing(status, left, right);
+ /* schedule segment for xrow handling */
s->left = 0; s->right = status->ending_segments;
status->ending_segments = s;
break;
segment_t*s = e->s1;
assert(e->p.x == s->a.x && e->p.y == s->a.y);
actlist_insert(status->actlist, s->a, s->b, s);
- segment_t*left = actlist_left(status->actlist, s);
- segment_t*right = actlist_right(status->actlist, s);
+ segment_t*left = s->left;
+ segment_t*right = s->right;
if(left)
schedule_crossing(status, left, s);
if(right)
#ifdef DEBUG
event_dump(e);
#endif
- if(actlist_right(status->actlist, e->s1) == e->s2 &&
- actlist_left(status->actlist, e->s2) == e->s1) {
+ if(e->s1->right == e->s2) {
+ assert(e->s2->left == e->s1);
exchange_two(status, e);
} else {
+ assert(e->s2->left != e->s1);
#ifdef DEBUG
fprintf(stderr, "Ignore this crossing ([%d] not next to [%d])\n", e->s1->nr, e->s2->nr);
#endif
assert(x<e->p.x);
edge_t*l= malloc(sizeof(edge_t));
l->a.y = l->b.y = y;
- /* TODO: strictly speaking we need to draw from low x to high x so that left/right fillstyles add up
- (because the horizontal line's fill style controls the area *below* the line)
+ /* we draw from low x to high x so that left/right fillstyles add up
+ (because the horizontal line's fill style controls the area *below* the line)
*/
- l->a.x = x;
- l->b.x = e->p.x;
+ l->a.x = e->p.x;
+ l->b.x = x;
l->next = poly->edges;
poly->edges = l;
#ifdef CHECKS
/* the output should always be intersection free polygons, so check this horizontal
line isn't hacking through any segments in the active list */
- segment_t* start = actlist_find(actlist, l->a, l->a);
- segment_t* s = actlist_find(actlist, l->b, l->b);
+ segment_t* start = actlist_find(actlist, l->b, l->b);
+ segment_t* s = actlist_find(actlist, l->a, l->a);
while(s!=start) {
assert(s->a.y == y || s->b.y == y);
s = s->left;
segment_t*left = 0;
segment_t*s = e->s1;
- windstate_t before,after;
switch(e->type) {
case EVENT_START: {
assert(e->p.x == s->a.x && e->p.y == s->a.y);
e.s2 = 0;
heap_put(queue, &e);
left = actlist_left(actlist, s);
-
- before = left?left->wind:windrule->start(context);
- after = s->wind = windrule->add(context, before, s->fs, s->dir, s->polygon_nr);
break;
}
case EVENT_END: {
left = actlist_left(actlist, s);
actlist_delete(actlist, s);
-
- before = s->wind;
- after = left?left->wind:windrule->start(context);
break;
}
default: assert(0);
x = e->p.x;
fill ^= 1;//(before.is_filled != after.is_filled);
#ifdef DEBUG
- fprintf(stderr, "%d) event=%s[%d] left:[%d] x:%d before:%d after:%d\n",
+ fprintf(stderr, "%d) event=%s[%d] left:[%d] x:%d\n",
y, e->type==EVENT_START?"start":"end",
s->nr,
left?left->nr:-1,
- x,
- before.is_filled, after.is_filled);
+ x);
#endif
if(e->type == EVENT_END)