polygon intersector: improved test routines
[swftools.git] / lib / gfxpoly / test.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <assert.h>
4 #include <memory.h>
5 #include <math.h>
6 #include "../gfxtools.h"
7 #include "poly.h"
8 #include "convert.h"
9 #include "renderpoly.h"
10
11 gfxline_t*mkstar(int x1, int y1, int x2, int y2)
12 {
13     gfxline_t*l=0,*line = 0;
14     int x;
15     for(x=x1;x<=x2;x+=50) {
16         l = rfx_calloc(sizeof(gfxline_t));
17         l->type = gfx_moveTo;
18         l->x = x;l->y = y1;
19         line = gfxline_append(line, l);
20
21         l = rfx_calloc(sizeof(gfxline_t));
22         l->type = gfx_lineTo;
23         l->x = x2-x;l->y = y2;
24         line = gfxline_append(line, l);
25     }
26     return line;
27 }
28
29 int test1()
30 {
31     gfxline_t*box1 = gfxline_makerectangle(50,50,150,150);
32     // put box2 and box3 on top of each other *snicker*
33     gfxline_t*box2 = gfxline_makerectangle(100,100,200,200);
34     gfxline_t*box3 = gfxline_makerectangle(100,100,200,200);
35     gfxline_t*star = mkstar(50,50, 150,150);
36     gfxline_t*b = 0;
37     b = gfxline_append(b, box1);
38     b = gfxline_append(b, box2);
39     b = gfxline_append(b, box3);
40     b = gfxline_append(b, star);
41
42     gfxmatrix_t matrix;
43     memset(&matrix, 0, sizeof(gfxmatrix_t));
44     double ua=0.1;
45     matrix.m00=cos(ua);matrix.m10=sin(ua);
46     matrix.m01=-sin(ua);matrix.m11=cos(ua);
47
48     gfxline_transform(b, &matrix);
49     gfxpoly_t*poly = gfxpoly_fillToPoly(b, 0.05);
50     gfxline_free(box1);
51     gfxline_free(box2);
52     gfxline_free(box3);
53     gfxline_free(star);
54
55     gfxpoly_dump(poly);
56     gfxpoly_process(poly, &windrule_evenodd);
57 }
58
59 int test_square(int width, int height, int num, double gridsize, char bitmaptest)
60 {
61     int t;
62     gfxline_t* line = malloc(sizeof(gfxline_t)*num);
63     for(t=0;t<num;t++) {
64         line[t].type = t?gfx_lineTo:gfx_moveTo;
65         line[t].x = (lrand48()%width);
66         line[t].y = (lrand48()%height);
67         line[t].next = &line[t+1];
68     }
69     line[num-1].x = line[0].x;
70     line[num-1].y = line[0].y;
71     line[num-1].next = 0;
72     
73     gfxpoly_t*poly = gfxpoly_fillToPoly(line, gridsize);
74     gfxline_free(line);
75
76     windrule_t*rule = &windrule_circular;
77     gfxpoly_t*poly2 = gfxpoly_process(poly, rule);
78     if(bitmaptest) {
79         intbbox_t bbox = intbbox_new(0, 0, width, height);
80         unsigned char*bitmap1 = render_polygon(poly, &bbox, 1.0, rule);
81         unsigned char*bitmap2 = render_polygon(poly2, &bbox, 1.0, &windrule_evenodd);
82         if(!compare_bitmaps(&bbox, bitmap1, bitmap2)) {
83             save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
84             assert(!"bitmaps don't match");
85         }
86     }
87     gfxpoly_destroy(poly2);
88     gfxpoly_destroy(poly);
89 }
90
91 int test2()
92 {
93     test_square(400,400, 3, 0.05, 1);
94
95     int t;
96     for(t=0;t<400;t++) {
97         test_square(400,400, 50, 0.05, 1);
98         test_square(200,3, 1000, 1.0, 0);
99         test_square(3,200, 1000, 1.0, 0);
100         test_square(10,10, 200, 1.0, 0);
101     }
102 }
103
104 #include "../rfxswf.h"
105 void test3()
106 {
107 #undef N
108 #undef RANGE
109 #define N 100
110 #define RANGE 400
111
112     int i;
113     gfxline_t* line = malloc(sizeof(gfxline_t)*N*2);
114     for(i=0;i<N;i++) {
115         line[i].type = i?gfx_lineTo:gfx_moveTo;
116         line[i].x = lrand48()%RANGE - RANGE/2;
117         line[i].y = lrand48()%RANGE - RANGE/2;
118         line[i].next = &line[i+1];
119         line[N*2-i-1].type = gfx_lineTo;
120         line[N*2-i-1].x = line[i].x;
121         line[N*2-i-1].y = line[i].y;
122         line[N*2-i-1].next = &line[N*2-i];
123     }
124     line[N*2-1].next = 0;
125
126     line[N-1].x = line[0].x;
127     line[N-1].y = line[0].y;
128     line[N-1].next = 0;
129
130     gfxmatrix_t m;
131     memset(&m, 0, sizeof(m));
132
133     SWF swf;
134     memset(&swf, 0, sizeof(SWF));
135     swf.movieSize.xmax = RANGE*20*1.41;
136     swf.movieSize.ymax = RANGE*20*1.41;
137     swf.fileVersion = 9;
138     swf.frameRate = 25*0x100;
139     TAG * tag = swf.firstTag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR);
140     swf_SetU8(tag, 0);
141     swf_SetU8(tag, 0);
142     swf_SetU8(tag, 0);
143
144     int t;
145     for(t=0;t<360;t++) {
146         m.m00 = cos(t*M_PI/180.0);
147         m.m01 = sin(t*M_PI/180.0);
148         m.m10 = -sin(t*M_PI/180.0);
149         m.m11 = cos(t*M_PI/180.0);
150         m.tx = RANGE*1.41/2;
151         m.ty = RANGE*1.41/2;
152         gfxline_t*l = gfxline_clone(line);
153         gfxline_transform(l, &m);
154         
155         gfxpoly_t*poly = gfxpoly_fillToPoly(l, 0.05);
156         gfxpoly_t*poly2 = gfxpoly_process(poly, &windrule_circular);
157
158         tag = swf_InsertTag(tag, ST_DEFINESHAPE);
159         SHAPE* s;
160         swf_ShapeNew(&s);
161         RGBA rgb;
162         rgb.r = rgb.g = 0x00; rgb.b = 0xff;
163         rgb.a = 255;
164         int fs = swf_ShapeAddSolidFillStyle(s,&rgb);
165         int ls = swf_ShapeAddLineStyle(s,20,&rgb);
166         swf_SetU16(tag,t+1);
167         swf_SetRect(tag,&swf.movieSize);
168         swf_SetShapeHeader(tag,s);
169
170 #define FILL
171 #ifdef FILL
172         swf_ShapeSetAll(tag,s,0,0,0,fs,0);
173         edge_t*e = poly2->edges;
174         while(e) {
175             swf_ShapeSetMove(tag, s, e->a.x, e->a.y);
176             swf_ShapeSetLine(tag, s, e->b.x - e->a.x, e->b.y - e->a.y);
177             e = e->next;
178         }
179 #else
180         swf_ShapeSetAll(tag,s,0,0,ls,0,0);
181         edge_t*e = poly2->edges;
182         while(e) {
183             swf_ShapeSetMove(tag, s, e->a.x, e->a.y);
184             swf_ShapeSetLine(tag, s, e->b.x - e->a.x, e->b.y - e->a.y);
185             
186             swf_ShapeSetCircle(tag, s, e->a.x, e->a.y, 5*20, 5*20);
187             swf_ShapeSetCircle(tag, s, e->b.x, e->b.y, 5*20, 5*20);
188             e = e->next;
189         }
190 #endif
191
192         swf_ShapeSetEnd(tag);
193         swf_ShapeFree(s);
194
195         gfxpoly_destroy(poly);
196         gfxpoly_destroy(poly2);
197
198         gfxline_free(l);
199    
200         if(t) {
201             tag = swf_InsertTag(tag,ST_REMOVEOBJECT2);
202             swf_SetU16(tag, t);
203         }
204         tag = swf_InsertTag(tag,ST_PLACEOBJECT2);
205         swf_ObjectPlace(tag,t+1,t+1,NULL,NULL,NULL);
206
207         tag = swf_InsertTag(tag, ST_SHOWFRAME);
208     }
209     tag = swf_InsertTag(tag, ST_END);
210
211     swf_SaveSWF(&swf, "test.swf");
212 }
213
214 #include <dirent.h>
215 void test4()
216 {
217     char*dir = "ps";
218     DIR*_dir = opendir(dir);
219     if(!_dir) return;
220     struct dirent*file;
221     while(1) {
222         file = readdir(_dir);
223         if (!file) 
224             break;
225         if(!strstr(file->d_name, ".ps")) 
226             continue;
227
228         char* filename = allocprintf("%s/%s", dir, file->d_name);
229         windrule_t*rule = &windrule_evenodd;
230         gfxpoly_t*poly = gfxpoly_from_file(filename, 0.01);
231         free(filename);
232
233         double zoom = 1.0;
234         intbbox_t bbox = intbbox_from_polygon(poly, zoom);
235
236         if(!gfxpoly_check(poly)) {
237             printf("bad polygon\n");
238             continue;
239         }
240
241         gfxpoly_t*poly2 = gfxpoly_process(poly, rule);
242         unsigned char*bitmap1 = render_polygon(poly, &bbox, zoom, rule);
243         unsigned char*bitmap2 = render_polygon(poly2, &bbox, zoom, &windrule_evenodd);
244         if(!bitmap_ok(&bbox, bitmap1) || !bitmap_ok(&bbox, bitmap2)) {
245             save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
246             assert(!"error in bitmaps");
247         }
248         if(!compare_bitmaps(&bbox, bitmap1, bitmap2)) {
249             save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
250             assert(!"bitmaps don't match");
251         }
252         gfxpoly_destroy(poly2);
253     }
254 }
255
256 int main()
257 {
258     test4();
259 }