summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b9c06d6)
raw | patch | inline | side by side (parent: b9c06d6)
author | buliabyak <buliabyak@users.sourceforge.net> | |
Tue, 18 Mar 2008 04:53:42 +0000 (04:53 +0000) | ||
committer | buliabyak <buliabyak@users.sourceforge.net> | |
Tue, 18 Mar 2008 04:53:42 +0000 (04:53 +0000) |
src/preferences-skeleton.h | patch | blob | history | |
src/svg/Makefile_insert | patch | blob | history | |
src/svg/path-string.cpp | [new file with mode: 0644] | patch | blob |
src/svg/path-string.h | patch | blob | history | |
src/svg/svg-path.cpp | patch | blob | history |
index ab8c29f428187bd6529b3a7438b28456ca96da13..225d572b064402e5c52233f78b86c5bff21c200b 100644 (file)
" images=\"4278190335\"" //ff0000ff
" clips=\"16711935\"" // 00ff00ff
" masks=\"65535\"/>\n" // 0x0000ffff
-" <group id=\"svgoutput\" usenamedcolors=\"0\" numericprecision=\"8\" minimumexponent=\"-8\" inlineattrs=\"0\" indent=\"2\"/>\n"
+" <group id=\"svgoutput\" usenamedcolors=\"0\" numericprecision=\"8\" minimumexponent=\"-8\" inlineattrs=\"0\" indent=\"2\" allowrelativecoordinates=\"1\" allowshorthands=\"1\" forcerepeatcommands=\"0\"/>\n"
" <group id=\"forkgradientvectors\" value=\"1\"/>\n"
" <group id=\"grids\""
" no_emphasize_when_zoomedout=\"0\">\n"
index 5c723dfac6bd8f39d745f2b2ebd1254527351dac..5e57c7068c8b2c72986c451e807d19cdeb71ca31 100644 (file)
--- a/src/svg/Makefile_insert
+++ b/src/svg/Makefile_insert
svg/gnome-canvas-bpath-util.h \
svg/itos.cpp \
svg/path-string.h \
+ svg/path-string.cpp \
svg/round.cpp \
svg/stringstream.h \
svg/stringstream.cpp \
diff --git a/src/svg/path-string.cpp b/src/svg/path-string.cpp
--- /dev/null
+++ b/src/svg/path-string.cpp
@@ -0,0 +1,57 @@
+/*
+ * Inkscape::SVG::PathString - builder for SVG path strings
+ *
+ * Copyright 2008 Jasper van de Gronde <th.v.d.gronde@hccnet.nl>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See the file COPYING for details.
+ *
+ */
+
+#include "svg/path-string.h"
+#include "prefs-utils.h"
+
+Inkscape::SVG::PathString::PathString() :
+ allow_relative_coordinates(0 != prefs_get_int_attribute("options.svgoutput", "allowrelativecoordinates", 1)),
+ allow_shorthands(0 != prefs_get_int_attribute("options.svgoutput", "allowshorthands", 1)),
+ force_repeat_commands(0 != prefs_get_int_attribute("options.svgoutput", "forcerepeatcommands", 0))
+{}
+
+void Inkscape::SVG::PathString::_appendOp(char abs_op, char rel_op) {
+ bool abs_op_repeated = _abs_state.prevop == abs_op && !force_repeat_commands;
+ bool rel_op_repeated = _rel_state.prevop == rel_op && !force_repeat_commands;
+ unsigned int const abs_added_size = abs_op_repeated ? 0 : 2;
+ unsigned int const rel_added_size = rel_op_repeated ? 0 : 2;
+ if ( _rel_state.str.size()+2 < _abs_state.str.size()+abs_added_size && allow_relative_coordinates ) {
+ // Copy rel to abs
+ _abs_state = _rel_state;
+ _abs_state.switches++;
+ abs_op_repeated = false;
+ // We do not have to copy abs to rel:
+ // _rel_state.str.size()+2 < _abs_state.str.size()+abs_added_size
+ // _rel_state.str.size()+rel_added_size < _abs_state.str.size()+2
+ // _abs_state.str.size()+2 > _rel_state.str.size()+rel_added_size
+ } else if ( _abs_state.str.size()+2 < _rel_state.str.size()+rel_added_size ) {
+ // Copy abs to rel
+ _rel_state = _abs_state;
+ _abs_state.switches++;
+ rel_op_repeated = false;
+ }
+ if ( !abs_op_repeated ) _abs_state.appendOp(abs_op);
+ if ( !rel_op_repeated ) _rel_state.appendOp(rel_op);
+}
+
+/*
+ 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:encoding=utf-8:textwidth=99 :
diff --git a/src/svg/path-string.h b/src/svg/path-string.h
index 3139466ef56854e155d763ae1ece73bf49652204..e90e110486780550a80de5754592cf1d67891d03 100644 (file)
--- a/src/svg/path-string.h
+++ b/src/svg/path-string.h
* Inkscape::SVG::PathString - builder for SVG path strings
*
* Copyright 2007 MenTaLguY <mental@rydia.net>
+ * Copyright 2008 Jasper van de Gronde <th.v.d.gronde@hccnet.nl>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#include <glibmm/ustring.h>
#include "libnr/nr-point.h"
+#include "libnr/nr-point-ops.h"
#include "svg/stringstream.h"
namespace Inkscape {
class PathString {
public:
- PathString() {}
+ PathString();
// default copy
// default assign
Glib::ustring const &ustring() const {
- return _str;
+ return (_abs_state <= _rel_state || !allow_relative_coordinates) ? _abs_state.str : _rel_state.str;
}
operator Glib::ustring const &() const {
}
char const *c_str() const {
- return _str.c_str();
+ return ustring().c_str();
}
PathString &moveTo(NR::Coord x, NR::Coord y) {
}
PathString &moveTo(NR::Point p) {
- _appendOp('M');
- _append(p);
+ _appendOp('M','m');
+ _appendPoint(p);
+
+ _current_point = _initial_point = p;
return *this;
}
}
PathString &lineTo(NR::Point p) {
- _appendOp('L');
- _append(p);
+ _appendOp('L','l');
+ _appendPoint(p);
+
+ _current_point = p;
return *this;
}
}
PathString &quadTo(NR::Point c, NR::Point p) {
- _appendOp('Q');
- _append(c);
- _append(p);
+ _appendOp('Q','q');
+ _appendPoint(c);
+ _appendPoint(p);
+
+ _current_point = p;
return *this;
}
{
return curveTo(NR::Point(x0, y0), NR::Point(x1, y1), NR::Point(x, y));
}
-
PathString &curveTo(NR::Point c0, NR::Point c1, NR::Point p) {
- _appendOp('C');
- _append(c0);
- _append(c1);
- _append(p);
+ _appendOp('C','c');
+ _appendPoint(c0);
+ _appendPoint(c1);
+ _appendPoint(p);
+
+ _current_point = p;
return *this;
}
bool large_arc, bool sweep,
NR::Point p)
{
- _appendOp('A');
- _append(NR::Point(rx, ry));
- _append(rot);
- _append(large_arc);
- _append(sweep);
- _append(p);
+ _appendOp('A','a');
+ _appendValue(NR::Point(rx,ry));
+ _appendValue(rot);
+ _appendFlag(large_arc);
+ _appendFlag(sweep);
+ _appendPoint(p);
+
+ _current_point = p;
return *this;
}
PathString &closePath() {
- _appendOp('z');
- return *this;
+ _abs_state.appendOp('z');
+ _rel_state.appendOp('z');
+ _current_point = _initial_point;
+ return *this;
}
private:
- void _appendOp(char op) {
- if (!_str.empty()) {
- _str.append(1, ' ');
- }
- _str.append(1, op);
+
+ void _appendOp(char abs_op, char rel_op);
+
+ void _appendFlag(bool flag) {
+ _abs_state.append(flag);
+ _rel_state.append(flag);
+ }
+
+ void _appendValue(NR::Coord v) {
+ _abs_state.append(v);
+ _rel_state.append(v);
}
- void _append(bool flag) {
- _str.append(1, ' ');
- _str.append(1, ( flag ? '1' : '0' ));
+ void _appendValue(NR::Point p) {
+ _abs_state.append(p);
+ _rel_state.append(p);
}
- void _append(NR::Coord v) {
- SVGOStringStream os;
- os << ' ' << v;
- _str.append(os.str());
+ void _appendX(NR::Coord x) {
+ _abs_state.append(x);
+ _rel_state.append(x-_current_point[NR::X]);
}
- void _append(NR::Point p) {
- SVGOStringStream os;
- os << ' ' << p[NR::X] << ',' << p[NR::Y];
- _str.append(os.str());
+ void _appendY(NR::Coord y) {
+ _abs_state.append(y);
+ _rel_state.append(y-_current_point[NR::Y]);
}
- Glib::ustring _str;
+ void _appendPoint(NR::Point p) {
+ _abs_state.append(p);
+ _rel_state.append(p-_current_point);
+ }
+
+ struct State {
+ 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;
+ }
+
+ void append(bool flag) {
+ str.append(1, ' ');
+ str.append(1, ( flag ? '1' : '0' ));
+ }
+
+ void append(NR::Coord v) {
+ SVGOStringStream os;
+ os << ' ' << v;
+ str.append(os.str());
+ }
+
+ void append(NR::Point p) {
+ SVGOStringStream os;
+ os << ' ' << p[NR::X] << ',' << p[NR::Y];
+ str.append(os.str());
+ }
+
+ bool operator<=(const State& s) const {
+ if ( str.size() < s.str.size() ) return true;
+ if ( str.size() > s.str.size() ) return false;
+ if ( switches < s.switches ) return true;
+ if ( switches > s.switches ) return false;
+ return true;
+ }
+
+ Glib::ustring str;
+ unsigned int switches;
+ char prevop;
+ } _abs_state, _rel_state; // State with the last operator being an absolute/relative operator
+
+ NR::Point _initial_point;
+ NR::Point _current_point;
+
+ bool const allow_relative_coordinates;
+ bool const allow_shorthands;
+ bool const force_repeat_commands;
};
}
diff --git a/src/svg/svg-path.cpp b/src/svg/svg-path.cpp
index 0239d2ae0cd843d32c916982ff9170fdee0d5007..30b259fa851142fae25d898f3dab343febcb8260 100644 (file)
--- a/src/svg/svg-path.cpp
+++ b/src/svg/svg-path.cpp
for (int i = 0; bpath[i].code != NR_END; i++){
switch (bpath [i].code){
case NR_LINETO:
- str.lineTo(bpath[i].x3, bpath[i].y3);
+ if (!closed || bpath[i+1].code == NR_LINETO || bpath[i+1].code == NR_CURVETO) {
+ str.lineTo(bpath[i].x3, bpath[i].y3);
+ }
break;
case NR_CURVETO: