Example #1
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
}
Example #2
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
}
Example #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;
}
Example #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;
}
Example #5
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;
}
Example #6
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;
}
/**
 * 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
}