diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-08-30 21:35:42 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-08-30 21:35:42 +0000 |
| commit | 8756c49b91fd4262b6770ac3b2f229209bdae96b (patch) | |
| tree | 67ac89d7bc7c69e04e811324734dccafc07f33c9 /src/svg | |
| parent | Merged from trunk (r12465). (diff) | |
| parent | Merge emf/wmf work (diff) | |
| download | inkscape-8756c49b91fd4262b6770ac3b2f229209bdae96b.tar.gz inkscape-8756c49b91fd4262b6770ac3b2f229209bdae96b.zip | |
Merged from trunk (r12488).
(bzr r11608.1.120)
Diffstat (limited to 'src/svg')
| -rw-r--r-- | src/svg/path-string.cpp | 72 | ||||
| -rw-r--r-- | src/svg/path-string.h | 24 | ||||
| -rw-r--r-- | src/svg/svg-length.cpp | 16 |
3 files changed, 74 insertions, 38 deletions
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/svg/svg-length.cpp b/src/svg/svg-length.cpp index d2f4332d8..ea438e91a 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -23,7 +23,7 @@ #include "svg.h" #include "stringstream.h" -#include "../unit-constants.h" +#include "util/units.h" static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, float *val, float *computed, char **next); @@ -330,6 +330,8 @@ static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, *next = (char *) e + 1; } return 1; + } else if (g_ascii_isspace(e[0])) { + return 0; // spaces are not allowed } else { /* Unitless */ if (unit) { @@ -365,7 +367,7 @@ static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, *unit = SVGLength::PT; } if (computed) { - *computed = v * PX_PER_PT; + *computed = v * Inkscape::Util::Quantity::convert(1, "pt", "px"); } break; case UVAL('p','c'): @@ -373,7 +375,7 @@ static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, *unit = SVGLength::PC; } if (computed) { - *computed = v * PX_PER_PC; + *computed = v * Inkscape::Util::Quantity::convert(1, "pc", "px"); } break; case UVAL('m','m'): @@ -381,7 +383,7 @@ static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, *unit = SVGLength::MM; } if (computed) { - *computed = v * PX_PER_MM; + *computed = v * Inkscape::Util::Quantity::convert(1, "mm", "px"); } break; case UVAL('c','m'): @@ -389,7 +391,7 @@ static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, *unit = SVGLength::CM; } if (computed) { - *computed = v * PX_PER_CM; + *computed = v * Inkscape::Util::Quantity::convert(1, "cm", "px"); } break; case UVAL('i','n'): @@ -397,7 +399,7 @@ static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, *unit = SVGLength::INCH; } if (computed) { - *computed = v * PX_PER_IN; + *computed = v * Inkscape::Util::Quantity::convert(1, "in", "px"); } break; case UVAL('f','t'): @@ -405,7 +407,7 @@ static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, *unit = SVGLength::FOOT; } if (computed) { - *computed = v * PX_PER_FT; + *computed = v * Inkscape::Util::Quantity::convert(1, "ft", "px"); } break; case UVAL('e','m'): |
