summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp')
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp150
1 files changed, 50 insertions, 100 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp
index abeb52be36c..ca1f4a7fc19 100644
--- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp
+++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp
@@ -2,7 +2,7 @@
** DvisvgmSpecialHandler.cpp **
** **
** This file is part of dvisvgm -- a fast DVI to SVG converter **
-** Copyright (C) 2005-2023 Martin Gieseking <martin.gieseking@uos.de> **
+** Copyright (C) 2005-2024 Martin Gieseking <martin.gieseking@uos.de> **
** **
** This program is free software; you can redistribute it and/or **
** modify it under the terms of the GNU General Public License as **
@@ -18,7 +18,6 @@
** along with this program; if not, see <http://www.gnu.org/licenses/>. **
*************************************************************************/
-#include <array>
#include <cstring>
#include <utility>
#include "Calculator.hpp"
@@ -27,6 +26,7 @@
#include "InputBuffer.hpp"
#include "InputReader.hpp"
#include "Length.hpp"
+#include "Message.hpp"
#include "SpecialActions.hpp"
#include "SVGTree.hpp"
#include "utility.hpp"
@@ -95,24 +95,23 @@ DvisvgmSpecialHandler::DvisvgmSpecialHandler () : _currentMacro(_macros.end())
void DvisvgmSpecialHandler::preprocess (const string&, istream &is, SpecialActions&) {
- struct Command {
+ constexpr struct Command {
const char *name;
void (DvisvgmSpecialHandler::*handler)(InputReader&);
- };
- constexpr array<Command, 5> commands {{
+ } commands[] = {
{"raw", &DvisvgmSpecialHandler::preprocessRaw},
{"rawdef", &DvisvgmSpecialHandler::preprocessRawDef},
{"rawset", &DvisvgmSpecialHandler::preprocessRawSet},
{"endrawset", &DvisvgmSpecialHandler::preprocessEndRawSet},
{"rawput", &DvisvgmSpecialHandler::preprocessRawPut}
- }};
+ };
StreamInputReader ir(is);
const string cmdstr = ir.getWord();
- auto it = find_if(commands.begin(), commands.end(), [&](const Command &cmd) {
+ auto it = find_if(begin(commands), end(commands), [&](const Command &cmd) {
return cmd.name == cmdstr;
});
- if (it != commands.end()) {
+ if (it != end(commands)) {
ir.skipSpace();
(this->*it->handler)(ir);
}
@@ -172,25 +171,26 @@ void DvisvgmSpecialHandler::preprocessRawPut (InputReader &ir) {
* @param[in] is the special statement is read from this stream
* @param[in] actions object providing the actions that can be performed by the SpecialHandler */
bool DvisvgmSpecialHandler::process (const string &prefix, istream &is, SpecialActions &actions) {
- struct Command {
+ constexpr struct Command {
const char *name;
void (DvisvgmSpecialHandler::*handler)(InputReader&, SpecialActions&);
+ } commands[] = {
+ {"raw", &DvisvgmSpecialHandler::processRaw},
+ {"rawdef", &DvisvgmSpecialHandler::processRawDef},
+ {"rawset", &DvisvgmSpecialHandler::processRawSet},
+ {"endrawset", &DvisvgmSpecialHandler::processEndRawSet},
+ {"rawput", &DvisvgmSpecialHandler::processRawPut},
+ {"bbox", &DvisvgmSpecialHandler::processBBox},
+ {"img", &DvisvgmSpecialHandler::processImg},
+ {"currentcolor", &DvisvgmSpecialHandler::processCurrentColor},
+ {"message", &DvisvgmSpecialHandler::processMessage}
};
- constexpr array<Command, 7> commands {{
- {"raw", &DvisvgmSpecialHandler::processRaw},
- {"rawdef", &DvisvgmSpecialHandler::processRawDef},
- {"rawset", &DvisvgmSpecialHandler::processRawSet},
- {"endrawset", &DvisvgmSpecialHandler::processEndRawSet},
- {"rawput", &DvisvgmSpecialHandler::processRawPut},
- {"bbox", &DvisvgmSpecialHandler::processBBox},
- {"img", &DvisvgmSpecialHandler::processImg}
- }};
StreamInputReader ir(is);
const string cmdstr = ir.getWord();
- auto it = find_if(commands.begin(), commands.end(), [&](const Command &cmd) {
+ auto it = find_if(begin(commands), end(commands), [&](const Command &cmd) {
return cmd.name == cmdstr;
});
- if (it != commands.end()) {
+ if (it != end(commands)) {
ir.skipSpace();
(this->*it->handler)(ir, actions);
}
@@ -198,80 +198,6 @@ bool DvisvgmSpecialHandler::process (const string &prefix, istream &is, SpecialA
}
-/** Replaces constants of the form {?name} by their corresponding value.
- * @param[in,out] str text to expand
- * @param[in] actions interfcae to the world outside the special handler */
-static void expand_constants (string &str, SpecialActions &actions) {
- bool repl_bbox = true;
- while (repl_bbox) {
- const auto pos = str.find("{?bbox ");
- if (pos == string::npos)
- repl_bbox = false;
- else {
- auto endpos = pos+7;
- while (endpos < str.length() && isalnum(str[endpos]))
- ++endpos;
- if (str[endpos] != '}')
- repl_bbox = false;
- else {
- BoundingBox &box = actions.bbox(str.substr(pos+7, endpos-pos-7));
- str.replace(pos, endpos-pos+1, box.svgViewBoxString());
- }
- }
- }
- struct Constant {
- const char *name;
- string val;
- };
- const array<Constant, 5> constants {{
- {"x", XMLString(actions.getX())},
- {"y", XMLString(actions.getY())},
- {"color", actions.getColor().svgColorString()},
- {"matrix", actions.getMatrix().toSVG()},
- {"nl", "\n"},
- }};
- for (const Constant &constant : constants) {
- const string pattern = string("{?")+constant.name+"}";
- auto pos = str.find(pattern);
- while (pos != string::npos) {
- str.replace(pos, strlen(constant.name)+3, constant.val);
- pos = str.find(pattern, pos+constant.val.length()); // look for further matches
- }
- }
-}
-
-
-/** 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, const SpecialActions &actions) {
- auto left = str.find("{?("); // start position of expression macro
- while (left != string::npos) {
- auto 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);
- XMLString valstr(val);
- str.replace(left, right-left+2, valstr);
- right = left+valstr.length()-1;
- }
- 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
@@ -281,8 +207,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);
+ xml = actions.expandText(xml);
_pageParser.parse(std::move(xml));
}
}
@@ -293,8 +218,7 @@ void DvisvgmSpecialHandler::processRawDef (InputReader &ir, SpecialActions &acti
if (_nestingLevel == 0) {
string xml = ir.getLine();
if (!xml.empty()) {
- evaluate_expressions(xml, actions);
- expand_constants(xml, actions);
+ xml = actions.expandText(xml);
_defsParser.parse(std::move(xml));
}
}
@@ -325,7 +249,7 @@ void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions &acti
char &type = defstr[0];
string def = defstr.substr(1);
if ((type == 'P' || type == 'D') && !def.empty()) {
- expand_constants(def, actions);
+ def = actions.expandText(def);
if (type == 'P')
_pageParser.parse(std::move(def));
else { // type == 'D'
@@ -452,6 +376,32 @@ void DvisvgmSpecialHandler::processImg (InputReader &ir, SpecialActions &actions
}
+void DvisvgmSpecialHandler::processCurrentColor (InputReader &ir, SpecialActions &actions) {
+ string param = ir.getString();
+ Color color = actions.getColor();
+ if (param.empty() || param == "on") {
+ SVGElement::CURRENTCOLOR = color;
+ SVGElement::USE_CURRENTCOLOR = true;
+ }
+ else if (param == "off") {
+ if (SVGElement::USE_CURRENTCOLOR) {
+ // force a color change to get the new currentColor setting recognized
+ actions.setColor(Color{uint32_t(color)+1});
+ actions.setColor(color);
+ SVGElement::USE_CURRENTCOLOR = false;
+ }
+ }
+ else
+ throw SpecialException("currentcolor: unknown parameter '"+param+"'");
+}
+
+
+void DvisvgmSpecialHandler::processMessage (InputReader &ir, SpecialActions &actions) {
+ string message = actions.expandText(ir.getLine());
+ Message::ustream() << message << "\n";
+}
+
+
void DvisvgmSpecialHandler::dviPreprocessingFinished () {
string id;
if (_currentMacro != _macros.end())
@@ -486,7 +436,7 @@ void DvisvgmSpecialHandler::dviEndPage (unsigned, SpecialActions &actions) {
}
-vector<const char*> DvisvgmSpecialHandler::prefixes() const {
+vector<const char*> DvisvgmSpecialHandler::prefixes () const {
vector<const char*> pfx {"dvisvgm:"};
return pfx;
}