1 #define SEEN_LIBNR_N_ART_BPATH_2GEOM_CPP
3 /** \file
4 * Contains functions to convert from NArtBpath to 2geom's Path
5 *
6 * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
7 *
8 * Released under GNU GPL, read the file 'COPYING' for more information
9 */
12 #include "libnr/n-art-bpath-2geom.h"
13 #include "svg/svg.h"
14 #include <glib.h>
15 #include <2geom/path.h>
16 #include <2geom/svg-path.h>
17 #include <2geom/svg-path-parser.h>
18 #include <2geom/sbasis-to-bezier.h>
20 //##########################################################
22 #include <iostream>
23 #include <sstream>
24 #include <string>
25 #include <boost/format.hpp>
27 static void curve_to_svgd(std::ostream & f, Geom::Curve const* c) {
28 if(Geom::LineSegment const *line_segment = dynamic_cast<Geom::LineSegment const *>(c)) {
29 f << boost::format("L %g,%g ") % (*line_segment)[1][0] % (*line_segment)[1][1];
30 }
31 else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const *>(c)) {
32 f << boost::format("Q %g,%g %g,%g ") % (*quadratic_bezier)[1][0] % (*quadratic_bezier)[1][0]
33 % (*quadratic_bezier)[2][0] % (*quadratic_bezier)[2][1];
34 }
35 else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const *>(c)) {
36 f << boost::format("C %g,%g %g,%g %g,%g ")
37 % (*cubic_bezier)[1][0] % (*cubic_bezier)[1][1]
38 % (*cubic_bezier)[2][0] % (*cubic_bezier)[2][1]
39 % (*cubic_bezier)[3][0] % (*cubic_bezier)[3][1];
40 }
41 // else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc *>(c)) {
42 // //get at the innards and spit them out as svgd
43 // }
44 else {
45 //this case handles sbasis as well as all other curve types
46 Geom::Path sbasis_path = Geom::path_from_sbasis(c->toSBasis(), 0.1);
48 //recurse to convert the new path resulting from the sbasis to svgd
49 for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) {
50 curve_to_svgd(f, &(*iter));
51 }
52 }
53 }
55 static void write_svgd(std::ostream & f, Geom::Path const &p) {
56 if(f == NULL) {
57 f << "ERRRRRRORRRRR";
58 return;
59 }
61 f << boost::format("M %g,%g ") % p.initialPoint()[0] % p.initialPoint()[1];
63 for(Geom::Path::const_iterator iter(p.begin()), end(p.end()); iter != end; ++iter) {
64 curve_to_svgd(f, &(*iter));
65 }
66 if(p.closed())
67 f << "Z ";
68 }
70 static void write_svgd(std::ostream & f, std::vector<Geom::Path> const &p) {
71 std::vector<Geom::Path>::const_iterator it(p.begin());
72 for(; it != p.end(); it++) {
73 write_svgd(f, *it);
74 }
75 }
77 std::vector<Geom::Path>
78 SVGD_to_2GeomPath (char const *svgd)
79 {
80 std::vector<Geom::Path> pathv;
82 try {
83 pathv = Geom::parse_svg_path(svgd);
84 }
85 catch (std::runtime_error e) {
86 g_warning("SVGPathParseError: %s", e.what());
87 }
89 return pathv;
90 }
93 std::vector<Geom::Path>
94 BPath_to_2GeomPath(NArtBpath const * bpath)
95 {
96 std::vector<Geom::Path> pathv;
97 char *svgpath = sp_svg_write_path(bpath);
98 if (!svgpath) {
99 g_warning("BPath_to_2GeomPath - empty path returned");
100 return pathv;
101 }
102 pathv = SVGD_to_2GeomPath(svgpath);
103 g_free(svgpath);
104 return pathv;
105 }
107 char *
108 SVGD_from_2GeomPath(std::vector<Geom::Path> const & path)
109 {
110 std::ostringstream ss;
111 write_svgd(ss, path);
112 ss.flush();
113 std::string str = ss.str();
114 char * svgd = g_strdup(str.c_str());
115 return svgd;
116 }
118 NArtBpath *
119 BPath_from_2GeomPath(std::vector<Geom::Path> const & path)
120 {
121 char * svgd = SVGD_from_2GeomPath(path);
122 NArtBpath *bpath = sp_svg_read_path(svgd);
123 g_free(svgd);
124 return bpath;
125 }
129 /*
130 Local Variables:
131 mode:c++
132 c-file-style:"stroustrup"
133 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
134 indent-tabs-mode:nil
135 fill-column:99
136 End:
137 */
138 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :