static ArtSVP * art_svp_merge_perturbed (const ArtSVP *svp1, const ArtSVP *svp2) { ArtVpath *vpath1, *vpath2; ArtVpath *vpath1_p, *vpath2_p; ArtSVP *svp1_p, *svp2_p; ArtSVP *svp_new; vpath1 = art_vpath_from_svp (svp1); vpath1_p = art_vpath_perturb (vpath1); art_free (vpath1); svp1_p = art_svp_from_vpath (vpath1_p); art_free (vpath1_p); vpath2 = art_vpath_from_svp (svp2); vpath2_p = art_vpath_perturb (vpath2); art_free (vpath2); svp2_p = art_svp_from_vpath (vpath2_p); art_free (vpath2_p); svp_new = art_svp_merge (svp1_p, svp2_p); #ifdef VERBOSE print_ps_svp (svp1_p); print_ps_svp (svp2_p); print_ps_svp (svp_new); #endif art_free (svp1_p); art_free (svp2_p); return svp_new; }
/** * 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; }
gfxpoly_t* gfxpoly_from_stroke(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, double miterLimit, double gridsize) { ArtVpath* vec = gfxline_to_ArtVpath(line, 0); msg("<verbose> Casting gfxline of %d segments to a stroke-polygon", gfxline_len(line)); ArtVpath* vec2 = art_vpath_perturb(vec); free(vec); vec = vec2; ArtSVP *svp = art_svp_vpath_stroke (vec, (joint_style==gfx_joinMiter)?ART_PATH_STROKE_JOIN_MITER: ((joint_style==gfx_joinRound)?ART_PATH_STROKE_JOIN_ROUND: ((joint_style==gfx_joinBevel)?ART_PATH_STROKE_JOIN_BEVEL:ART_PATH_STROKE_JOIN_BEVEL)), (cap_style==gfx_capButt)?ART_PATH_STROKE_CAP_BUTT: ((cap_style==gfx_capRound)?ART_PATH_STROKE_CAP_ROUND: ((cap_style==gfx_capSquare)?ART_PATH_STROKE_CAP_SQUARE:ART_PATH_STROKE_CAP_SQUARE)), width, //line_width miterLimit, //miter_limit 0.05 //flatness ); free(vec); return (gfxpoly_t*)svp; }
/** * 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 }