implemented stroke merging
authorMatthias Kramm <kramm@matthias-kramms-macbook-pro.local>
Fri, 29 May 2009 03:19:32 +0000 (20:19 -0700)
committerMatthias Kramm <kramm@matthias-kramms-macbook-pro.local>
Fri, 29 May 2009 03:19:32 +0000 (20:19 -0700)
lib/gfxpoly/convert.c
lib/gfxpoly/poly.c
lib/gfxpoly/poly.h
lib/gfxpoly/test.c

index 9cd560c..9f54542 100644 (file)
@@ -133,7 +133,7 @@ void finish_segment(compactpoly_t*data)
     gfxpolystroke_t*s = rfx_calloc(sizeof(gfxpolystroke_t));
     s->next = data->poly->strokes;
     data->poly->strokes = s;
-    s->num_points = data->num_points;
+    s->num_points = s->points_size = data->num_points;
     s->dir = data->dir;
     s->points = p;
     assert(data->dir != DIR_UNKNOWN);
index 2b55041..226584a 100644 (file)
@@ -136,7 +136,8 @@ typedef struct _status {
     windrule_t*windrule;
     windcontext_t*context;
     segment_t*ending_segments;
-    polywriter_t writer;
+
+    gfxpolystroke_t*strokes;
 #ifdef CHECKS
     dict_t*seen_crossings; //list of crossing we saw so far
     dict_t*intersecting_segs; //list of segments intersecting in this scanline
@@ -647,13 +648,38 @@ static void insert_point_into_segment(status_t*status, segment_t*s, point_t p)
         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
+       /* XXX we probably will never output circular/anticircular polygons, but if
+          we do, we would need to set the segment direction here */
+       fillstyle_t*fs = s->fs_out;
+
         // omit horizontal lines
         if(s->pos.y != p.y) {
             point_t a = s->pos;
             point_t b = p;
             assert(a.y != b.y);
-           status->writer.moveto(&status->writer, a.x, a.y);
-           status->writer.lineto(&status->writer, b.x, b.y);
+
+            gfxpolystroke_t*stroke = status->strokes;
+           while(stroke) {
+               point_t p = stroke->points[stroke->num_points-1];
+               if(p.x == a.x && p.y == a.y && stroke->fs == fs)
+                   break;
+               stroke = stroke->next;
+           }
+           if(!stroke) {
+               stroke = rfx_calloc(sizeof(gfxpolystroke_t));
+               stroke->dir = DIR_DOWN;
+               stroke->fs = fs;
+               stroke->next = status->strokes;
+               status->strokes = stroke;
+               stroke->points_size = 2;
+               stroke->points = rfx_calloc(sizeof(point_t)*stroke->points_size);
+               stroke->points[0] = a;
+               stroke->num_points = 1;
+           } else if(stroke->num_points == stroke->points_size) {
+               stroke->points_size *= 2;
+               stroke->points = rfx_realloc(stroke->points, sizeof(point_t)*stroke->points_size);
+           }
+           stroke->points[stroke->num_points++] = b;
         }
     } else {
 #ifdef DEBUG
@@ -1195,8 +1221,6 @@ gfxpoly_t* gfxpoly_process(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*co
     status.windrule = windrule;
     status.context = context;
     status.actlist = actlist_new();
-    gfxpolywriter_init(&status.writer);
-    status.writer.setgridsize(&status.writer, poly->gridsize);
 
 #ifdef CHECKS
     status.seen_crossings = dict_new2(&point_type);
@@ -1254,8 +1278,11 @@ gfxpoly_t* gfxpoly_process(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*co
     queue_destroy(&status.queue);
     xrow_destroy(status.xrow);
 
-    gfxpoly_t*p = (gfxpoly_t*)status.writer.finish(&status.writer);
+    gfxpoly_t*p = (gfxpoly_t*)malloc(sizeof(gfxpoly_t));
+    p->gridsize = poly->gridsize;
+    p->strokes = status.strokes;
 
+    gfxpoly_dump(p);
     add_horizontals(p, &windrule_evenodd, context); // output is always even/odd
     return p;
 }
index fc825b4..186075a 100644 (file)
@@ -6,7 +6,7 @@
 #include "../types.h"
 
 //#define DEBUG
-#define CHECKS
+//#define CHECKS
 
 /* features */
 #define SPLAY
@@ -48,6 +48,7 @@ typedef struct _windrule
 
 typedef struct _gfxpolystroke {
     segment_dir_t dir;
+    int points_size;
     int num_points;
     point_t*points;
     fillstyle_t*fs;
index a6a5ab5..c58c3d5 100644 (file)
@@ -139,7 +139,7 @@ int test_speed()
 {
     //gfxline_t* b = mkchessboard();
     //gfxline_t* b = mkrandomshape(100,7);
-    gfxline_t* b = make_circles(100);
+    gfxline_t* b = make_circles(30);
 
     gfxmatrix_t m;
     memset(&m, 0, sizeof(gfxmatrix_t));
@@ -439,21 +439,33 @@ void test4(int argn, char*argv[])
 #include "../gfxdevice.h"
 #include "../pdf/pdf.h"
 
+static int max_segments = 0;
+static int max_any_segments = 0;
 void extract_polygons_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color) 
 {
     //gfxpoly_t*c = gfxpoly_from_gfxline(line, 0.05);
     //gfxpoly_free(c);
 
+    //gfxpoly_t*poly1 = gfxpoly_from_gfxline(line, 0.05);
     gfxpoly_t*poly1 = gfxpoly_from_gfxline(line, 0.05);
 
     //gfxline_dump(line, stderr, "");
     //gfxpoly_dump(poly);
 
-    if(gfxpoly_size(poly1)>100000) {
-       fprintf(stderr, "%d segments (skipping)\n", gfxpoly_size(poly1));
+    int size = gfxpoly_size(poly1);
+    if(size == 4) {
+       //rectangles are boring.
+       gfxpoly_destroy(poly1);
+       return;
+    }
+
+    max_any_segments = size > max_any_segments? size : max_any_segments;
+    if(size>100000) {
+       fprintf(stderr, "%d segments (skipping)\n", size);
        return;
     } else {
-       //fprintf(stderr, "%d segments\n", gfxpoly_size(poly));
+       max_segments = size > max_segments? size : max_segments;
+       fprintf(stderr, "%d segments (max so far: %d/%d)\n", size, max_segments, max_any_segments);
     }
 
     if(!gfxpoly_check(poly1)) {