888e4d6ab79e01e315980633d96d36aca775429b
[swftools.git] / lib / gfxpoly / test.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <memory.h>
4 #include <math.h>
5 #include "../gfxtools.h"
6 #include "poly.h"
7 #include "convert.h"
8 #include "renderpoly.h"
9
10 gfxline_t*mkstar(int x1, int y1, int x2, int y2)
11 {
12     gfxline_t*l=0,*line = 0;
13     int x;
14     for(x=x1;x<=x2;x+=50) {
15         l = rfx_calloc(sizeof(gfxline_t));
16         l->type = gfx_moveTo;
17         l->x = x;l->y = y1;
18         line = gfxline_append(line, l);
19
20         l = rfx_calloc(sizeof(gfxline_t));
21         l->type = gfx_lineTo;
22         l->x = x2-x;l->y = y2;
23         line = gfxline_append(line, l);
24     }
25     return line;
26 }
27
28 gfxline_t* mkrandomshape(int range, int n)
29 {
30     int i;
31     gfxline_t* line = malloc(sizeof(gfxline_t)*n*2);
32     for(i=0;i<n;i++) {
33         line[i].type = i?gfx_lineTo:gfx_moveTo;
34         line[i].x = lrand48()%range - range/2;
35         line[i].y = lrand48()%range - range/2;
36         line[i].next = &line[i+1];
37         line[n*2-i-1].type = gfx_lineTo;
38         line[n*2-i-1].x = line[i].x;
39         line[n*2-i-1].y = line[i].y;
40         line[n*2-i-1].next = &line[n*2-i];
41     }
42     line[n*2-1].next = 0;
43     line[n-1].x = line[0].x;
44     line[n-1].y = line[0].y;
45     line[n-1].next = 0;
46 }
47
48 gfxline_t* mkchessboard()
49 {
50     gfxline_t*b = 0;
51     int x,y;
52     unsigned int r = 0;
53     int spacing = 20;
54
55     int num_caros = 40;
56     int l = 5;
57     char do_centerpiece=1;
58
59     //int num_caros = 4;
60     //int l=1;
61     //char do_centerpiece=0;
62
63     for(x=-l;x<=l;x++) 
64     for(y=-l;y<=l;y++) {
65         /* pseudo random */ 
66         r = crc32_add_byte(r, x);r = crc32_add_byte(r, y);
67         if(r&1) {
68             gfxline_t*box;
69             if(r&2) {
70                 box = gfxline_makerectangle(x*spacing,y*spacing,(x+1)*spacing,(y+1)*spacing);
71             } else {
72                 box = gfxline_makerectangle((x+1)*spacing,y*spacing,x*spacing,(y+1)*spacing);
73             }
74             b = gfxline_append(b, box);
75         }
76     }
77
78     int t;
79     for(t=0;t<num_caros;t++) {
80         r = crc32_add_byte(r, t);
81         int x=(r%10-5)*spacing;
82         int y=((r>>4)%10-5)*spacing;
83         int sizex = ((r>>8)%4)*spacing;
84         int sizey = sizex;
85         if(r&65536)
86             sizex = -sizex;
87         gfxline_t*l = malloc(sizeof(gfxline_t)*5);
88         l[0].type = gfx_moveTo;l[0].next = &l[1];
89         l[1].type = gfx_lineTo;l[1].next = &l[2];
90         l[2].type = gfx_lineTo;l[2].next = &l[3];
91         l[3].type = gfx_lineTo;l[3].next = &l[4];
92         l[4].type = gfx_lineTo;l[4].next = 0;
93         l[0].x = x;
94         l[0].y = y-sizey;
95         l[1].x = x+sizex;
96         l[1].y = y;
97         l[2].x = x;
98         l[2].y = y+sizey;
99         l[3].x = x-sizex;
100         l[3].y = y;
101         l[4].x = x;
102         l[4].y = y-sizey;
103         gfxline_append(b, l);
104     }
105     if(do_centerpiece)
106     for(t=0;t<5;t++) {
107         gfxline_t*l = gfxline_makerectangle(-9*spacing,-10,9*spacing,10);
108         gfxmatrix_t matrix;
109         memset(&matrix, 0, sizeof(gfxmatrix_t));
110         double ua=t*0.43;
111         matrix.m00=cos(ua);matrix.m10=sin(ua);
112         matrix.m01=-sin(ua);matrix.m11=cos(ua);
113         gfxline_transform(l, &matrix);
114         gfxline_append(b, l);
115     }
116     return b;
117 }
118
119 int test0()
120 {
121     gfxline_t* b = mkchessboard();
122
123     gfxmatrix_t m;
124     memset(&m, 0, sizeof(gfxmatrix_t));
125     int t = 28;
126     m.m00 = cos(t*M_PI/180.0);
127     m.m01 = sin(t*M_PI/180.0);
128     m.m10 = -sin(t*M_PI/180.0);
129     m.m11 = cos(t*M_PI/180.0);
130     m.tx = 400*1.41/2;
131     m.ty = 400*1.41/2;
132     gfxline_transform(b, &m);
133
134     gfxpoly_t*poly = gfxpoly_from_gfxline(b, 0.05);
135     gfxpoly_t*poly2 = gfxpoly_process(poly, &windrule_evenodd);
136     gfxpoly_destroy(poly2);
137     gfxpoly_destroy(poly);
138 }
139
140 int test1(int argn, char*argv[])
141 {
142     gfxline_t*box1 = gfxline_makerectangle(50,50,150,150);
143     // put box2 and box3 on top of each other *snicker*
144     gfxline_t*box2 = gfxline_makerectangle(100,100,200,200);
145     gfxline_t*box3 = gfxline_makerectangle(100,100,200,200);
146     gfxline_t*star = mkstar(50,50, 150,150);
147     gfxline_t*b = 0;
148     b = gfxline_append(b, box1);
149     b = gfxline_append(b, box2);
150     b = gfxline_append(b, box3);
151     //b = gfxline_append(b, star);
152
153     gfxmatrix_t matrix;
154     memset(&matrix, 0, sizeof(gfxmatrix_t));
155     double ua=0.1;
156     matrix.m00=cos(ua);matrix.m10=sin(ua);
157     matrix.m01=-sin(ua);matrix.m11=cos(ua);
158
159     //gfxline_transform(b, &matrix);
160
161     gfxpoly_t*poly = gfxpoly_from_gfxline(b, 0.05);
162     gfxline_free(box1);
163     gfxline_free(box2);
164     gfxline_free(box3);
165     gfxline_free(star);
166
167     gfxpoly_dump(poly);
168     gfxpoly_t*poly2 = gfxpoly_process(poly, &windrule_evenodd);
169     gfxpoly_destroy(poly2);
170     gfxpoly_destroy(poly);
171 }
172
173 int test_square(int width, int height, int num, double gridsize, char bitmaptest)
174 {
175     int t;
176     gfxline_t* line = malloc(sizeof(gfxline_t)*num);
177     for(t=0;t<num;t++) {
178         line[t].type = t?gfx_lineTo:gfx_moveTo;
179         line[t].x = (lrand48()%width);
180         line[t].y = (lrand48()%height);
181         line[t].next = &line[t+1];
182     }
183     line[num-1].x = line[0].x;
184     line[num-1].y = line[0].y;
185     line[num-1].next = 0;
186     
187     gfxpoly_t*poly = gfxpoly_from_gfxline(line, gridsize);
188     gfxline_free(line);
189
190     windrule_t*rule = &windrule_circular;
191     gfxpoly_t*poly2 = gfxpoly_process(poly, rule);
192     if(bitmaptest) {
193         intbbox_t bbox = intbbox_new(0, 0, width, height);
194         unsigned char*bitmap1 = render_polygon(poly, &bbox, 1.0, rule);
195         unsigned char*bitmap2 = render_polygon(poly2, &bbox, 1.0, &windrule_evenodd);
196         if(!compare_bitmaps(&bbox, bitmap1, bitmap2)) {
197             save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
198             assert(!"bitmaps don't match");
199         }
200     }
201     gfxpoly_destroy(poly2);
202     gfxpoly_destroy(poly);
203 }
204
205 int test2(int argn, char*argv[])
206 {
207     test_square(400,400, 3, 0.05, 1);
208
209     int t;
210     for(t=0;t<400;t++) {
211         test_square(400,400, 50, 0.05, 1);
212         test_square(200,3, 1000, 1.0, 0);
213         test_square(3,200, 1000, 1.0, 0);
214         test_square(10,10, 200, 1.0, 0);
215     }
216 }
217
218 #include "../rfxswf.h"
219 void test3(int argn, char*argv[])
220 {
221 #undef N
222 #undef RANGE
223 #define N 100
224 #define RANGE 400
225
226     //gfxline_t*line = mkrandomshape(RANGE, N);
227     //windrule_t*rule = &windrule_circular;
228     gfxline_t*line = mkchessboard();
229     windrule_t*rule = &windrule_evenodd;
230
231     gfxmatrix_t m;
232     memset(&m, 0, sizeof(m));
233
234     SWF swf;
235     memset(&swf, 0, sizeof(SWF));
236     swf.movieSize.xmax = RANGE*20*1.41;
237     swf.movieSize.ymax = RANGE*20*1.41;
238     swf.fileVersion = 9;
239     swf.frameRate = 25*0x100;
240     TAG * tag = swf.firstTag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR);
241     swf_SetU8(tag, 0);
242     swf_SetU8(tag, 0);
243     swf_SetU8(tag, 0);
244
245     int t;
246     for(t=0;t<360;t++) {
247         m.m00 = cos(t*M_PI/180.0);
248         m.m01 = sin(t*M_PI/180.0);
249         m.m10 = -sin(t*M_PI/180.0);
250         m.m11 = cos(t*M_PI/180.0);
251         m.tx = RANGE*1.41/2;
252         m.ty = RANGE*1.41/2;
253
254         gfxline_t*l = gfxline_clone(line);
255         gfxline_transform(l, &m);
256         
257         gfxpoly_t*poly = gfxpoly_from_gfxline(l, 0.05);
258         gfxpoly_t*poly2 = gfxpoly_process(poly, rule);
259
260         tag = swf_InsertTag(tag, ST_DEFINESHAPE);
261         SHAPE* s;
262         swf_ShapeNew(&s);
263         RGBA rgb;
264         rgb.r = rgb.g = 0x00; rgb.b = 0xff;
265         rgb.a = 255;
266         int fs = swf_ShapeAddSolidFillStyle(s,&rgb);
267         int ls = swf_ShapeAddLineStyle(s,20,&rgb);
268         swf_SetU16(tag,t+1);
269         swf_SetRect(tag,&swf.movieSize);
270         swf_SetShapeHeader(tag,s);
271
272 #define FILL
273 #ifdef FILL
274         swf_ShapeSetAll(tag,s,0,0,0,fs,0);
275         edge_t*e = poly2->edges;
276         while(e) {
277 #define ROTATE
278 #ifdef ROTATE
279             swf_ShapeSetMove(tag, s, e->a.y, e->a.x);
280             swf_ShapeSetLine(tag, s, e->b.y - e->a.y, e->b.x - e->a.x);
281 #else
282             swf_ShapeSetMove(tag, s, e->a.x, e->a.y);
283             swf_ShapeSetLine(tag, s, e->b.x - e->a.x, e->b.y - e->a.y);
284 #endif
285             e = e->next;
286         }
287 #else
288         swf_ShapeSetAll(tag,s,0,0,ls,0,0);
289         edge_t*e = poly2->edges;
290         while(e) {
291             swf_ShapeSetMove(tag, s, e->a.x, e->a.y);
292             swf_ShapeSetLine(tag, s, e->b.x - e->a.x, e->b.y - e->a.y);
293             
294             swf_ShapeSetCircle(tag, s, e->a.x, e->a.y, 5*20, 5*20);
295             swf_ShapeSetCircle(tag, s, e->b.x, e->b.y, 5*20, 5*20);
296             e = e->next;
297         }
298 #endif
299
300         swf_ShapeSetEnd(tag);
301         swf_ShapeFree(s);
302
303         gfxpoly_destroy(poly);
304         gfxpoly_destroy(poly2);
305
306         gfxline_free(l);
307    
308         if(t) {
309             tag = swf_InsertTag(tag,ST_REMOVEOBJECT2);
310             swf_SetU16(tag, t);
311         }
312         tag = swf_InsertTag(tag,ST_PLACEOBJECT2);
313         swf_ObjectPlace(tag,t+1,t+1,NULL,NULL,NULL);
314
315         tag = swf_InsertTag(tag, ST_SHOWFRAME);
316     }
317     tag = swf_InsertTag(tag, ST_END);
318
319     swf_SaveSWF(&swf, "test.swf");
320 }
321
322 #include <dirent.h>
323 void test4(int argn, char*argv[])
324 {
325     char*dir = "ps";
326     DIR*_dir = opendir(dir);
327     if(!_dir) return;
328     struct dirent*file;
329     while(1) {
330         file = readdir(_dir);
331         if (!file) 
332             break;
333         if(!strstr(file->d_name, ".ps")) 
334             continue;
335
336         char* filename;
337
338         if(argn<2)
339             filename = allocprintf("%s/%s", dir, file->d_name);
340         else
341             filename = argv[1];
342
343         windrule_t*rule = &windrule_evenodd;
344         gfxpoly_t*poly = gfxpoly_from_file(filename, 1.0);//0.01);
345
346         if(argn!=2)
347             free(filename);
348
349         double zoom = 1.0;
350         intbbox_t bbox = intbbox_from_polygon(poly, zoom);
351
352         if(!gfxpoly_check(poly)) {
353             printf("bad polygon\n");
354             continue;
355         }
356
357         gfxpoly_t*poly2 = gfxpoly_process(poly, rule);
358         unsigned char*bitmap1 = render_polygon(poly, &bbox, zoom, rule);
359         unsigned char*bitmap2 = render_polygon(poly2, &bbox, zoom, &windrule_evenodd);
360         if(!bitmap_ok(&bbox, bitmap1) || !bitmap_ok(&bbox, bitmap2)) {
361             save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
362             assert(!"error in bitmaps");
363         }
364         if(!compare_bitmaps(&bbox, bitmap1, bitmap2)) {
365             save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
366             assert(!"bitmaps don't match");
367         }
368         free(bitmap1);
369         free(bitmap2);
370         gfxpoly_destroy(poly);
371         gfxpoly_destroy(poly2);
372         if(argn==2) 
373             break;
374     }
375     closedir(_dir);
376 }
377
378 #include "../gfxdevice.h"
379 #include "../pdf/pdf.h"
380
381 void extract_polygons_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color) 
382 {
383     gfxpoly_t*poly = gfxpoly_from_gfxline(line, 0.05);
384     printf("%d segments\n", gfxpoly_size(poly));
385
386     if(!gfxpoly_check(poly)) {
387         gfxpoly_destroy(poly);
388         printf("bad polygon\n");
389         return;
390     }
391
392     windrule_t*rule = &windrule_evenodd;
393         
394     double zoom = 1.0;
395     intbbox_t bbox = intbbox_from_polygon(poly, zoom);
396     unsigned char*bitmap1 = render_polygon(poly, &bbox, zoom, rule);
397     if(!bitmap_ok(&bbox, bitmap1)) {
398         printf("bad polygon or error in renderer\n");
399         return;
400     }
401     gfxpoly_t*poly2 = gfxpoly_process(poly, rule);
402     unsigned char*bitmap2 = render_polygon(poly2, &bbox, zoom, &windrule_evenodd);
403     if(!bitmap_ok(&bbox, bitmap2)) {
404         save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
405         assert(!"error in bitmap");
406     }
407     if(!compare_bitmaps(&bbox, bitmap1, bitmap2)) {
408         save_two_bitmaps(&bbox, bitmap1, bitmap2, "error.png");
409         assert(!"bitmaps don't match");
410     }
411     free(bitmap1);
412     free(bitmap2);
413
414     gfxpoly_destroy(poly);
415     gfxpoly_destroy(poly2);
416 }
417 int extract_polygons_setparameter(gfxdevice_t*dev, const char*key, const char*value) {
418     return 0;
419 }
420 void extract_polygons_startclip(gfxdevice_t*dev, gfxline_t*line) 
421 {
422     extract_polygons_fill(dev, line, 0);
423 }
424 void extract_polygons_fillbitmap(gfxdevice_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*imgcoord2devcoord, gfxcxform_t*cxform)
425 {
426     extract_polygons_fill(dev, line, 0);
427 }
428 void extract_polygons_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*gradcoord2devcoord)
429 {
430     extract_polygons_fill(dev, line, 0);
431 }
432 void extract_polygons_drawlink(gfxdevice_t*dev, gfxline_t*line, const char*action)
433 {
434     extract_polygons_fill(dev, line, 0);
435 }
436 void extract_polygons_addfont(gfxdevice_t*dev, gfxfont_t*font)
437 {
438     int t;
439     for(t=0;t<font->num_glyphs;t++) {
440         //extract_polygons_fill(dev, font->glyphs[t].line, 0);
441     }
442 }
443 void extract_polygons_endclip(gfxdevice_t*dev)
444 {
445 }
446 void extract_polygons_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
447 {
448 }
449 void extract_polygons_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyph, gfxcolor_t*color, gfxmatrix_t*matrix)
450 {
451 }
452     
453 gfxdevice_t extract_polygons = 
454 {
455 name: "extract polygons",
456 setparameter:extract_polygons_setparameter,
457 startclip: extract_polygons_startclip,
458 endclip: extract_polygons_endclip,
459 stroke: extract_polygons_stroke,
460 fill: extract_polygons_fill,
461 fillbitmap: extract_polygons_fillbitmap,
462 fillgradient: extract_polygons_fillgradient,
463 addfont: extract_polygons_addfont,
464 drawchar: extract_polygons_drawchar,
465 drawlink: extract_polygons_drawlink,
466 startpage: 0,
467 endpage: 0,
468 geterror: 0,
469 finish: 0,
470 internal: 0
471 };
472
473 void test5(int argn, char*argv[])
474 {
475     gfxsource_t*driver = gfxsource_pdf_create();
476     char*dir = "pdfs";
477     DIR*_dir = opendir(dir);
478     if(!_dir) return;
479     struct dirent*file;
480     while(1) {
481         file = readdir(_dir);
482         if (!file) 
483             break;
484         if(!strstr(file->d_name, ".pdf")) 
485             continue;
486         char* filename = allocprintf("%s/%s", dir, file->d_name);
487
488         gfxdocument_t*doc = driver->open(driver, filename);
489         gfxdevice_t*out = &extract_polygons;
490         int t;
491         for(t=1;t<=doc->num_pages;t++) {
492             printf("%s (page %d)\n", filename, t);
493             gfxpage_t* page = doc->getpage(doc, t);
494             page->render(page, out);
495             page->destroy(page);
496         }
497         doc->destroy(doc);
498         free(filename);
499     }
500     closedir(_dir);
501     driver->destroy(driver);
502 }
503
504 int main(int argn, char*argv[])
505 {
506     test5(argn, argv);
507 }