Exemplo n.º 1
0
/**
 * art_svp_intersect: Compute the intersection of two sorted vector paths.
 * @svp1: One sorted vector path.
 * @svp2: The other sorted vector path.
 *
 * Computes the intersection of the two argument svp's. Given two
 * svp's with winding numbers of 0 and 1 everywhere, the resulting
 * winding number will be 1 where both of the argument svp's has a
 * winding number 1, 0 otherwise. The result is newly allocated.
 *
 * Currently, this routine has accuracy problems pending the
 * implementation of the new intersector.
 *
 * Return value: The intersection of @svp1 and @svp2.
 **/
ArtSVP *
art_svp_intersect (const ArtSVP *svp1, const ArtSVP *svp2)
{
#ifdef ART_USE_NEW_INTERSECTOR 
  ArtSVP *svp3, *svp_new;
  ArtSvpWriter *swr;
#ifdef	ROBIN_DEBUG
	dump_svp("art_svp_intersect svp1", svp1);
	dump_svp("art_svp_intersect svp2", svp2);
#endif

  svp3 = art_svp_merge (svp1, svp2);
  swr = art_svp_writer_rewind_new (ART_WIND_RULE_INTERSECT);
  art_svp_intersector (svp3, swr);
  svp_new = art_svp_writer_rewind_reap (swr);
  art_free (svp3); /* shallow free because svp3 contains shared segments */
#ifdef	ROBIN_DEBUG
  dump_svp("art_svp_intersect svp_new", svp_new);
#endif

  return svp_new;
#else
  ArtSVP *svp3, *svp4, *svp_new;

  svp3 = art_svp_merge_perturbed (svp1, svp2);
  svp4 = art_svp_uncross (svp3);
  art_svp_free (svp3);

  svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_INTERSECT);
  art_svp_free (svp4);
  return svp_new;
#endif
}
Exemplo n.º 2
0
/**
 * art_svp_diff: Compute the symmetric difference of two sorted vector paths.
 * @svp1: One sorted vector path.
 * @svp2: The other sorted vector path.
 *
 * Computes the symmetric of the two argument svp's. Given two svp's
 * with winding numbers of 0 and 1 everywhere, the resulting winding
 * number will be 1 where either, but not both, of the argument svp's
 * has a winding number 1, 0 otherwise. The result is newly allocated.
 *
 * Currently, this routine has accuracy problems pending the
 * implementation of the new intersector.
 *
 * Return value: The symmetric difference of @svp1 and @svp2.
 **/
ArtSVP *
art_svp_diff (const ArtSVP *svp1, const ArtSVP *svp2)
{
#ifdef ART_USE_NEW_INTERSECTOR 
  ArtSVP *svp3, *svp_new;
  ArtSvpWriter *swr;

  svp3 = art_svp_merge (svp1, svp2);
  swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN);
  art_svp_intersector (svp3, swr);
  svp_new = art_svp_writer_rewind_reap (swr);
  art_free (svp3); /* shallow free because svp3 contains shared segments */

  return svp_new;
#else
  ArtSVP *svp3, *svp4, *svp_new;

  svp3 = art_svp_merge_perturbed (svp1, svp2);
  svp4 = art_svp_uncross (svp3);
  art_svp_free (svp3);

  svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_ODDEVEN);
  art_svp_free (svp4);
  return svp_new;
#endif
}
Exemplo n.º 3
0
/**
 * art_svp_diff: Compute the symmetric difference of two sorted vector paths.
 * @svp1: One sorted vector path.
 * @svp2: The other sorted vector path.
 *
 * Computes the symmetric of the two argument svp's. Given two svp's
 * with winding numbers of 0 and 1 everywhere, the resulting winding
 * number will be 1 where either, but not both, of the argument svp's
 * has a winding number 1, 0 otherwise. The result is newly allocated.
 *
 * Currently, this routine has accuracy problems pending the
 * implementation of the new intersector.
 *
 * Return value: The symmetric difference of @svp1 and @svp2.
 **/
