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.cpp194
1 files changed, 107 insertions, 87 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp
index ad09f800d7e..720da8ddeca 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-2017 Martin Gieseking <martin.gieseking@uos.de> **
+** Copyright (C) 2005-2018 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,7 @@
** along with this program; if not, see <http://www.gnu.org/licenses/>. **
*************************************************************************/
-#include <config.h>
+#include <array>
#include <cstring>
#include <utility>
#include "DvisvgmSpecialHandler.hpp"
@@ -26,6 +26,7 @@
#include "InputReader.hpp"
#include "Length.hpp"
#include "SpecialActions.hpp"
+#include "utility.hpp"
#include "XMLNode.hpp"
#include "XMLString.hpp"
@@ -42,20 +43,21 @@ void DvisvgmSpecialHandler::preprocess (const char*, istream &is, SpecialActions
struct Command {
const char *name;
void (DvisvgmSpecialHandler::*handler)(InputReader&);
- } commands[] = {
+ };
+ constexpr array<Command, 5> commands {{
{"raw", &DvisvgmSpecialHandler::preprocessRaw},
{"rawdef", &DvisvgmSpecialHandler::preprocessRawDef},
{"rawset", &DvisvgmSpecialHandler::preprocessRawSet},
{"endrawset", &DvisvgmSpecialHandler::preprocessEndRawSet},
- {"rawput", &DvisvgmSpecialHandler::preprocessRawPut},
- };
+ {"rawput", &DvisvgmSpecialHandler::preprocessRawPut}
+ }};
StreamInputReader ir(is);
- string cmd = ir.getWord();
- for (size_t i=0; i < sizeof(commands)/sizeof(Command); i++) {
- if (commands[i].name == cmd) {
+ string cmdstr = ir.getWord();
+ for (const Command &command : commands) {
+ if (command.name == cmdstr) {
ir.skipSpace();
- (this->*commands[i].handler)(ir);
+ (this->*command.handler)(ir);
return;
}
}
@@ -92,7 +94,7 @@ void DvisvgmSpecialHandler::preprocessRaw (InputReader &ir) {
return;
string str = ir.getLine();
if (!str.empty())
- _currentMacro->second.emplace_back(string("P")+str);
+ _currentMacro->second.emplace_back("P"+str);
}
@@ -101,7 +103,7 @@ void DvisvgmSpecialHandler::preprocessRawDef (InputReader &ir) {
return;
string str = ir.getLine();
if (!str.empty())
- _currentMacro->second.emplace_back(string("D")+str);
+ _currentMacro->second.emplace_back("D"+str);
}
@@ -119,21 +121,22 @@ bool DvisvgmSpecialHandler::process (const char *prefix, istream &is, SpecialAct
struct Command {
const char *name;
void (DvisvgmSpecialHandler::*handler)(InputReader&, SpecialActions&);
- } commands[] = {
+ };
+ 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},
- };
+ {"img", &DvisvgmSpecialHandler::processImg}
+ }};
StreamInputReader ir(is);
- string cmd = ir.getWord();
- for (size_t i=0; i < sizeof(commands)/sizeof(Command); i++) {
- if (commands[i].name == cmd) {
+ string cmdstr = ir.getWord();
+ for (const Command &command : commands) {
+ if (command.name == cmdstr) {
ir.skipSpace();
- (this->*commands[i].handler)(ir, actions);
+ (this->*command.handler)(ir, actions);
return true;
}
}
@@ -145,20 +148,9 @@ bool DvisvgmSpecialHandler::process (const char *prefix, istream &is, SpecialAct
* @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) {
- struct Constant {
- const char *name;
- string val;
- }
- constants[] = {
- {"x", XMLString(actions.getX())},
- {"y", XMLString(actions.getY())},
- {"color", actions.getColor().svgColorString()},
- {"nl", "\n"},
- {0, ""}
- };
bool repl_bbox = true;
while (repl_bbox) {
- size_t pos = str.find(string("{?bbox "));
+ size_t pos = str.find("{?bbox ");
if (pos == string::npos)
repl_bbox = false;
else {
@@ -173,12 +165,22 @@ static void expand_constants (string &str, SpecialActions &actions) {
repl_bbox = false;
}
}
- for (const Constant *p=constants; p->name; p++) {
- const string pattern = string("{?")+p->name+"}";
+ struct Constant {
+ const char *name;
+ string val;
+ };
+ const array<Constant, 4> constants {{
+ {"x", XMLString(actions.getX())},
+ {"y", XMLString(actions.getY())},
+ {"color", actions.getColor().svgColorString()},
+ {"nl", "\n"},
+ }};
+ for (const Constant &constant : constants) {
+ const string pattern = string("{?")+constant.name+"}";
size_t pos = str.find(pattern);
while (pos != string::npos) {
- str.replace(pos, strlen(p->name)+3, p->val);
- pos = str.find(pattern, pos+p->val.length()); // look for further matches
+ str.replace(pos, strlen(constant.name)+3, constant.val);
+ pos = str.find(pattern, pos+constant.val.length()); // look for further matches
}
}
}
@@ -189,7 +191,7 @@ void DvisvgmSpecialHandler::processRaw (InputReader &ir, SpecialActions &actions
string str = ir.getLine();
if (!str.empty()) {
expand_constants(str, actions);
- actions.appendToPage(new XMLTextNode(str));
+ actions.appendToPage(util::make_unique<XMLTextNode>(str));
}
}
}
@@ -200,7 +202,7 @@ void DvisvgmSpecialHandler::processRawDef (InputReader &ir, SpecialActions &acti
string str = ir.getLine();
if (!str.empty()) {
expand_constants(str, actions);
- actions.appendToDefs(new XMLTextNode(str));
+ actions.appendToDefs(util::make_unique<XMLTextNode>(str));
}
}
}
@@ -221,7 +223,7 @@ void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions &acti
if (_nestingLevel > 0)
return;
string id = ir.getString();
- MacroMap::iterator it = _macros.find(id);
+ auto it = _macros.find(id);
if (it == _macros.end())
throw SpecialException("undefined SVG fragment '" + id + "' referenced");
@@ -232,9 +234,9 @@ void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions &acti
if ((type == 'P' || type == 'D') && !def.empty()) {
expand_constants(def, actions);
if (type == 'P')
- actions.appendToPage(new XMLTextNode(def));
+ actions.appendToPage(util::make_unique<XMLTextNode>(def));
else { // type == 'D'
- actions.appendToDefs(new XMLTextNode(def));
+ actions.appendToDefs(util::make_unique<XMLTextNode>(def));
type = 'L'; // locked
}
}
@@ -248,11 +250,20 @@ void DvisvgmSpecialHandler::processRawPut (InputReader &ir, SpecialActions &acti
* @param[in] h height of the rectangle in PS point units
* @param[in] d depth of the rectangle in PS point units
* @param[in] actions object providing the actions that can be performed by the SpecialHandler */
-static void update_bbox (double w, double h, double d, SpecialActions &actions) {
+static void update_bbox (Length w, Length h, Length d, SpecialActions &actions) {
double x = actions.getX();
double y = actions.getY();
- actions.embed(BoundingBox(x, y, x+w, y-h));
- actions.embed(BoundingBox(x, y, x+w, y+d));
+ actions.embed(BoundingBox(x, y, x+w.bp(), y-h.bp()));
+ actions.embed(BoundingBox(x, y, x+w.bp(), y+d.bp()));
+}
+
+
+/** Reads a length value including a trailing unit specifier and returns it. */
+static Length read_length (InputReader &ir) {
+ ir.skipSpace();
+ double val = ir.getDouble();
+ string unit = isalpha(ir.peek()) ? ir.getString(2) : "pt";
+ return Length(val, unit);
}
@@ -264,57 +275,66 @@ static void update_bbox (double w, double h, double d, SpecialActions &actions)
void DvisvgmSpecialHandler::processBBox (InputReader &ir, SpecialActions &actions) {
ir.skipSpace();
int c = ir.peek();
- if (isalpha(c)) {
- while (!isspace(ir.peek())) // skip trailing characters
- ir.get();
- if (c == 'n') {
- ir.skipSpace();
- string name;
- while (isalnum(ir.peek()))
- name += char(ir.get());
- ir.skipSpace();
- if (!name.empty() && ir.eof())
- actions.bbox(name, true); // create new user box
- }
- else if (c == 'a' || c == 'f') {
- double p[4];
- for (int i=0; i < 4; i++)
- p[i] = ir.getDouble()*Length::pt2bp;
- BoundingBox b(p[0], p[1], p[2], p[3]);
- if (c == 'a')
- actions.embed(b);
- else {
- actions.bbox() = b;
- actions.bbox().lock();
+ try {
+ if (!isalpha(c))
+ c = 'r'; // no mode specifier => relative box parameters
+ else {
+ while (!isspace(ir.peek())) // skip trailing characters
+ ir.get();
+ if (c == 'n') { // "new": create new local bounding box
+ ir.skipSpace();
+ string name;
+ while (isalnum(ir.peek()))
+ name += char(ir.get());
+ ir.skipSpace();
+ if (!name.empty() && ir.eof())
+ actions.bbox(name, true); // create new user box
+ }
+ else if (c == 'a' || c == 'f') { // "abs" or "fix"
+ Length lengths[4];
+ for (int i=0; i < 4; i++)
+ lengths[i] = read_length(ir);
+ BoundingBox b(lengths[0], lengths[1], lengths[2], lengths[3]);
+ if (c == 'a')
+ actions.embed(b);
+ else {
+ actions.bbox() = b;
+ actions.bbox().lock();
+ }
}
}
+ if (c == 'r') {
+ Length w = read_length(ir);
+ Length h = read_length(ir);
+ Length d = read_length(ir);
+ update_bbox(w, h, d, actions);
+ }
}
- else
- c = 'r'; // no mode specifier => relative box parameters
-
- if (c == 'r') {
- double w = ir.getDouble()*Length::pt2bp;
- double h = ir.getDouble()*Length::pt2bp;
- double d = ir.getDouble()*Length::pt2bp;
- update_bbox(w, h, d, actions);
+ catch (const UnitException &e) {
+ throw SpecialException(string("dvisvgm:bbox: ") + e.what());
}
}
void DvisvgmSpecialHandler::processImg (InputReader &ir, SpecialActions &actions) {
- double w = ir.getDouble()*Length::pt2bp;
- double h = ir.getDouble()*Length::pt2bp;
- string f = ir.getString();
- update_bbox(w, h, 0, actions);
- XMLElementNode *img = new XMLElementNode("image");
- img->addAttribute("x", actions.getX());
- img->addAttribute("y", actions.getY());
- img->addAttribute("width", w);
- img->addAttribute("height", h);
- img->addAttribute("xlink:href", f);
- if (!actions.getMatrix().isIdentity())
- img->addAttribute("transform", actions.getMatrix().getSVG());
- actions.appendToPage(img);
+ try {
+ Length w = read_length(ir);
+ Length h = read_length(ir);
+ string f = ir.getString();
+ update_bbox(w, h, 0, actions);
+ auto img = util::make_unique<XMLElementNode>("image");
+ img->addAttribute("x", actions.getX());
+ img->addAttribute("y", actions.getY());
+ img->addAttribute("width", w.bp());
+ img->addAttribute("height", h.bp());
+ img->addAttribute("xlink:href", f);
+ if (!actions.getMatrix().isIdentity())
+ img->addAttribute("transform", actions.getMatrix().getSVG());
+ actions.appendToPage(std::move(img));
+ }
+ catch (const UnitException &e) {
+ throw SpecialException(string("dvisvgm:img: ") + e.what());
+ }
}
@@ -342,7 +362,7 @@ void DvisvgmSpecialHandler::dviEndPage (unsigned, SpecialActions&) {
}
-const char** DvisvgmSpecialHandler::prefixes () const {
- static const char *pfx[] = {"dvisvgm:", 0};
+const vector<const char*> DvisvgmSpecialHandler::prefixes () const {
+ const vector<const char*> pfx {"dvisvgm:"};
return pfx;
}