X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsvg%2Fpath-string.h;h=9079acfb44294cb7580ce538b6a53bcb8a75357d;hb=08552a5241b350988214a3fc4b8f55e9cd2bbdaa;hp=bba4c8473969b550d09e10505d96cb6cc6ffbb4a;hpb=117336bcc334c1d380b7592f1639c1a586a28559;p=inkscape.git diff --git a/src/svg/path-string.h b/src/svg/path-string.h index bba4c8473..9079acfb4 100644 --- a/src/svg/path-string.h +++ b/src/svg/path-string.h @@ -1,4 +1,4 @@ -/* +/** * Inkscape::SVG::PathString - builder for SVG path strings * * Copyright 2007 MenTaLguY @@ -17,8 +17,9 @@ #define SEEN_INKSCAPE_SVG_PATH_STRING_H #include -#include "libnr/nr-point.h" -#include "libnr/nr-point-ops.h" +#include +#include +#include <2geom/point.h> namespace Inkscape { @@ -31,23 +32,31 @@ public: // default copy // default assign - Glib::ustring const &ustring() const { - return (_abs_state <= _rel_state || !allow_relative_coordinates) ? _abs_state.str : _rel_state.str; + std::string const &string() { + std::string const &t = tail(); + final.reserve(commonbase.size()+t.size()); + final = commonbase; + final += tail(); + return final; + } + + operator std::string const &() { + return string(); } - operator Glib::ustring const &() const { - return ustring(); + operator Glib::ustring const () const { + return commonbase + tail(); } - char const *c_str() const { - return ustring().c_str(); + char const *c_str() { + return string().c_str(); } - PathString &moveTo(NR::Coord x, NR::Coord y) { - return moveTo(NR::Point(x, y)); + PathString &moveTo(Geom::Coord x, Geom::Coord y) { + return moveTo(Geom::Point(x, y)); } - PathString &moveTo(NR::Point p) { + PathString &moveTo(Geom::Point p) { _appendOp('M','m'); _appendPoint(p, true); @@ -55,47 +64,47 @@ public: return *this; } - PathString &lineTo(NR::Coord x, NR::Coord y) { - return lineTo(NR::Point(x, y)); + PathString &lineTo(Geom::Coord x, Geom::Coord y) { + return lineTo(Geom::Point(x, y)); } - PathString &lineTo(NR::Point p) { + PathString &lineTo(Geom::Point p) { _appendOp('L','l'); _appendPoint(p, true); return *this; } - PathString &horizontalLineTo(NR::Coord x) { + PathString &horizontalLineTo(Geom::Coord x) { _appendOp('H','h'); _appendX(x, true); return *this; } - PathString &verticalLineTo(NR::Coord y) { + PathString &verticalLineTo(Geom::Coord y) { _appendOp('V','v'); _appendY(y, true); return *this; } - PathString &quadTo(NR::Coord cx, NR::Coord cy, NR::Coord x, NR::Coord y) { - return quadTo(NR::Point(cx, cy), NR::Point(x, y)); + PathString &quadTo(Geom::Coord cx, Geom::Coord cy, Geom::Coord x, Geom::Coord y) { + return quadTo(Geom::Point(cx, cy), Geom::Point(x, y)); } - PathString &quadTo(NR::Point c, NR::Point p) { + PathString &quadTo(Geom::Point c, Geom::Point p) { _appendOp('Q','q'); _appendPoint(c, false); _appendPoint(p, true); return *this; } - PathString &curveTo(NR::Coord x0, NR::Coord y0, - NR::Coord x1, NR::Coord y1, - NR::Coord x, NR::Coord y) + PathString &curveTo(Geom::Coord x0, Geom::Coord y0, + Geom::Coord x1, Geom::Coord y1, + Geom::Coord x, Geom::Coord y) { - return curveTo(NR::Point(x0, y0), NR::Point(x1, y1), NR::Point(x, y)); + return curveTo(Geom::Point(x0, y0), Geom::Point(x1, y1), Geom::Point(x, y)); } - PathString &curveTo(NR::Point c0, NR::Point c1, NR::Point p) { + PathString &curveTo(Geom::Point c0, Geom::Point c1, Geom::Point p) { _appendOp('C','c'); _appendPoint(c0, false); _appendPoint(c1, false); @@ -103,12 +112,15 @@ public: return *this; } - PathString &arcTo(NR::Coord rx, NR::Coord ry, NR::Coord rot, + /** + * \param rot the angle in degrees + */ + PathString &arcTo(Geom::Coord rx, Geom::Coord ry, Geom::Coord rot, bool large_arc, bool sweep, - NR::Point p) + Geom::Point p) { _appendOp('A','a'); - _appendValue(NR::Point(rx,ry)); + _appendValue(Geom::Point(rx,ry)); _appendValue(rot); _appendFlag(large_arc); _appendFlag(sweep); @@ -132,32 +144,32 @@ private: _rel_state.append(flag); } - void _appendValue(NR::Coord v) { + void _appendValue(Geom::Coord v) { _abs_state.append(v); _rel_state.append(v); } - void _appendValue(NR::Point p) { + void _appendValue(Geom::Point p) { _abs_state.append(p); _rel_state.append(p); } - void _appendX(NR::Coord x, bool sc) { + void _appendX(Geom::Coord x, bool sc) { double rx; _abs_state.append(x, rx); - _rel_state.appendRelative(rx, _current_point[NR::X]); - if (sc) _current_point[NR::X] = rx; + _rel_state.appendRelative(rx, _current_point[Geom::X]); + if (sc) _current_point[Geom::X] = rx; } - void _appendY(NR::Coord y, bool sc) { + void _appendY(Geom::Coord y, bool sc) { double ry; _abs_state.append(y, ry); - _rel_state.appendRelative(ry, _current_point[NR::Y]); - if (sc) _current_point[NR::Y] = ry; + _rel_state.appendRelative(ry, _current_point[Geom::Y]); + if (sc) _current_point[Geom::Y] = ry; } - void _appendPoint(NR::Point p, bool sc) { - NR::Point rp; + void _appendPoint(Geom::Point p, bool sc) { + Geom::Point rp; _abs_state.append(p, rp); _rel_state.appendRelative(rp, _current_point); if (sc) _current_point = rp; @@ -167,22 +179,22 @@ private: State() { prevop = 0; switches = 0; } void appendOp(char op) { - if (!str.empty()) str.append(1, ' '); - str.append(1, op); - prevop = op == 'M' ? 'L' : op == 'm' ? 'l' : op; + if (prevop != 0) str += ' '; + str += op; + prevop = ( op == 'M' ? 'L' : op == 'm' ? 'l' : op ); } void append(bool flag) { - str.append(1, ' '); - str.append(1, ( flag ? '1' : '0' )); + str += ' '; + str += ( flag ? '1' : '0' ); } - void append(NR::Coord v); - void append(NR::Point v); - void append(NR::Coord v, NR::Coord& rv); - void append(NR::Point p, NR::Point& rp); - void appendRelative(NR::Coord v, NR::Coord r); - void appendRelative(NR::Point p, NR::Point r); + void append(Geom::Coord v); + void append(Geom::Point v); + void append(Geom::Coord v, Geom::Coord& rv); + void append(Geom::Point p, Geom::Point& rp); + void appendRelative(Geom::Coord v, Geom::Coord r); + void appendRelative(Geom::Point p, Geom::Point r); bool operator<=(const State& s) const { if ( str.size() < s.str.size() ) return true; @@ -192,16 +204,32 @@ private: return true; } - Glib::ustring str; + // Note: changing this to Glib::ustring might cause problems in path-string.cpp because it assumes that + // size() returns the size of the string in BYTES (and Glib::ustring::resize is terribly slow) + std::string str; unsigned int switches; char prevop; + + private: + void appendNumber(double v, int precision=numericprecision, int minexp=minimumexponent); + void appendNumber(double v, double &rv, int precision=numericprecision, int minexp=minimumexponent); + void appendRelativeCoord(Geom::Coord v, Geom::Coord r); } _abs_state, _rel_state; // State with the last operator being an absolute/relative operator - NR::Point _initial_point; - NR::Point _current_point; + Geom::Point _initial_point; + Geom::Point _current_point; + + // If both states have a common prefix it is stored here. + // Separating out the common prefix prevents repeated copying between the states + // to cause a quadratic time complexity (in the number of characters/operators) + std::string commonbase; + std::string final; + std::string const &tail() const { return ((_abs_state <= _rel_state || !allow_relative_coordinates) ? _abs_state.str : _rel_state.str); } bool const allow_relative_coordinates; bool const force_repeat_commands; + static int numericprecision; + static int minimumexponent; }; }