optimized gfxpoly to gfxline conversion
authorMatthias Kramm <kramm@quiss.org>
Fri, 5 Jun 2009 15:53:42 +0000 (17:53 +0200)
committerMatthias Kramm <kramm@quiss.org>
Fri, 5 Jun 2009 15:53:42 +0000 (17:53 +0200)
lib/gfxpoly/Makefile
lib/gfxpoly/convert.c
lib/gfxpoly/poly.c
lib/gfxpoly/poly.h
lib/gfxpoly/stroke.h [new file with mode: 0644]
lib/gfxpoly/test.c
lib/gfxpoly/test_stroke.c

index 36b6b2e..2065984 100644 (file)
@@ -1,7 +1,7 @@
 all: test stroke
 include ../../Makefile.common
 
-CC = gcc -O3 -fomit-frame-pointer
+CC = gcc -O2 -g
 #CC = gcc -O3
 
 ../libbase.a: ../q.c ../q.h ../mem.c ../mem.h
@@ -13,7 +13,7 @@ CC = gcc -O3 -fomit-frame-pointer
 testheap: ../libbase.a testheap.c
        $(CC) testheap.c ../libbase.a -o testheap -lm -lz -ljpeg
 
-OBJS = active.o convert.o poly.o wind.o renderpoly.o xrow.o
+OBJS = active.o convert.o poly.o wind.o renderpoly.o xrow.o stroke.o
 
 active.o: active.c active.h poly.h
        $(CC) -c active.c -o active.o
@@ -36,12 +36,14 @@ xrow.o: xrow.c xrow.h ../q.h ../mem.h
 stroke.o: stroke.c poly.h convert.h wind.h
        $(CC) -c stroke.c -o stroke.o
 
-stroke: test_stroke.c stroke.o $(OBJS) ../libgfx.a ../libbase.a ../librfxswf.a ../libgfxswf.a
-       $(CC) test_stroke.c stroke.o $(OBJS) ../libgfx.a ../libbase.a ../librfxswf.a ../libgfxswf.a -o stroke $(LIBS)
+GFX=../gfxfont.o ../gfxtools.o  ../devices/ops.o ../devices/polyops.o ../devices/text.o ../devices/bbox.o ../devices/render.o ../devices/rescale.o ../devices/record.o
 
-SWF = ../librfxswf.a ../libpdf.a ../libgfx.a -lstdc++
-test: ../libbase.a ../libgfx.a test.c $(OBJS) poly.h convert.h
-       $(CC) test.c $(OBJS) $(SWF) ../libbase.a ../libgfx.a -o test $(LIBS)
+stroke: test_stroke.c $(OBJS) ../libgfxswf.a ../librfxswf.a ../libbase.a 
+       $(CC) test_stroke.c $(OBJS) ../librfxswf.a ../libgfxswf.a $(GFX) ../libbase.a -o stroke $(LIBS)
+
+SWF = ../librfxswf.a ../libpdf.a -lstdc++
+test: ../libbase.a test.c $(OBJS) poly.h convert.h $(GFX) 
+       $(CC) test.c $(OBJS) $(SWF) ../libbase.a $(GFX) -o test $(LIBS)
 
 clean: 
        rm -f *.o test stroke
index 3d9763b..c6e365d 100644 (file)
@@ -345,8 +345,8 @@ void gfxdrawer_target_poly(gfxdrawer_t*d, double gridsize)
 {
     polydraw_internal_t*i = (polydraw_internal_t*)rfx_calloc(sizeof(polydraw_internal_t));
     d->internal = i;
-    i->lastx = 0x7fffffff; // convert_coord can never return this value
-    i->lasty = 0x7fffffff;
+    i->lastx = INVALID_COORD; // convert_coord can never return this value
+    i->lasty = INVALID_COORD;
     d->moveTo = polydraw_moveTo;
     d->lineTo = polydraw_lineTo;
     d->splineTo = polydraw_splineTo;
@@ -356,6 +356,7 @@ void gfxdrawer_target_poly(gfxdrawer_t*d, double gridsize)
     i->z = 1.0 / gridsize;
 }
 
+#if 0
 gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly)
 {
     gfxpolystroke_t*stroke;
@@ -382,6 +383,77 @@ gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly)
     l[count-1].next = 0;
     return l;
 }
+#endif
+
+gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly)
+{
+    gfxpolystroke_t*stroke;
+    int count = 0;
+    if(!poly->strokes)
+       return 0;
+    dict_t*d = dict_new2(&point_type);
+    dict_t*todo = dict_new2(&ptr_type);
+    for(stroke=poly->strokes;stroke;stroke=stroke->next) {
+       dict_put(todo, stroke, stroke);
+       assert(stroke->num_points>1);
+       count += stroke->num_points;
+       if(stroke->dir == DIR_UP) {
+           dict_put(d, &stroke->points[stroke->num_points-1], stroke);
+       } else {
+           dict_put(d, &stroke->points[0], stroke);
+       }
+    }
+    gfxpolystroke_t*next_todo = poly->strokes;
+    gfxline_t*l = malloc(sizeof(gfxline_t)*count);
+    count = 0;
+    stroke = poly->strokes;
+    point_t last = {INVALID_COORD, INVALID_COORD};
+    while(stroke) {
+       assert(dict_contains(todo, stroke));
+       int t;
+       int pos = 0;
+       int incr = 1;
+       if(stroke->dir == DIR_UP) {
+           pos = stroke->num_points-1;
+           incr = -1;
+       }
+       if(last.x != stroke->points[pos].x || last.y != stroke->points[pos].y) {
+           l[count].x = stroke->points[pos].x * poly->gridsize;
+           l[count].y = stroke->points[pos].y * poly->gridsize;
+           l[count].type = gfx_moveTo;
+           l[count].next = &l[count+1];
+           count++;
+       }
+       pos += incr;
+       for(t=1;t<stroke->num_points;t++) {
+           l[count].x = stroke->points[pos].x * poly->gridsize;
+           l[count].y = stroke->points[pos].y * poly->gridsize;
+           l[count].type = gfx_lineTo;
+           l[count].next = &l[count+1];
+           count++;
+           pos += incr;
+       }
+       last = stroke->points[pos-incr];
+       char del = dict_del(todo, stroke);
+       assert(del);
+       assert(!dict_contains(todo, stroke));
+
+       /* try to find a poly which starts at the point we drew last */
+       stroke = dict_lookup(d, &last);
+       while(!dict_contains(todo, stroke)) {
+           stroke = next_todo;
+           if(!next_todo) {
+               stroke = 0;
+               break;
+           }
+           next_todo = next_todo->next;
+       }
+    }
+    l[count-1].next = 0;
+    dict_destroy(todo);
+    dict_destroy(d);
+    return l;
+}
 
 static windcontext_t onepolygon = {1};
 gfxline_t* gfxpoly_circular_to_evenodd(gfxline_t*line, double gridsize)
index 72d5ab1..efb51fe 100644 (file)
@@ -3,7 +3,6 @@
 #include <math.h>
 #include "../mem.h"
 #include "../types.h"
-#include "../q.h"
 #include "../MD5.h"
 #include "poly.h"
 #include "active.h"
@@ -69,7 +68,7 @@ static void point_free(void*o)
     p->y = 0;
     free(p);
 }
-static type_t point_type = {
+type_t point_type = {
     equals: point_equals,
     hash: point_hash,
     dup: point_dup,
index 270734f..d1d5154 100644 (file)
@@ -6,7 +6,7 @@
 #include "../types.h"
 
 //#define DEBUG
-//#define CHECKS
+#define CHECKS
 
 /* features */
 #define SPLAY
@@ -16,10 +16,12 @@ typedef enum {DIR_UP, DIR_DOWN, DIR_UNKNOWN} segment_dir_t;
 typedef enum {EVENT_CROSS, EVENT_END, EVENT_START, EVENT_HORIZONTAL} eventtype_t;
 typedef enum {SLOPE_POSITIVE, SLOPE_NEGATIVE} slope_t;
 
+#define INVALID_COORD (0x7fffffff)
 typedef struct _point {
     int32_t x;
     int32_t y;
 } point_t;
+type_t point_type;
 
 typedef struct _fillstyle {
     void*internal;
diff --git a/lib/gfxpoly/stroke.h b/lib/gfxpoly/stroke.h
new file mode 100644 (file)
index 0000000..5f54a6e
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __stroke_h__
+#define __stroke_h__
+#include "../gfxdevice.h"
+#include "poly.h"
+gfxpoly_t* gfxpoly_from_stroke(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit, double gridsize);
+#endif
index ccf2a3f..6530340 100644 (file)
@@ -190,6 +190,10 @@ int test0(int argn, char*argv[])
     gfxline_free(box1);
     gfxline_free(box2);
     gfxpoly_t*poly3 = gfxpoly_process(poly1, poly2, &windrule_intersect, &twopolygons);
+    gfxpoly_dump(poly3);
+    gfxline_t*line = gfxline_from_gfxpoly(poly3);
+    gfxline_dump(line, stdout, "");
+    gfxline_free(line);
     gfxpoly_destroy(poly1);
     gfxpoly_destroy(poly2);
     gfxpoly_destroy(poly3);
index 9068c57..faaff03 100644 (file)
@@ -1,6 +1,7 @@
 #include <math.h>
 #include "../gfxtools.h"
 #include "stroke.h"
+#include "convert.h"
 
 int main()
 {