Skip to content

Commit

Permalink
simplified code to lookup PS operators
Browse files Browse the repository at this point in the history
  • Loading branch information
mgieseki committed Oct 31, 2017
1 parent c8532b0 commit f9dcf53
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 104 deletions.
16 changes: 0 additions & 16 deletions src/InputReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,6 @@ bool InputReader::check (const char *s, bool consume) {
}


int InputReader::compare (const char *s, bool consume) {
size_t count = 0;
for (const char *p=s; *p; p++) {
int c = peek(count++);
if (c != *p)
return c < *p ? -1 : 1;
}
int c = peek(count);
if (c < 0 || !isspace(c))
return 1;
if (consume)
skip(count);
return 0;
}


/** Reads an integer from the buffer. All characters that are part of
* the read integer constant are skipped. If this function returns false,
* the buffer pointer points to the same position as before the function call.
Expand Down
2 changes: 0 additions & 2 deletions src/InputReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class InputReader {
virtual bool eof () const =0;
virtual bool check (char c) const {return peek() == c;}
virtual bool check (const char *s, bool consume=true);
virtual int compare (const char *s, bool consume=true);
virtual void skip (size_t n);
virtual bool skipUntil (const char *s);
virtual int find (char c) const;
Expand Down Expand Up @@ -103,5 +102,4 @@ class StringMatcher {
size_t _charsRead;
};


#endif
156 changes: 70 additions & 86 deletions src/PSInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
** along with this program; if not, see <http://www.gnu.org/licenses/>. **
*************************************************************************/

#include <algorithm>
#include <cstring>
#include <fstream>
#include <sstream>
#include <unordered_map>
#include "FileFinder.hpp"
#include "InputReader.hpp"
#include "Message.hpp"
Expand Down Expand Up @@ -238,108 +240,90 @@ int GSDLLCALL PSInterpreter::output (void *inst, const char *buf, int len) {
}


/** Converts a vector of strings to a vector of doubles.
* @param[in] str the strings to be converted
* @param[out] d the resulting doubles */
static void str2double (const vector<string> &str, vector<double> &d) {
for (size_t i=0; i < str.size(); i++) {
istringstream iss(str[i]);
iss >> d[i];
}
}


