From 2cdbdbb4012575119c1a92e9c4662df9f4e81737 Mon Sep 17 00:00:00 2001 From: Matthias Kramm Date: Fri, 5 Jun 2009 17:53:42 +0200 Subject: [PATCH] optimized gfxpoly to gfxline conversion --- lib/gfxpoly/Makefile | 16 +++++----- lib/gfxpoly/convert.c | 76 +++++++++++++++++++++++++++++++++++++++++++-- lib/gfxpoly/poly.c | 3 +- lib/gfxpoly/poly.h | 4 ++- lib/gfxpoly/stroke.h | 6 ++++ lib/gfxpoly/test.c | 4 +++ lib/gfxpoly/test_stroke.c | 1 + 7 files changed, 98 insertions(+), 12 deletions(-) create mode 100644 lib/gfxpoly/stroke.h diff --git a/lib/gfxpoly/Makefile b/lib/gfxpoly/Makefile index 36b6b2e..2065984 100644 --- a/lib/gfxpoly/Makefile +++ b/lib/gfxpoly/Makefile @@ -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 diff --git a/lib/gfxpoly/convert.c b/lib/gfxpoly/convert.c index 3d9763b..c6e365d 100644 --- a/lib/gfxpoly/convert.c +++ b/lib/gfxpoly/convert.c @@ -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;tnum_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) diff --git a/lib/gfxpoly/poly.c b/lib/gfxpoly/poly.c index 72d5ab1..efb51fe 100644 --- a/lib/gfxpoly/poly.c +++ b/lib/gfxpoly/poly.c @@ -3,7 +3,6 @@ #include #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, diff --git a/lib/gfxpoly/poly.h b/lib/gfxpoly/poly.h index 270734f..d1d5154 100644 --- a/lib/gfxpoly/poly.h +++ b/lib/gfxpoly/poly.h @@ -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 index 0000000..5f54a6e --- /dev/null +++ b/lib/gfxpoly/stroke.h @@ -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 diff --git a/lib/gfxpoly/test.c b/lib/gfxpoly/test.c index ccf2a3f..6530340 100644 --- a/lib/gfxpoly/test.c +++ b/lib/gfxpoly/test.c @@ -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); diff --git a/lib/gfxpoly/test_stroke.c b/lib/gfxpoly/test_stroke.c index 9068c57..faaff03 100644 --- a/lib/gfxpoly/test_stroke.c +++ b/lib/gfxpoly/test_stroke.c @@ -1,6 +1,7 @@ #include #include "../gfxtools.h" #include "stroke.h" +#include "convert.h" int main() { -- 1.7.10.4