switched several parts of the polygon processor to a more compact polygon representation
[swftools.git] / lib / gfxpoly / renderpoly.c
index 2373a64..c1a428f 100644 (file)
@@ -36,10 +36,10 @@ static inline void add_pixel(renderbuf_t*buf, double x, int y, segment_dir_t dir
     p.fs = fs;
     p.e = e;
     p.polygon_nr = polygon_nr;
-
-    if(x >= buf->bbox.xmax || y >= buf->bbox.ymax || y < buf->bbox.ymin) 
-        return;
     
+    if(y >= buf->bbox.ymax || y < buf->bbox.ymin) 
+        return;
+
     renderline_t*l = &buf->lines[y-buf->bbox.ymin];
 
     if(l->num == l->size) {
@@ -120,7 +120,7 @@ static void fill_bitwise(unsigned char*line, int x1, int x2)
     }
 }
 
-unsigned char* render_polygon(gfxpoly_t*polygon, intbbox_t*bbox, double zoom, windrule_t*rule)
+unsigned char* render_polygon(gfxpoly_t*polygon, intbbox_t*bbox, double zoom, windrule_t*rule, windcontext_t*context)
 {
     renderbuf_t _buf, *buf=&_buf;
     buf->width = (bbox->xmax - bbox->xmin);
@@ -128,9 +128,10 @@ unsigned char* render_polygon(gfxpoly_t*polygon, intbbox_t*bbox, double zoom, wi
     buf->bbox = *bbox;
     buf->zoom = zoom * polygon->gridsize;
     int width8 = (buf->width+7) >> 3;
+    char bleeding = 0;
     unsigned char* image = (unsigned char*)malloc(width8*buf->height);
     memset(image, 0, width8*buf->height);
-    
+
     buf->lines = (renderline_t*)rfx_alloc(buf->height*sizeof(renderline_t));
     int y;
     for(y=0;y<buf->height;y++) {
@@ -152,27 +153,29 @@ unsigned char* render_polygon(gfxpoly_t*polygon, intbbox_t*bbox, double zoom, wi
        int num = buf->lines[y].num;
         qsort(points, num, sizeof(renderpoint_t), compare_renderpoints);
         int lastx = 0;
-
-        windstate_t fill = rule->start(1);
+        
+        windstate_t fill = rule->start(context);
         for(n=0;n<num;n++) {
             renderpoint_t*p = &points[n];
             int x = (int)(p->x - bbox->xmin);
-            
+
             if(x < lastx)
-                x = lastx;
-            if(x > buf->width) {
-                break;
-            }
-            if(fill.is_filled && x!=lastx) {
+                x = lastx; 
+            if(x > buf->width)
+                x = buf->width;
+
+            if(fill.is_filled && lastx<x) {
                 fill_bitwise(line, lastx, x);
             }
-            fill = rule->add(fill, p->fs, p->dir, p->polygon_nr);
+            fill = rule->add(context, fill, p->fs, p->dir, p->polygon_nr);
             lastx = x;
         }
         if(fill.is_filled && lastx!=buf->width) {
             /* we're bleeding, fill over padding, too. */
             fprintf(stderr, "Polygon %08x is bleeding in line %d\n", polygon, y);
             fill_bitwise(line, lastx, width8*8);
+           assert(line[width8-1]&0x01);
+           bleeding = 1;
         }
     }
     
@@ -182,6 +185,9 @@ unsigned char* render_polygon(gfxpoly_t*polygon, intbbox_t*bbox, double zoom, wi
         }
         memset(&buf->lines[y], 0, sizeof(renderline_t));
     }
+    if(bleeding) {
+       assert(!bitmap_ok(bbox, image));
+    }
     free(buf->lines);buf->lines=0;
     return image;
 }
@@ -192,6 +198,14 @@ unsigned char* render_polygon(gfxpoly_t*polygon, intbbox_t*bbox, double zoom, wi
 static inline max(double a, double b) {return a>b?a:b;}
 static inline min(double a, double b) {return a<b?a:b;}
 
+static int adjust_x(int xmin, int xmax)
+{
+    xmax += 8;
+    while(((xmax - xmin)&0x07) != 0x04)
+        xmax++;
+    return xmax;
+}
+
 intbbox_t intbbox_new(int x1, int y1, int x2, int y2)
 {
     intbbox_t b;
@@ -199,8 +213,9 @@ intbbox_t intbbox_new(int x1, int y1, int x2, int y2)
     b.ymin = y1;
     b.xmax = x2;
     b.ymax = y2;
-    b.width = x2-x1;
-    b.height = y2-y1;
+    b.xmax = adjust_x(b.xmin, b.xmax);
+    b.width = b.xmax - b.xmin;
+    b.height = b.ymax - b.ymin;
     return b;
 }
 
@@ -232,7 +247,7 @@ intbbox_t intbbox_from_polygon(gfxpoly_t*polygon, double zoom)
         if(x2 > b.xmax) b.xmax = x2;
         if(y2 > b.ymax) b.ymax = y2;
     }
-
+    
     if(b.xmax > (int)(MAX_WIDTH*zoom))
        b.xmax = (int)(MAX_WIDTH*zoom);
     if(b.ymax > (int)(MAX_HEIGHT*zoom))
@@ -246,15 +261,11 @@ intbbox_t intbbox_from_polygon(gfxpoly_t*polygon, double zoom)
        b.xmin = b.xmax;
     if(b.ymin > b.ymax) 
        b.ymin = b.ymax;
-        
-    b.xmax += 8;
-    while(((b.xmax - b.xmin)&0x07) != 0x04)
-        b.xmax++;
+    
+    b.xmax = adjust_x(b.xmin, b.xmax);
 
     b.width = b.xmax - b.xmin;
     b.height = b.ymax - b.ymin;
-    printf("%dx%d\n", b.width, b.height);
-
     return b;
 }
 
@@ -281,8 +292,6 @@ int bitmap_ok(intbbox_t*bbox, unsigned char*data)
 {
     int y;
     int width8 = (bbox->width+7) >> 3;
-    if((bbox->width&7) == 0)
-        return 1;
     for(y=0;y<bbox->height;y++) {
         if(data[width8-1]&0x01)
             return 0; //bleeding