1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*************************************************************************
** PSInterpreter.hpp **
** **
** This file is part of dvisvgm -- a fast DVI to SVG converter **
** Copyright (C) 2005-2017 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 **
** published by the Free Software Foundation; either version 3 of **
** the License, or (at your option) any later version. **
** **
** This program is distributed in the hope that it will be useful, but **
** WITHOUT ANY WARRANTY; without even the implied warranty of **
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
** GNU General Public License for more details. **
** **
** You should have received a copy of the GNU General Public License **
** along with this program; if not, see <http://www.gnu.org/licenses/>. **
*************************************************************************/
#ifndef PSINTERPRETER_HPP
#define PSINTERPRETER_HPP
#include <cstring>
#include <istream>
#include <string>
#include <vector>
#include "Ghostscript.hpp"
#include "InputReader.hpp"
#include "MessageException.hpp"
struct PSException : public MessageException
{
PSException (const std::string &msg) : MessageException(msg) {}
};
/** This interface provides the template methods called by PSInterpreter when executing a PS snippet.
* Each method corresponds to a PostScript operator of the same name. */
struct PSActions
{
virtual ~PSActions () =default;
virtual void applyscalevals (std::vector<double> &p) =0;
virtual void clip (std::vector<double> &p) =0;
virtual void clippath (std::vector<double> &p) =0;
virtual void closepath (std::vector<double> &p) =0;
virtual void curveto (std::vector<double> &p) =0;
virtual void eoclip (std::vector<double> &p) =0;
virtual void eofill (std::vector<double> &p) =0;
virtual void fill (std::vector<double> &p) =0;
virtual void gsave (std::vector<double> &p) =0;
virtual void grestore (std::vector<double> &p) =0;
virtual void grestoreall (std::vector<double> &p) =0;
virtual void initclip (std::vector<double> &p) =0;
virtual void lineto (std::vector<double> &p) =0;
virtual void makepattern (std::vector<double> &p) =0;
virtual void moveto (std::vector<double> &p) =0;
virtual void newpath (std::vector<double> &p) =0;
virtual void querypos (std::vector<double> &p) =0;
virtual void restore (std::vector<double> &p) =0;
virtual void rotate (std::vector<double> &p) =0;
virtual void save (std::vector<double> &p) =0;
virtual void scale (std::vector<double> &p) =0;
virtual void setcmykcolor (std::vector<double> &cmyk) =0;
virtual void setdash (std::vector<double> &p) =0;
virtual void setgray (std::vector<double> &p) =0;
virtual void sethsbcolor (std::vector<double> &hsb) =0;
virtual void setlinecap (std::vector<double> &p) =0;
virtual void setlinejoin (std::vector<double> &p) =0;
virtual void setlinewidth (std::vector<double> &p) =0;
virtual void setmatrix (std::vector<double> &p) =0;
virtual void setmiterlimit (std::vector<double> &p) =0;
virtual void setopacityalpha (std::vector<double> &p) =0;
virtual void setpattern (std::vector<double> &p) =0;
virtual void setrgbcolor (std::vector<double> &rgb) =0;
virtual void shfill (std::vector<double> &rgb) =0;
virtual void stroke (std::vector<double> &p) =0;
virtual void translate (std::vector<double> &p) =0;
virtual void executed () {} // triggered if one of the above PS operators has been executed
};
class PSFilter;
/** This class provides methods to execute chunks of PostScript code and calls
* several template methods on invocation of selected PS operators (see PSActions). */
class PSInterpreter
{
enum Mode {PS_NONE, PS_RUNNING, PS_QUIT};
public:
explicit PSInterpreter (PSActions *actions=0);
PSInterpreter (const PSInterpreter &psi) =delete;
bool execute (const char *str, size_t len, bool flush=true);
bool execute (const char *str, bool flush=true) {return execute(str, std::strlen(str), flush);}
bool execute (const std::string &str, bool flush=true) {return execute(str.c_str(), flush);}
bool execute (std::istream &is, bool flush=true);
bool executeRaw (const std::string &str, int n);
bool active () const {return _mode != PS_QUIT;}
void limit (size_t max_bytes) {_bytesToRead = max_bytes;}
void setFilter (PSFilter *filter) {_filter = filter;}
PSActions* setActions (PSActions *actions);
const std::vector<std::string>& rawData () const {return _rawData;}
protected:
void init ();
// callback functions
static int GSDLLCALL input (void *inst, char *buf, int len);
static int GSDLLCALL output (void *inst, const char *buf, int len);
static int GSDLLCALL error (void *inst, const char *buf, int len);
void checkStatus (int status);
void callActions (InputReader &cib);
private:
Ghostscript _gs;
Mode _mode; ///< current execution mode
PSActions *_actions; ///< actions to be performed
PSFilter *_filter; ///< active filter used to process PS code
size_t _bytesToRead; ///< if > 0, maximal number of bytes to be processed by following calls of execute()
std::vector<char> _linebuf;
std::string _errorMessage; ///< text of error message
bool _inError; ///< true if scanning error message
bool _initialized; ///< true if PSInterpreter has been completely initialized
std::vector<std::string> _rawData; ///< raw data received
static const char *GSARGS[]; ///< parameters passed to Ghostscript
static const char *PSDEFS; ///< initial PostScript definitions
};
#endif
|