diff options
author | Norbert Preining <norbert@preining.info> | 2020-03-22 03:00:48 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-03-22 03:00:48 +0000 |
commit | 75d8dfa80524727ddb7d8ae217ed6463efba84cf (patch) | |
tree | a1a1db248828dd36aecb1697d64d28a2ff813d29 /dviware/dvisvgm/src | |
parent | 3e43bc594a14e8c4fc21d6a71f22a23dd78fe252 (diff) |
CTAN sync 202003220300
Diffstat (limited to 'dviware/dvisvgm/src')
-rw-r--r-- | dviware/dvisvgm/src/Calculator.cpp | 1 | ||||
-rw-r--r-- | dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp | 33 | ||||
-rw-r--r-- | dviware/dvisvgm/src/Matrix.cpp | 2 | ||||
-rw-r--r-- | dviware/dvisvgm/src/NumericRanges.hpp | 9 | ||||
-rw-r--r-- | dviware/dvisvgm/src/PageRanges.cpp | 1 | ||||
-rw-r--r-- | dviware/dvisvgm/src/PageRanges.hpp | 5 |
6 files changed, 39 insertions, 12 deletions
diff --git a/dviware/dvisvgm/src/Calculator.cpp b/dviware/dvisvgm/src/Calculator.cpp index c5dc00df4d..0fdcf0f2fa 100644 --- a/dviware/dvisvgm/src/Calculator.cpp +++ b/dviware/dvisvgm/src/Calculator.cpp @@ -71,6 +71,7 @@ double Calculator::term (istream &is, bool skip) { // term: for (;;) switch (lookAhead(is)) { case '*': left *= prim(is, true); break; // prim '*' prim => $1 * $3 + case '(': left *= prim(is, false); break; // prim '*' prim => $1 * $3 case '/': { // prim '/' prim => $1 / $3 double denom = prim(is, true); if (denom == 0) diff --git a/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp b/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp index b2af27d636..1f331659f0 100644 --- a/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp +++ b/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp @@ -21,6 +21,7 @@ #include <array> #include <cstring> #include <utility> +#include "Calculator.hpp" #include "DvisvgmSpecialHandler.hpp" #include "InputBuffer.hpp" #include "InputReader.hpp" @@ -190,6 +191,35 @@ static void expand_constants (string &str, SpecialActions &actions) { } +/** Evaluates substrings of the form {?(expr)} where 'expr' is a math expression, + * and replaces the substring by the computed value. + * @param[in,out] str string to scan for expressions */ +static void evaluate_expressions (string &str, SpecialActions &actions) { + size_t left = str.find("{?("); // start position of expression macro + while (left != string::npos) { + size_t right = str.find(")}", left+2); // end position of expression macro + if (right == string::npos) + break; + Calculator calc; + calc.setVariable("x", actions.getX()); + calc.setVariable("y", actions.getY()); + string expr = str.substr(left+3, right-left-3); // math expression to evaluate + if (util::normalize_space(expr).empty()) // no expression given, e.g. {?( )} + str.erase(left, right-left+2); // => replace with empty string + else { + try { + double val = calc.eval(expr); + str.replace(left, right-left+2, XMLString(val)); + } + catch (CalculatorException &e) { + throw SpecialException(string(e.what())+" in '{?("+expr+")}'"); + } + } + left = str.find("{?(", right+1); // find next expression macro + } +} + + /** Processes raw SVG fragments from the input stream. The SVG data must represent * a single or multiple syntactically complete XML parts, like opening/closing tags, * comments, or CDATA blocks. These must not be split and distributed over several @@ -199,6 +229,7 @@ void DvisvgmSpecialHandler::processRaw (InputReader &ir, SpecialActions &actions if (_nestingLevel == 0) { string xml = ir.getLine(); if (!xml.empty()) { + evaluate_expressions(xml, actions); expand_constants(xml, actions); _pageParser.parse(xml, actions); } @@ -536,4 +567,4 @@ void DvisvgmSpecialHandler::XMLParser::flush (SpecialActions &actions) { tags.resize(tags.length()-2); throw SpecialException("missing closing tags: "+tags); } -}
\ No newline at end of file +} diff --git a/dviware/dvisvgm/src/Matrix.cpp b/dviware/dvisvgm/src/Matrix.cpp index 75d571877a..d0dcb2124d 100644 --- a/dviware/dvisvgm/src/Matrix.cpp +++ b/dviware/dvisvgm/src/Matrix.cpp @@ -538,7 +538,7 @@ Matrix Matrix::parseSVGTransform (const string &transform) { } else if (parse_transform_cmd(iss, "scale", 1, 2, params)) { if (params.size() == 1) - params.push_back(1); + params.push_back(params[0]); if (ne(params[0], 1) || ne(params[1], 1)) matrix.rmultiply(ScalingMatrix(params[0], params[1])); } diff --git a/dviware/dvisvgm/src/NumericRanges.hpp b/dviware/dvisvgm/src/NumericRanges.hpp index a6ee109568..1669f7ddce 100644 --- a/dviware/dvisvgm/src/NumericRanges.hpp +++ b/dviware/dvisvgm/src/NumericRanges.hpp @@ -26,8 +26,7 @@ #include <utility> template <class T> -class NumericRanges -{ +class NumericRanges { public: using Range = std::pair<T,T>; using Container = std::list<Range>; @@ -54,7 +53,7 @@ template <class T> void NumericRanges<T>::addRange (T first, T last) { if (first > last) std::swap(first, last); - typename Container::iterator it = _ranges.begin(); + auto it = _ranges.begin(); while (it != _ranges.end() && first > it->first+1 && first > it->second+1) ++it; if (it == _ranges.end() || last < it->first-1 || first > it->second+1) @@ -65,8 +64,8 @@ void NumericRanges<T>::addRange (T first, T last) { } // merge adjacent ranges if (it != _ranges.end()) { - typename Container::iterator l = it; - typename Container::iterator r = it; + auto l = it; + auto r = it; if (l == _ranges.begin()) l = _ranges.end(); else diff --git a/dviware/dvisvgm/src/PageRanges.cpp b/dviware/dvisvgm/src/PageRanges.cpp index a08ad4aa54..2623d2ef46 100644 --- a/dviware/dvisvgm/src/PageRanges.cpp +++ b/dviware/dvisvgm/src/PageRanges.cpp @@ -18,7 +18,6 @@ ** along with this program; if not, see <http://www.gnu.org/licenses/>. ** *************************************************************************/ -#include <sstream> #include "InputBuffer.hpp" #include "InputReader.hpp" #include "PageRanges.hpp" diff --git a/dviware/dvisvgm/src/PageRanges.hpp b/dviware/dvisvgm/src/PageRanges.hpp index e6909b9cd1..555338449a 100644 --- a/dviware/dvisvgm/src/PageRanges.hpp +++ b/dviware/dvisvgm/src/PageRanges.hpp @@ -21,13 +21,10 @@ #ifndef PAGERANGES_HPP #define PAGERANGES_HPP -#include <list> #include <string> -#include <utility> #include "NumericRanges.hpp" -class PageRanges : public NumericRanges<int> -{ +class PageRanges : public NumericRanges<int> { public: bool parse (const std::string &str, int max_page=0); size_t numberOfPages () const; |