From d9c673867f424647c1586c356cc0ac1d34d0a98a Mon Sep 17 00:00:00 2001 From: johanengelen Date: Sun, 13 Apr 2008 21:01:01 +0000 Subject: [PATCH] move live_effects/n-art-bpath-2geom.* to libnr/n-art-bpath-2geom.* --- src/libnr/n-art-bpath-2geom.cpp | 138 ++++++ .../n-art-bpath-2geom.h | 0 src/live_effects/effect.cpp | 2 +- src/live_effects/lpe-bendpath.cpp | 2 +- src/live_effects/lpe-curvestitch.cpp | 2 +- src/live_effects/lpe-patternalongpath.cpp | 2 +- src/live_effects/lpe-vonkoch.cpp | 2 +- src/live_effects/lpe-vonkoch.h | 2 +- src/live_effects/lpegroupbbox.cpp | 2 +- src/live_effects/n-art-bpath-2geom.cpp | 415 ------------------ src/live_effects/parameter/path.cpp | 2 +- src/object-snapper.cpp | 2 +- src/ui/clipboard.cpp | 2 +- 13 files changed, 148 insertions(+), 425 deletions(-) create mode 100644 src/libnr/n-art-bpath-2geom.cpp rename src/{live_effects => libnr}/n-art-bpath-2geom.h (100%) delete mode 100644 src/live_effects/n-art-bpath-2geom.cpp diff --git a/src/libnr/n-art-bpath-2geom.cpp b/src/libnr/n-art-bpath-2geom.cpp new file mode 100644 index 000000000..89ac85b2b --- /dev/null +++ b/src/libnr/n-art-bpath-2geom.cpp @@ -0,0 +1,138 @@ +#define SEEN_LIBNR_N_ART_BPATH_2GEOM_CPP + +/** \file + * Contains functions to convert from NArtBpath to 2geom's Path + * + * Copyright (C) Johan Engelen 2007 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "libnr/n-art-bpath-2geom.h" +#include "svg/svg.h" +#include +#include <2geom/path.h> +#include <2geom/svg-path.h> +#include <2geom/svg-path-parser.h> +#include <2geom/sbasis-to-bezier.h> + +//########################################################## + +#include +#include +#include +#include + +static void curve_to_svgd(std::ostream & f, Geom::Curve const* c) { + if(Geom::LineSegment const *line_segment = dynamic_cast(c)) { + f << boost::format("L %g,%g ") % (*line_segment)[1][0] % (*line_segment)[1][1]; + } + else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast(c)) { + f << boost::format("Q %g,%g %g,%g ") % (*quadratic_bezier)[1][0] % (*quadratic_bezier)[1][0] + % (*quadratic_bezier)[2][0] % (*quadratic_bezier)[2][1]; + } + else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast(c)) { + f << boost::format("C %g,%g %g,%g %g,%g ") + % (*cubic_bezier)[1][0] % (*cubic_bezier)[1][1] + % (*cubic_bezier)[2][0] % (*cubic_bezier)[2][1] + % (*cubic_bezier)[3][0] % (*cubic_bezier)[3][1]; + } +// else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast(c)) { +// //get at the innards and spit them out as svgd +// } + else { + //this case handles sbasis as well as all other curve types + Geom::Path sbasis_path = Geom::path_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) { + curve_to_svgd(f, &(*iter)); + } + } +} + +static void write_svgd(std::ostream & f, Geom::Path const &p) { + if(f == NULL) { + f << "ERRRRRRORRRRR"; + return; + } + + f << boost::format("M %g,%g ") % p.initialPoint()[0] % p.initialPoint()[1]; + + for(Geom::Path::const_iterator iter(p.begin()), end(p.end()); iter != end; ++iter) { + curve_to_svgd(f, &(*iter)); + } + if(p.closed()) + f << "Z "; +} + +static void write_svgd(std::ostream & f, std::vector const &p) { + std::vector::const_iterator it(p.begin()); + for(; it != p.end(); it++) { + write_svgd(f, *it); + } +} + +std::vector +SVGD_to_2GeomPath (char const *svgd) +{ + std::vector pathv; + + try { + pathv = Geom::parse_svg_path(svgd); + } + catch (std::runtime_error e) { + g_warning("SVGPathParseError: %s", e.what()); + } + + return pathv; +} + + +std::vector +BPath_to_2GeomPath(NArtBpath const * bpath) +{ + std::vector pathv; + char *svgpath = sp_svg_write_path(bpath); + if (!svgpath) { + g_warning("BPath_to_2GeomPath - empty path returned"); + return pathv; + } + pathv = SVGD_to_2GeomPath(svgpath); + g_free(svgpath); + return pathv; +} + +char * +SVGD_from_2GeomPath(std::vector const & path) +{ + std::ostringstream ss; + write_svgd(ss, path); + ss.flush(); + std::string str = ss.str(); + char * svgd = g_strdup(str.c_str()); + return svgd; +} + +NArtBpath * +BPath_from_2GeomPath(std::vector const & path) +{ + char * svgd = SVGD_from_2GeomPath(path); + NArtBpath *bpath = sp_svg_read_path(svgd); + g_free(svgd); + return bpath; +} + + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/n-art-bpath-2geom.h b/src/libnr/n-art-bpath-2geom.h similarity index 100% rename from src/live_effects/n-art-bpath-2geom.h rename to src/libnr/n-art-bpath-2geom.h diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index a1507dbc7..22fd14510 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -21,7 +21,7 @@ #include "live_effects/lpeobject.h" #include "live_effects/parameter/parameter.h" #include -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "display/curve.h" #include diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index b9f414df0..8ce3ce788 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -15,7 +15,7 @@ #include "display/curve.h" #include #include -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "svg/svg.h" #include "ui/widget/scalar.h" diff --git a/src/live_effects/lpe-curvestitch.cpp b/src/live_effects/lpe-curvestitch.cpp index 18647cf48..a9bb6931f 100644 --- a/src/live_effects/lpe-curvestitch.cpp +++ b/src/live_effects/lpe-curvestitch.cpp @@ -18,7 +18,7 @@ #include #include "sp-item.h" #include "sp-path.h" -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "xml/repr.h" #include <2geom/path.h> diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index d36050a7f..9ab085d54 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -10,7 +10,7 @@ #include "sp-shape.h" #include "display/curve.h" #include -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "svg/svg.h" #include "ui/widget/scalar.h" diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index a4b3062d9..159d11428 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -15,7 +15,7 @@ #include "display/curve.h" #include #include -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "svg/svg.h" #include "ui/widget/scalar.h" diff --git a/src/live_effects/lpe-vonkoch.h b/src/live_effects/lpe-vonkoch.h index 45e97295c..c4126e5e6 100644 --- a/src/live_effects/lpe-vonkoch.h +++ b/src/live_effects/lpe-vonkoch.h @@ -15,7 +15,7 @@ #include "live_effects/parameter/enum.h" #include "live_effects/parameter/bool.h" -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" // needed for on-canvas editting: #include "tools-switch.h" diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 1468e5dde..64bdef465 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -14,7 +14,7 @@ #include "display/curve.h" #include #include -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "svg/svg.h" #include "ui/widget/scalar.h" diff --git a/src/live_effects/n-art-bpath-2geom.cpp b/src/live_effects/n-art-bpath-2geom.cpp deleted file mode 100644 index 72d4a6917..000000000 --- a/src/live_effects/n-art-bpath-2geom.cpp +++ /dev/null @@ -1,415 +0,0 @@ -#define SEEN_LIBNR_N_ART_BPATH_2GEOM_CPP - -/** \file - * Contains functions to convert from NArtBpath to 2geom's Path - * - * Copyright (C) Johan Engelen 2007 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - - -#include "live_effects/n-art-bpath-2geom.h" -#include "svg/svg.h" -#include -#include <2geom/path.h> -#include <2geom/svg-path.h> -#include <2geom/svg-path-parser.h> -#include <2geom/sbasis-to-bezier.h> - -#define LPE_USE_2GEOM_CONVERSION - -//########################################################## - -#include -#include -#include -#include - -static void curve_to_svgd(std::ostream & f, Geom::Curve const* c) { - if(Geom::LineSegment const *line_segment = dynamic_cast(c)) { - f << boost::format("L %g,%g ") % (*line_segment)[1][0] % (*line_segment)[1][1]; - } - else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast(c)) { - f << boost::format("Q %g,%g %g,%g ") % (*quadratic_bezier)[1][0] % (*quadratic_bezier)[1][0] - % (*quadratic_bezier)[2][0] % (*quadratic_bezier)[2][1]; - } - else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast(c)) { - f << boost::format("C %g,%g %g,%g %g,%g ") - % (*cubic_bezier)[1][0] % (*cubic_bezier)[1][1] - % (*cubic_bezier)[2][0] % (*cubic_bezier)[2][1] - % (*cubic_bezier)[3][0] % (*cubic_bezier)[3][1]; - } -// else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast(c)) { -// //get at the innards and spit them out as svgd -// } - else { - //this case handles sbasis as well as all other curve types - Geom::Path sbasis_path = Geom::path_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) { - curve_to_svgd(f, &(*iter)); - } - } -} - -static void write_svgd(std::ostream & f, Geom::Path const &p) { - if(f == NULL) { - f << "ERRRRRRORRRRR"; - return; - } - - f << boost::format("M %g,%g ") % p.initialPoint()[0] % p.initialPoint()[1]; - - for(Geom::Path::const_iterator iter(p.begin()), end(p.end()); iter != end; ++iter) { - curve_to_svgd(f, &(*iter)); - } - if(p.closed()) - f << "Z "; -} - -static void write_svgd(std::ostream & f, std::vector const &p) { - std::vector::const_iterator it(p.begin()); - for(; it != p.end(); it++) { - write_svgd(f, *it); - } -} - -//########################################################## -#ifndef LPE_USE_2GEOM_CONVERSION - -static -Geom::Point point(double *nums, int ix) { - return Geom::Point(nums[ix], nums[ix + 1]); -} - -using namespace Geom; - -class OldPathBuilder { -public: - OldPathBuilder(double const &c = Geom_EPSILON) : _current_path(NULL) { - _continuity_tollerance = c; - } - - void startPathRel(Point const &p0) { startPath(p0 + _current_point); } - void startPath(Point const &p0) { - _pathset.push_back(Geom::Path()); - _current_path = &_pathset.back(); - _initial_point = _current_point = p0; - } - - void pushLineRel(Point const &p0) { pushLine(p0 + _current_point); } - void pushLine(Point const &p1) { - if (!_current_path) startPath(_current_point); - _current_path->appendNew(p1); - _current_point = p1; - } - - void pushLineRel(Point const &p0, Point const &p1) { pushLine(p0 + _current_point, p1 + _current_point); } - void pushLine(Point const &p0, Point const &p1) { - if(p0 != _current_point) startPath(p0); - pushLine(p1); - } - - void pushHorizontalRel(Coord y) { pushHorizontal(y + _current_point[1]); } - void pushHorizontal(Coord y) { - if (!_current_path) startPath(_current_point); - pushLine(Point(_current_point[0], y)); - } - - void pushVerticalRel(Coord x) { pushVertical(x + _current_point[0]); } - void pushVertical(Coord x) { - if (!_current_path) startPath(_current_point); - pushLine(Point(x, _current_point[1])); - } - - void pushQuadraticRel(Point const &p1, Point const &p2) { pushQuadratic(p1 + _current_point, p2 + _current_point); } - void pushQuadratic(Point const &p1, Point const &p2) { - if (!_current_path) startPath(_current_point); - _current_path->appendNew(p1, p2); - _current_point = p2; - } - - void pushQuadraticRel(Point const &p0, Point const &p1, Point const &p2) { - pushQuadratic(p0 + _current_point, p1 + _current_point, p2 + _current_point); - } - void pushQuadratic(Point const &p0, Point const &p1, Point const &p2) { - if(p0 != _current_point) startPath(p0); - pushQuadratic(p1, p2); - } - - void pushCubicRel(Point const &p1, Point const &p2, Point const &p3) { - pushCubic(p1 + _current_point, p2 + _current_point, p3 + _current_point); - } - void pushCubic(Point const &p1, Point const &p2, Point const &p3) { - if (!_current_path) startPath(_current_point); - _current_path->appendNew(p1, p2, p3); - _current_point = p3; - } - - void pushCubicRel(Point const &p0, Point const &p1, Point const &p2, Point const &p3) { - pushCubic(p0 + _current_point, p1 + _current_point, p2 + _current_point, p3 + _current_point); - } - void pushCubic(Point const &p0, Point const &p1, Point const &p2, Point const &p3) { - if(p0 != _current_point) startPath(p0); - pushCubic(p1, p2, p3); - } -/* - void pushEllipseRel(Point const &radii, double rotation, bool large, bool sweep, Point const &end) { - pushEllipse(radii, rotation, large, sweep, end + _current_point); - } - void pushEllipse(Point const &radii, double rotation, bool large, bool sweep, Point const &end) { - if (!_current_path) startPath(_current_point); - _current_path->append(SVGEllipticalArc(_current_point, radii[0], radii[1], rotation, large, sweep, end)); - _current_point = end; - } - - void pushEllipseRel(Point const &initial, Point const &radii, double rotation, bool large, bool sweep, Point const &end) { - pushEllipse(initial + _current_point, radii, rotation, large, sweep, end + _current_point); - } - void pushEllipse(Point const &initial, Point const &radii, double rotation, bool large, bool sweep, Point const &end) { - if(initial != _current_point) startPath(initial); - pushEllipse(radii, rotation, large, sweep, end); - }*/ - - void pushSBasis(SBasisCurve &sb) { - pushSBasis(sb.sbasis()); - } - void pushSBasis(D2 sb) { - Point initial = Point(sb[X][0][0], sb[Y][0][0]); - if (!_current_path) startPath(_current_point); - if (distance(initial, _current_point) > _continuity_tollerance) { - startPath(initial); - } else if (_current_point != initial) { - /* in this case there are three possible options - 1. connect the points with tiny line segments - this may well translate into bug reports from - users claiming "duplicate or extraneous nodes" - 2. fudge the initial point of the multidimsb - we've chosen to do this here but question the - numerical stability of this decision - 3. translate the whole sbasis so that initial is coincident - with _current_point. this could very well lead - to an accumulation of error for paths that expect - to meet in the end. - perhaps someday an option could be made to allow - the user to choose between these alternatives - if the need arises - */ - sb[X][0][0] = _current_point[X]; - sb[Y][0][0] = _current_point[Y]; - } - _current_path->append(sb); - } - - void closePath() { - if (_current_path) { - _current_path->close(true); - _current_path = NULL; - } - _current_point = _initial_point = Point(); - } - - std::vector const &peek() const { return _pathset; } - -private: - std::vector _pathset; - Path *_current_path; - Point _current_point; - Point _initial_point; - double _continuity_tollerance; -}; - -static -std::vector -read_svgd(std::istringstream & s) { - assert(s); - - OldPathBuilder builder; - - char mode = 0; - - double nums[7]; - int cur = 0; - while(!s.eof()) { - char ch; - s >> ch; - if((ch >= 'A' and ch <= 'Z') or (ch >= 'a' and ch <= 'z')) { - mode = ch; - cur = 0; - } else if (ch == ' ' or ch == '\t' or ch == '\n' or ch == '\r' or ch == ',') - continue; - else if ((ch >= '0' and ch <= '9') or ch == '-' or ch == '.' or ch == '+') { - s.unget(); - //TODO: use something else, perhaps. Unless the svg path number spec matches scan. - s >> nums[cur]; - cur++; - } - - switch(mode) { - //FIXME: "If a moveto is followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit lineto commands." - case 'm': - if(cur >= 2) { - builder.startPathRel(point(nums, 0)); - cur = 0; - } - break; - case 'M': - if(cur >= 2) { - builder.startPath(point(nums, 0)); - cur = 0; - } - break; - case 'l': - if(cur >= 2) { - builder.pushLineRel(point(nums, 0)); - cur = 0; - } - break; - case 'L': - if(cur >= 2) { - builder.pushLine(point(nums, 0)); - cur = 0; - } - break; - case 'h': - if(cur >= 1) { - builder.pushHorizontalRel(nums[0]); - cur = 0; - } - break; - case 'H': - if(cur >= 1) { - builder.pushHorizontal(nums[0]); - cur = 0; - } - break; - case 'v': - if(cur >= 1) { - builder.pushVerticalRel(nums[0]); - cur = 0; - } - break; - case 'V': - if(cur >= 1) { - builder.pushVertical(nums[0]); - cur = 0; - } - break; - case 'c': - if(cur >= 6) { - builder.pushCubicRel(point(nums, 0), point(nums, 2), point(nums, 4)); - cur = 0; - } - break; - case 'C': - if(cur >= 6) { - builder.pushCubic(point(nums, 0), point(nums, 2), point(nums, 4)); - cur = 0; - } - break; - case 'q': - if(cur >= 4) { - builder.pushQuadraticRel(point(nums, 0), point(nums, 2)); - cur = 0; - } - break; - case 'Q': - if(cur >= 4) { - builder.pushQuadratic(point(nums, 0), point(nums, 2)); - cur = 0; - } - break; - case 'a': - if(cur >= 7) { - //builder.pushEllipseRel(point(nums, 0), nums[2], nums[3] > 0, nums[4] > 0, point(nums, 5)); - cur = 0; - } - break; - case 'A': - if(cur >= 7) { - //builder.pushEllipse(point(nums, 0), nums[2], nums[3] > 0, nums[4] > 0, point(nums, 5)); - cur = 0; - } - break; - case 'z': - case 'Z': - builder.closePath(); - break; - } - } - return builder.peek(); -} - - -#endif -//########################################################## - -std::vector -SVGD_to_2GeomPath (char const *svgd) -{ - std::vector pathv; -#ifdef LPE_USE_2GEOM_CONVERSION - try { - pathv = Geom::parse_svg_path(svgd); - } - catch (std::runtime_error e) { - g_warning("SVGPathParseError: %s", e.what()); - } -#else - std::istringstream ss; - std::string svgd_string = svgd; - ss.str(svgd_string); - pathv = read_svgd(ss); -#endif - return pathv; -} - - -std::vector -BPath_to_2GeomPath(NArtBpath const * bpath) -{ - std::vector pathv; - char *svgpath = sp_svg_write_path(bpath); - if (!svgpath) { - g_warning("BPath_to_2GeomPath - empty path returned"); - return pathv; - } - pathv = SVGD_to_2GeomPath(svgpath); - g_free(svgpath); - return pathv; -} - -char * -SVGD_from_2GeomPath(std::vector const & path) -{ - std::ostringstream ss; - write_svgd(ss, path); - ss.flush(); - std::string str = ss.str(); - char * svgd = g_strdup(str.c_str()); - return svgd; -} - -NArtBpath * -BPath_from_2GeomPath(std::vector const & path) -{ - char * svgd = SVGD_from_2GeomPath(path); - NArtBpath *bpath = sp_svg_read_path(svgd); - g_free(svgd); - return bpath; -} - - - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index d7237e54b..689ec4a8c 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -8,7 +8,7 @@ #include "live_effects/parameter/path.h" #include "live_effects/effect.h" -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "svg/svg.h" #include <2geom/svg-path-parser.h> #include <2geom/sbasis-to-bezier.h> diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 8c728cd97..f05422770 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -15,7 +15,7 @@ #include "libnr/nr-path.h" #include "libnr/nr-rect-ops.h" #include "libnr/nr-point-fns.h" -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "2geom/path-intersection.h" #include "document.h" #include "sp-namedview.h" diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index f0537b720..ebbf6ee1c 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -69,7 +69,7 @@ #include "text-context.h" #include "text-editing.h" #include "tools-switch.h" -#include "live_effects/n-art-bpath-2geom.h" +#include "libnr/n-art-bpath-2geom.h" #include "path-chemistry.h" /// @brief Made up mimetype to represent Gdk::Pixbuf clipboard contents -- 2.30.2