ArtSVP *
art_svp_diff (const ArtSVP *svp1, const ArtSVP *svp2)
{
  ArtSVP *svp3, *svp4, *svp_new;

  svp3 = art_svp_merge_perturbed (svp1, svp2);
  svp4 = art_svp_uncross (svp3);
  art_svp_free (svp3);

  svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_ODDEVEN);
  art_svp_free (svp4);
  return svp_new;
}
Exemplo n.º 4
0
/**
 * art_svp_intersect: Compute the intersection of two sorted vector paths.
 * @svp1: One sorted vector path.
 * @svp2: The other sorted vector path.
 *
 * Computes the intersection of the two argument svp's. Given two
 * svp's with winding numbers of 0 and 1 everywhere, the resulting
 * winding number will be 1 where both of the argument svp's has a
 * winding number 1, 0 otherwise. The result is newly allocated.
 *
 * Currently, this routine has accuracy problems pending the
 * implementation of the new intersector.
 *
 * Return value: The intersection of @svp1 and @svp2.
 **/
ArtSVP *
art_svp_intersect (const ArtSVP *svp1, const ArtSVP *svp2)
{
  ArtSVP *svp3, *svp4, *svp_new;

  svp3 = art_svp_merge_perturbed (svp1, svp2);
  svp4 = art_svp_uncross (svp3);
  art_svp_free (svp3);

  svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_INTERSECT);
  art_svp_free (svp4);
  return svp_new;
}
Exemplo n.º 5
0
ArtSVP* run_intersector(ArtSVP*svp, ArtWindRule rule)
{
    ArtSvpWriter * swr = art_svp_writer_rewind_new(rule);

    double zoom = 1.0;
    intbbox_t bbox = get_svp_bbox(svp, zoom);

    art_svp_intersector(svp, swr);
    ArtSVP*result = art_svp_writer_rewind_reap(swr);
    clean_svp(result);
    if(!check_svp(result)) {
	current_svp = result;
	art_report_error(); // might set art_error_in_intersector
    } else {
        msg("<verbose> Comparing polygon renderings of size %dx%d and %dx%d", bbox.width, bbox.height, bbox.width, bbox.height);
        unsigned char*data1 = render_svp(svp, &bbox, zoom, rule);
        unsigned char*data2 = render_svp(result, &bbox, zoom, ART_WIND_RULE_ODDEVEN);
        if(!compare_bitmaps(&bbox, data1, data2)) {
            msg("<verbose> Bad SVP rewinding result- polygons don't match");
            current_svp = result;
            art_report_error(); // might set art_error_in_intersector
        }
        free(data1);
        free(data2);
    }

    if(art_error_in_intersector) {
	msg("<verbose> Error in polygon processing");
	art_svp_free(result);
	art_error_in_intersector=0;
	return 0;
    }
    return result;
}
Exemplo n.º 6
0
static void
test_intersection(void)
{
    ArtVpath vp0[] = {
        { ART_MOVETO, 10, 10},
        { ART_LINETO, 60, 60},
        { ART_LINETO, 110, 10},
        { ART_LINETO, 10, 10},
        { ART_END, 0, 0}
    },
    vp1[]= {
        {ART_MOVETO, 110,34.999999999999993},
        {ART_LINETO, 10,35},
        {ART_LINETO, 10,36},
        {ART_LINETO, 110,35.999999999999993},
        {ART_LINETO, 110,34.999999999999993},
        {ART_END, 0,0}
    },
    vp2[]= {
        {ART_MOVETO, 110,35.999999999999993},
        {ART_LINETO, 10,36},
        {ART_LINETO, 10,37},
        {ART_LINETO, 110,36.999999999999993},
        {ART_LINETO, 110,35.999999999999993},
        {ART_END, 0,0}
    },
    *vp[] = {vp0, vp1, vp2};
    ArtSVP *svp[3], *svpi;
    int i;
    for(i=0; i<3; i++) {
        svp[i]=art_svp_from_vpath(vp[i]);
        printf("vpath[%d]\n", i);
        print_vpath(vp[i]);
        printf("svp[%d]\n", i);
        print_svp(svp[i]);
    }
    for(i=2; i>0; i--) {
        svpi = art_svp_intersect(svp[i],svp[0]);
        printf("svp[%d] & svp[0]\n", i);
        print_svp(svpi);
        art_svp_free(svpi);
    }

    for(i=0; i<3; i++) {
        art_svp_free(svp[i]);
    }
}
Exemplo n.º 7
0
/**
 * art_svp_union: Compute the union of two sorted vector paths.
 * @svp1: One sorted vector path.
 * @svp2: The other sorted vector path.
 *
 * Computes the union of the two argument svp's. Given two svp's with
 * winding numbers of 0 and 1 everywhere, the resulting winding number
 * will be 1 where either (or both) of the argument svp's has a
 * winding number 1, 0 otherwise. The result is newly allocated.
 *
 * Currently, this routine has accuracy problems pending the
 * implementation of the new intersector.
 *
 * Return value: The union of @svp1 and @svp2.
 **/
