1 /* Libart_LGPL - library of basic graphic primitives
2 * Copyright (C) 1998, 1999 Raph Levien
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
24 #include "art_vpath.h"
26 #include "art_svp_vpath.h"
27 #include "art_gray_svp.h"
28 #include "art_rgb_svp.h"
29 #include "art_svp_vpath_stroke.h"
30 #include "art_svp_ops.h"
31 #include "art_affine.h"
32 #include "art_rgb_affine.h"
33 #include "art_rgb_bitmap_affine.h"
34 #include "art_rgb_rgba_affine.h"
35 #include "art_alphagamma.h"
36 #include "art_svp_point.h"
37 #include "art_vpath_dash.h"
38 #include "art_render.h"
39 #include "art_render_gradient.h"
40 #include "art_render_svp.h"
41 #include "art_svp_intersect.h"
51 ArtPoint ps, pd, ptmp;
53 for (i = 0; i < 6; i++)
55 src[i] = (rand () * 2.0 / RAND_MAX) - 1.0;
56 src2[i] = (rand () * 2.0 / RAND_MAX) - 1.0;
73 src2[1] = -0.17364818;
79 ps.x = rand() * 100.0 / RAND_MAX;
80 ps.y = rand() * 100.0 / RAND_MAX;
82 art_affine_point (&pd, &ps, src);
83 art_affine_invert (dst, src);
84 art_affine_point (&ptmp, &pd, dst);
85 art_affine_to_string (str, src);
86 printf ("src = %s\n", str);
87 art_affine_to_string (str, dst);
88 printf ("dst = %s\n", str);
89 printf ("point (%g, %g) -> (%g, %g) -> (%g, %g)\n",
90 ps.x, ps.y, pd.x, pd.y, ptmp.x, ptmp.y);
92 art_affine_point (&ptmp, &ps, src);
93 art_affine_point (&pd, &ptmp, src2);
94 art_affine_to_string (str, src2);
95 printf ("src2 = %s\n", str);
96 printf ("point (%g, %g) -> (%g, %g) -> (%g, %g)\n",
97 ps.x, ps.y, ptmp.x, ptmp.y, pd.x, pd.y);
98 art_affine_multiply (dst, src, src2);
99 art_affine_to_string (str, dst);
100 printf ("dst = %s\n", str);
101 art_affine_point (&pd, &ps, dst);
102 printf ("point (%g, %g) -> (%g, %g)\n",
103 ps.x, ps.y, pd.x, pd.y);
115 vec = art_new (ArtVpath, n + 2);
116 for (i = 0; i < n; i++)
118 vec[i].code = i ? ART_LINETO : ART_MOVETO;
119 r = rand () * (250.0 / RAND_MAX);
121 r = r + 0.9 * (250 - r);
123 th = i * 2 * M_PI / n;
124 vec[i].x = 250 + r * cos (th);
125 vec[i].y = 250 - r * sin (th);
127 vec[i].code = ART_LINETO;
131 vec[i].code = ART_END;
137 #define TILE_SIZE 512
149 print_svp (ArtSVP *vp)
153 for (i = 0; i < vp->n_segs; i++)
155 printf ("segment %d, dir = %s (%f, %f) - (%f, %f)\n",
156 i, vp->segs[i].dir ? "down" : "up",
160 vp->segs[i].bbox.y1);
161 for (j = 0; j < vp->segs[i].n_points; j++)
162 printf (" (%g, %g)\n",
163 vp->segs[i].points[j].x,
164 vp->segs[i].points[j].y);
170 print_vpath (ArtVpath *vpath)
174 for (i = 0; vpath[i].code != ART_END; i++)
175 printf ("%g %g %s\n",
176 vpath[i].x, vpath[i].y,
177 vpath[i].code == ART_MOVETO_OPEN ? "moveto %open" :
178 vpath[i].code == ART_MOVETO ? "moveto" :
179 vpath[i].code == ART_LINETO ? "lineto" :
188 ArtVpath *vpath, *vpath2, *vpath3;
191 art_u8 buf[512 * 512 * BYTES_PP];
194 art_u8 colorimg[256][256][3];
195 art_u8 rgbaimg[256][256][4];
196 art_u8 bitimg[16][2];
201 ArtAlphaGamma *alphagamma;
202 double dash_data[] = { 20 };
207 dash.dash = dash_data;
214 vpath = randstar (50);
215 svp = art_svp_from_vpath (vpath);
218 vpath2 = randstar (50);
220 vpath3 = art_vpath_dash (vpath2, &dash);
222 svp2 = art_svp_vpath_stroke (vpath3,
223 ART_PATH_STROKE_JOIN_MITER,
224 ART_PATH_STROKE_CAP_BUTT,
230 svp2 = art_svp_from_vpath (vpath2);
234 svp3 = art_svp_intersect (svp, svp2);
243 for (y = 0; y < 256; y++)
244 for (x = 0; x < 256; x++)
246 colorimg[y][x][0] = (x + y) >> 1;
247 colorimg[y][x][1] = (x + (255 - y)) >> 1;
248 colorimg[y][x][2] = ((255 - x) + y) >> 1;
250 rgbaimg[y][x][0] = (x + y) >> 1;
251 rgbaimg[y][x][1] = (x + (255 - y)) >> 1;
252 rgbaimg[y][x][2] = ((255 - x) + y) >> 1;
253 rgbaimg[y][x][3] = y;
256 for (y = 0; y < 16; y++)
257 for (x = 0; x < 2; x++)
258 bitimg[y][x] = (x << 4) | y;
282 alphagamma = art_alphagamma_new (1.8);
288 printf ("P6\n512 512\n255\n");
290 printf ("P5\n512 512\n255\n");
292 for (iter = 0; iter < NUM_ITERS; iter++)
293 for (j = 0; j < 512; j += TILE_SIZE)
294 for (i = 0; i < 512; i += TILE_SIZE)
297 art_rgb_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE,
299 buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
301 art_rgb_svp_alpha (svp2, i, j, i + TILE_SIZE, j + TILE_SIZE,
303 buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
305 art_rgb_svp_alpha (svp3, i, j, i + TILE_SIZE, j + TILE_SIZE,
307 buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
309 art_rgb_affine (buf + (j * 512 + i) * BYTES_PP,
310 i, j, i + TILE_SIZE, j + TILE_SIZE, 512 * BYTES_PP,
311 (art_u8 *)colorimg, 256, 256, 256 * 3,
313 ART_FILTER_NEAREST, alphagamma);
314 art_rgb_rgba_affine (buf + (j * 512 + i) * BYTES_PP,
315 i, j, i + TILE_SIZE, j + TILE_SIZE,
317 (art_u8 *)rgbaimg, 256, 256, 256 * 4,
319 ART_FILTER_NEAREST, alphagamma);
320 art_rgb_bitmap_affine (buf + (j * 512 + i) * BYTES_PP,
321 i, j, i + TILE_SIZE, j + TILE_SIZE,
323 (art_u8 *)bitimg, 16, 16, 2,
326 ART_FILTER_NEAREST, alphagamma);
328 art_gray_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE,
329 buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP);
338 fwrite (buf, 1, 512 * 512 * BYTES_PP, stdout);
347 art_u8 buf[512 * 512 * BYTES_PP];
353 vpath = randstar (20);
355 svp = art_svp_from_vpath (vpath);
357 svp = art_svp_vpath_stroke (vpath,
358 ART_PATH_STROKE_JOIN_MITER,
359 ART_PATH_STROKE_CAP_BUTT,
365 art_rgb_svp_aa (svp, 0, 0, 512, 512,
371 for (y = 0; y < 512; y++)
373 for (x = 0; x < 512; x++)
375 wind = art_svp_point_wind (svp, x, y);
376 buf[ix] = 204 - wind * 51;
377 dist = art_svp_point_dist (svp, x, y);
378 if (((x | y) & 0x3f) == 0)
380 fprintf (stderr, "%d,%d: %f\n", x, y, dist);
382 buf[ix + 1] = 255 - dist;
387 printf ("P6\n512 512\n255\n");
388 fwrite (buf, 1, 512 * 512 * BYTES_PP, stdout);
395 ArtVpath *vpath, *vpath2;
396 double dash_data[] = { 10, 4, 1, 4};
401 dash.dash = dash_data;
403 vpath = randstar (50);
404 vpath2 = art_vpath_dash (vpath, &dash);
406 print_vpath (vpath2);
407 printf ("showpage\n");
413 test_render_gradient (art_u8 *buf)
415 ArtGradientLinear gradient;
416 ArtGradientStop stops[3] = {
417 { 0.0, { 0x7fff, 0x0000, 0x0000, 0x7fff }},
418 { 0.5, { 0x0000, 0x0000, 0x0000, 0x1000 }},
419 { 1.0, { 0x0000, 0x7fff, 0x0000, 0x7fff }}
426 gradient.b = -0.0015;
428 gradient.spread = ART_GRADIENT_PAD;
429 gradient.n_stops = sizeof(stops) / sizeof(stops[0]);
430 gradient.stops = stops;
432 vpath = randstar (50);
433 svp = art_svp_from_vpath (vpath);
435 render = art_render_new (0, 0, 512, 512, buf, 512 * 3, 3, 8, ART_ALPHA_NONE,
437 art_render_svp (render, svp);
438 art_render_gradient_linear (render, &gradient, ART_FILTER_NEAREST);
439 art_render_invoke (render);
444 test_render_rad_gradient (art_u8 *buf)
446 ArtGradientRadial gradient;
447 ArtGradientStop stops[3] = {
448 { 0.0, { 0xffff, 0x0000, 0x0000, 0xffff }},
449 { 0.5, { 0xe000, 0xe000, 0x0000, 0xe000 }},
450 { 1.0, { 0x0000, 0x0000, 0x0000, 0x0000 }}
456 gradient.affine[0] = 3.0 / 512;
457 gradient.affine[1] = 0;
458 gradient.affine[2] = 0;
459 gradient.affine[3] = 3.0 / 512;
460 gradient.affine[4] = -1.5;
461 gradient.affine[5] = -1.5;
465 gradient.n_stops = sizeof(stops) / sizeof(stops[0]);
466 gradient.stops = stops;
468 vpath = randstar (50);
469 svp = art_svp_from_vpath (vpath);
471 render = art_render_new (0, 0, 512, 512, buf, 512 * 3, 3, 8, ART_ALPHA_NONE,
473 art_render_svp (render, svp);
474 art_render_gradient_radial (render, &gradient, ART_FILTER_NEAREST);
475 art_render_invoke (render);
484 art_u8 buf[512 * 512 * 3];
486 ArtPixMaxDepth color[3] = {0x0000, 0x0000, 0x8000 };
488 const int n_iter = 1;
490 vpath = randstar (50);
491 svp = art_svp_from_vpath (vpath);
493 for (i = 0; i < n_iter; i++)
497 render = art_render_new (0, 0, 512, 512, buf, 512 * 3, 3, 8, ART_ALPHA_NONE,
499 art_render_clear_rgb (render, 0xfff0c0);
500 art_render_svp (render, svp);
501 art_render_image_solid (render, color);
502 art_render_invoke (render);
504 art_rgb_svp_aa (svp, 0, 0, 512, 512, 0xfff0c0, 0x000080,
510 test_render_gradient (buf);
512 test_render_rad_gradient (buf);
514 printf ("P6\n512 512\n255\n");
515 fwrite (buf, 1, 512 * 512 * 3, stdout);
519 output_svp_ppm (const ArtSVP *svp)
521 art_u8 buf[512 * 512 * 3];
522 art_rgb_svp_aa (svp, 0, 0, 512, 512, 0xfff0c0, 0x000080,
524 printf ("P6\n512 512\n255\n");
525 fwrite (buf, 1, 512 * 512 * 3, stdout);
529 test_intersect (void)
535 { ART_MOVETO, 100, 100 },
536 { ART_LINETO, 300, 400 },
537 { ART_LINETO, 400, 200 },
538 { ART_LINETO, 100, 100 },
539 { ART_MOVETO, 110, 110 },
540 { ART_LINETO, 310, 410 },
541 { ART_LINETO, 410, 210 },
542 { ART_LINETO, 110, 110 },
547 { ART_MOVETO, 100, 100 },
548 { ART_LINETO, 400, 400 },
549 { ART_LINETO, 400, 100 },
550 { ART_LINETO, 100, 400 },
551 { ART_LINETO, 100, 100 },
556 { ART_MOVETO, 100, 100 },
557 { ART_LINETO, 100, 400 },
558 { ART_LINETO, 400, 400 },
559 { ART_LINETO, 400, 100 },
560 { ART_LINETO, 100, 100 },
567 { ART_MOVETO, 100 + XOFF, 100 + YOFF },
568 { ART_LINETO, 100 + XOFF, 400 + YOFF },
569 { ART_LINETO, 400 + XOFF, 400 + YOFF },
570 { ART_LINETO, 400 + XOFF, 100 + YOFF },
571 { ART_LINETO, 100 + XOFF, 100 + YOFF },
579 svp = art_svp_from_vpath (vpath);
581 #define RUN_INTERSECT
583 swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN);
584 art_svp_intersector (svp, swr);
586 svp2 = art_svp_writer_rewind_reap (swr);
590 output_svp_ppm (svp2);
605 fprintf (stderr, "usage: testart <test>\n"
606 " where <test> is one of:\n"
607 " testpat -- make random star + gradients test pattern\n"
608 " gradient -- test pattern for rendered gradients\n"
609 " dash -- dash test (output is valid PostScript)\n"
610 " dist -- distance test\n"
611 " intersect -- softball test for intersector\n");
616 main (int argc, char **argv)
621 if (!strcmp (argv[1], "testpat"))
623 else if (!strcmp (argv[1], "gradient"))
625 else if (!strcmp (argv[1], "dist"))
627 else if (!strcmp (argv[1], "dash"))
629 else if (!strcmp (argv[1], "intersect"))