#include #include #include #include #include #include #include #include #include #include #include static void art_render_image_gray_negotiate (ArtImageSource *self, ArtRender *render, ArtImageSourceFlags *p_flags, int *p_buf_depth, ArtAlphaType *p_alpha); static void art_render_image_gray_opaq (ArtRenderCallback *self, ArtRender *render, art_u8 *dest, int y); static void art_render_nop_done (ArtRenderCallback *self, ArtRender *render); void art_gray_fill_run (art_u8 *buf, art_u8 gray, int n); static ArtImageSource imgsrc = { { art_render_image_gray_opaq, art_render_nop_done, }, art_render_image_gray_negotiate, }; #define BRICKS_POINTS 18 static double bricks [] = { -100.0, 100.0, 100.0, 100.0, 100.0, 25.0, 0.0, 25.0, 0.0, 12.0, 0.0, -12.0, 0.0, -25.0, 100.0, -25.0, 100.0, -100.0, -100.0, -100.0, -100.0, -25.0, 0.0, -25.0, 0.0, -12.0, 0.0, 12.0, 0.0, 25.0, -100.0, 25.0, -100.0, 100.0, 0.0, 0.0, }; #define STAR_POINTS 47 static double star [] = { 0.0, 0.0, 0.0, 256.0, 53.0, 250.0, 0.0, 0.0, 104.0, 233.5, 150.0, 207.0, 0.0, 0.0, 190.0, 171.0, 221.5, 128.0, 0.0, 0.0, 243.0, 79.0, 254.5, 26.5, 0.0, 0.0, 254.5, -27.0, 243.0, -79.0, 0.0, 0.0, 221.5, -127.5, 190.0, -171.0, 0.0, 0.0, 150.0, -207.0, 104.0, -233.5, 0.0, 0.0, 53.0, -250.0, 0.0, -256.0, 0.0, 0.0, -53.5, -250.0, -104.0, -233.5, 0.0, 0.0, -150.0, -207.0, -190.0, -171.0, 0.0, 0.0, -221.5, -128.0, -243.0, -79.0, 0.0, 0.0, -254.5, -27.0, -254.5, 26.5, 0.0, 0.0, -243.0, 79.0, -221.5, 128.0, 0.0, 0.0, -190.0, 171.0, -150.0, 207.0, 0.0, 0.0, -104.0, 233.5, -53.5, 250.0, 0.0, 0.0, 0.0, 0.0, }; #define WIDTH 550 #define HEIGHT 550 int main (int argc, char *argv[]) { ArtVpath *vpath, *pert_vpath; ArtSVP *svp, *svp2; ArtSvpWriter *swr; ArtRender *render; ArtPixMaxDepth bg = 0x00; ArtPixMaxDepth fg = 0xff; int num_points, use_perturb, render_bitmap; double *polygon; int i; unsigned char *pixmap; polygon = star; num_points = STAR_POINTS; use_perturb = 1; render_bitmap = 0; for (i=1 ; i < argc; i++) { if (!strcmp (argv[i], "--no-perturb") || !strcmp (argv[i], "+p")) use_perturb = 0; else if (!strcmp (argv[i], "--perturb") || !strcmp (argv[i], "-p")) use_perturb = 1; else if (!strcmp (argv[i], "--render") || !strcmp (argv[i], "-r")) render_bitmap = 1; else if (!strcmp (argv[i], "star")) { polygon = star; num_points = STAR_POINTS; } else if (!strcmp (argv[i], "bricks")) { polygon = bricks; num_points = BRICKS_POINTS; } else { fprintf (stderr, "Unknown option: %s\n", argv[i]); } } vpath = art_new (ArtVpath, num_points); for (i=0; i < num_points; i++) { vpath[i].code = (i == 0 ? ART_MOVETO : ART_LINETO); vpath[i].x = polygon[2*i]; vpath[i].y = polygon[2*i+1]; } vpath[num_points - 1].code = ART_END; fprintf (stderr, "-------------------------\nsvp_from_vpath...\n"); svp = art_svp_from_vpath (vpath); art_free (vpath); swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN); art_svp_intersector (svp, swr); svp2 = art_svp_writer_rewind_reap (swr); art_svp_free (svp); if (render_bitmap) { int opacity = 0xffff; int bpp = 1; ArtPixMaxDepth color[3] = {0x0000, 0x0000, 0x8000 }; pixmap = calloc (sizeof (char), WIDTH*HEIGHT*bpp); fprintf (stderr, "art_render_new\n"); render = art_render_new (-WIDTH/2+1, -HEIGHT/2+1, WIDTH/2, HEIGHT/2, pixmap, WIDTH*bpp, bpp, 8, ART_ALPHA_NONE, NULL); // art_render_mask_solid (render, opacity); art_render_clear (render, color); art_render_svp (render, svp2); fprintf (stderr, "art_render_image_solid\n"); // art_render_image_solid (render, color); art_render_add_image_source (render, &imgsrc); fprintf (stderr, "art_render_invoke\n"); art_render_invoke (render); fprintf (stderr, "output...\n"); fprintf (stdout, "P5 %d %d 255 ", WIDTH, HEIGHT); fwrite (pixmap, 1, WIDTH * HEIGHT, stdout); } else { printf ("you may start this program with \"--render\" " "to write a PGM-image to stdout\n"); } // art_svp_free (svp); return 0; } static void art_render_image_gray_negotiate (ArtImageSource *self, ArtRender *render, ArtImageSourceFlags *p_flags, int *p_buf_depth, ArtAlphaType *p_alpha) { ArtImageSourceFlags flags = 0; static void (*render_cbk) (ArtRenderCallback *self, ArtRender *render, art_u8 *dest, int y); render_cbk = NULL; if (render->depth == 8 && render->n_chan == 1 && render->alpha_type == ART_ALPHA_NONE) { if (render->clear) { render_cbk = art_render_image_gray_opaq; flags |= ART_IMAGE_SOURCE_CAN_CLEAR | ART_IMAGE_SOURCE_CAN_COMPOSITE; } } if (render_cbk == NULL) fprintf (stderr, "art_render_image_gray_negotiate: wrong image format\n"); self->super.render = render_cbk; *p_flags = flags; } static void art_render_image_gray_opaq (ArtRenderCallback *self, ArtRender *render, art_u8 *dest, int y) { ArtRenderMaskRun *run = render->run; int n_run = render->n_run; art_u8 gray; int x0 = render->x0; int x1 = render->x1; int run_x0, run_x1; int i; int ix; if (n_run > 0) { run_x1 = run[0].x; if (run_x1 > x0) { gray = 0; art_gray_fill_run (dest, gray, run_x1 - x0); } for (i = 0; i < n_run - 1; i++) { run_x0 = run_x1; run_x1 = run[i + 1].x; gray = (run[i].alpha >> 16) & 0xff; ix = run_x0 - x0; if (run_x1 - run_x0 == 1) { dest[ix] = gray; } else { art_gray_fill_run (dest + ix, gray, run_x1 - run_x0); } } } else { run_x1 = x0; } if (run_x1 < x1) { gray = 0; art_gray_fill_run (dest + (run_x1 - x0), gray, x1 - run_x1); } } void art_gray_fill_run (art_u8 *buf, art_u8 gray, int n) { memset (buf, gray, n); } static void art_render_nop_done (ArtRenderCallback *self, ArtRender *render) { }