ArtSVP *
art_svp_union (const ArtSVP *svp1, const ArtSVP *svp2)
{
  ArtSVP *svp3, *svp4, *svp_new;

  svp3 = art_svp_merge_perturbed (svp1, svp2);
  svp4 = art_svp_uncross (svp3);
  art_svp_free (svp3);

  svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_POSITIVE);
#ifdef VERBOSE
  print_ps_svp (svp4);
  print_ps_svp (svp_new);
#endif
  art_svp_free (svp4);
  return svp_new;
}
Exemplo n.º 8
0
gfxline_t* gfxpoly_circular_to_evenodd(gfxline_t*line, double gridsize)
{
    msg("<verbose> Converting circular-filled gfxline of %d segments to even-odd filled gfxline", gfxline_len(line));
    ArtSVP* svp = gfxfillToSVP(line, 1);

    ArtSVP* svp_rewinded;
    
    svp_rewinded = run_intersector(svp, ART_WIND_RULE_NONZERO);
    if(!svp_rewinded) {
	art_svp_free(svp);
	return 0;
    }

    gfxline_t* result = gfxline_from_gfxpoly((gfxpoly_t*)svp_rewinded);
    art_svp_free(svp);
    art_svp_free(svp_rewinded);
    return result;
}
Exemplo n.º 9
0
/**
 * art_svp_vpath_stroke: Stroke a vector path.
 * @vpath: #ArtVPath to stroke.
 * @join: Join style.
 * @cap: Cap style.
 * @line_width: Width of stroke.
 * @miter_limit: Miter limit.
 * @flatness: Flatness.
 *
 * Computes an svp representing the stroked outline of @vpath. The
 * width of the stroked line is @line_width.
 *
 * Lines are joined according to the @join rule. Possible values are
 * ART_PATH_STROKE_JOIN_MITER (for mitered joins),
 * ART_PATH_STROKE_JOIN_ROUND (for round joins), and
 * ART_PATH_STROKE_JOIN_BEVEL (for bevelled joins). The mitered join
 * is converted to a bevelled join if the miter would extend to a
 * distance of more than @miter_limit * @line_width from the actual
 * join point.
 *
 * If there are open subpaths, the ends of these subpaths are capped
 * according to the @cap rule. Possible values are
 * ART_PATH_STROKE_CAP_BUTT (squared cap, extends exactly to end
 * point), ART_PATH_STROKE_CAP_ROUND (rounded half-circle centered at
 * the end point), and ART_PATH_STROKE_CAP_SQUARE (squared cap,
 * extending half @line_width past the end point).
 *
 * The @flatness parameter controls the accuracy of the rendering. It
 * is most important for determining the number of points to use to
 * approximate circular arcs for round lines and joins. In general, the
 * resulting vector path will be within @flatness pixels of the "ideal"
 * path containing actual circular arcs. I reserve the right to use
 * the @flatness parameter to convert bevelled joins to miters for very
 * small turn angles, as this would reduce the number of points in the
 * resulting outline path.
 *
 * The resulting path is "clean" with respect to self-intersections, i.e.
 * the winding number is 0 or 1 at each point.
 *
 * Return value: Resulting stroked outline in svp format.
 **/
ArtSVP *
art_svp_vpath_stroke (ArtVpath *vpath,
		      ArtPathStrokeJoinType join,
		      ArtPathStrokeCapType cap,
		      double line_width,
		      double miter_limit,
		      double flatness)
{
  ArtVpath *vpath_stroke, *vpath2;
  ArtSVP *svp, *svp2, *svp3;

  vpath_stroke = art_svp_vpath_stroke_raw (vpath, join, cap,
					   line_width, miter_limit, flatness);
#ifdef VERBOSE
  print_ps_vpath (vpath_stroke);
#endif
  vpath2 = art_vpath_perturb (vpath_stroke);
#ifdef VERBOSE
  print_ps_vpath (vpath2);
#endif
  art_free (vpath_stroke);
  svp = art_svp_from_vpath (vpath2);
#ifdef VERBOSE
  print_ps_svp (svp);
#endif
  art_free (vpath2);
  svp2 = art_svp_uncross (svp);
#ifdef VERBOSE
  print_ps_svp (svp2);
#endif
  art_svp_free (svp);
  svp3 = art_svp_rewind_uncrossed (svp2, ART_WIND_RULE_NONZERO);
#ifdef VERBOSE
  print_ps_svp (svp3);
#endif
  art_svp_free (svp2);

  return svp3;
}
Exemplo n.º 10
0
gfxpoly_t* gfxpoly_from_fill(gfxline_t*line, double gridsize)
{
    /* I'm not sure whether doing perturbation here is actually
       a good idea- if that line has been run through the machinery
       several times already, it might be safer to leave it alone,
       since it should already be in a format libart can handle */
#ifdef PERTURBATE
    ArtSVP* svp = gfxfillToSVP(line, 1);
#else
    ArtSVP* svp = gfxfillToSVP(line, 0);
#endif

#ifdef DEBUG
    char filename[80];
    static int counter = 0;
    sprintf(filename, "svp%d.ps", counter);
    write_svp_postscript(filename, svp);
    sprintf(filename, "gfxline%d.ps", counter);
    write_gfxline_postscript(filename, line);
#endif

    /* we do xor-filling by default, so dir is always 1 
       (actually for oddeven rewinding it makes no difference, but
        it's "cleaner")
     */
    int t;
    for(t=0; t<svp->n_segs; t++) {
        svp->segs[t].dir = 1;
    }
            
    /* for some reason, we need to rewind / self-intersect the polygons that gfxfillToSVP
       returns- art probably uses a different fill mode (circular?) for vpaths */
    ArtSVP*svp_uncrossed=0;
   
#ifdef DEBUG
    sprintf(filename, "svp%d_in.ps", counter);
    write_svp_postscript(filename, svp);
    counter++;
#endif

    svp_uncrossed = run_intersector(svp, ART_WIND_RULE_ODDEVEN);

    art_svp_free(svp);
    svp=svp_uncrossed;

    return (gfxpoly_t*)svp;
}
Exemplo n.º 11
0
/**
 * art_svp_vpath_stroke: Stroke a vector path.
 * @vpath: #ArtVPath to stroke.
 * @join: Join style.
 * @cap: Cap style.
 * @line_width: Width of stroke.
 * @miter_limit: Miter limit.
 * @flatness: Flatness.
 *
 * Computes an svp representing the stroked outline of @vpath. The
 * width of the stroked line is @line_width.
 *
 * Lines are joined according to the @join rule. Possible values are
 * ART_PATH_STROKE_JOIN_MITER (for mitered joins),
 * ART_PATH_STROKE_JOIN_ROUND (for round joins), and
 * ART_PATH_STROKE_JOIN_BEVEL (for bevelled joins). The mitered join
 * is converted to a bevelled join if the miter would extend to a
 * distance of more than @miter_limit * @line_width from the actual
 * join point.
 *
 * If there are open subpaths, the ends of these subpaths are capped
 * according to the @cap rule. Possible values are
 * ART_PATH_STROKE_CAP_BUTT (squared cap, extends exactly to end
 * point), ART_PATH_STROKE_CAP_ROUND (rounded half-circle centered at
 * the end point), and ART_PATH_STROKE_CAP_SQUARE (squared cap,
 * extending half @line_width past the end point).
 *
 * The @flatness parameter controls the accuracy of the rendering. It
 * is most important for determining the number of points to use to
 * approximate circular arcs for round lines and joins. In general, the
 * resulting vector path will be within @flatness pixels of the "ideal"
 * path containing actual circular arcs. I reserve the right to use
 * the @flatness parameter to convert bevelled joins to miters for very
 * small turn angles, as this would reduce the number of points in the
 * resulting outline path.
 *
 * The resulting path is "clean" with respect to self-intersections, i.e.
 * the winding number is 0 or 1 at each point.
 *
 * Return value: Resulting stroked outline in svp format.
 **/
