+
+
+static void insert_point_into_segment(status_t*status, segment_t*s, point_t p)
+{
+ assert(s->pos.x != p.x || s->pos.y != p.y);
+
+#ifdef CHECKS
+ if(!dict_contains(status->segs_with_point, s))
+ dict_put(status->segs_with_point, s, 0);
+ assert(s->fs_out_ok);
+#endif
+
+ if(s->fs_out) {
+#ifdef DEBUG
+ fprintf(stderr, "[%d] receives next point (%d,%d)->(%d,%d) (drawing)\n", s->nr,
+ s->pos.x, s->pos.y, p.x, p.y);
+#endif
+ // omit horizontal lines
+ if(s->pos.y != p.y) {
+ edge_t*e = rfx_calloc(sizeof(edge_t));
+#ifdef DEBUG
+ e->tmp = s->nr;
+#endif
+ e->a = s->pos;
+ e->b = p;
+ assert(e->a.y != e->b.y);
+ e->next = status->output;
+ status->output = e;
+ }
+ } else {
+#ifdef DEBUG
+ fprintf(stderr, "[%d] receives next point (%d,%d) (omitting)\n", s->nr, p.x, p.y);
+#endif
+ }
+ s->pos = p;
+}
+
+typedef struct _segrange {
+ double xmin;
+ segment_t*segmin;
+ double xmax;
+ segment_t*segmax;
+} segrange_t;
+
+void segrange_adjust_endpoints(segrange_t*range, int y)
+{
+#define XPOS_EQ(s1,s2,ypos) (XPOS((s1),(ypos))==XPOS((s2),(ypos)))
+#ifdef CHECK
+ /* this would mean that the segment left/right of the minimum/maximum
+ intersects the current segment exactly at the scanline, but somehow
+ wasn't found to be passing through the same snapping box */
+ assert(!min || !min->left || !XPOS_EQ(min, min->left, y));
+ assert(!max || !max->right || !XPOS_EQ(max, max->right, y));
+#endif
+
+ /* this doesn't actually ever happen anymore (see checks above) */
+ segment_t*min = range->segmin;
+ segment_t*max = range->segmax;
+ if(min) while(min->left && XPOS_EQ(min, min->left, y)) {
+ min = min->left;
+ }
+ if(max) while(max->right && XPOS_EQ(max, max->right, y)) {
+ max = max->right;
+ }
+ range->segmin = min;
+ range->segmax = max;
+}
+void segrange_test_segment_min(segrange_t*range, segment_t*seg, int y)
+{
+ if(!seg) return;
+ /* 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) {
+ range->segmin = seg;
+ range->xmin = x;
+ }
+}
+void segrange_test_segment_max(segrange_t*range, segment_t*seg, int y)
+{
+ if(!seg) return;
+ double x = XPOS(seg, y);
+ if(!range->segmax || x>range->xmax) {
+ range->segmax = seg;
+ range->xmax = x;
+ }
+}
+