all: test stroke
include ../../Makefile.common
-CC = gcc -g
+CC = gcc -O3 -fomit-frame-pointer
#CC = gcc -O3
../libbase.a: ../q.c ../q.h ../mem.c ../mem.h
xrow.o: xrow.c xrow.h ../q.h ../mem.h
$(CC) -c xrow.c -o xrow.o
-stroke: stroke.c ../libgfx.a ../libbase.a ../librfxswf.a ../libgfxswf.a
- $(CC) stroke.c ../libgfx.a ../libbase.a ../librfxswf.a ../libgfxswf.a -o stroke $(LIBS)
+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)
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)
clean:
- rm -f *.o test
+ rm -f *.o test stroke
data->poly->strokes = 0;
}
-gfxpoly_t* gfxpoly_from_gfxline(gfxline_t*line, double gridsize)
+gfxpoly_t* gfxpoly_from_fill(gfxline_t*line, double gridsize)
{
polywriter_t writer;
gfxpolywriter_init(&writer);
typedef struct _polydraw_internal
{
+ double lx, ly;
int32_t lastx, lasty;
double z;
+ char last;
polywriter_t writer;
} polydraw_internal_t;
if(i->lastx != x || i->lasty != y) {
i->writer.moveto(&i->writer, x, y);
}
+ i->lx = _x;
+ i->ly = _y;
i->lastx = x;
i->lasty = y;
+ i->last = 1;
}
static void polydraw_lineTo(gfxdrawer_t*d, gfxcoord_t _x, gfxcoord_t _y)
{
polydraw_internal_t*i = (polydraw_internal_t*)d->internal;
+ if(!i->last) {
+ polydraw_moveTo(d, _x, _y);
+ return;
+ }
int32_t x = convert_coord(_x, i->z);
int32_t y = convert_coord(_y, i->z);
if(i->lastx != x || i->lasty != y) {
i->writer.lineto(&i->writer, x, y);
}
+ i->lx = _x;
+ i->ly = _y;
i->lastx = x;
i->lasty = y;
+ i->last = 1;
}
static void polydraw_splineTo(gfxdrawer_t*d, gfxcoord_t sx, gfxcoord_t sy, gfxcoord_t x, gfxcoord_t y)
{
polydraw_internal_t*i = (polydraw_internal_t*)d->internal;
- double c = fabs(x-2*sx+i->lastx) + fabs(y-2*sy+i->lasty);
+ if(!i->last) {
+ polydraw_moveTo(d, x, y);
+ return;
+ }
+ double c = fabs(x-2*sx+i->lx) + fabs(y-2*sy+i->ly);
int parts = (int)(sqrt(c)*SUBFRACTION);
if(!parts) parts = 1;
int t;
int32_t nx,ny;
for(t=0;t<parts;t++) {
- nx = convert_coord((double)(t*t*x + 2*t*(parts-t)*sx + (parts-t)*(parts-t)*i->lastx)/(double)(parts*parts), i->z);
- ny = convert_coord((double)(t*t*y + 2*t*(parts-t)*sy + (parts-t)*(parts-t)*i->lasty)/(double)(parts*parts), i->z);
+ nx = convert_coord((double)(t*t*x + 2*t*(parts-t)*sx + (parts-t)*(parts-t)*i->lx)/(double)(parts*parts), i->z);
+ ny = convert_coord((double)(t*t*y + 2*t*(parts-t)*sy + (parts-t)*(parts-t)*i->ly)/(double)(parts*parts), i->z);
if(nx != i->lastx || ny != i->lasty) {
i->writer.lineto(&i->writer, nx, ny);
i->lastx = nx; i->lasty = ny;
ny = convert_coord(y,i->z);
if(nx != i->lastx || ny != i->lasty) {
i->writer.lineto(&i->writer, nx, ny);
- i->lastx = nx; i->lasty = ny;
}
+ i->lx = x;
+ i->ly = y;
+ i->lastx = nx;
+ i->lasty = ny;
+ i->last = 1;
}
static void* polydraw_result(gfxdrawer_t*d)
{
i->z = 1.0 / gridsize;
}
+gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly)
+{
+ gfxpolystroke_t*stroke;
+ int count = 0;
+ for(stroke=poly->strokes;stroke;stroke=stroke->next) {
+ assert(stroke->num_points);
+ count += stroke->num_points;
+ }
+ if(!count) return 0;
+ gfxline_t*l = malloc(sizeof(gfxline_t)*count);
+ count = 0;
+ /* TODO: it might make sense to concatenate strokes */
+ for(stroke=poly->strokes;stroke;stroke=stroke->next) {
+ int t;
+ for(t=0;t<stroke->num_points;t++) {
+ l[count+t].x = stroke->points[t].x * poly->gridsize;
+ l[count+t].y = stroke->points[t].y * poly->gridsize;
+ l[count+t].type = gfx_lineTo;
+ l[count+t].next = &l[count+t+1];
+ }
+ l[count].type = gfx_moveTo;
+ count+=stroke->num_points;
+ }
+ l[count-1].next = 0;
+ return l;
+}
+
void gfxdrawer_target_poly(gfxdrawer_t*d, double gridsize);
void gfxpolywriter_init(polywriter_t*w);
-gfxpoly_t* gfxpoly_from_gfxline(gfxline_t*line, double gridsize);
+gfxpoly_t* gfxpoly_from_fill(gfxline_t*line, double gridsize);
gfxpoly_t* gfxpoly_from_file(const char*filename, double gridsize);
void gfxpoly_destroy(gfxpoly_t*poly);
+gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly);
+
#endif //__poly_convert_h__
} status_t;
+int gfxpoly_num_segments(gfxpoly_t*poly)
+{
+ gfxpolystroke_t*stroke = poly->strokes;
+ int count = 0;
+ for(;stroke;stroke=stroke->next) {
+ count++;
+ }
+ return count;
+}
int gfxpoly_size(gfxpoly_t*poly)
{
int s,t;
}
}
if(s) {
-#ifdef DEBUG
- fprintf(stderr, "attaching contingency of stroke %08x to segment [%d] %s\n",
- stroke, s, s->delta.y?"":"(horizontal)");
-#endif
s->stroke = stroke;
s->stroke_pos = pos;
}
s->fs_out = status->windrule->diff(&wind, &s->wind);
#ifdef DEBUG
- fprintf(stderr, "[%d] %s/%d/%s/%s %s\n", s->nr, s->dir==DIR_UP?"up":"down", s->wind.wind_nr, s->wind.is_filled?"fill":"nofill", s->fs_out?"draw":"omit",
+ fprintf(stderr, "[%d] dir=%s wind=%d wind.filled=%s fs_old/new=%s/%s %s\n", s->nr, s->dir==DIR_UP?"up":"down", s->wind.wind_nr, s->wind.is_filled?"fill":"nofill",
+ fs_old?"draw":"omit", s->fs_out?"draw":"omit",
fs_old!=s->fs_out?"CHANGED":"");
#endif
assert(!(!s->changed && fs_old!=s->fs_out));
e = hqueue_get(&hqueue);
} while(e && y == e->p.y);
- assert(!fill); // check that polygon is not bleeding
+#ifdef CHECKS
+ char bleeding = fill;
+ assert(!bleeding);
+#endif
}
actlist_destroy(actlist);
hqueue_destroy(&hqueue);
}
-gfxpoly_t* gfxpoly_process(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*context)
+gfxpoly_t* gfxpoly_process(gfxpoly_t*poly1, gfxpoly_t*poly2, windrule_t*windrule, windcontext_t*context)
{
- current_polygon = poly;
+ current_polygon = poly1;
status_t status;
memset(&status, 0, sizeof(status_t));
queue_init(&status.queue);
- gfxpoly_enqueue(poly, &status.queue, 0, /*polygon nr*/0);
+ gfxpoly_enqueue(poly1, &status.queue, 0, /*polygon nr*/0);
+ if(poly2) {
+ assert(poly1->gridsize == poly2->gridsize);
+ gfxpoly_enqueue(poly2, &status.queue, 0, /*polygon nr*/1);
+ }
status.windrule = windrule;
status.context = context;
xrow_destroy(status.xrow);
gfxpoly_t*p = (gfxpoly_t*)malloc(sizeof(gfxpoly_t));
- p->gridsize = poly->gridsize;
+ p->gridsize = poly1->gridsize;
p->strokes = status.strokes;
- gfxpoly_dump(p);
add_horizontals(p, &windrule_evenodd, context); // output is always even/odd
return p;
}
+
+static windcontext_t twopolygons = {2};
+gfxpoly_t* gfxpoly_intersect(gfxpoly_t*p1, gfxpoly_t*p2)
+{
+ return gfxpoly_process(p1, p2, &windrule_intersect, &twopolygons);
+}
+gfxpoly_t* gfxpoly_union(gfxpoly_t*p1, gfxpoly_t*p2)
+{
+ return gfxpoly_process(p1, p2, &windrule_union, &twopolygons);
+}
} point_t;
typedef struct _fillstyle {
- char is_filled;
+ void*internal;
} fillstyle_t;
typedef struct _windstate
void gfxpoly_fail(char*expr, char*file, int line, const char*function);
char gfxpoly_check(gfxpoly_t*poly);
+int gfxpoly_num_segments(gfxpoly_t*poly);
int gfxpoly_size(gfxpoly_t*poly);
void gfxpoly_dump(gfxpoly_t*poly);
void gfxpoly_save(gfxpoly_t*poly, const char*filename);
-gfxpoly_t* gfxpoly_process(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*context);
+gfxpoly_t* gfxpoly_process(gfxpoly_t*poly1, gfxpoly_t*poly2, windrule_t*windrule, windcontext_t*context);
+
+gfxpoly_t* gfxpoly_intersect(gfxpoly_t*p1, gfxpoly_t*p2);
+gfxpoly_t* gfxpoly_union(gfxpoly_t*p1, gfxpoly_t*p2);
#ifndef CHECKS
#ifdef assert
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
-#include <assert.h>
#include "../gfxdevice.h"
#include "../gfxtools.h"
+#include "poly.h"
+#include "wind.h"
+#include "convert.h"
/* notice: left/right for a coordinate system where y goes up, not down */
typedef enum {LEFT=0, RIGHT=1} leftright_t;
//double dy = (-c*step/2 + lasty);
double dx = x + cos(a-step/2)*r2;
double dy = y + sin(a-step/2)*r2;
- //draw->lineto(draw, xx, yy);
+ //draw->lineTo(draw, xx, yy);
draw->splineTo(draw, dx, dy, xx, yy);
lastx = xx;
lasty = yy;
{
char do_draw=0;
leftright_t lastdir = LEFT;
- int start = 0;
- int end = num-1;
- int incr = 1;
- int pos = 0;
width/=2;
if(width<=0)
num--;
}
}
+
+ int start = 0;
+ int end = num-1;
+ int incr = 1;
+ int pos = 0;
double alimit = atan(limit / width);
adding a stroke outline to the right side and line caps after each
pass */
int pass;
+ double lastw=0;
for(pass=0;pass<2;pass++) {
int pos;
- double lastw=0;
for(pos=start;pos!=end;pos+=incr) {
//printf("%d) %.2f %.2f\n", pos, p[pos].x, p[pos].y);
double dx = p[pos+incr].x - p[pos].x;
lastw = w;
}
- /* draw stroke ends */
+ /* draw stroke ends. We draw duplicates of some points here. The drawer
+ implementationshould be smart enough to remove them. */
+ double c = cos(lastw-M_PI/2)*width;
+ double s = sin(lastw-M_PI/2)*width;
if(cap == gfx_capButt) {
- double c = cos(lastw-M_PI/2)*width;
- double s = sin(lastw-M_PI/2)*width;
+ draw->lineTo(draw, p[pos].x+c, p[pos].y+s);
draw->lineTo(draw, p[pos].x-c, p[pos].y-s);
} else if(cap == gfx_capRound) {
+ draw->lineTo(draw, p[pos].x+c, p[pos].y+s);
draw_arc(draw, p[pos].x, p[pos].y, lastw-M_PI/2, lastw+M_PI/2, width);
} else if(cap == gfx_capSquare) {
double c = cos(lastw-M_PI/2)*width;
double s = sin(lastw-M_PI/2)*width;
+ draw->lineTo(draw, p[pos].x+c, p[pos].y+s);
draw->lineTo(draw, p[pos].x+c-s, p[pos].y+s+c);
draw->lineTo(draw, p[pos].x-c-s, p[pos].y-s+c);
draw->lineTo(draw, p[pos].x-c, p[pos].y-s);
start=num-1;
end=0;
incr=-1;
+ lastw += M_PI; // for dots
}
}
free(points);
}
-int main()
+static windcontext_t onepolygon = {1};
+gfxpoly_t* gfxpoly_from_stroke(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit, double gridsize)
{
- gfxline_t l[4];
- l[0].type = gfx_moveTo;
- l[0].x = 100;l[0].sx=2;
- l[0].y = 100;l[0].sy=2;
- l[0].next = &l[1];
- l[1].type = gfx_lineTo;
- l[1].x = 100;l[1].sx=2;
- l[1].y = 200;l[1].sy=-2;
- l[1].next = &l[2];
- l[2].type = gfx_lineTo;
- l[2].x = 250;l[2].sx=4;
- l[2].y = 200;l[2].sy=0;
- l[2].next = &l[3];
- l[3].type = gfx_lineTo;
- l[3].x = 200;l[3].sx=0;
- l[3].y = 150;l[3].sy=4;
- l[3].next = 0;
-
-
- gfxdevice_t dev;
- gfxdevice_swf_init(&dev);
- dev.setparameter(&dev, "framerate", "25.0");
- int t;
- for(t=0;t<300;t++) {
- dev.startpage(&dev, 700,700);
- gfxline_t*g = l;
- while(g) {
- g->x += g->sx;
- g->y += g->sy;
- if(g->x<200) {g->x=400-g->x;g->sx=-g->sx;}
- if(g->y<200) {g->y=400-g->y;g->sy=-g->sy;}
- if(g->x>500) {g->x=1000-g->x;g->sx=-g->sx;}
- if(g->y>500) {g->y=1000-g->y;g->sy=-g->sy;}
- g = g->next;
- }
- gfxdrawer_t d;
- gfxdrawer_target_gfxline(&d);
- double width = t/3.0;
- if(width>50) width=100-width;
-
- draw_stroke(l, &d, width, gfx_capRound, gfx_joinBevel, 500);
- gfxline_t*line = (gfxline_t*)d.result(&d);
- //gfxline_dump(line, stdout, "");
-
- gfxcolor_t black = {255,0,0,0};
- gfxcolor_t cyan = {255,0,128,128};
- dev.stroke(&dev, l, 2, &black, gfx_capRound, gfx_joinRound, 0);
- dev.stroke(&dev, line, 2, &cyan, gfx_capRound, gfx_joinRound, 0);
- gfxline_free(line);
- dev.endpage(&dev);
- }
-
- gfxresult_t* result = dev.finish(&dev);
- result->save(result, "test.swf");
- result->destroy(result);
+ gfxdrawer_t d;
+ gfxdrawer_target_poly(&d, gridsize);
+ draw_stroke(line, &d, width, cap_style, joint_style, miterLimit);
+ gfxpoly_t*poly = (gfxpoly_t*)d.result(&d);
+ assert(gfxpoly_check(poly));
+ gfxpoly_t*poly2 = gfxpoly_process(poly, 0, &windrule_circular, &onepolygon);
+ gfxpoly_destroy(poly);
+ return poly2;
}
+
}
static windcontext_t onepolygon = {1};
+static windcontext_t twopolygons = {2};
int test_speed()
{
m.ty = 400*1.41/2;
gfxline_t*l = gfxline_clone(b);
gfxline_transform(l, &m);
- gfxpoly_t*poly = gfxpoly_from_gfxline(b, 0.05);
+ gfxpoly_t*poly = gfxpoly_from_fill(b, 0.05);
- gfxpoly_t*poly2 = gfxpoly_process(poly, &windrule_evenodd, &onepolygon);
+ gfxpoly_t*poly2 = gfxpoly_process(poly, 0, &windrule_evenodd, &onepolygon);
gfxpoly_destroy(poly);
gfxpoly_destroy(poly2);
gfxline_free(l);
gfxline_free(b);
}
+int test0(int argn, char*argv[])
+{
+ gfxline_t*box1 = gfxline_makerectangle(-100,-100,100,100);
+ gfxline_t*box2 = gfxline_makerectangle(-100,-100,100,100);
+ gfxline_t*box3 = gfxline_makerectangle(-100,-100,100,100);
+ //gfxline_append(box2, box3);
+
+ gfxmatrix_t matrix;
+ memset(&matrix, 0, sizeof(gfxmatrix_t));
+ double ua=M_PI/4;
+ matrix.m00=cos(ua);matrix.m10=sin(ua);
+ matrix.m01=-sin(ua);matrix.m11=cos(ua);
+ //gfxline_transform(box1, &matrix);
+
+ //gfxline_t*b = 0;
+ //b = gfxline_append(b, box1);
+ //b = gfxline_append(b, box2);
+ //gfxline_dump(b, stderr, "");
+
+ gfxpoly_t*poly1 = gfxpoly_from_fill(box1, 0.05);
+ gfxpoly_t*poly2 = gfxpoly_from_fill(box2, 0.05);
+
+ gfxline_free(box1);
+ gfxline_free(box2);
+ gfxpoly_t*poly3 = gfxpoly_process(poly1, poly2, &windrule_intersect, &twopolygons);
+ gfxpoly_destroy(poly1);
+ gfxpoly_destroy(poly2);
+ gfxpoly_destroy(poly3);
+}
+
+
int test1(int argn, char*argv[])
{
gfxline_t*box1 = gfxline_makerectangle(50,50,150,150);
//gfxline_transform(b, &matrix);
gfxline_dump(b, stderr, "");
- gfxpoly_t*poly = gfxpoly_from_gfxline(b, 0.05);
+ gfxpoly_t*poly = gfxpoly_from_fill(b, 0.05);
gfxline_free(box1);
gfxline_free(box2);
gfxline_free(star);
gfxpoly_dump(poly);
- gfxpoly_t*poly2 = gfxpoly_process(poly, &windrule_evenodd, &onepolygon);
+ gfxpoly_t*poly2 = gfxpoly_process(poly, 0, &windrule_evenodd, &onepolygon);
gfxpoly_destroy(poly);
gfxpoly_destroy(poly2);
}
line[num-1].y = line[0].y;
line[num-1].next = 0;
- gfxpoly_t*poly1 = gfxpoly_from_gfxline(line, gridsize);
+ gfxpoly_t*poly1 = gfxpoly_from_fill(line, gridsize);
gfxline_free(line);
windrule_t*rule = &windrule_circular;
- gfxpoly_t*poly2 = gfxpoly_process(poly1, rule, &onepolygon);
+ gfxpoly_t*poly2 = gfxpoly_process(poly1, 0, rule, &onepolygon);
if(bitmaptest) {
intbbox_t bbox = intbbox_new(0, 0, width, height);
unsigned char*bitmap1 = render_polygon(poly1, &bbox, 1.0, rule, &onepolygon);
gfxline_t*l = gfxline_clone(line);
gfxline_transform(l, &m);
- gfxpoly_t*poly1 = gfxpoly_from_gfxline(l, 0.05);
+ gfxpoly_t*poly1 = gfxpoly_from_fill(l, 0.05);
- gfxpoly_t*poly2 = gfxpoly_process(poly1, rule, &onepolygon);
+ gfxpoly_t*poly2 = gfxpoly_process(poly1, 0, rule, &onepolygon);
tag = swf_InsertTag(tag, ST_DEFINESHAPE);
SHAPE* s;
continue;
}
- gfxpoly_t*poly2 = gfxpoly_process(poly1, rule, &onepolygon);
+ gfxpoly_t*poly2 = gfxpoly_process(poly1, 0, rule, &onepolygon);
int pass;
for(pass=0;pass<2;pass++) {
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_t*c = gfxpoly_from_fill(line, 0.05);
//gfxpoly_free(c);
- //gfxpoly_t*poly1 = gfxpoly_from_gfxline(line, 0.05);
- gfxpoly_t*poly1 = gfxpoly_from_gfxline(line, 0.05);
+ //gfxpoly_t*poly1 = gfxpoly_from_fill(line, 0.05);
+ gfxpoly_t*poly1 = gfxpoly_from_fill(line, 0.05);
//gfxline_dump(line, stderr, "");
//gfxpoly_dump(poly);
fprintf(stderr, "bad polygon or error in renderer\n");
return;
}
- gfxpoly_t*poly2 = gfxpoly_process(poly1, rule, &onepolygon);
+ gfxpoly_t*poly2 = gfxpoly_process(poly1, 0, rule, &onepolygon);
unsigned char*bitmap2 = render_polygon(poly2, &bbox, zoom, &windrule_evenodd, &onepolygon);
if(!bitmap_ok(&bbox, bitmap2)) {
save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
int main(int argn, char*argv[])
{
- test4(argn, argv);
+ test0(argn, argv);
}
--- /dev/null
+#include <math.h>
+#include "../gfxtools.h"
+#include "stroke.h"
+
+int main()
+{
+ gfxline_t l[512], f[256*5];
+
+ int width=700,height=700;
+ gfxdevice_t dev;
+ gfxdevice_swf_init(&dev);
+ dev.setparameter(&dev, "framerate", "25.0");
+ int t;
+ for(t=0;t<300;t++) {
+ dev.startpage(&dev, 700,700);
+ /*gfxline_t*g = l;
+ while(g) {
+ g->x += g->sx;
+ g->y += g->sy;
+ if(g->sx || g->sy) {
+ if(g->x<200) {g->x=400-g->x;g->sx=-g->sx;}
+ if(g->y<200) {g->y=400-g->y;g->sy=-g->sy;}
+ if(g->x>500) {g->x=1000-g->x;g->sx=-g->sx;}
+ if(g->y>500) {g->y=1000-g->y;g->sy=-g->sy;}
+ }
+ g = g->next;
+ }*/
+
+ int i;
+ for(i=0;i<512;i++) {
+ double a = i*0.05+t*M_PI/150;
+ double r = 50+i*0.5;
+ l[i].x = cos(a)*r + width/2;
+ l[i].y = sin(a)*r + height/2;
+ l[i].sx = (int)((l[i].x-width/2)/30);
+ l[i].sy = (int)((l[i].y-height/2)/30);
+ l[i].sx = l[i].sy = 0;
+ l[i].type = gfx_lineTo;
+ l[i].next = &l[i+1];
+ }
+ l[0].type = gfx_moveTo;
+ l[i-1].next = 0;
+
+ int xx,yy;
+ i = 0;
+ for(yy=0;yy<16;yy++)
+ for(xx=0;xx<16;xx++) if((xx^yy)&1) {
+ double x = -128+xx*64+t*128.0/300;
+ double y = -128+yy*64;//+t*64.0/300;
+ f[i].x = x;
+ f[i].y = y;
+ f[i].next = &f[i+1];f[i++].type = gfx_moveTo;
+ f[i].x = x+64;
+ f[i].y = y;
+ f[i].next = &f[i+1];f[i++].type = gfx_lineTo;
+ f[i].x = x+64;
+ f[i].y = y+64;
+ f[i].next = &f[i+1];f[i++].type = gfx_lineTo;
+ f[i].x = x;
+ f[i].y = y+64;
+ f[i].next = &f[i+1];f[i++].type = gfx_lineTo;
+ f[i].x = x;
+ f[i].y = y;
+ f[i].next = &f[i+1];f[i++].type = gfx_lineTo;
+ }
+ f[i-1].next = 0;
+
+ double width = 40;
+
+ //gfxdrawer_t d;
+ //gfxdrawer_target_gfxline(&d);
+ //draw_stroke(l, &d, width, gfx_capRound, gfx_joinBevel, 500);
+ //gfxline_t*line = (gfxline_t*)d.result(&d);
+
+ //gfxpoly_t*p = gfxpoly_fromstroke(l, width, gfx_capRound, gfx_joinRound, 500);
+ gfxpoly_t*p1 = gfxpoly_from_stroke(l, width, gfx_capRound, gfx_joinRound, 500, 0.05);
+ assert(gfxpoly_check(p1));
+
+ //gfxpoly_t*p2 = gfxpoly_from_fill(f, 0.05);
+ gfxline_t*l2 = gfxline_clone(l);
+
+ double c = cos(t*M_PI/75);
+ double s = sin(t*M_PI/75);
+ static int x1 = 0, xdir = 1;
+ static int y1 = 0, ydir = 5;
+ x1+=xdir; if(x1>=150) {x1=300-x1;xdir=-xdir;} if(x1<-150) {x1=-300-x1;xdir=-xdir;}
+ y1+=ydir; if(y1>=150) {y1=300-y1;ydir=-ydir;} if(y1<-150) {y1=-300-y1;ydir=-ydir;}
+ gfxmatrix_t m = { c, s, -(350+x1)*c-350*s+350,
+ -s, c, 350*s-(350+x1)*c+350};
+ gfxline_transform(l2, &m);
+ gfxpoly_t*p2 = gfxpoly_from_stroke(l2, width, gfx_capRound, gfx_joinRound, 500, 0.05);
+ assert(gfxpoly_check(p2));
+
+ gfxpoly_t*p3 = gfxpoly_intersect(p1, p2);
+ assert(gfxpoly_check(p3));
+
+ //gfxpoly_t*p4 = gfxpoly_from_fill(f, 0.05);
+ //gfxpoly_t*p5 = gfxpoly_intersect(p1, p4);
+
+ gfxline_t*line = gfxline_from_gfxpoly(p3);
+ gfxpoly_destroy(p1);
+ gfxpoly_destroy(p2);
+ gfxpoly_destroy(p3);
+
+ //gfxline_dump(line, stdout, "");
+
+ gfxcolor_t blue = {255,0,0,255};
+ gfxline_t*r = gfxline_makerectangle(0,0,700,700);
+ dev.fill(&dev, r, &blue);
+
+ gfxcolor_t black = {255,0,0,64};
+ gfxcolor_t white = {255,255,255,255};
+ gfxcolor_t cyan = {255,0,192,192};
+ //dev.stroke(&dev, l, 2, &black, gfx_capRound, gfx_joinRound, 0);
+ //dev.stroke(&dev, line, 2, &cyan, gfx_capRound, gfx_joinRound, 0);
+ dev.fill(&dev, line, &black);
+ gfxmatrix_t m2 = {1.0, 0, -10,
+ 0, 1.0, -10};
+ gfxline_transform(line, &m2);
+ dev.fill(&dev, line, &cyan);
+ dev.stroke(&dev, line, 2.0, &white, gfx_capRound, gfx_joinRound, 0);
+
+ gfxline_free(line);
+ dev.endpage(&dev);
+ }
+
+ gfxresult_t* result = dev.finish(&dev);
+ result->save(result, "test.swf");
+ result->destroy(result);
+}
windstate_t intersect_start(windcontext_t*context)
{
- windstate_t w;
- return w;
+ return windstate_nonfilled;
}
windstate_t intersect_add(windcontext_t*context, windstate_t left, fillstyle_t*edge, segment_dir_t dir, int master)
assert(master < context->num_polygons);
left.wind_nr ^= 1<<master;
- if(left.wind_nr == (1<<context->num_polygons)-1)
- left.is_filled = 1;
+ left.is_filled = (left.wind_nr == (1<<context->num_polygons)-1);
return left;
}
{
assert(master<sizeof(left.wind_nr)*8); //up to 32/64 polygons max
left.wind_nr ^= 1<<master;
- if(left.wind_nr!=0)
- left.is_filled = 1;
+ left.is_filled = (left.wind_nr!=0);
return left;
}
if(!i->start) {
fprintf(stderr, "Error: drawing startpoint is a spline\n");
- linedraw_moveTo(d, 0, 0);
+ linedraw_moveTo(d, x, y);
+ return;
}
l->type = gfx_splineTo;