ArtSVP *
art_svp_vpath_stroke (ArtVpath *vpath,
                      ArtPathStrokeJoinType join,
                      ArtPathStrokeCapType cap,
                      double line_width,
                      double miter_limit,
                      double flatness)
{
#ifdef ART_USE_NEW_INTERSECTOR
    ArtVpath *vpath_stroke;
    ArtSVP *svp, *svp2;
    ArtSvpWriter *swr;

    vpath_stroke = art_svp_vpath_stroke_raw (vpath, join, cap,
                   line_width, miter_limit, flatness);
#ifdef VERBOSE
    print_ps_vpath (vpath_stroke);
#endif
    svp = art_svp_from_vpath (vpath_stroke);
#ifdef VERBOSE
    print_ps_svp (svp);
#endif
    art_free (vpath_stroke);

    swr = art_svp_writer_rewind_new (ART_WIND_RULE_NONZERO);
    art_svp_intersector (svp, swr);

    svp2 = art_svp_writer_rewind_reap (swr);
#ifdef VERBOSE
    print_ps_svp (svp2);
#endif
    art_svp_free (svp);
    return svp2;
#else
    ArtVpath *vpath_stroke, *vpath2;
    ArtSVP *svp, *svp2, *svp3;

    vpath_stroke = art_svp_vpath_stroke_raw (vpath, join, cap,
                   line_width, miter_limit, flatness);
#ifdef VERBOSE
    print_ps_vpath (vpath_stroke);
#endif
    vpath2 = art_vpath_perturb (vpath_stroke);
#ifdef VERBOSE
    print_ps_vpath (vpath2);
#endif
    art_free (vpath_stroke);
    svp = art_svp_from_vpath (vpath2);
#ifdef VERBOSE
    print_ps_svp (svp);
#endif
    art_free (vpath2);
    svp2 = art_svp_uncross (svp);
#ifdef VERBOSE
    print_ps_svp (svp2);
#endif
    art_svp_free (svp);
    svp3 = art_svp_rewind_uncrossed (svp2, ART_WIND_RULE_NONZERO);
#ifdef VERBOSE
    print_ps_svp (svp3);
#endif
    art_svp_free (svp2);

    return svp3;
#endif
}
Exemplo n.º 12
0
static void
test_intersect (void)
{
    ArtVpath vpath[] = {

#if 0
        /* two triangles */
        { ART_MOVETO, 100, 100 },
        { ART_LINETO, 300, 400 },
        { ART_LINETO, 400, 200 },
        { ART_LINETO, 100, 100 },
        { ART_MOVETO, 110, 110 },
        { ART_LINETO, 310, 410 },
        { ART_LINETO, 410, 210 },
        { ART_LINETO, 110, 110 },
#endif

#if 0
        /* a bowtie */
        { ART_MOVETO, 100, 100 },
        { ART_LINETO, 400, 400 },
        { ART_LINETO, 400, 100 },
        { ART_LINETO, 100, 400 },
        { ART_LINETO, 100, 100 },
#endif

#if 1
        /* a square */
        { ART_MOVETO, 100, 100 },
        { ART_LINETO, 100, 400 },
        { ART_LINETO, 400, 400 },
        { ART_LINETO, 400, 100 },
        { ART_LINETO, 100, 100 },
#endif

#if 1
        /* another square */
#define XOFF 10
#define YOFF 10
        { ART_MOVETO, 100 + XOFF, 100 + YOFF },
        { ART_LINETO, 100 + XOFF, 400 + YOFF },
        { ART_LINETO, 400 + XOFF, 400 + YOFF },
        { ART_LINETO, 400 + XOFF, 100 + YOFF },
        { ART_LINETO, 100 + XOFF, 100 + YOFF },
#endif

        { ART_END, 0, 0}
    };
    ArtSVP *svp, *svp2;
    ArtSvpWriter *swr;

    svp = art_svp_from_vpath (vpath);

#define RUN_INTERSECT
#ifdef RUN_INTERSECT
    swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN);
    art_svp_intersector (svp, swr);

    svp2 = art_svp_writer_rewind_reap (swr);
