source: trunk/third/libart_lgpl/testart.c @ 18256

Revision 18256, 14.0 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18255, which included commits to RCS files with non-trunk default branches.
Line 
1/* Libart_LGPL - library of basic graphic primitives
2 * Copyright (C) 1998, 1999 Raph Levien
3 *
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.
8 *
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.
13 *
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.
18 */
19
20#include <stdio.h>
21#include <string.h>
22#include <math.h>
23#include "art_misc.h"
24#include "art_vpath.h"
25#include "art_svp.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"
42
43#ifdef DEAD_CODE
44static void
45test_affine (void) {
46  double src[6];
47  double dst[6];
48  double src2[6];
49  char str[128];
50  int i;
51  ArtPoint ps, pd, ptmp;
52
53  for (i = 0; i < 6; i++)
54    {
55      src[i] = (rand () * 2.0 / RAND_MAX) - 1.0;
56      src2[i] = (rand () * 2.0 / RAND_MAX) - 1.0;
57    }
58#if 0
59  src[0] = 0.9999999;
60  src[1] = -0.000001;
61  src[2] = 0.000001;
62  src[3] = 0.9999999;
63  src[4] = 0;
64  src[5] = 0;
65#if 1
66  src[0] = 0.98480775;
67  src[1] = -0.17364818;
68  src[2] = 0.17364818;
69  src[3] = 0.98480775;
70#endif
71
72  src2[0] = 0.98480775;
73  src2[1] = -0.17364818;
74  src2[2] = 0.17364818;
75  src2[3] = 0.98480775;
76#endif
77
78
79  ps.x = rand() * 100.0 / RAND_MAX;
80  ps.y = rand() * 100.0 / RAND_MAX;
81
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);
91
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);
104
105}
106#endif
107
108static ArtVpath *
109randstar (int n)
110{
111  ArtVpath *vec;
112  int i;
113  double r, th;
114
115  vec = art_new (ArtVpath, n + 2);
116  for (i = 0; i < n; i++)
117    {
118      vec[i].code = i ? ART_LINETO : ART_MOVETO;
119      r = rand () * (250.0 / RAND_MAX);
120#if 0
121      r = r + 0.9 * (250 - r);
122#endif
123      th = i * 2 * M_PI / n;
124      vec[i].x = 250 + r * cos (th);
125      vec[i].y = 250 - r * sin (th);
126    }
127  vec[i].code = ART_LINETO;
128  vec[i].x = vec[0].x;
129  vec[i].y = vec[0].y;
130  i++;
131  vec[i].code = ART_END;
132  vec[i].x = 0;
133  vec[i].y = 0;
134  return vec;
135}
136
137#define TILE_SIZE 512
138#define NUM_ITERS 1
139#define COLOR
140
141#ifdef COLOR
142#define BYTES_PP 3
143#else
144#define BYTES_PP 1
145#endif
146
147#ifndef nDEAD_CODE
148static void
149print_svp (ArtSVP *vp)
150{
151  int i, j;
152
153  for (i = 0; i < vp->n_segs; i++)
154    {
155      printf ("segment %d, dir = %s (%f, %f) - (%f, %f)\n",
156              i, vp->segs[i].dir ? "down" : "up",
157              vp->segs[i].bbox.x0,
158              vp->segs[i].bbox.y0,
159              vp->segs[i].bbox.x1,
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);
165    }
166}
167#endif
168
169static void
170print_vpath (ArtVpath *vpath)
171{
172  int i;
173
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" :
180            "?");
181
182  printf ("stroke\n");
183}
184
185static void
186make_testpat (void)
187{
188  ArtVpath *vpath, *vpath2, *vpath3;
189  ArtSVP *svp, *svp2;
190  ArtSVP *svp3;
191  art_u8 buf[512 * 512 * BYTES_PP];
192  int i, j;
193  int iter;
194  art_u8 colorimg[256][256][3];
195  art_u8 rgbaimg[256][256][4];
196  art_u8 bitimg[16][2];
197  int x, y;
198  double affine[6];
199  double affine2[6];
200  double affine3[6];
201  ArtAlphaGamma *alphagamma;
202  double dash_data[] = { 20 };
203  ArtVpathDash dash;
204
205  dash.offset = 0;
206  dash.n_dash = 1;
207  dash.dash = dash_data;
208
209#ifdef TEST_AFFINE
210  test_affine ();
211  exit (0);
212#endif
213
214  vpath = randstar (50);
215  svp = art_svp_from_vpath (vpath);
216  art_free (vpath);
217
218  vpath2 = randstar (50);
219#if 1
220  vpath3 = art_vpath_dash (vpath2, &dash);
221  art_free (vpath2);
222  svp2 = art_svp_vpath_stroke (vpath3,
223                               ART_PATH_STROKE_JOIN_MITER,
224                               ART_PATH_STROKE_CAP_BUTT,
225                               15,
226                               4,
227                               0.5);
228  art_free (vpath3);
229#else
230  svp2 = art_svp_from_vpath (vpath2);
231#endif
232
233#if 1
234  svp3 = art_svp_intersect (svp, svp2);
235#else
236  svp3 = svp2;
237#endif
238
239#if 0
240  print_svp (svp);
241#endif
242
243  for (y = 0; y < 256; y++)
244    for (x = 0; x < 256; x++)
245      {
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;
249
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;
254      }
255
256  for (y = 0; y < 16; y++)
257    for (x = 0; x < 2; x++)
258      bitimg[y][x] = (x << 4) | y;
259
260  affine[0] = 0.5;
261  affine[1] = .2;
262  affine[2] = -.2;
263  affine[3] = 0.5;
264  affine[4] = 64;
265  affine[5] = 64;
266 
267  affine2[0] = 1;
268  affine2[1] = -.2;
269  affine2[2] = .2;
270  affine2[3] = 1;
271  affine2[4] = 128;
272  affine2[5] = 128;
273
274  affine3[0] = 5;
275  affine3[1] = -.2;
276  affine3[2] = .2;
277  affine3[3] = 5;
278  affine3[4] = 384;
279  affine3[5] = 32;
280
281#if 0
282  alphagamma = art_alphagamma_new (1.8);
283#else
284  alphagamma = NULL;
285#endif
286
287#ifdef COLOR
288  printf ("P6\n512 512\n255\n");
289#else
290  printf ("P5\n512 512\n255\n");
291#endif
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)
295        {
296#ifdef COLOR
297          art_rgb_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE,
298                          0xffe0a0, 0x100040,
299                          buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
300                          alphagamma);
301          art_rgb_svp_alpha (svp2, i, j, i + TILE_SIZE, j + TILE_SIZE,
302                             0xff000080,
303                             buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
304                             alphagamma);
305          art_rgb_svp_alpha (svp3, i, j, i + TILE_SIZE, j + TILE_SIZE,
306                             0x00ff0080,
307                             buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
308                             alphagamma);
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,
312                          affine,
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,
316                               512 * BYTES_PP,
317                               (art_u8 *)rgbaimg, 256, 256, 256 * 4,
318                               affine2,
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,
322                                 512 * BYTES_PP,
323                                 (art_u8 *)bitimg, 16, 16, 2,
324                                 0xffff00ff,
325                                 affine3,
326                                 ART_FILTER_NEAREST, alphagamma);
327#else
328          art_gray_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE,
329                           buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP);
330#endif
331        }
332
333  art_svp_free (svp2);
334  art_svp_free (svp3);
335  art_svp_free (svp);
336
337#if 1
338  fwrite (buf, 1, 512 * 512 * BYTES_PP, stdout);
339#endif
340}
341
342static void
343test_dist (void)
344{
345  ArtVpath *vpath;
346  ArtSVP *svp;
347  art_u8 buf[512 * 512 * BYTES_PP];
348  int x, y;
349  int ix;
350  double dist;
351  int wind;
352
353  vpath = randstar (20);
354#ifdef NO_STROKE
355  svp = art_svp_from_vpath (vpath);
356#else
357  svp = art_svp_vpath_stroke (vpath,
358                               ART_PATH_STROKE_JOIN_MITER,
359                               ART_PATH_STROKE_CAP_BUTT,
360                               15,
361                               4,
362                               0.5);
363#endif
364
365  art_rgb_svp_aa (svp, 0, 0, 512, 512,
366                  0xffe0a0, 0x100040,
367                  buf, 512 * BYTES_PP,
368                  NULL);
369
370  ix = 0;
371  for (y = 0; y < 512; y++)
372    {
373      for (x = 0; x < 512; x++)
374        {
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)
379            {
380              fprintf (stderr, "%d,%d: %f\n", x, y, dist);
381            }
382          buf[ix + 1] = 255 - dist;
383          ix += 3;
384        }
385    }
386
387  printf ("P6\n512 512\n255\n");
388  fwrite (buf, 1, 512 * 512 * BYTES_PP, stdout);
389
390}
391
392static void
393test_dash (void)
394{
395  ArtVpath *vpath, *vpath2;
396  double dash_data[] = { 10, 4, 1, 4};
397  ArtVpathDash dash;
398         
399  dash.offset = 0;
400  dash.n_dash = 3;
401  dash.dash = dash_data;
402 
403  vpath = randstar (50);
404  vpath2 = art_vpath_dash (vpath, &dash);
405  printf ("%%!\n");
406  print_vpath (vpath2);
407  printf ("showpage\n");
408  art_free (vpath);
409  art_free (vpath2);
410}
411
412static void
413test_render_gradient (art_u8 *buf)
414{
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 }}
420  };
421  ArtVpath *vpath;
422  ArtSVP *svp;
423  ArtRender *render;
424
425  gradient.a = 0.003;
426  gradient.b = -0.0015;
427  gradient.c = 0.1;
428  gradient.spread = ART_GRADIENT_PAD;
429  gradient.n_stops = sizeof(stops) / sizeof(stops[0]);
430  gradient.stops = stops;
431
432  vpath = randstar (50);
433  svp = art_svp_from_vpath (vpath);
434
435  render = art_render_new (0, 0, 512, 512, buf, 512 * 3, 3, 8, ART_ALPHA_NONE,
436                           NULL);
437  art_render_svp (render, svp);
438  art_render_gradient_linear (render, &gradient, ART_FILTER_NEAREST);
439  art_render_invoke (render);
440
441}
442
443static void
444test_render_rad_gradient (art_u8 *buf)
445{
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 }}
451  };
452  ArtVpath *vpath;
453  ArtSVP *svp;
454  ArtRender *render;
455
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;
462  gradient.fx = 0.9;
463  gradient.fy = 0.1;
464 
465  gradient.n_stops = sizeof(stops) / sizeof(stops[0]);
466  gradient.stops = stops;
467
468  vpath = randstar (50);
469  svp = art_svp_from_vpath (vpath);
470
471  render = art_render_new (0, 0, 512, 512, buf, 512 * 3, 3, 8, ART_ALPHA_NONE,
472                           NULL);
473  art_render_svp (render, svp);
474  art_render_gradient_radial (render, &gradient, ART_FILTER_NEAREST);
475  art_render_invoke (render);
476
477}
478
479static void
480test_gradient (void)
481{
482  ArtVpath *vpath;
483  ArtSVP *svp;
484  art_u8 buf[512 * 512 * 3];
485  ArtRender *render;
486  ArtPixMaxDepth color[3] = {0x0000, 0x0000, 0x8000 };
487  int i;
488  const int n_iter = 1;
489
490  vpath = randstar (50);
491  svp = art_svp_from_vpath (vpath);
492
493  for (i = 0; i < n_iter; i++)
494    {
495#define USE_RENDER
496#ifdef USE_RENDER
497      render = art_render_new (0, 0, 512, 512, buf, 512 * 3, 3, 8, ART_ALPHA_NONE,
498                               NULL);
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);
503#else
504      art_rgb_svp_aa (svp, 0, 0, 512, 512, 0xfff0c0, 0x000080,
505                      buf, 512 * 3, NULL);
506#endif
507    }
508
509#if 1
510  test_render_gradient (buf);
511#endif
512  test_render_rad_gradient (buf);
513
514  printf ("P6\n512 512\n255\n");
515  fwrite (buf, 1, 512 * 512 * 3, stdout);
516}
517
518static void
519output_svp_ppm (const ArtSVP *svp)
520{
521  art_u8 buf[512 * 512 * 3];
522  art_rgb_svp_aa (svp, 0, 0, 512, 512, 0xfff0c0, 0x000080,
523                  buf, 512 * 3, NULL);
524  printf ("P6\n512 512\n255\n");
525  fwrite (buf, 1, 512 * 512 * 3, stdout);
526}
527
528static void
529test_intersect (void)
530{
531  ArtVpath vpath[] = {
532
533#if 0
534    /* two triangles */
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 },
543#endif
544
545#if 0
546    /* a bowtie */
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 },
552#endif
553
554#if 1
555    /* a square */
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 },
561#endif
562
563#if 1
564    /* another square */
565#define XOFF 10
566#define YOFF 10
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 },
572#endif
573
574    { ART_END, 0, 0}
575  };
576  ArtSVP *svp, *svp2;
577  ArtSvpWriter *swr;
578
579  svp = art_svp_from_vpath (vpath);
580
581#define RUN_INTERSECT
582#ifdef RUN_INTERSECT
583  swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN);
584  art_svp_intersector (svp, swr);
585
586  svp2 = art_svp_writer_rewind_reap (swr);
587#endif
588
589#if 0
590  output_svp_ppm (svp2);
591#else
592  print_svp (svp2);
593#endif
594
595  art_svp_free (svp);
596
597#ifdef RUN_INTERSECT
598  art_svp_free (svp2);
599#endif
600}
601
602static void
603usage (void)
604{
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");
612  exit (1);
613}
614
615int
616main (int argc, char **argv)
617{
618  if (argc < 2)
619    usage ();
620
621  if (!strcmp (argv[1], "testpat"))
622    make_testpat ();
623  else if (!strcmp (argv[1], "gradient"))
624    test_gradient ();
625  else if (!strcmp (argv[1], "dist"))
626    test_dist ();
627  else if (!strcmp (argv[1], "dash"))
628    test_dash ();
629  else if (!strcmp (argv[1], "intersect"))
630    test_intersect ();
631  else
632    usage ();
633  return 0;
634}
Note: See TracBrowser for help on using the repository browser.