/** Evaluates a command emitted by Ghostscript and invokes the corresponding
* method of interface class PSActions.
* @param[in] in reader pointing to the next command */
void PSInterpreter::callActions (InputReader &in) {
// array of currently supported operators (must be ascendingly sorted)
static const struct Operator {
const char *name; // name of operator
struct Operator {
int pcount; // number of parameters (< 0 : variable number of parameters)
void (PSActions::*op)(vector<double> &p); // operation handler
} operators [] = {
{"applyscalevals", 3, &PSActions::applyscalevals},
{"clip", 0, &PSActions::clip},
{"clippath", 0, &PSActions::clippath},
{"closepath", 0, &PSActions::closepath},
{"curveto", 6, &PSActions::curveto},
{"eoclip", 0, &PSActions::eoclip},
{"eofill", 0, &PSActions::eofill},
{"fill", 0, &PSActions::fill},
{"grestore", 0, &PSActions::grestore},
{"grestoreall", 0, &PSActions::grestoreall},
{"gsave", 0, &PSActions::gsave},
{"initclip", 0, &PSActions::initclip},
{"lineto", 2, &PSActions::lineto},
{"makepattern", -1, &PSActions::makepattern},
{"moveto", 2, &PSActions::moveto},
{"newpath", 1, &PSActions::newpath},
{"querypos", 2, &PSActions::querypos},
{"raw", -1, 0},
{"restore", 1, &PSActions::restore},
{"rotate", 1, &PSActions::rotate},
{"save", 1, &PSActions::save},
{"scale", 2, &PSActions::scale},
{"setcmykcolor", 4, &PSActions::setcmykcolor},
{"setdash", -1, &PSActions::setdash},
{"setgray", 1, &PSActions::setgray},
{"sethsbcolor", 3, &PSActions::sethsbcolor},
{"setlinecap", 1, &PSActions::setlinecap},
{"setlinejoin", 1, &PSActions::setlinejoin},
{"setlinewidth", 1, &PSActions::setlinewidth},
{"setmatrix", 6, &PSActions::setmatrix},
{"setmiterlimit", 1, &PSActions::setmiterlimit},
{"setopacityalpha", 1, &PSActions::setopacityalpha},
{"setpattern", -1, &PSActions::setpattern},
{"setrgbcolor", 3, &PSActions::setrgbcolor},
{"shfill", -1, &PSActions::shfill},
{"stroke", 0, &PSActions::stroke},
{"translate", 2, &PSActions::translate},
void (PSActions::*handler)(vector<double> &p); // operation handler
};
static const unordered_map<string, Operator> operators {
{"applyscalevals", { 3, &PSActions::applyscalevals}},
{"clip", { 0, &PSActions::clip}},
{"clippath", { 0, &PSActions::clippath}},
{"closepath", { 0, &PSActions::closepath}},
{"curveto", { 6, &PSActions::curveto}},
{"eoclip", { 0, &PSActions::eoclip}},
{"eofill", { 0, &PSActions::eofill}},
{"fill", { 0, &PSActions::fill}},
{"grestore", { 0, &PSActions::grestore}},
{"grestoreall", { 0, &PSActions::grestoreall}},
{"gsave", { 0, &PSActions::gsave}},
{"initclip", { 0, &PSActions::initclip}},
{"lineto", { 2, &PSActions::lineto}},
{"makepattern", {-1, &PSActions::makepattern}},
{"moveto", { 2, &PSActions::moveto}},
{"newpath", { 1, &PSActions::newpath}},
{"querypos", { 2, &PSActions::querypos}},
{"raw", {-1, nullptr}},
{"restore", { 1, &PSActions::restore}},
{"rotate", { 1, &PSActions::rotate}},
{"save", { 1, &PSActions::save}},
{"scale", { 2, &PSActions::scale}},
{"setcmykcolor", { 4, &PSActions::setcmykcolor}},
{"setdash", {-1, &PSActions::setdash}},
{"setgray", { 1, &PSActions::setgray}},
{"sethsbcolor", { 3, &PSActions::sethsbcolor}},
{"setlinecap", { 1, &PSActions::setlinecap}},
{"setlinejoin", { 1, &PSActions::setlinejoin}},
{"setlinewidth", { 1, &PSActions::setlinewidth}},
{"setmatrix", { 6, &PSActions::setmatrix}},
{"setmiterlimit", { 1, &PSActions::setmiterlimit}},
{"setopacityalpha",{ 1, &PSActions::setopacityalpha}},
{"setpattern", {-1, &PSActions::setpattern}},
{"setrgbcolor", { 3, &PSActions::setrgbcolor}},
{"shfill", {-1, &PSActions::shfill}},
{"stroke", { 0, &PSActions::stroke}},
{"translate", { 2, &PSActions::translate}},
};
if (_actions) {
in.skipSpace();
// binary search
int first=0, last=sizeof(operators)/sizeof(Operator)-1;
while (first <= last) {
int mid = first+(last-first)/2;
int cmp = in.compare(operators[mid].name);
if (cmp < 0)
last = mid-1;
else if (cmp > 0)
first = mid+1;
auto it = operators.find(in.getWord());
if (it != operators.end()) {
if (!it->second.handler) { // raw string data received?
_rawData.clear();
in.skipSpace();
while (!in.eof()) {
_rawData.emplace_back(in.getString());
in.skipSpace();
}
}
else {
if (!operators[mid].op) { // raw string data received
_rawData.clear();
// collect parameters
vector<string> params;
int pcount = it->second.pcount;
if (pcount < 0) { // variable number of parameters?
in.skipSpace();
while (!in.eof()) {
_rawData.emplace_back(in.getString());
while (!in.eof()) { // read all available parameters
params.emplace_back(in.getString());
in.skipSpace();
}
}
else {
// collect parameters and call handler
vector<string> params;
int pcount = operators[mid].pcount;
if (pcount < 0) { // variable number of parameters?
else { // fix number of parameters
for (int i=0; i < pcount; i++) {
in.skipSpace();
while (!in.eof()) { // read all available parameters
params.emplace_back(in.getString());
in.skipSpace();
}
}
else { // fix number of parameters
for (int i=0; i < pcount; i++) {
in.skipSpace();
params.emplace_back(in.getString());
}
params.emplace_back(in.getString());
}
vector<double> v(params.size());
str2double(params, v);
(_actions->*operators[mid].op)(v);
_actions->executed();
}
break;
// convert parameter strings to doubles
vector<double> v(params.size());
transform(params.begin(), params.end(), v.begin(), [](const string &str) {
return stod(str);
});
// call operator handler
(_actions->*it->second.handler)(v);
_actions->executed();
}
}
}
Expand Down

0 comments on commit f9dcf53

Please sign in to comment.