static void sp_path_convert_to_guides(SPItem *item) { SPPath *path = SP_PATH(item); if (!path->_curve) { return; } std::list<std::pair<Geom::Point, Geom::Point> > pts; Geom::Affine const i2dt(path->i2dt_affine()); Geom::PathVector const & pv = path->_curve->get_pathvector(); for(Geom::PathVector::const_iterator pit = pv.begin(); pit != pv.end(); ++pit) { for(Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_default(); ++cit) { // only add curves for straight line segments if( is_straight_curve(*cit) ) { pts.push_back(std::make_pair(cit->initialPoint() * i2dt, cit->finalPoint() * i2dt)); } } } sp_guide_pt_pairs_to_guides(item->document, pts); }
/* * sp_svg_write_polygon: Write points attribute for polygon tag. * pathv may only contain paths with only straight line segments * Return value: points attribute string. */ static gchar *sp_svg_write_polygon(Geom::PathVector const & pathv) { Inkscape::SVGOStringStream os; for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit) { for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_default(); ++cit) { if ( is_straight_curve(*cit) ) { os << cit->finalPoint()[0] << "," << cit->finalPoint()[1] << " "; } else { g_error("sp_svg_write_polygon: polygon path contains non-straight line segments"); } } } return g_strdup(os.str().c_str()); }
/* * Can be called recursively. * If optimize_stroke == false, the view Rect is not used. */ static void feed_curve_to_cairo(cairo_t *cr, Geom::Curve const &c, Geom::Affine const & trans, Geom::Rect view, bool optimize_stroke) { if( is_straight_curve(c) ) { Geom::Point end_tr = c.finalPoint() * trans; if (!optimize_stroke) { cairo_line_to(cr, end_tr[0], end_tr[1]); } else { Geom::Rect swept(c.initialPoint()*trans, end_tr); if (swept.intersects(view)) { cairo_line_to(cr, end_tr[0], end_tr[1]); } else { cairo_move_to(cr, end_tr[0], end_tr[1]); } } } else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const*>(&c)) { std::vector<Geom::Point> points = quadratic_bezier->points(); points[0] *= trans; points[1] *= trans; points[2] *= trans; Geom::Point b1 = points[0] + (2./3) * (points[1] - points[0]); Geom::Point b2 = b1 + (1./3) * (points[2] - points[0]); if (!optimize_stroke) { cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][0], points[2][1]); } else { Geom::Rect swept(points[0], points[2]); swept.expandTo(points[1]); if (swept.intersects(view)) { cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][0], points[2][1]); } else { cairo_move_to(cr, points[2][0], points[2][1]); } } } else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const*>(&c)) { std::vector<Geom::Point> points = cubic_bezier->points(); //points[0] *= trans; // don't do this one here for fun: it is only needed for optimized strokes points[1] *= trans; points[2] *= trans; points[3] *= trans; if (!optimize_stroke) { cairo_curve_to(cr, points[1][0], points[1][1], points[2][0], points[2][1], points[3][0], points[3][1]); } else { points[0] *= trans; // didn't transform this point yet Geom::Rect swept(points[0], points[3]); swept.expandTo(points[1]); swept.expandTo(points[2]); if (swept.intersects(view)) { cairo_curve_to(cr, points[1][0], points[1][1], points[2][0], points[2][1], points[3][0], points[3][1]); } else { cairo_move_to(cr, points[3][0], points[3][1]); } } } // else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc *>(c)) { // //TODO: get at the innards and spit them out to cairo // } else { //this case handles sbasis as well as all other curve types Geom::Path sbasis_path = Geom::cubicbezierpath_from_sbasis(c.toSBasis(), 0.1); //recurse to convert the new path resulting from the sbasis to svgd for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) { feed_curve_to_cairo(cr, *iter, trans, view, optimize_stroke); } } }