summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2013-08-15 19:10:29 +0000
committertavmjong-free <tavmjong@free.fr>2013-08-15 19:10:29 +0000
commit69ac4cffff595c46b3f8dd2bcceab6bccf6e4581 (patch)
tree2c7ef901ce3cdfb685d19fccce140aa1fbb25854 /src
parentFix Gtk+ 3 build failure and make check (diff)
downloadinkscape-69ac4cffff595c46b3f8dd2bcceab6bccf6e4581.tar.gz
inkscape-69ac4cffff595c46b3f8dd2bcceab6bccf6e4581.zip
Add option to write out path data using only relative coordinates
(in addition to using only absolute coordinates or using a mixture of absolute and relative coordinates optimized for length). (bzr r12480)
Diffstat (limited to 'src')
-rw-r--r--src/preferences-skeleton.h2
-rw-r--r--src/svg/path-string.cpp72
-rw-r--r--src/svg/path-string.h24
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp8
-rw-r--r--src/ui/dialog/inkscape-preferences.h2
5 files changed, 73 insertions, 35 deletions
diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h
index c5d972966..17b912d33 100644
--- a/src/preferences-skeleton.h
+++ b/src/preferences-skeleton.h
@@ -326,7 +326,7 @@ static char const preferences_skeleton[] =
" minimumexponent=\"-8\" "
" inlineattrs=\"0\" "
" indent=\"2\" "
-" allowrelativecoordinates=\"1\" "
+" pathstring_format=\"2\" "
" forcerepeatcommands=\"0\" "
" incorrect_attributes_warn=\"1\" "
" incorrect_attributes_remove=\"0\" "
diff --git a/src/svg/path-string.cpp b/src/svg/path-string.cpp
index 61e9c90a2..6dddeadff 100644
--- a/src/svg/path-string.cpp
+++ b/src/svg/path-string.cpp
@@ -2,6 +2,7 @@
* Inkscape::SVG::PathString - builder for SVG path strings
*
* Copyright 2008 Jasper van de Gronde <th.v.d.gronde@hccnet.nl>
+ * Copyright 2013 Tavmjong Bah <tavmjong@free.fr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -25,44 +26,65 @@ static int const maxprec = 16;
int Inkscape::SVG::PathString::numericprecision;
int Inkscape::SVG::PathString::minimumexponent;
+Inkscape::SVG::PATHSTRING_FORMAT Inkscape::SVG::PathString::format;
Inkscape::SVG::PathString::PathString() :
- allow_relative_coordinates(Inkscape::Preferences::get()->getBool("/options/svgoutput/allowrelativecoordinates", true)),
force_repeat_commands(Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands"))
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ format = (PATHSTRING_FORMAT)prefs->getIntLimited("/options/svgoutput/pathstring_format", 1, 0, PATHSTRING_FORMAT_SIZE - 1 );
numericprecision = std::max<int>(minprec,std::min<int>(maxprec, prefs->getInt("/options/svgoutput/numericprecision", 8)));
minimumexponent = prefs->getInt("/options/svgoutput/minimumexponent", -8);
}
+// For absolute and relative paths... the entire path is kept in the "tail".
+// For optimized path, at a switch between absolute and relative, add tail to commonbase.
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 ) {
- // Store common prefix
- commonbase += _rel_state.str;
- _rel_state.str.clear();
- // 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 ) {
- // Store common prefix
- commonbase += _abs_state.str;
- _abs_state.str.clear();
- // Copy abs to rel
- _rel_state = _abs_state;
- _abs_state.switches++;
- rel_op_repeated = false;
+
+ // For absolute and relative paths... do nothing.
+ switch (format) {
+ case PATHSTRING_ABSOLUTE:
+ if ( !abs_op_repeated ) _abs_state.appendOp(abs_op);
+ break;
+ case PATHSTRING_RELATIVE:
+ if ( !rel_op_repeated ) _rel_state.appendOp(rel_op);
+ break;
+ case PATHSTRING_OPTIMIZE:
+ {
+ 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 ) {
+
+ // Store common prefix
+ commonbase += _rel_state.str;
+ _rel_state.str.clear();
+ // 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 ) {
+
+ // Store common prefix
+ commonbase += _abs_state.str;
+ _abs_state.str.clear();
+ // 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);
+ }
+ break;
+ default:
+ std::cout << "Better not be here!" << std::endl;
}
- if ( !abs_op_repeated ) _abs_state.appendOp(abs_op);
- if ( !rel_op_repeated ) _rel_state.appendOp(rel_op);
}
void Inkscape::SVG::PathString::State::append(Geom::Coord v) {
diff --git a/src/svg/path-string.h b/src/svg/path-string.h
index 11018e65c..3a891873d 100644
--- a/src/svg/path-string.h
+++ b/src/svg/path-string.h
@@ -1,6 +1,7 @@
/*
* Copyright 2007 MenTaLguY <mental@rydia.net>
* Copyright 2008 Jasper van de Gronde <th.v.d.gronde@hccnet.nl>
+ * Copyright 2013 Tavmjong Bah <tavmjong@free.fr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,6 +24,14 @@ namespace Inkscape {
namespace SVG {
+// Relative vs. absolute coordinates
+enum PATHSTRING_FORMAT {
+ PATHSTRING_ABSOLUTE, // Use only absolute coordinates
+ PATHSTRING_RELATIVE, // Use only relative coordinates
+ PATHSTRING_OPTIMIZE, // Optimize for path string length
+ PATHSTRING_FORMAT_SIZE
+};
+
/**
* Builder for SVG path strings.
*/
@@ -38,6 +47,7 @@ public:
final.reserve(commonbase.size()+t.size());
final = commonbase;
final += tail();
+ // std::cout << " final: " << final << std::endl;
return final;
}
@@ -130,12 +140,10 @@ public:
}
PathString &closePath() {
- commonbase += _abs_state.str;
- _abs_state.str.clear();
- _rel_state = _abs_state;
+
_abs_state.appendOp('Z');
_rel_state.appendOp('z');
- _rel_state.switches++;
+
_current_point = _initial_point;
return *this;
}
@@ -229,9 +237,13 @@ private:
// 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); }
+ std::string const &tail() const {
+ return ( (format == PATHSTRING_ABSOLUTE) ||
+ (format == PATHSTRING_OPTIMIZE && _abs_state <= _rel_state ) ?
+ _abs_state.str : _rel_state.str );
+ }
- bool const allow_relative_coordinates;
+ static PATHSTRING_FORMAT format;
bool const force_repeat_commands;
static int numericprecision;
static int minimumexponent;
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index 7890b0b4c..b06c1fd1f 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -879,8 +879,12 @@ void InkscapePreferences::initPageIO()
_page_svgoutput.add_group_header( _("Path data"));
- _svgoutput_allowrelativecoordinates.init( _("Allow relative coordinates"), "/options/svgoutput/allowrelativecoordinates", true);
- _page_svgoutput.add_line( true, "", _svgoutput_allowrelativecoordinates, "", _("If set, relative coordinates may be used in path data"), false);
+ int const numPathstringFormat = 3;
+ Glib::ustring pathstringFormatLabels[numPathstringFormat] = {_("Absolute"), _("Relative"), _("Optimized")};
+ int pathstringFormatValues[numPathstringFormat] = {0, 1, 2};
+
+ _svgoutput_pathformat.init("/options/svgoutput/pathstring_format", pathstringFormatLabels, pathstringFormatValues, numPathstringFormat, 2);
+ _page_svgoutput.add_line( true, _("Path string format"), _svgoutput_pathformat, "", _("Path data should be written: only with absolute coordinates, only with relative coordinates, or optimized for string length (mixed absolute and relative coordinates)"), false);
_svgoutput_forcerepeatcommands.init( _("Force repeat commands"), "/options/svgoutput/forcerepeatcommands", false);
_page_svgoutput.add_line( true, "", _svgoutput_forcerepeatcommands, "", _("Force repeating of the same path command (for example, 'L 1,2 L 3,4' instead of 'L 1,2 3,4')"), false);
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index 37c05df05..56222fb22 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -426,7 +426,7 @@ protected:
UI::Widget::PrefSpinButton _svgoutput_minimumexponent;
UI::Widget::PrefCheckButton _svgoutput_inlineattrs;
UI::Widget::PrefSpinButton _svgoutput_indent;
- UI::Widget::PrefCheckButton _svgoutput_allowrelativecoordinates;
+ UI::Widget::PrefCombo _svgoutput_pathformat;
UI::Widget::PrefCheckButton _svgoutput_forcerepeatcommands;
// Attribute Checking controls for SVG Output page: