diff options
Diffstat (limited to 'dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp')
-rw-r--r-- | dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp b/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp index abeb52be36..0a84038500 100644 --- a/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp +++ b/dviware/dvisvgm/src/DvisvgmSpecialHandler.cpp @@ -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); } @@ -219,17 +219,16 @@ static void expand_constants (string &str, SpecialActions &actions) { } } } - struct Constant { + const struct Constant { const char *name; string val; - }; - const array<Constant, 5> constants {{ + } constants[] = { {"x", XMLString(actions.getX())}, {"y", XMLString(actions.getY())}, - {"color", actions.getColor().svgColorString()}, + {"color", SVGElement::USE_CURRENTCOLOR && SVGElement::CURRENTCOLOR == actions.getColor() ? "currentColor" : 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); @@ -452,6 +451,34 @@ 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 = ir.getLine(); + evaluate_expressions(message, actions); + expand_constants(message, actions); + Message::mstream() << message << "\n"; +} + + void DvisvgmSpecialHandler::dviPreprocessingFinished () { string id; if (_currentMacro != _macros.end()) @@ -486,7 +513,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; } |