#endif

#if 0
    output_svp_ppm (svp2);
#else
    print_svp (svp2);
#endif

    art_svp_free (svp);

#ifdef RUN_INTERSECT
    art_svp_free (svp2);
#endif
}
Exemplo n.º 13
0
static void
make_testpat (void)
{
    ArtVpath *vpath, *vpath2, *vpath3;
    ArtSVP *svp, *svp2;
    ArtSVP *svp3;
    art_u8 buf[512 * 512 * BYTES_PP];
    int i, j;
    int iter;
    art_u8 colorimg[256][256][3];
    art_u8 rgbaimg[256][256][4];
    art_u8 bitimg[16][2];
    int x, y;
    double affine[6];
    double affine2[6];
    double affine3[6];
    ArtAlphaGamma *alphagamma;
    double dash_data[] = { 20 };
    ArtVpathDash dash;

    dash.offset = 0;
    dash.n_dash = 1;
    dash.dash = dash_data;

#ifdef TEST_AFFINE
    test_affine ();
    exit (0);
#endif

    vpath = randstar (50);
    svp = art_svp_from_vpath (vpath);
    art_free (vpath);

    vpath2 = randstar (50);
#if 1
    vpath3 = art_vpath_dash (vpath2, &dash);
    art_free (vpath2);
    svp2 = art_svp_vpath_stroke (vpath3,
                                 ART_PATH_STROKE_JOIN_MITER,
                                 ART_PATH_STROKE_CAP_BUTT,
                                 15,
                                 4,
                                 0.5);
    art_free (vpath3);
#else
    svp2 = art_svp_from_vpath (vpath2);
#endif

#if 1
    svp3 = art_svp_intersect (svp, svp2);
#else
    svp3 = svp2;
#endif

#if 0
    print_svp (svp);
#endif

    for (y = 0; y < 256; y++)
        for (x = 0; x < 256; x++)
        {
            colorimg[y][x][0] = (x + y) >> 1;
            colorimg[y][x][1] = (x + (255 - y)) >> 1;
            colorimg[y][x][2] = ((255 - x) + y) >> 1;

            rgbaimg[y][x][0] = (x + y) >> 1;
            rgbaimg[y][x][1] = (x + (255 - y)) >> 1;
            rgbaimg[y][x][2] = ((255 - x) + y) >> 1;
            rgbaimg[y][x][3] = y;
        }

    for (y = 0; y < 16; y++)
        for (x = 0; x < 2; x++)
            bitimg[y][x] = (x << 4) | y;

    affine[0] = 0.5;
    affine[1] = .2;
    affine[2] = -.2;
    affine[3] = 0.5;
    affine[4] = 64;
    affine[5] = 64;

    affine2[0] = 1;
    affine2[1] = -.2;
    affine2[2] = .2;
    affine2[3] = 1;
    affine2[4] = 128;
    affine2[5] = 128;

    affine3[0] = 5;
    affine3[1] = -.2;
    affine3[2] = .2;
    affine3[3] = 5;
    affine3[4] = 384;
    affine3[5] = 32;

#if 0
    alphagamma = art_alphagamma_new (1.8);
#else
    alphagamma = NULL;
#endif

#ifdef COLOR
    printf ("P6\n512 512\n255\n");
#else
    printf ("P5\n512 512\n255\n");
#endif
    for (iter = 0; iter < NUM_ITERS; iter++)
        for (j = 0; j < 512; j += TILE_SIZE)
            for (i = 0; i < 512; i += TILE_SIZE)
            {
#ifdef COLOR
                art_rgb_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE,
                                0xffe0a0, 0x100040,
                                buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
                                alphagamma);
                art_rgb_svp_alpha (svp2, i, j, i + TILE_SIZE, j + TILE_SIZE,
                                   0xff000080,
                                   buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
                                   alphagamma);
                art_rgb_svp_alpha (svp3, i, j, i + TILE_SIZE, j + TILE_SIZE,
                                   0x00ff0080,
                                   buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
                                   alphagamma);
                art_rgb_affine (buf + (j * 512 + i) * BYTES_PP,
                                i, j, i + TILE_SIZE, j + TILE_SIZE, 512 * BYTES_PP,
                                (art_u8 *)colorimg, 256, 256, 256 * 3,
                                affine,
                                ART_FILTER_NEAREST, alphagamma);
                art_rgb_rgba_affine (buf + (j * 512 + i) * BYTES_PP,
                                     i, j, i + TILE_SIZE, j + TILE_SIZE,
                                     512 * BYTES_PP,
                                     (art_u8 *)rgbaimg, 256, 256, 256 * 4,
                                     affine2,
                                     ART_FILTER_NEAREST, alphagamma);
                art_rgb_bitmap_affine (buf + (j * 512 + i) * BYTES_PP,
                                       i, j, i + TILE_SIZE, j + TILE_SIZE,
                                       512 * BYTES_PP,
                                       (art_u8 *)bitimg, 16, 16, 2,
                                       0xffff00ff,
                                       affine3,
                                       ART_FILTER_NEAREST, alphagamma);
#else
                art_gray_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE,
                                 buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP);
#endif
            }

    art_svp_free (svp2);
    art_svp_free (svp3);
    art_svp_free (svp);

#if 1
    fwrite (buf, 1, 512 * 512 * BYTES_PP, stdout);
#endif
}
Exemplo n.º 14
0
void art_draw_poly(art_buffer_p buffer, art_context_p context, int filled,
		   float *x, float *y, int n, int closed)
{
  ArtVpath *vec, *vec2;
  ArtSVP *svp;
  double dash_data[2];
  ArtVpathDash dash;
  ArtDRect drect;
  ArtIRect irect;
  int i, mark = 0;

  vec = art_new(ArtVpath, n + 1 + closed);
  for(i = 0; i < n; i++) {
    vec[mark].code = i ? ART_LINETO : ART_MOVETO;
    if(i == 0 || i == n - 1 || hypot(x[i] - vec[mark - 1].x,
				     (buffer->height - y[i]) - 
				     vec[mark - 1].y) > 1.0) {
      vec[mark].x = x[i];
      vec[mark].y = buffer->height - y[i];
      mark++;
    }
  }
  n = mark;
  if(closed) {
    vec[n].code = ART_LINETO;
    vec[n].x = vec[0].x;
    vec[n].y = vec[0].y;
  }
  vec[n + closed].code = ART_END;
  vec[n + closed].x = 0;
  vec[n + closed].y = 0;
  if(context->current_dash_on > 0) {
    dash.offset = 0;
    dash_data[0] = context->current_dash_on;
    dash_data[1] = context->current_dash_off;
    dash.n_dash = 2;
    dash.dash = dash_data;
    vec2 = art_vpath_dash(vec, &dash);
    art_free(vec);
    vec = vec2;
  }

  if(filled)
    svp = art_svp_from_vpath(vec);
  else
    svp = art_svp_vpath_stroke(vec, context->current_jointype, 
			       context->current_captype,
			       context->current_linewidth,
			       context->current_miterlimit, 
			       context->current_flatness);
  art_free(vec);

  art_drect_svp(&drect, svp);
  art_drect_to_irect(&irect, &drect);
  if(irect.x1 > buffer->width)
    irect.x1 = buffer->width;
  if(irect.y1 > buffer->height)
    irect.y1 = buffer->height;
  if(irect.x0 < 0)
    irect.x0 = 0;
  if(irect.y0 < 0)
    irect.y0 = 0;
  art_rgb_svp_alpha(svp, irect.x0, irect.y0, irect.x1, irect.y1, 
		    context->current_color,
		    buffer->buffer + (irect.y0 * buffer->width + irect.x0) * 3,
		    buffer->width * 3, NULL);
  art_svp_free(svp);
}
Exemplo n.º 15
0
void finalize_selectregion(void)
{
  GList *itemlist;
  struct Item *item;
  ArtVpath *vpath;
  ArtSVP *lassosvp;
  int i, n;
  double *pt;
  
  ui.cur_item_type = ITEM_NONE;
  
  // build SVP for the lasso path
  n = ui.cur_path.num_points;
  vpath = g_malloc((n+2)*sizeof(ArtVpath));
  for (i=0; i<n; i++) { 
    vpath[i].x = ui.cur_path.coords[2*i];
    vpath[i].y = ui.cur_path.coords[2*i+1];
  }
  vpath[n].x = vpath[0].x; vpath[n].y = vpath[0].y;
  vpath[0].code = ART_MOVETO;
  for (i=1; i<=n; i++) vpath[i].code = ART_LINETO;
  vpath[n+1].code = ART_END;
  lassosvp = art_svp_from_vpath(vpath);
  g_free(vpath);

  // see which items we selected
  for (itemlist = ui.selection->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
    item = (struct Item *)itemlist->data;
    if (hittest_item(lassosvp, item)) {
      // update the selection bbox
      if (ui.selection->items==NULL || ui.selection->bbox.left>item->bbox.left)
        ui.selection->bbox.left = item->bbox.left;
      if (ui.selection->items==NULL || ui.selection->bbox.right<item->bbox.right)
        ui.selection->bbox.right = item->bbox.right;
      if (ui.selection->items==NULL || ui.selection->bbox.top>item->bbox.top)
        ui.selection->bbox.top = item->bbox.top;
      if (ui.selection->items==NULL || ui.selection->bbox.bottom<item->bbox.bottom)
        ui.selection->bbox.bottom = item->bbox.bottom;
      // add the item
      ui.selection->items = g_list_append(ui.selection->items, item); 
    }
  }
  art_svp_free(lassosvp);
  
  if (ui.selection->items == NULL) {
    // if we clicked inside a text zone or image?
    pt = ui.cur_path.coords; 
    item = click_is_in_text_or_image(ui.selection->layer, pt[0], pt[1]);
    if (item!=NULL) {
      for (i=0; i<n; i++, pt+=2) {
        if (pt[0]<item->bbox.left || pt[0]>item->bbox.right || pt[1]<item->bbox.top || pt[1]>item->bbox.bottom)
          { item = NULL; break; }
      }
    }
    if (item!=NULL) {
      ui.selection->items = g_list_append(ui.selection->items, item);
      g_memmove(&(ui.selection->bbox), &(item->bbox), sizeof(struct BBox));
    }
  }

  if (ui.selection->items == NULL) reset_selection();
  else { // make a selection rectangle instead of the lasso shape
    gtk_object_destroy(GTK_OBJECT(ui.selection->canvas_item));
    ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
      gnome_canvas_rect_get_type(), "width-pixels", 1, 
      "outline-color-rgba", 0x000000ff,
      "fill-color-rgba", 0x80808040,
      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, 
      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
    make_dashed(ui.selection->canvas_item);
    ui.selection->type = ITEM_SELECTRECT;
  }

  update_cursor();
  update_copy_paste_enabled();
  update_font_button();
}
Exemplo n.º 16
0
void gfxpoly_destroy(gfxpoly_t*poly)
{
    ArtSVP*svp = (ArtSVP*)poly;
    art_svp_free(svp);
}