diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src')
54 files changed, 1006 insertions, 646 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp index e2873311574..8d0ee51b841 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.cpp @@ -29,7 +29,7 @@ using namespace std; /** Collect all background color changes while preprocessing the DVI file. * We need them in order to apply the correct background colors even if * not all but only selected DVI pages are converted. */ -void BgColorSpecialHandler::preprocess (const char*, std::istream &is, SpecialActions &actions) { +void BgColorSpecialHandler::preprocess (const string&, std::istream &is, SpecialActions &actions) { Color color = ColorSpecialHandler::readColor(is); unsigned pageno = actions.getCurrentPageNumber(); if (_pageColors.empty() || _pageColors.back().second != color) { @@ -41,7 +41,7 @@ void BgColorSpecialHandler::preprocess (const char*, std::istream &is, SpecialAc } -bool BgColorSpecialHandler::process (const char*, istream &, SpecialActions&) { +bool BgColorSpecialHandler::process (const string&, istream&, SpecialActions&) { return true; } @@ -62,7 +62,7 @@ void BgColorSpecialHandler::dviBeginPage (unsigned pageno, SpecialActions &actio } -const vector<const char*> BgColorSpecialHandler::prefixes () const { - const vector<const char*> pfx {"background"}; +vector<const char*> BgColorSpecialHandler::prefixes() const { + vector<const char*> pfx {"background"}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp index 06572ab1a7e..d8e0b760f85 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BgColorSpecialHandler.hpp @@ -26,14 +26,13 @@ #include "SpecialHandler.hpp" -class BgColorSpecialHandler : public SpecialHandler, public DVIBeginPageListener -{ +class BgColorSpecialHandler : public SpecialHandler { public: - void preprocess (const char *prefix, std::istream &is, SpecialActions &actions) override; - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + void preprocess (const std::string &prefix, std::istream &is, SpecialActions &actions) override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; const char* info () const override {return "background color special";} const char* name () const override {return "bgcolor";} - const std::vector<const char*> prefixes () const override; + std::vector<const char*> prefixes() const override; protected: void dviBeginPage (unsigned pageno, SpecialActions &actions) override; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp index 1b1f234a604..ebdbd485d6a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BoundingBox.cpp @@ -234,8 +234,8 @@ void BoundingBox::scale (double sx, double sy) { void BoundingBox::transform (const Matrix &tm) { if (!_locked) { - DPair ul = tm * DPair(_lrx, _lry); - DPair lr = tm * DPair(_ulx, _uly); + DPair ul = tm * DPair(_ulx, _uly); + DPair lr = tm * DPair(_lrx, _lry); DPair ll = tm * DPair(_ulx, _lry); DPair ur = tm * DPair(_lrx, _uly); _ulx = min(min(ul.x(), lr.x()), min(ur.x(), ll.x())); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp index 851737628fb..b72a50fc3ce 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.cpp @@ -42,7 +42,9 @@ void CommandLine::parse (int argc, char **argv) { _files.push_back(argv[i]); else { iss.get(); // skip dash - if (iss.peek() != '-') + if (iss.peek() < 0) + _singleDashParsed = true; + else if (iss.peek() != '-') parseShortOption(iss, argc, argv, i); else { iss.get(); // skip dash @@ -94,8 +96,6 @@ static void type_error (const Option &option, bool shortname) { void CommandLine::parseShortOption (istringstream &iss, int argc, char **argv, int &argn) { bool combined = false; do { - if (iss.peek() < 0) - throw CommandLineException("missing character after '-'"); char shortname = static_cast<char>(iss.get()); if (!isalnum(shortname)) throw CommandLineException(string("syntax error: -")+shortname); @@ -184,11 +184,15 @@ void CommandLine::help (ostream &os, int mode) const { os << PROGRAM_NAME << ' '<< PROGRAM_VERSION << "\n\n"; os << _summary << "\n\n"; // print usage info - size_t start=0, pos=0; string usage = _usage; - while ((pos = usage.find('\n', start)) != string::npos || start < usage.length()) { - os << (start == 0 ? "Usage: " : " ") << PROGRAM_NAME << ' ' << usage.substr(start, pos) << '\n'; - start = (pos != string::npos ? pos+1 : string::npos); + int count=0; + while (!usage.empty()) { + size_t pos = usage.find('\n'); + os << (count++ == 0 ? "Usage: " : " ") << PROGRAM_NAME << ' ' << usage.substr(0, pos) << '\n'; + if (pos != string::npos) + usage = usage.substr(pos+1); + else + usage.clear(); } if (mode > 0) os << '\n'; @@ -197,6 +201,7 @@ void CommandLine::help (ostream &os, int mode) const { unordered_map<Option*, pair<string,string>> linecols; size_t col1width=0; for (const OptSectPair &ospair : options()) { + size_t pos; string line = ospair.first->helpline(); if ((pos = line.find('\t')) != string::npos) { linecols.emplace(ospair.first, pair<string,string>(line.substr(0, pos), line.substr(pos+1))); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp index e4e6788aef6..a541f065291 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CLCommandLine.hpp @@ -37,6 +37,8 @@ class CommandLine { virtual ~CommandLine () =default; void parse (int argc, char **argv); void help (std::ostream &os, int mode=0) const; + void addFilename (std::string fname) {_files.emplace_back(fname);} + bool singleDashGiven () const {return _singleDashParsed;} const std::vector<std::string>& filenames () const {return _files;} protected: @@ -52,12 +54,12 @@ class CommandLine { const char *_summary; const char *_usage; const char *_copyright; + bool _singleDashParsed=false; ///< true if a single '-' w/o a following char was parsed std::vector<std::string> _files; }; -struct CommandLineException : public MessageException -{ +struct CommandLineException : public MessageException { CommandLineException (const std::string &msg) : MessageException(msg) {} }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp index b4e90eacec2..f5511935a18 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Calculator.cpp @@ -154,7 +154,7 @@ char Calculator::lex (istream &is) { try { _numValue = stod(str); } - catch (exception) { + catch (const exception&) { throw CalculatorException("invalid number: "+str); } break; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp index ffca4aa780d..e129fdcedcb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.cpp @@ -91,7 +91,7 @@ Color ColorSpecialHandler::readColor (istream &is) { } -bool ColorSpecialHandler::process (const char *, istream &is, SpecialActions &actions) { +bool ColorSpecialHandler::process (const string&, istream &is, SpecialActions &actions) { string cmd; is >> cmd; if (cmd == "push") // color push <model> <params> @@ -113,8 +113,8 @@ bool ColorSpecialHandler::process (const char *, istream &is, SpecialActions &ac } -const vector<const char*> ColorSpecialHandler::prefixes () const { - const vector<const char*> pfx {"color"}; +vector<const char*> ColorSpecialHandler::prefixes() const { + vector<const char*> pfx {"color"}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp index e36901564b2..fb7e7050d8c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ColorSpecialHandler.hpp @@ -28,15 +28,14 @@ #include "SpecialHandler.hpp" -class ColorSpecialHandler : public SpecialHandler -{ +class ColorSpecialHandler : public SpecialHandler { public: - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; static Color readColor (std::istream &is); static Color readColor (const std::string &model, std::istream &is); const char* name () const override {return "color";} const char* info () const override {return "complete support of color specials";} - const std::vector<const char*> prefixes () const override; + std::vector<const char*> prefixes() const override; private: std::stack<Color> _colorStack; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp index d742d6a877d..1ae9f188d30 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp @@ -15,12 +15,11 @@ using CL::Option; using CL::TypedOption; -class CommandLine : public CL::CommandLine -{ +class CommandLine : public CL::CommandLine { public: CommandLine () : CL::CommandLine( "This program converts DVI files, as created by TeX/LaTeX, to\nthe XML-based scalable vector graphics format SVG.", - "[options] dvifile\n-E [options] epsfile", + "[options] dvifile\n--eps [options] epsfile\n--pdf [options] pdffile", "Copyright (C) 2005-2018 Martin Gieseking <martin.gieseking@uos.de>" ) {} @@ -35,7 +34,7 @@ class CommandLine : public CL::CommandLine Option colorOpt {"color", '\0', "colorize messages"}; Option colornamesOpt {"colornames", '\0', "prefer color names to RGB values if possible"}; Option commentsOpt {"comments", '\0', "add comments with additional information"}; - Option epsOpt {"eps", 'E', "convert an EPS file to SVG"}; + Option epsOpt {"eps", 'E', "convert EPS file to SVG"}; Option exactOpt {"exact", 'e', "compute exact glyph boxes"}; TypedOption<std::string, Option::ArgMode::REQUIRED> fontFormatOpt {"font-format", 'f', "format", "svg", "select file format of embedded fonts"}; TypedOption<std::string, Option::ArgMode::REQUIRED> fontmapOpt {"fontmap", 'm', "filenames", "evaluate (additional) font map files"}; @@ -55,11 +54,13 @@ class CommandLine : public CL::CommandLine Option noStylesOpt {"no-styles", '\0', "don't use CSS styles to reference fonts"}; TypedOption<std::string, Option::ArgMode::REQUIRED> outputOpt {"output", 'o', "pattern", "set name pattern of output files"}; TypedOption<std::string, Option::ArgMode::REQUIRED> pageOpt {"page", 'p', "ranges", "1", "choose page(s) to convert"}; + Option pdfOpt {"pdf", 'P', "convert PDF file to SVG"}; TypedOption<int, Option::ArgMode::REQUIRED> precisionOpt {"precision", 'd', "number", 0, "set number of decimal points (0-6)"}; - TypedOption<double, Option::ArgMode::OPTIONAL> progressOpt {"progress", 'P', "delay", 0.5, "enable progress indicator"}; + TypedOption<double, Option::ArgMode::OPTIONAL> progressOpt {"progress", '\0', "delay", 0.5, "enable progress indicator"}; Option relativeOpt {"relative", 'R', "create relative path commands"}; TypedOption<double, Option::ArgMode::REQUIRED> rotateOpt {"rotate", 'r', "angle", "rotate page content clockwise"}; TypedOption<std::string, Option::ArgMode::REQUIRED> scaleOpt {"scale", 'c', "sx[,sy]", "scale page content"}; + Option stdinOpt {"stdin", '\0', "read input file from stdin"}; Option stdoutOpt {"stdout", 's', "write SVG output to stdout"}; TypedOption<std::string, Option::ArgMode::OPTIONAL> tmpdirOpt {"tmpdir", '\0', "path", "set/print the directory for temporary files"}; TypedOption<bool, Option::ArgMode::OPTIONAL> traceAllOpt {"trace-all", 'a', "retrace", false, "trace all glyphs of bitmap fonts"}; @@ -89,6 +90,10 @@ class CommandLine : public CL::CommandLine #if !defined(DISABLE_GS) {&epsOpt, 0}, #endif +#if !defined(DISABLE_GS) + {&pdfOpt, 0}, +#endif + {&stdinOpt, 0}, {&bboxOpt, 1}, #if !defined(DISABLE_GS) {&clipjoinOpt, 1}, diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp index 720da8ddeca..da9b4b7540b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.cpp @@ -39,7 +39,7 @@ DvisvgmSpecialHandler::DvisvgmSpecialHandler () } -void DvisvgmSpecialHandler::preprocess (const char*, istream &is, SpecialActions&) { +void DvisvgmSpecialHandler::preprocess (const string&, istream &is, SpecialActions&) { struct Command { const char *name; void (DvisvgmSpecialHandler::*handler)(InputReader&); @@ -53,7 +53,7 @@ void DvisvgmSpecialHandler::preprocess (const char*, istream &is, SpecialActions }}; StreamInputReader ir(is); - string cmdstr = ir.getWord(); + const string cmdstr = ir.getWord(); for (const Command &command : commands) { if (command.name == cmdstr) { ir.skipSpace(); @@ -117,7 +117,7 @@ void DvisvgmSpecialHandler::preprocessRawPut (InputReader &ir) { * @param[in] prefix special prefix read by the SpecialManager * @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 char *prefix, istream &is, SpecialActions &actions) { +bool DvisvgmSpecialHandler::process (const string &prefix, istream &is, SpecialActions &actions) { struct Command { const char *name; void (DvisvgmSpecialHandler::*handler)(InputReader&, SpecialActions&); @@ -132,7 +132,7 @@ bool DvisvgmSpecialHandler::process (const char *prefix, istream &is, SpecialAct {"img", &DvisvgmSpecialHandler::processImg} }}; StreamInputReader ir(is); - string cmdstr = ir.getWord(); + const string cmdstr = ir.getWord(); for (const Command &command : commands) { if (command.name == cmdstr) { ir.skipSpace(); @@ -362,7 +362,7 @@ void DvisvgmSpecialHandler::dviEndPage (unsigned, SpecialActions&) { } -const vector<const char*> DvisvgmSpecialHandler::prefixes () const { - const vector<const char*> pfx {"dvisvgm:"}; +vector<const char*> DvisvgmSpecialHandler::prefixes() const { + vector<const char*> pfx {"dvisvgm:"}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp index 242aa6a4aa4..0b6bc9bd428 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DvisvgmSpecialHandler.hpp @@ -29,8 +29,7 @@ class InputReader; class SpecialActions; -class DvisvgmSpecialHandler : public SpecialHandler, public DVIPreprocessingListener, public DVIEndPageListener -{ +class DvisvgmSpecialHandler : public SpecialHandler { using StringVector = std::vector<std::string>; using MacroMap = std::unordered_map<std::string, StringVector>; @@ -38,9 +37,9 @@ class DvisvgmSpecialHandler : public SpecialHandler, public DVIPreprocessingList DvisvgmSpecialHandler (); const char* name () const override {return "dvisvgm";} const char* info () const override {return "special set for embedding raw SVG snippets";} - const std::vector<const char*> prefixes () const override; - void preprocess (const char *prefix, std::istream &is, SpecialActions &actions) override; - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + std::vector<const char*> prefixes() const override; + void preprocess (const std::string &prefix, std::istream &is, SpecialActions &actions) override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; protected: void preprocessRaw (InputReader &ir); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp index ef1096ef6b9..dd71ff92ab8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.cpp @@ -56,8 +56,7 @@ static size_t getline (istream &is, char *line, size_t n) { } -EPSFile::EPSFile (const std::string& fname) : _ifs(fname.c_str(), ios::binary), _headerValid(false), _offset(0), _pslength(0) -{ +EPSFile::EPSFile (const string &fname) : _ifs(fname, ios::binary) { if (_ifs) { if (getUInt32(_ifs) != 0xC6D3D0C5) // no binary header present? _ifs.seekg(0); // go back to the first byte @@ -84,10 +83,10 @@ istream& EPSFile::istream () const { } -/** Extracts the bounding box information from the DSC header/footer (if present) - * @param[out] box the extracted bounding box - * @return true if %%BoundingBox data could be read successfully */ -bool EPSFile::bbox (BoundingBox &box) const { +/** Extracts the bounding box information from the DSC header/footer (if present). + * @return the extracted bounding box */ +BoundingBox EPSFile::bbox () const { + BoundingBox box; std::istream &is = EPSFile::istream(); if (is) { char buf[64]; @@ -105,10 +104,10 @@ bool EPSFile::bbox (BoundingBox &box) const { ir.parseInt(val[i]); } box = BoundingBox(val[0], val[1], val[2], val[3]); - return true; + break; } } } } - return false; + return box; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp index 28d2aa8264c..fa996367bea 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSFile.hpp @@ -22,23 +22,23 @@ #define EPSFILE_HPP #include <fstream> +#include <istream> #include <string> #include "BoundingBox.hpp" -class EPSFile -{ +class EPSFile { public: EPSFile (const std::string &fname); std::istream& istream () const; bool hasValidHeader () const {return _headerValid;} - bool bbox (BoundingBox &box) const; + BoundingBox bbox () const; uint32_t pslength () const {return _pslength;} private: mutable std::ifstream _ifs; - bool _headerValid; ///< true if file has a valid header - uint32_t _offset; ///< stream offset where ASCII part of the file begins - uint32_t _pslength; ///< length of PS section (in bytes) + bool _headerValid=false; ///< true if file has a valid header + uint32_t _offset=0; ///< stream offset where ASCII part of the file begins + uint32_t _pslength=0; ///< length of PS section (in bytes) }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp index 6965a65a9e9..8e7dd29f9b2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.hpp @@ -21,53 +21,19 @@ #ifndef EPSTOSVG_HPP #define EPSTOSVG_HPP -#include <memory> -#include <string> -#include "SpecialActions.hpp" -#include "SVGTree.hpp" +#include "EPSFile.hpp" +#include "ImageToSVG.hpp" -struct SVGOutputBase; - -class EPSToSVG : protected SpecialActions { +class EPSToSVG : public ImageToSVG { public: - EPSToSVG (const std::string &fname, SVGOutputBase &out) : _fname(fname), _out(out), _x(0), _y(0) {} - void convert (); - void setTransformation (const Matrix &m); - void setPageSize (const std::string &name); + EPSToSVG (const std::string &fname, SVGOutputBase &out) : ImageToSVG(fname, out) {} protected: - // implement abstract base class SpecialActions - double getX () const override {return _x;} - double getY () const override {return _y;} - void setX (double x) override {_x = x; _svg.setX(x);} - void setY (double y) override {_y = y; _svg.setY(y);} - void finishLine () override {} - void setColor (const Color &color) override {_svg.setColor(color);} - Color getColor () const override {return _svg.getColor();} - void setMatrix (const Matrix &m) override {_svg.setMatrix(m);} - const Matrix& getMatrix () const override {return _svg.getMatrix();} - void getPageTransform (Matrix &matrix) const override {} - void setBgColor (const Color &color) override {} - void appendToPage(std::unique_ptr<XMLNode> &&node) override {_svg.appendToPage(std::move(node));} - void appendToDefs(std::unique_ptr<XMLNode> &&node) override {_svg.appendToDefs(std::move(node));} - void prependToPage(std::unique_ptr<XMLNode> &&node) override {_svg.prependToPage(std::move(node));} - void pushContextElement (std::unique_ptr<XMLElementNode> &&node) override {_svg.pushContextElement(std::move(node));} - void popContextElement () override {_svg.popContextElement();} - void embed (const BoundingBox &bbox) override {_bbox.embed(bbox);} - void embed (const DPair &p, double r=0) override {if (r==0) _bbox.embed(p); else _bbox.embed(p, r);} - void progress (const char *id) override; - unsigned getCurrentPageNumber() const override {return 0;} - BoundingBox& bbox () override {return _bbox;} - BoundingBox& bbox (const std::string &name, bool reset=false) override {return _bbox;} - std::string getSVGFilename (unsigned pageno) const override; - std::string getBBoxFormatString () const override {return "";} - - private: - std::string _fname; ///< name of EPS file - SVGTree _svg; - SVGOutputBase &_out; - double _x, _y; - BoundingBox _bbox; + std::string imageFormat () const override {return "EPS";} + bool imageIsValid () const override {return EPSFile(filename()).hasValidHeader();} + BoundingBox imageBBox () const override {return EPSFile(filename()).bbox();} + std::string psSpecialCmd () const override {return "psfile=";} }; #endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp index 83f167e428e..1b7b172cedc 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp @@ -138,7 +138,7 @@ static double read_length (InputReader &in) { } -bool EmSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { +bool EmSpecialHandler::process (const string &prefix, istream &is, SpecialActions &actions) { // em:moveto => move graphic cursor to dvi position // em:lineto => draw line from graphic cursor to dvi cursor, then move graphic cursor to dvi position // em:linewidth <w> => set line width to <w> @@ -167,7 +167,7 @@ bool EmSpecialHandler::process (const char *prefix, istream &is, SpecialActions }; StreamInputReader ir(is); - string cmdstr = ir.getWord(); + const string cmdstr = ir.getWord(); for (Command *cmd=commands; cmd->name; cmd++) { if (cmdstr == cmd->name) { (this->*cmd->handler)(ir, actions); @@ -258,7 +258,7 @@ void EmSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) { } -const vector<const char*> EmSpecialHandler::prefixes () const { - const vector<const char*> pfx {"em:"}; +vector<const char*> EmSpecialHandler::prefixes() const { + vector<const char*> pfx {"em:"}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp index 36990ce17ba..3c58e55f06d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.hpp @@ -29,7 +29,7 @@ class InputReader; class SpecialActions; -class EmSpecialHandler : public SpecialHandler, public DVIEndPageListener { +class EmSpecialHandler : public SpecialHandler { struct Line { Line (int pp1, int pp2, char cc1, char cc2, double w) : p1(pp1), p2(pp2), c1(cc1), c2(cc2), width(w) {} int p1, p2; ///< point numbers of line ends @@ -41,8 +41,8 @@ class EmSpecialHandler : public SpecialHandler, public DVIEndPageListener { EmSpecialHandler (); const char* name () const override {return "em";} const char* info () const override {return "line drawing statements of the emTeX special set";} - const std::vector<const char*> prefixes () const override; - bool process (const char *prefix, std::istream &in, SpecialActions &actions) override; + std::vector<const char*> prefixes() const override; + bool process (const std::string &prefix, std::istream &in, SpecialActions &actions) override; protected: void dviEndPage (unsigned pageno, SpecialActions &actions) override; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp index 40a7aa01c22..405a6f2da21 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileFinder.cpp @@ -142,6 +142,7 @@ const char* FileFinder::findFile (const std::string &fname, const char *ftype) c // to work around this, we try to lookup the files by calling kpsewhich. Process process("kpsewhich", "-format=cmap "+fname); process.run(&buf); + buf = util::trim(buf); return buf.empty() ? nullptr : buf.c_str(); } try { diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp index 769ff0a7c23..4804b56f404 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FileSystem.cpp @@ -310,7 +310,8 @@ bool FileSystem::exists (const string &fname) { bool FileSystem::isDirectory (const string &fname) { if (const char *cfname = fname.c_str()) { #ifdef _WIN32 - return GetFileAttributes(cfname) & FILE_ATTRIBUTE_DIRECTORY; + auto attr = GetFileAttributes(cfname); + return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY); #else struct stat attr; return stat(cfname, &attr) == 0 && S_ISDIR(attr.st_mode); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp index 5672a8b4eb0..dab7175e4fd 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp @@ -203,18 +203,21 @@ bool Ghostscript::revision (gsapi_revision_t *r) { } -/** Returns product name and revision number of the GS library. - * @param[in] revonly if true, only the revision number is returned */ -string Ghostscript::revision (bool revonly) { +/** Returns the revision number of the GS library. */ +int Ghostscript::revision () { gsapi_revision_t r; - if (revision(&r)) { - ostringstream oss; - if (!revonly) - oss << r.product << ' '; - oss << (r.revision/100) << '.' << setfill('0') << setw(2) << (r.revision%100); - return oss.str(); - } - return ""; + if (revision(&r)) + return static_cast<int>(r.revision); + return 0; +} + + +/** Returns the revision of the GS library as a string of the form "MAJOR.MINOR". */ +string Ghostscript::revisionstr () { + string revstr; + if (int rev = revision()) + revstr = to_string(rev/100) + "." + to_string(rev%100); + return revstr; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp index 258055f7672..06f1d38fa9b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.hpp @@ -38,8 +38,7 @@ #endif #if defined(DISABLE_GS) -struct Ghostscript -{ +struct Ghostscript { using Stdin = int (GSDLLCALLPTR)(void *caller, char *buf, int len); using Stdout = int (GSDLLCALLPTR)(void *caller, const char *str, int len); using Stderr = int (GSDLLCALLPTR)(void *caller, const char *str, int len); @@ -49,7 +48,8 @@ struct Ghostscript bool init (int argc, const char **argv, void *caller=0) {return false;} bool available () {return false;} bool revision (gsapi_revision_t *r) {return false;} - std::string revision (bool revonly=false) {return "";} + int revision () {return 0;} + std::string revisionstr () {return "";} int set_stdio (Stdin in, Stdout out, Stderr err) {return 0;} int run_string_begin (int user_errors, int *pexit_code) {return 0;} int run_string_continue (const char *str, unsigned int length, int user_errors, int *pexit_code) {return 0;} @@ -79,7 +79,8 @@ class Ghostscript bool init (int argc, const char **argv, void *caller=0); bool available (); bool revision (gsapi_revision_t *r); - std::string revision (bool revonly=false); + int revision (); + std::string revisionstr (); int set_stdio (Stdin in, Stdout out, Stderr err); int run_string_begin (int user_errors, int *pexit_code); int run_string_continue (const char *str, unsigned int length, int user_errors, int *pexit_code); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp index 86f0ef022bf..52ed5efe780 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.cpp @@ -26,7 +26,7 @@ using namespace std; -void HtmlSpecialHandler::preprocess (const char *, istream &is, SpecialActions &actions) { +void HtmlSpecialHandler::preprocess (const string&, istream &is, SpecialActions &actions) { StreamInputReader ir(is); ir.skipSpace(); // collect page number and ID of named anchors @@ -41,7 +41,7 @@ void HtmlSpecialHandler::preprocess (const char *, istream &is, SpecialActions & } -bool HtmlSpecialHandler::process (const char *, istream &is, SpecialActions &actions) { +bool HtmlSpecialHandler::process (const string&, istream &is, SpecialActions &actions) { _active = true; StreamInputReader ir(is); ir.skipSpace(); @@ -80,7 +80,7 @@ void HtmlSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) { } -const vector<const char*> HtmlSpecialHandler::prefixes () const { - const vector<const char*> pfx {"html:"}; +vector<const char*> HtmlSpecialHandler::prefixes() const { + vector<const char*> pfx {"html:"}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp index 125f69192fd..3bebabd4746 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HtmlSpecialHandler.hpp @@ -28,14 +28,14 @@ class SpecialActions; -class HtmlSpecialHandler : public SpecialHandler, public DVIEndPageListener, public DVIPositionListener { +class HtmlSpecialHandler : public SpecialHandler { public: HtmlSpecialHandler () : _active(false) {} - void preprocess (const char *prefix, std::istream &is, SpecialActions &actions) override; - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + void preprocess (const std::string &prefix, std::istream &is, SpecialActions &actions) override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; const char* name () const override {return "html";} const char* info () const override {return "hyperref specials";} - const std::vector<const char*> prefixes () const override; + std::vector<const char*> prefixes() const override; protected: void dviEndPage (unsigned pageno, SpecialActions &actions) override; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp index 06958c1b963..27285fbb7c2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EPSToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.cpp @@ -1,5 +1,5 @@ /************************************************************************* -** EPSToSVG.cpp ** +** ImageToSVG.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** ** Copyright (C) 2005-2018 Martin Gieseking <martin.gieseking@uos.de> ** @@ -21,8 +21,7 @@ #include <config.h> #include <fstream> #include <sstream> -#include "EPSFile.hpp" -#include "EPSToSVG.hpp" +#include "ImageToSVG.hpp" #include "Message.hpp" #include "MessageException.hpp" #include "PsSpecialHandler.hpp" @@ -34,20 +33,18 @@ using namespace std; -void EPSToSVG::convert () { +void ImageToSVG::convert () { #ifndef HAVE_LIBGS if (!Ghostscript().available()) - throw MessageException("Ghostscript is required to process the EPS file"); + throw MessageException("Ghostscript is required to process "+imageFormat()+" files"); #endif - EPSFile epsfile(_fname); - if (!epsfile.hasValidHeader()) - throw PSException("invalid EPS file"); + if (!imageIsValid()) + throw PSException("invalid "+imageFormat()+" file"); - BoundingBox bbox; - epsfile.bbox(bbox); - if (bbox.width() == 0 || bbox.height() == 0) - Message::wstream(true) << "bounding box of file " << _fname << " is empty\n"; - Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing file " << _fname << '\n'; + BoundingBox bbox = imageBBox(); + if (bbox.valid() && (bbox.width() == 0 || bbox.height() == 0)) + Message::wstream(true) << "bounding box of " << imageFormat() << " file is empty\n"; + Message::mstream(false, Message::MC_PAGE_NUMBER) << "processing " << imageFormat() << " file\n"; Message::mstream().indent(1); _svg.newPage(1); // create a psfile special and forward it to the PsSpecialHandler @@ -59,7 +56,7 @@ void EPSToSVG::convert () { "ury=" << bbox.maxY(); try { PsSpecialHandler pshandler; - pshandler.process("psfile=", ss, *this); + pshandler.process(psSpecialCmd(), ss, *this); } catch (...) { progress(0); // remove progress message @@ -79,23 +76,23 @@ void EPSToSVG::convert () { else { const double bp2pt = 72.27/72; const double bp2mm = 25.4/72; - Message::mstream(false, Message::MC_PAGE_SIZE) << "graphic size: " << XMLString(bbox.width()*bp2pt) << "pt" - " x " << XMLString(bbox.height()*bp2pt) << "pt" - " (" << XMLString(bbox.width()*bp2mm) << "mm" - " x " << XMLString(bbox.height()*bp2mm) << "mm)\n"; + Message::mstream(false, Message::MC_PAGE_SIZE) << "graphic size: " << XMLString(_bbox.width()*bp2pt) << "pt" + " x " << XMLString(_bbox.height()*bp2pt) << "pt" + " (" << XMLString(_bbox.width()*bp2mm) << "mm" + " x " << XMLString(_bbox.height()*bp2mm) << "mm)\n"; Message::mstream(false, Message::MC_PAGE_WRITTEN) << "output written to " << svgfname << '\n'; } } -string EPSToSVG::getSVGFilename (unsigned pageno) const { +string ImageToSVG::getSVGFilename (unsigned pageno) const { if (pageno == 1) return _out.filename(1, 1); return ""; } -void EPSToSVG::progress (const char *id) { +void ImageToSVG::progress (const char *id) { static double time=0; static bool draw=false; // show progress indicator? static size_t count=0; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp new file mode 100644 index 00000000000..a9424af38fb --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ImageToSVG.hpp @@ -0,0 +1,80 @@ +/************************************************************************* +** ImageToSVG.hpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** 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 ** +** 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 IMAGETOSVG_HPP +#define IMAGETOSVG_HPP + +#include <istream> +#include <memory> +#include <string> +#include "SpecialActions.hpp" +#include "SVGTree.hpp" + +struct SVGOutputBase; + +class ImageToSVG : protected SpecialActions { + public: + ImageToSVG (const std::string &fname, SVGOutputBase &out) : _fname(fname), _out(out) {} + virtual ~ImageToSVG () =default; + void convert (); + void setTransformation (const Matrix &m); + void setPageSize (const std::string &name); + std::string filename () const {return _fname;} + + protected: + virtual std::string imageFormat () const =0; + virtual bool imageIsValid () const =0; + virtual BoundingBox imageBBox () const =0; + virtual std::string psSpecialCmd () const =0; + // implement abstract base class SpecialActions + double getX () const override {return _x;} + double getY () const override {return _y;} + void setX (double x) override {_x = x; _svg.setX(x);} + void setY (double y) override {_y = y; _svg.setY(y);} + void finishLine () override {} + void setColor (const Color &color) override {_svg.setColor(color);} + Color getColor () const override {return _svg.getColor();} + void setMatrix (const Matrix &m) override {_svg.setMatrix(m);} + const Matrix& getMatrix () const override {return _svg.getMatrix();} + void getPageTransform (Matrix &matrix) const override {} + void setBgColor (const Color &color) override {} + void appendToPage(std::unique_ptr<XMLNode> &&node) override {_svg.appendToPage(std::move(node));} + void appendToDefs(std::unique_ptr<XMLNode> &&node) override {_svg.appendToDefs(std::move(node));} + void prependToPage(std::unique_ptr<XMLNode> &&node) override {_svg.prependToPage(std::move(node));} + void pushContextElement (std::unique_ptr<XMLElementNode> &&node) override {_svg.pushContextElement(std::move(node));} + void popContextElement () override {_svg.popContextElement();} + void embed (const BoundingBox &bbox) override {_bbox.embed(bbox);} + void embed (const DPair &p, double r=0) override {if (r==0) _bbox.embed(p); else _bbox.embed(p, r);} + void progress (const char *id) override; + unsigned getCurrentPageNumber() const override {return 0;} + BoundingBox& bbox () override {return _bbox;} + BoundingBox& bbox (const std::string &name, bool reset=false) override {return _bbox;} + std::string getSVGFilename (unsigned pageno) const override; + std::string getBBoxFormatString () const override {return "";} + + private: + std::string _fname; ///< name of image file + SVGTree _svg; + SVGOutputBase &_out; + double _x=0, _y=0; + BoundingBox _bbox; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am index 9d098904169..e073594a218 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am @@ -85,7 +85,6 @@ libdvisvgm_a_SOURCES = \ EncFile.hpp \ EPSFile.cpp \ EPSFile.hpp \ - EPSToSVG.cpp \ EPSToSVG.hpp \ FileFinder.cpp \ FileFinder.hpp \ @@ -126,6 +125,8 @@ libdvisvgm_a_SOURCES = \ HtmlSpecialHandler.hpp \ HyperlinkManager.cpp \ HyperlinkManager.hpp \ + ImageToSVG.cpp \ + ImageToSVG.hpp \ InputBuffer.cpp \ InputBuffer.hpp \ InputReader.cpp \ @@ -158,6 +159,7 @@ libdvisvgm_a_SOURCES = \ PathClipper.hpp \ PDFParser.cpp \ PDFParser.hpp \ + PDFToSVG.hpp \ PdfSpecialHandler.cpp \ PdfSpecialHandler.hpp \ PreScanDVIReader.cpp \ @@ -180,6 +182,8 @@ libdvisvgm_a_SOURCES = \ ShadingPatch.hpp \ SignalHandler.cpp \ SignalHandler.hpp \ + SourceInput.cpp \ + SourceInput.hpp \ SpecialActions.hpp \ SpecialHandler.hpp \ SpecialManager.cpp \ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in index dfaa9fb0896..838276b69ed 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in @@ -153,45 +153,47 @@ am__libdvisvgm_a_SOURCES_DIST = AGLTable.hpp BasicDVIReader.cpp \ DvisvgmSpecialHandler.cpp DvisvgmSpecialHandler.hpp \ DVIToSVG.cpp DVIToSVG.hpp DVIToSVGActions.cpp \ DVIToSVGActions.hpp EmSpecialHandler.cpp EmSpecialHandler.hpp \ - EncFile.cpp EncFile.hpp EPSFile.cpp EPSFile.hpp EPSToSVG.cpp \ - EPSToSVG.hpp FileFinder.cpp FileFinder.hpp FilePath.cpp \ - FilePath.hpp FileSystem.cpp FileSystem.hpp FixWord.hpp \ - Font.cpp Font.hpp FontCache.cpp FontCache.hpp FontEncoding.cpp \ - FontEncoding.hpp FontEngine.cpp FontEngine.hpp FontManager.cpp \ - FontManager.hpp FontMap.cpp FontMap.hpp FontMetrics.cpp \ - FontMetrics.hpp FontStyle.hpp FontWriter.cpp FontWriter.hpp \ - GFGlyphTracer.cpp GFGlyphTracer.hpp GFReader.cpp GFReader.hpp \ - GFTracer.cpp GFTracer.hpp Ghostscript.cpp Ghostscript.hpp \ - Glyph.hpp GlyphTracerMessages.hpp GraphicsPath.hpp \ + EncFile.cpp EncFile.hpp EPSFile.cpp EPSFile.hpp EPSToSVG.hpp \ + FileFinder.cpp FileFinder.hpp FilePath.cpp FilePath.hpp \ + FileSystem.cpp FileSystem.hpp FixWord.hpp Font.cpp Font.hpp \ + FontCache.cpp FontCache.hpp FontEncoding.cpp FontEncoding.hpp \ + FontEngine.cpp FontEngine.hpp FontManager.cpp FontManager.hpp \ + FontMap.cpp FontMap.hpp FontMetrics.cpp FontMetrics.hpp \ + FontStyle.hpp FontWriter.cpp FontWriter.hpp GFGlyphTracer.cpp \ + GFGlyphTracer.hpp GFReader.cpp GFReader.hpp GFTracer.cpp \ + GFTracer.hpp Ghostscript.cpp Ghostscript.hpp Glyph.hpp \ + GlyphTracerMessages.hpp GraphicsPath.hpp \ HtmlSpecialHandler.cpp HtmlSpecialHandler.hpp \ - HyperlinkManager.cpp HyperlinkManager.hpp InputBuffer.cpp \ - InputBuffer.hpp InputReader.cpp InputReader.hpp JFM.cpp \ - JFM.hpp Length.cpp Length.hpp macros.hpp MapLine.cpp \ - MapLine.hpp Matrix.cpp Matrix.hpp Message.cpp Message.hpp \ - MessageException.hpp MetafontWrapper.cpp MetafontWrapper.hpp \ - NoPsSpecialHandler.cpp NoPsSpecialHandler.hpp \ - NumericRanges.hpp PageRanges.cpp PageRanges.hpp PageSize.cpp \ - PageSize.hpp Pair.hpp PapersizeSpecialHandler.cpp \ - PapersizeSpecialHandler.hpp PathClipper.cpp PathClipper.hpp \ - PDFParser.cpp PDFParser.hpp PdfSpecialHandler.cpp \ - PdfSpecialHandler.hpp PreScanDVIReader.cpp \ - PreScanDVIReader.hpp Process.cpp Process.hpp psdefs.cpp \ - PSFilter.hpp PSInterpreter.cpp PSInterpreter.hpp PSPattern.cpp \ - PSPattern.hpp PSPreviewFilter.cpp PSPreviewFilter.hpp \ - PsSpecialHandler.cpp PsSpecialHandler.hpp RangeMap.cpp \ - RangeMap.hpp ShadingPatch.cpp ShadingPatch.hpp \ - SignalHandler.cpp SignalHandler.hpp SpecialActions.hpp \ - SpecialHandler.hpp SpecialManager.cpp SpecialManager.hpp \ - StreamReader.cpp StreamReader.hpp StreamWriter.cpp \ - StreamWriter.hpp Subfont.cpp Subfont.hpp SVGCharHandler.cpp \ - SVGCharHandler.hpp SVGCharHandlerFactory.cpp \ - SVGCharHandlerFactory.hpp SVGCharPathHandler.cpp \ - SVGCharPathHandler.hpp SVGCharTspanTextHandler.cpp \ - SVGCharTspanTextHandler.hpp SVGOutput.cpp SVGOutput.hpp \ - SVGSingleCharTextHandler.cpp SVGSingleCharTextHandler.hpp \ - SVGTree.cpp SVGTree.hpp System.cpp System.hpp \ - TensorProductPatch.cpp TensorProductPatch.hpp Terminal.cpp \ - Terminal.hpp TFM.cpp TFM.hpp ToUnicodeMap.cpp ToUnicodeMap.hpp \ + HyperlinkManager.cpp HyperlinkManager.hpp ImageToSVG.cpp \ + ImageToSVG.hpp InputBuffer.cpp InputBuffer.hpp InputReader.cpp \ + InputReader.hpp JFM.cpp JFM.hpp Length.cpp Length.hpp \ + macros.hpp MapLine.cpp MapLine.hpp Matrix.cpp Matrix.hpp \ + Message.cpp Message.hpp MessageException.hpp \ + MetafontWrapper.cpp MetafontWrapper.hpp NoPsSpecialHandler.cpp \ + NoPsSpecialHandler.hpp NumericRanges.hpp PageRanges.cpp \ + PageRanges.hpp PageSize.cpp PageSize.hpp Pair.hpp \ + PapersizeSpecialHandler.cpp PapersizeSpecialHandler.hpp \ + PathClipper.cpp PathClipper.hpp PDFParser.cpp PDFParser.hpp \ + PDFToSVG.hpp PdfSpecialHandler.cpp PdfSpecialHandler.hpp \ + PreScanDVIReader.cpp PreScanDVIReader.hpp Process.cpp \ + Process.hpp psdefs.cpp PSFilter.hpp PSInterpreter.cpp \ + PSInterpreter.hpp PSPattern.cpp PSPattern.hpp \ + PSPreviewFilter.cpp PSPreviewFilter.hpp PsSpecialHandler.cpp \ + PsSpecialHandler.hpp RangeMap.cpp RangeMap.hpp \ + ShadingPatch.cpp ShadingPatch.hpp SignalHandler.cpp \ + SignalHandler.hpp SourceInput.cpp SourceInput.hpp \ + SpecialActions.hpp SpecialHandler.hpp SpecialManager.cpp \ + SpecialManager.hpp StreamReader.cpp StreamReader.hpp \ + StreamWriter.cpp StreamWriter.hpp Subfont.cpp Subfont.hpp \ + SVGCharHandler.cpp SVGCharHandler.hpp \ + SVGCharHandlerFactory.cpp SVGCharHandlerFactory.hpp \ + SVGCharPathHandler.cpp SVGCharPathHandler.hpp \ + SVGCharTspanTextHandler.cpp SVGCharTspanTextHandler.hpp \ + SVGOutput.cpp SVGOutput.hpp SVGSingleCharTextHandler.cpp \ + SVGSingleCharTextHandler.hpp SVGTree.cpp SVGTree.hpp \ + System.cpp System.hpp TensorProductPatch.cpp \ + TensorProductPatch.hpp Terminal.cpp Terminal.hpp TFM.cpp \ + TFM.hpp ToUnicodeMap.cpp ToUnicodeMap.hpp \ TpicSpecialHandler.cpp TpicSpecialHandler.hpp \ TriangularPatch.cpp TriangularPatch.hpp TrueTypeFont.cpp \ TrueTypeFont.hpp TTFAutohint.cpp TTFAutohint.hpp Unicode.cpp \ @@ -210,25 +212,26 @@ am_libdvisvgm_a_OBJECTS = BasicDVIReader.$(OBJEXT) Bezier.$(OBJEXT) \ Directory.$(OBJEXT) DLLoader.$(OBJEXT) DVIReader.$(OBJEXT) \ DvisvgmSpecialHandler.$(OBJEXT) DVIToSVG.$(OBJEXT) \ DVIToSVGActions.$(OBJEXT) EmSpecialHandler.$(OBJEXT) \ - EncFile.$(OBJEXT) EPSFile.$(OBJEXT) EPSToSVG.$(OBJEXT) \ - FileFinder.$(OBJEXT) FilePath.$(OBJEXT) FileSystem.$(OBJEXT) \ - Font.$(OBJEXT) FontCache.$(OBJEXT) FontEncoding.$(OBJEXT) \ + EncFile.$(OBJEXT) EPSFile.$(OBJEXT) FileFinder.$(OBJEXT) \ + FilePath.$(OBJEXT) FileSystem.$(OBJEXT) Font.$(OBJEXT) \ + FontCache.$(OBJEXT) FontEncoding.$(OBJEXT) \ FontEngine.$(OBJEXT) FontManager.$(OBJEXT) FontMap.$(OBJEXT) \ FontMetrics.$(OBJEXT) FontWriter.$(OBJEXT) \ GFGlyphTracer.$(OBJEXT) GFReader.$(OBJEXT) GFTracer.$(OBJEXT) \ Ghostscript.$(OBJEXT) HtmlSpecialHandler.$(OBJEXT) \ - HyperlinkManager.$(OBJEXT) InputBuffer.$(OBJEXT) \ - InputReader.$(OBJEXT) JFM.$(OBJEXT) Length.$(OBJEXT) \ - MapLine.$(OBJEXT) Matrix.$(OBJEXT) Message.$(OBJEXT) \ - MetafontWrapper.$(OBJEXT) NoPsSpecialHandler.$(OBJEXT) \ - PageRanges.$(OBJEXT) PageSize.$(OBJEXT) \ - PapersizeSpecialHandler.$(OBJEXT) PathClipper.$(OBJEXT) \ - PDFParser.$(OBJEXT) PdfSpecialHandler.$(OBJEXT) \ - PreScanDVIReader.$(OBJEXT) Process.$(OBJEXT) psdefs.$(OBJEXT) \ - PSInterpreter.$(OBJEXT) PSPattern.$(OBJEXT) \ - PSPreviewFilter.$(OBJEXT) PsSpecialHandler.$(OBJEXT) \ - RangeMap.$(OBJEXT) ShadingPatch.$(OBJEXT) \ - SignalHandler.$(OBJEXT) SpecialManager.$(OBJEXT) \ + HyperlinkManager.$(OBJEXT) ImageToSVG.$(OBJEXT) \ + InputBuffer.$(OBJEXT) InputReader.$(OBJEXT) JFM.$(OBJEXT) \ + Length.$(OBJEXT) MapLine.$(OBJEXT) Matrix.$(OBJEXT) \ + Message.$(OBJEXT) MetafontWrapper.$(OBJEXT) \ + NoPsSpecialHandler.$(OBJEXT) PageRanges.$(OBJEXT) \ + PageSize.$(OBJEXT) PapersizeSpecialHandler.$(OBJEXT) \ + PathClipper.$(OBJEXT) PDFParser.$(OBJEXT) \ + PdfSpecialHandler.$(OBJEXT) PreScanDVIReader.$(OBJEXT) \ + Process.$(OBJEXT) psdefs.$(OBJEXT) PSInterpreter.$(OBJEXT) \ + PSPattern.$(OBJEXT) PSPreviewFilter.$(OBJEXT) \ + PsSpecialHandler.$(OBJEXT) RangeMap.$(OBJEXT) \ + ShadingPatch.$(OBJEXT) SignalHandler.$(OBJEXT) \ + SourceInput.$(OBJEXT) SpecialManager.$(OBJEXT) \ StreamReader.$(OBJEXT) StreamWriter.$(OBJEXT) \ Subfont.$(OBJEXT) SVGCharHandler.$(OBJEXT) \ SVGCharHandlerFactory.$(OBJEXT) SVGCharPathHandler.$(OBJEXT) \ @@ -499,45 +502,47 @@ libdvisvgm_a_SOURCES = AGLTable.hpp BasicDVIReader.cpp \ DvisvgmSpecialHandler.cpp DvisvgmSpecialHandler.hpp \ DVIToSVG.cpp DVIToSVG.hpp DVIToSVGActions.cpp \ DVIToSVGActions.hpp EmSpecialHandler.cpp EmSpecialHandler.hpp \ - EncFile.cpp EncFile.hpp EPSFile.cpp EPSFile.hpp EPSToSVG.cpp \ - EPSToSVG.hpp FileFinder.cpp FileFinder.hpp FilePath.cpp \ - FilePath.hpp FileSystem.cpp FileSystem.hpp FixWord.hpp \ - Font.cpp Font.hpp FontCache.cpp FontCache.hpp FontEncoding.cpp \ - FontEncoding.hpp FontEngine.cpp FontEngine.hpp FontManager.cpp \ - FontManager.hpp FontMap.cpp FontMap.hpp FontMetrics.cpp \ - FontMetrics.hpp FontStyle.hpp FontWriter.cpp FontWriter.hpp \ - GFGlyphTracer.cpp GFGlyphTracer.hpp GFReader.cpp GFReader.hpp \ - GFTracer.cpp GFTracer.hpp Ghostscript.cpp Ghostscript.hpp \ - Glyph.hpp GlyphTracerMessages.hpp GraphicsPath.hpp \ + EncFile.cpp EncFile.hpp EPSFile.cpp EPSFile.hpp EPSToSVG.hpp \ + FileFinder.cpp FileFinder.hpp FilePath.cpp FilePath.hpp \ + FileSystem.cpp FileSystem.hpp FixWord.hpp Font.cpp Font.hpp \ + FontCache.cpp FontCache.hpp FontEncoding.cpp FontEncoding.hpp \ + FontEngine.cpp FontEngine.hpp FontManager.cpp FontManager.hpp \ + FontMap.cpp FontMap.hpp FontMetrics.cpp FontMetrics.hpp \ + FontStyle.hpp FontWriter.cpp FontWriter.hpp GFGlyphTracer.cpp \ + GFGlyphTracer.hpp GFReader.cpp GFReader.hpp GFTracer.cpp \ + GFTracer.hpp Ghostscript.cpp Ghostscript.hpp Glyph.hpp \ + GlyphTracerMessages.hpp GraphicsPath.hpp \ HtmlSpecialHandler.cpp HtmlSpecialHandler.hpp \ - HyperlinkManager.cpp HyperlinkManager.hpp InputBuffer.cpp \ - InputBuffer.hpp InputReader.cpp InputReader.hpp JFM.cpp \ - JFM.hpp Length.cpp Length.hpp macros.hpp MapLine.cpp \ - MapLine.hpp Matrix.cpp Matrix.hpp Message.cpp Message.hpp \ - MessageException.hpp MetafontWrapper.cpp MetafontWrapper.hpp \ - NoPsSpecialHandler.cpp NoPsSpecialHandler.hpp \ - NumericRanges.hpp PageRanges.cpp PageRanges.hpp PageSize.cpp \ - PageSize.hpp Pair.hpp PapersizeSpecialHandler.cpp \ - PapersizeSpecialHandler.hpp PathClipper.cpp PathClipper.hpp \ - PDFParser.cpp PDFParser.hpp PdfSpecialHandler.cpp \ - PdfSpecialHandler.hpp PreScanDVIReader.cpp \ - PreScanDVIReader.hpp Process.cpp Process.hpp psdefs.cpp \ - PSFilter.hpp PSInterpreter.cpp PSInterpreter.hpp PSPattern.cpp \ - PSPattern.hpp PSPreviewFilter.cpp PSPreviewFilter.hpp \ - PsSpecialHandler.cpp PsSpecialHandler.hpp RangeMap.cpp \ - RangeMap.hpp ShadingPatch.cpp ShadingPatch.hpp \ - SignalHandler.cpp SignalHandler.hpp SpecialActions.hpp \ - SpecialHandler.hpp SpecialManager.cpp SpecialManager.hpp \ - StreamReader.cpp StreamReader.hpp StreamWriter.cpp \ - StreamWriter.hpp Subfont.cpp Subfont.hpp SVGCharHandler.cpp \ - SVGCharHandler.hpp SVGCharHandlerFactory.cpp \ - SVGCharHandlerFactory.hpp SVGCharPathHandler.cpp \ - SVGCharPathHandler.hpp SVGCharTspanTextHandler.cpp \ - SVGCharTspanTextHandler.hpp SVGOutput.cpp SVGOutput.hpp \ - SVGSingleCharTextHandler.cpp SVGSingleCharTextHandler.hpp \ - SVGTree.cpp SVGTree.hpp System.cpp System.hpp \ - TensorProductPatch.cpp TensorProductPatch.hpp Terminal.cpp \ - Terminal.hpp TFM.cpp TFM.hpp ToUnicodeMap.cpp ToUnicodeMap.hpp \ + HyperlinkManager.cpp HyperlinkManager.hpp ImageToSVG.cpp \ + ImageToSVG.hpp InputBuffer.cpp InputBuffer.hpp InputReader.cpp \ + InputReader.hpp JFM.cpp JFM.hpp Length.cpp Length.hpp \ + macros.hpp MapLine.cpp MapLine.hpp Matrix.cpp Matrix.hpp \ + Message.cpp Message.hpp MessageException.hpp \ + MetafontWrapper.cpp MetafontWrapper.hpp NoPsSpecialHandler.cpp \ + NoPsSpecialHandler.hpp NumericRanges.hpp PageRanges.cpp \ + PageRanges.hpp PageSize.cpp PageSize.hpp Pair.hpp \ + PapersizeSpecialHandler.cpp PapersizeSpecialHandler.hpp \ + PathClipper.cpp PathClipper.hpp PDFParser.cpp PDFParser.hpp \ + PDFToSVG.hpp PdfSpecialHandler.cpp PdfSpecialHandler.hpp \ + PreScanDVIReader.cpp PreScanDVIReader.hpp Process.cpp \ + Process.hpp psdefs.cpp PSFilter.hpp PSInterpreter.cpp \ + PSInterpreter.hpp PSPattern.cpp PSPattern.hpp \ + PSPreviewFilter.cpp PSPreviewFilter.hpp PsSpecialHandler.cpp \ + PsSpecialHandler.hpp RangeMap.cpp RangeMap.hpp \ + ShadingPatch.cpp ShadingPatch.hpp SignalHandler.cpp \ + SignalHandler.hpp SourceInput.cpp SourceInput.hpp \ + SpecialActions.hpp SpecialHandler.hpp SpecialManager.cpp \ + SpecialManager.hpp StreamReader.cpp StreamReader.hpp \ + StreamWriter.cpp StreamWriter.hpp Subfont.cpp Subfont.hpp \ + SVGCharHandler.cpp SVGCharHandler.hpp \ + SVGCharHandlerFactory.cpp SVGCharHandlerFactory.hpp \ + SVGCharPathHandler.cpp SVGCharPathHandler.hpp \ + SVGCharTspanTextHandler.cpp SVGCharTspanTextHandler.hpp \ + SVGOutput.cpp SVGOutput.hpp SVGSingleCharTextHandler.cpp \ + SVGSingleCharTextHandler.hpp SVGTree.cpp SVGTree.hpp \ + System.cpp System.hpp TensorProductPatch.cpp \ + TensorProductPatch.hpp Terminal.cpp Terminal.hpp TFM.cpp \ + TFM.hpp ToUnicodeMap.cpp ToUnicodeMap.hpp \ TpicSpecialHandler.cpp TpicSpecialHandler.hpp \ TriangularPatch.cpp TriangularPatch.hpp TrueTypeFont.cpp \ TrueTypeFont.hpp TTFAutohint.cpp TTFAutohint.hpp Unicode.cpp \ @@ -683,7 +688,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Directory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DvisvgmSpecialHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EPSFile.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EPSToSVG.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EmSpecialHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EncFile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileFinder.Po@am__quote@ @@ -703,6 +707,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Ghostscript.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HtmlSpecialHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HyperlinkManager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ImageToSVG.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InputBuffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InputReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/JFM.Po@am__quote@ @@ -734,6 +739,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SVGTree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShadingPatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SignalHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SourceInput.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpecialManager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamReader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamWriter.Po@am__quote@ diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp index d22cc45f690..bce560c1dee 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MiKTeXCom.cpp @@ -18,7 +18,6 @@ ** along with this program; if not, see <http://www.gnu.org/licenses/>. ** *************************************************************************/ -#include <stdio.h> #include <comdef.h> #include <string> #include "MessageException.hpp" diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp index a1df816cb67..67d61447a16 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.cpp @@ -24,7 +24,7 @@ using namespace std; -bool NoPsSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { +bool NoPsSpecialHandler::process (const string&, istream&, SpecialActions&) { _count++; return true; } @@ -39,7 +39,7 @@ void NoPsSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) { } -const vector<const char*> NoPsSpecialHandler::prefixes () const { - const vector<const char*> pfx {"header=", "psfile=", "PSfile=", "ps:", "ps::", "!", "\""}; +vector<const char*> NoPsSpecialHandler::prefixes() const { + vector<const char*> pfx {"header=", "psfile=", "PSfile=", "ps:", "ps::", "!", "\""}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp index 33922799b2f..fbd088d2703 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/NoPsSpecialHandler.hpp @@ -23,14 +23,13 @@ #include "SpecialHandler.hpp" -class NoPsSpecialHandler : public SpecialHandler, public DVIEndPageListener -{ +class NoPsSpecialHandler : public SpecialHandler { public: NoPsSpecialHandler () : _count(0) {} - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; const char* name () const override {return 0;} const char* info () const override {return 0;} - const std::vector<const char*> prefixes () const override; + std::vector<const char*> prefixes() const override; protected: void dviEndPage (unsigned pageno, SpecialActions &actions) override; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp new file mode 100644 index 00000000000..570eecd6384 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PDFToSVG.hpp @@ -0,0 +1,47 @@ +/************************************************************************* +** PDFToSVG.hpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** 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 ** +** 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 PDFTOSVG_HPP +#define PDFTOSVG_HPP + +#include <fstream> +#include "ImageToSVG.hpp" + +class PDFToSVG : public ImageToSVG { + public: + PDFToSVG (const std::string &fname, SVGOutputBase &out) : ImageToSVG(fname, out) {} + + protected: + bool imageIsValid () const override { + std::ifstream ifs(filename()); + if (ifs) { + char buf[16]; + ifs.getline(buf, 16); + return std::strncmp(buf, "%PDF-1.", 7) == 0; + } + return false; + } + std::string imageFormat () const override {return "PDF";} + BoundingBox imageBBox () const override {return BoundingBox();} + std::string psSpecialCmd () const override {return "pdffile=";} +}; + +#endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp index 57441da6eca..f87a6467a09 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.cpp @@ -33,29 +33,27 @@ using namespace std; -const char *PSInterpreter::GSARGS[] = { - "gs", // dummy name - "-q", // be quiet, suppress gs banner -// "-dSAFER", // disallow writing of files - "-dNODISPLAY", // we don't need a display device - "-dNOPAUSE", // keep going - "-dWRITESYSTEMDICT", // leave systemdict writable as some operators must be replaced - "-dNOPROMPT", -// "-dNOBIND", -}; - - /** Constructs a new PSInterpreter object. * @param[in] actions template methods to be executed after recognizing the corresponding PS operator. */ PSInterpreter::PSInterpreter (PSActions *actions) - : _mode(PS_NONE), _actions(actions), _filter(0), _bytesToRead(0), _inError(false), _initialized(false) + : _mode(PS_NONE), _actions(actions) { } void PSInterpreter::init () { if (!_initialized) { - _gs.init(sizeof(GSARGS)/sizeof(char*), GSARGS, this); + vector<const char*> gsargs { + "gs", // dummy name + "-q", // be quiet, suppress gs banner + "-dNODISPLAY", // we don't need a display device + "-dNOPAUSE", // keep going + "-dWRITESYSTEMDICT", // leave systemdict writable as some operators must be replaced + "-dNOPROMPT" + }; + if (int gsrev = _gs.revision()) + gsargs.emplace_back(gsrev == 922 ? "-dREALLYDELAYBIND" : "-dDELAYBIND"); + _gs.init(gsargs.size(), gsargs.data(), this); _gs.set_stdio(input, output, error); _initialized = true; // Before executing any random PS code redefine some operators and run @@ -265,12 +263,14 @@ void PSInterpreter::callActions (InputReader &in) { {"makepattern", {-1, &PSActions::makepattern}}, {"moveto", { 2, &PSActions::moveto}}, {"newpath", { 1, &PSActions::newpath}}, + {"pdfpagebox", { 4, &PSActions::pdfpagebox}}, {"querypos", { 2, &PSActions::querypos}}, {"raw", {-1, nullptr}}, {"restore", { 1, &PSActions::restore}}, {"rotate", { 1, &PSActions::rotate}}, {"save", { 1, &PSActions::save}}, {"scale", { 2, &PSActions::scale}}, + {"setblendmode", { 1, &PSActions::setblendmode}}, {"setcmykcolor", { 4, &PSActions::setcmykcolor}}, {"setdash", {-1, &PSActions::setdash}}, {"setgray", { 1, &PSActions::setgray}}, @@ -281,6 +281,7 @@ void PSInterpreter::callActions (InputReader &in) { {"setmatrix", { 6, &PSActions::setmatrix}}, {"setmiterlimit", { 1, &PSActions::setmiterlimit}}, {"setopacityalpha",{ 1, &PSActions::setopacityalpha}}, + {"setshapealpha", { 1, &PSActions::setshapealpha}}, {"setpagedevice", { 0, &PSActions::setpagedevice}}, {"setpattern", {-1, &PSActions::setpattern}}, {"setrgbcolor", { 3, &PSActions::setrgbcolor}}, diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp index ae75152899e..2db857e0f61 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PSInterpreter.hpp @@ -55,11 +55,13 @@ struct PSActions { 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 pdfpagebox (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 setblendmode (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; @@ -70,10 +72,11 @@ struct PSActions { 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 setshapealpha (std::vector<double> &p) =0; virtual void setpagedevice (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 shfill (std::vector<double> &p) =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 @@ -113,15 +116,14 @@ class PSInterpreter { 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() + PSActions *_actions=nullptr; ///< actions to be performed + PSFilter *_filter=nullptr; ///< active filter used to process PS code + size_t _bytesToRead=0; ///< 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 + bool _inError=false; ///< true if scanning error message + bool _initialized=false; ///< 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 }; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp index 00cd7428757..10ed7d96a64 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.cpp @@ -24,11 +24,11 @@ using namespace std; -void PapersizeSpecialHandler::preprocess (const char*, std::istream &is, SpecialActions &actions) { +void PapersizeSpecialHandler::preprocess (const string&, std::istream &is, SpecialActions &actions) { string params; is >> params; Length w, h; - size_t splitpos = params.find(','); + const size_t splitpos = params.find(','); try { if (splitpos == string::npos) { w.set(params); @@ -45,7 +45,7 @@ void PapersizeSpecialHandler::preprocess (const char*, std::istream &is, Special } -bool PapersizeSpecialHandler::process (const char*, std::istream&, SpecialActions&) { +bool PapersizeSpecialHandler::process (const string&, std::istream&, SpecialActions&) { return true; } @@ -92,7 +92,7 @@ void PapersizeSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actio } -const vector<const char*> PapersizeSpecialHandler::prefixes () const { - const vector<const char*> pfx {"papersize="}; +vector<const char*> PapersizeSpecialHandler::prefixes() const { + vector<const char*> pfx {"papersize="}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp index c38b58cd649..ac5f42d9d2b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PapersizeSpecialHandler.hpp @@ -26,16 +26,16 @@ #include "Length.hpp" #include "SpecialHandler.hpp" -class PapersizeSpecialHandler : public SpecialHandler, public DVIEndPageListener { +class PapersizeSpecialHandler : public SpecialHandler { using DoublePair = std::pair<double,double>; // (width, height) using PageSize = std::pair<unsigned,DoublePair>; // page number -> (width, height) public: - void preprocess (const char *prefix, std::istream &is, SpecialActions &actions) override; - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + void preprocess (const std::string &prefix, std::istream &is, SpecialActions &actions) override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; const char* info () const override {return "special to set the page size";} const char* name () const override {return "papersize";} - const std::vector<const char*> prefixes () const override; + std::vector<const char*> prefixes() const override; void storePaperSize (unsigned pageno, Length width, Length height); void reset () {_pageSizes.clear();} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp index 06d1daadf5d..34da25efba9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.cpp @@ -39,10 +39,10 @@ using namespace std; using CmdHandler = void (PdfSpecialHandler::*)(StreamInputReader&, SpecialActions&); -void PdfSpecialHandler::preprocess (const char*, istream &is, SpecialActions &actions) { +void PdfSpecialHandler::preprocess (const string&, istream &is, SpecialActions &actions) { StreamInputReader ir(is); ir.skipSpace(); - string cmdstr = ir.getWord(); + const string cmdstr = ir.getWord(); static unordered_map<string, CmdHandler> commands = { {"bann", &PdfSpecialHandler::preprocessBeginAnn}, {"bannot", &PdfSpecialHandler::preprocessBeginAnn}, @@ -56,11 +56,11 @@ void PdfSpecialHandler::preprocess (const char*, istream &is, SpecialActions &ac } -bool PdfSpecialHandler::process (const char*, istream &is, SpecialActions &actions) { +bool PdfSpecialHandler::process (const string&, istream &is, SpecialActions &actions) { _active = true; StreamInputReader ir(is); ir.skipSpace(); - string cmdstr = ir.getWord(); + const string cmdstr = ir.getWord(); ir.skipSpace(); // dvipdfm(x) specials currently supported static unordered_map<string, CmdHandler> commands = { @@ -283,7 +283,7 @@ void PdfSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) { } -const vector<const char*> PdfSpecialHandler::prefixes () const { - const vector<const char*> pfx {"pdf:"}; +vector<const char*> PdfSpecialHandler::prefixes() const { + vector<const char*> pfx {"pdf:"}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp index 5027af86606..8e3b7ebb59a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PdfSpecialHandler.hpp @@ -25,13 +25,13 @@ class StreamInputReader; -class PdfSpecialHandler : public SpecialHandler, public DVIPositionListener, public DVIEndPageListener { +class PdfSpecialHandler : public SpecialHandler { public: const char* info () const override {return "PDF hyperlink, font map, and pagesize specials";} const char* name () const override {return "pdf";} - const std::vector<const char*> prefixes () const override; - void preprocess (const char *prefix, std::istream &is, SpecialActions &actions) override; - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + std::vector<const char*> prefixes() const override; + void preprocess (const std::string &prefix, std::istream &is, SpecialActions &actions) override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; protected: // handlers for corresponding PDF specials diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp index 238bacb2373..adb364855a4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Process.cpp @@ -76,8 +76,10 @@ bool Process::run (string *out) { if (!subprocess.run(_cmd, _paramstr)) return false; for (;;) { - if (out) + if (out) { + out->clear(); subprocess.readFromPipe(*out); + } Subprocess::State state = subprocess.state(); if (state != Subprocess::State::RUNNING) return state == Subprocess::State::FINISHED; @@ -133,12 +135,22 @@ bool Subprocess::readFromPipe (string &out) { return false; bool success=false; - DWORD len; - while (PeekNamedPipe(_pipeReadHandle, NULL, 0, NULL, &len, NULL) && len > 0) { // prevent blocking - char buf[4096]; - success = ReadFile(_pipeReadHandle, buf, sizeof(buf), &len, NULL); - if (success && len > 0) + bool processExited=false; + DWORD len=0; + while (PeekNamedPipe(_pipeReadHandle, NULL, 0, NULL, &len, NULL)) { // prevent blocking + if (len == 0) { + if (processExited) + break; + // process still busy + processExited = (!_childProcHandle || WaitForSingleObject(_childProcHandle, 100) != WAIT_TIMEOUT); + } + else { + char buf[4096]; + success = ReadFile(_pipeReadHandle, buf, sizeof(buf), &len, NULL); + if (!success || len == 0) + break; out.append(buf, len); + } } return success; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp index 8c5e7276ddb..f6aa64fc144 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.cpp @@ -18,12 +18,14 @@ ** along with this program; if not, see <http://www.gnu.org/licenses/>. ** *************************************************************************/ +#include <array> #include <cmath> #include <fstream> #include <memory> #include <sstream> #include "EPSFile.hpp" #include "FileFinder.hpp" +#include "FileSystem.hpp" #include "Message.hpp" #include "PathClipper.hpp" #include "PSPattern.hpp" @@ -34,18 +36,9 @@ #include "TensorProductPatch.hpp" #include "TriangularPatch.hpp" - using namespace std; -static inline double str2double (const string &str) { - double ret; - istringstream iss(str); - iss >> ret; - return ret; -} - - bool PsSpecialHandler::COMPUTE_CLIPPATHS_INTERSECTIONS = false; bool PsSpecialHandler::SHADING_SEGMENT_OVERLAP = false; int PsSpecialHandler::SHADING_SEGMENT_SIZE = 20; @@ -85,7 +78,8 @@ void PsSpecialHandler::initgraphics () { _linecap = _linejoin = 0; // butt end caps and miter joins _miterlimit = 4; _xmlnode = _savenode = nullptr; - _opacityalpha = 1; // fully opaque + _opacityalpha = _shapealpha = 1; // fully opaque + _blendmode = 0; // "normal" mode (no blending) _sx = _sy = _cos = 1.0; _pattern = nullptr; _currentcolor = Color::BLACK; @@ -170,17 +164,17 @@ void PsSpecialHandler::executeAndSync (istream &is, bool updatePos) { } -void PsSpecialHandler::preprocess (const char *prefix, istream &is, SpecialActions &actions) { +void PsSpecialHandler::preprocess (const string &prefix, istream &is, SpecialActions &actions) { initialize(); if (_psSection != PS_HEADERS) return; _actions = &actions; - if (*prefix == '!') { + if (prefix == "!") { _headerCode += "\n"; _headerCode += string(istreambuf_iterator<char>(is), istreambuf_iterator<char>()); } - else if (strcmp(prefix, "header=") == 0) { + else if (prefix == "header=") { // read and execute PS header file string fname; is >> fname; @@ -189,9 +183,9 @@ void PsSpecialHandler::preprocess (const char *prefix, istream &is, SpecialActio } -bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { +bool PsSpecialHandler::process (const string &prefix, istream &is, SpecialActions &actions) { // process PS headers only once (in prescan) - if (*prefix == '!' || strcmp(prefix, "header=") == 0) + if (prefix == "!" || prefix == "header=") return true; _actions = &actions; @@ -199,23 +193,23 @@ bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions if (_psSection != PS_BODY) enterBodySection(); - if (*prefix == '"' || strcmp(prefix, "pst:") == 0) { + if (prefix == "\"" || prefix == "pst:") { // read and execute literal PostScript code (isolated by a wrapping save/restore pair) moveToDVIPos(); _psi.execute("\n@beginspecial @setspecial "); executeAndSync(is, false); _psi.execute("\n@endspecial "); } - else if (strcmp(prefix, "psfile=") == 0 || strcmp(prefix, "PSfile=") == 0) { + else if (prefix == "psfile=" || prefix == "PSfile=" || prefix == "pdffile=") { if (_actions) { StreamInputReader in(is); - string fname = in.getQuotedString(in.peek() == '"' ? '"' : 0); + const string fname = in.getQuotedString(in.peek() == '"' ? '"' : 0); unordered_map<string,string> attr; in.parseAttributes(attr); - psfile(fname, attr); + imgfile(prefix == "pdffile=" ? FileType::PDF : FileType::EPS, fname, attr); } } - else if (strcmp(prefix, "ps::") == 0) { + else if (prefix == "ps::") { if (_actions) _actions->finishLine(); // reset DVI position on next DVI command if (is.peek() == '[') { @@ -266,46 +260,57 @@ bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions } -/** Handles psfile special. - * @param[in] fname EPS file to be included - * @param[in] attr attributes given with \\special psfile */ -void PsSpecialHandler::psfile (const string &fname, const unordered_map<string,string> &attr) { +/** Handles a psfile/pdffile special which places an external EPS/PDF graphic + * at the current DVI position. The lower left corner (llx,lly) of the + * given bounding box is placed at the DVI position. + * @param[in] filetype type of file to process (EPS or PDF) + * @param[in] fname EPS/PDF file to be included + * @param[in] attr attributes given with psfile/pdffile special */ +void PsSpecialHandler::imgfile (FileType filetype, const string &fname, const unordered_map<string,string> &attr) { const char *filepath = FileFinder::instance().lookup(fname, false); + if (!filepath && FileSystem::exists(fname)) + filepath = fname.c_str(); if (!filepath) { - Message::wstream(true) << "file '" << fname << "' not found in special 'psfile'\n"; + Message::wstream(true) << "file '" << fname << "' not found\n"; return; } unordered_map<string,string>::const_iterator it; - // bounding box of EPS figure (lower left and upper right corner) - double llx = (it = attr.find("llx")) != attr.end() ? str2double(it->second) : 0; - double lly = (it = attr.find("lly")) != attr.end() ? str2double(it->second) : 0; - double urx = (it = attr.find("urx")) != attr.end() ? str2double(it->second) : 0; - double ury = (it = attr.find("ury")) != attr.end() ? str2double(it->second) : 0; + // bounding box of EPS figure in PS point units (lower left and upper right corner) + double llx = (it = attr.find("llx")) != attr.end() ? stod(it->second) : 0; + double lly = (it = attr.find("lly")) != attr.end() ? stod(it->second) : 0; + double urx = (it = attr.find("urx")) != attr.end() ? stod(it->second) : 0; + double ury = (it = attr.find("ury")) != attr.end() ? stod(it->second) : 0; + + if (filetype == FileType::PDF && llx == 0 && lly == 0 && urx == 0 && ury == 0) { + _psi.execute("\n("+fname+")@getpdfpagebox "); + if (_pdfpagebox.valid()) { + llx = _pdfpagebox.minX(); + lly = _pdfpagebox.minY(); + urx = _pdfpagebox.maxX(); + ury = _pdfpagebox.maxY(); + } + } - // desired width/height of resulting figure - double rwi = (it = attr.find("rwi")) != attr.end() ? str2double(it->second)/10.0 : -1; - double rhi = (it = attr.find("rhi")) != attr.end() ? str2double(it->second)/10.0 : -1; + // desired width and height of the untransformed figure in PS point units + double rwi = (it = attr.find("rwi")) != attr.end() ? stod(it->second)/10.0 : -1; + double rhi = (it = attr.find("rhi")) != attr.end() ? stod(it->second)/10.0 : -1; if (rwi == 0 || rhi == 0 || urx-llx == 0 || ury-lly == 0) return; // user transformations (default values chosen according to dvips manual) - double hoffset = (it = attr.find("hoffset")) != attr.end() ? str2double(it->second) : 0; - double voffset = (it = attr.find("voffset")) != attr.end() ? str2double(it->second) : 0; -// double hsize = (it = attr.find("hsize")) != attr.end() ? str2double(it->second) : 612; -// double vsize = (it = attr.find("vsize")) != attr.end() ? str2double(it->second) : 792; - double hscale = (it = attr.find("hscale")) != attr.end() ? str2double(it->second) : 100; - double vscale = (it = attr.find("vscale")) != attr.end() ? str2double(it->second) : 100; - double angle = (it = attr.find("angle")) != attr.end() ? str2double(it->second) : 0; - - Matrix m(1); - m.rotate(angle).scale(hscale/100, vscale/100).translate(hoffset, voffset); - BoundingBox bbox(llx, lly, urx, ury); - bbox.transform(m); + // order of transformations: rotate, scale, translate/offset + double hoffset = (it = attr.find("hoffset")) != attr.end() ? stod(it->second) : 0; + double voffset = (it = attr.find("voffset")) != attr.end() ? stod(it->second) : 0; +// double hsize = (it = attr.find("hsize")) != attr.end() ? stod(it->second) : 612; +// double vsize = (it = attr.find("vsize")) != attr.end() ? stod(it->second) : 792; + double hscale = (it = attr.find("hscale")) != attr.end() ? stod(it->second) : 100; + double vscale = (it = attr.find("vscale")) != attr.end() ? stod(it->second) : 100; + double angle = (it = attr.find("angle")) != attr.end() ? stod(it->second) : 0; // compute factors to scale the bounding box to width rwi and height rhi - double sx = rwi/bbox.width(); - double sy = rhi/bbox.height(); + double sx = rwi/abs(llx-urx); + double sy = rhi/abs(lly-ury); if (sx == 0 || sy == 0) return; @@ -314,34 +319,32 @@ void PsSpecialHandler::psfile (const string &fname, const unordered_map<string,s if (sx < 0) sx = sy = 1.0; // neither rwi nor rhi set // save current DVI position - const double x = _actions->getX(); - const double y = _actions->getY(); + double x = _actions->getX(); + double y = _actions->getY(); // all following drawings are relative to (0,0) _actions->setX(0); _actions->setY(0); moveToDVIPos(); - // transform current DVI position and bounding box location - // according to current transformation matrix - DPair llTrans = _actions->getMatrix()*DPair(llx, -lly); - DPair urTrans = _actions->getMatrix()*DPair(urx, -ury); - DPair dviposTrans = _actions->getMatrix()*DPair(x, y); - auto groupNode = util::make_unique<XMLElementNode>("g"); // append following elements to this group _xmlnode = groupNode.get(); - _psi.execute("\n@beginspecial @setspecial /setpagedevice{@setpagedevice}def "); // enter \special environment - EPSFile epsfile(filepath); - _psi.limit(epsfile.pslength()); // limit the number of bytes going to be processed - _psi.execute(epsfile.istream()); // process EPS file - _psi.limit(0); // disable limitation - _psi.execute("\n@endspecial "); // leave special environment + _psi.execute( + "\n@beginspecial @setspecial" // enter special environment + "/setpagedevice{@setpagedevice}def" // activate processing of operator "setpagedevice" + "[1 0 0 -1 0 0] setmatrix" // don't apply outer PS transformations + "(" + string(filepath) + ")run " // execute file content + "@endspecial " // leave special environment + ); if (!groupNode->empty()) { // has anything been drawn? Matrix matrix(1); - matrix.rotate(angle).scale(hscale/100, vscale/100).translate(hoffset, voffset); - matrix.translate(-llTrans); - matrix.scale(sx, sy); // resize image to width "rwi" and height "rhi" - matrix.translate(dviposTrans); // move image to current DVI position + if (filetype == FileType::PDF) + matrix.translate(-llx, -lly).scale(1, -1); //.translate(0, lly); // flip vertically + else + matrix.translate(-llx, lly); + matrix.scale(sx, sy).rotate(-angle).scale(hscale/100, vscale/100); + matrix.translate(x+hoffset, y-voffset); // move image to current DVI position + matrix.rmultiply(_actions->getMatrix()); if (!matrix.isIdentity()) groupNode->addAttribute("transform", matrix.getSVG()); _actions->appendToPage(std::move(groupNode)); @@ -354,10 +357,12 @@ void PsSpecialHandler::psfile (const string &fname, const unordered_map<string,s moveToDVIPos(); // update bounding box - m.scale(sx, -sy); - m.translate(dviposTrans); - bbox = BoundingBox(DPair(0, 0), abs(urTrans-llTrans)); - bbox.transform(m); + BoundingBox bbox(0, 0, urx-llx, ury-lly); + Matrix matrix(1); + matrix.scale(sx, -sy).rotate(-angle).scale(hscale/100, vscale/100); + matrix.translate(x+hoffset, y-voffset); + matrix.rmultiply(_actions->getMatrix()); + bbox.transform(matrix); _actions->embed(bbox); } @@ -474,7 +479,8 @@ void PsSpecialHandler::setpagedevice (std::vector<double> &p) { _linewidth = 1; _linecap = _linejoin = 0; // butt end caps and miter joins _miterlimit = 4; - _opacityalpha = 1; // fully opaque + _opacityalpha = _shapealpha = 1; // fully opaque + _blendmode = 0; // "normal" mode (no blending) _sx = _sy = _cos = 1.0; _pattern = nullptr; _currentcolor = Color::BLACK; @@ -529,6 +535,17 @@ void PsSpecialHandler::closepath (vector<double>&) { } +static string css_blendmode_name (int mode) { + static const array<const char*,16> modenames = {{ + "normal", "multiply", "screen", "overlay", "soft-light", "hard-light", "color-dodge", "color-burn", + "darken", "lighten", "difference", "exclusion", "hue", "saturation", "color", "luminosity" + }}; + if (mode < 0 || mode > 15) + return ""; + return modenames[mode]; +} + + /** Draws the current path recorded by previously executed path commands (moveto, lineto,...). * @param[in] p not used */ void PsSpecialHandler::stroke (vector<double> &p) { @@ -578,8 +595,10 @@ void PsSpecialHandler::stroke (vector<double> &p) { path->addAttribute("stroke-linecap", _linecap == 1 ? "round" : "square"); if (_linejoin > 0) // default value is "miter", no need to set it explicitly path->addAttribute("stroke-linejoin", _linecap == 1 ? "round" : "bevel"); - if (_opacityalpha < 1) - path->addAttribute("stroke-opacity", _opacityalpha); + if (_opacityalpha < 1 || _shapealpha < 1) + path->addAttribute("stroke-opacity", _opacityalpha*_shapealpha); + if (_blendmode > 0 && _blendmode < 16) + path->addAttribute("style", "mix-blend-mode:"+css_blendmode_name(_blendmode)); if (!_dashpattern.empty()) { ostringstream oss; for (size_t i=0; i < _dashpattern.size(); i++) { @@ -647,8 +666,10 @@ void PsSpecialHandler::fill (vector<double> &p, bool evenodd) { } if (evenodd) // SVG default fill rule is "nonzero" algorithm path->addAttribute("fill-rule", "evenodd"); - if (_opacityalpha < 1) - path->addAttribute("fill-opacity", _opacityalpha); + if (_opacityalpha < 1 || _shapealpha < 1) + path->addAttribute("fill-opacity", _opacityalpha*_shapealpha); + if (_blendmode > 0 && _blendmode < 16) + path->addAttribute("style", "mix-blend-mode:"+css_blendmode_name(_blendmode)); if (_xmlnode) _xmlnode->append(std::move(path)); else { @@ -1246,9 +1267,10 @@ void PsSpecialHandler::ClippingStack::dup (int saveID) { } -const vector<const char*> PsSpecialHandler::prefixes () const { - const vector<const char*> pfx { +vector<const char*> PsSpecialHandler::prefixes() const { + vector<const char*> pfx { "header=", // read and execute PS header file prior to the following PS statements + "pdffile=", // process PDF file "psfile=", // read and execute PS file "PSfile=", // dito "ps:", // execute literal PS code wrapped by @beginspecial and @endspecial diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp index a9683be77d6..1a16412fbb2 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/PsSpecialHandler.hpp @@ -36,7 +36,7 @@ class PSPattern; class XMLElementNode; -class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, protected PSActions { +class PsSpecialHandler : public SpecialHandler, protected PSActions { using Path = GraphicsPath<double>; using ColorSpace = Color::ColorSpace; @@ -76,15 +76,16 @@ class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, prote }; enum PsSection {PS_NONE, PS_HEADERS, PS_BODY}; + enum class FileType {EPS, PDF}; public: PsSpecialHandler (); ~PsSpecialHandler (); const char* name () const override {return "ps";} const char* info () const override {return "dvips PostScript specials";} - const std::vector<const char*> prefixes () const override; - void preprocess (const char *prefix, std::istream &is, SpecialActions &actions) override; - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + std::vector<const char*> prefixes() const override; + void preprocess (const std::string &prefix, std::istream &is, SpecialActions &actions) override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; void setDviScaleFactor (double dvi2bp) override {_previewFilter.setDviScaleFactor(dvi2bp);} void enterBodySection (); @@ -100,7 +101,7 @@ class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, prote void moveToDVIPos (); void executeAndSync (std::istream &is, bool updatePos); void processHeaderFile (const char *fname); - void psfile (const std::string &fname, const std::unordered_map<std::string,std::string> &attr); + void imgfile (FileType type, const std::string &fname, const std::unordered_map<std::string,std::string> &attr); void dviEndPage (unsigned pageno, SpecialActions &actions) override; void clip (Path &path, bool evenodd); void processSequentialPatchMesh (int shadingTypeID, ColorSpace cspace, VectorIterator<double> &it); @@ -127,11 +128,13 @@ class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, prote void makepattern (std::vector<double> &p) override; void moveto (std::vector<double> &p) override; void newpath (std::vector<double> &p) override; + void pdfpagebox (std::vector<double> &p) override {_pdfpagebox = BoundingBox(p[0], p[1], p[2], p[3]);} void querypos (std::vector<double> &p) override {_currentpoint = DPair(p[0], p[1]);} void restore (std::vector<double> &p) override; void rotate (std::vector<double> &p) override; void save (std::vector<double> &p) override; void scale (std::vector<double> &p) override; + void setblendmode (std::vector<double> &p) override {_blendmode = int(p[0]);} void setcmykcolor (std::vector<double> &cmyk) override; void setdash (std::vector<double> &p) override; void setgray (std::vector<double> &p) override; @@ -142,6 +145,7 @@ class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, prote void setmatrix (std::vector<double> &p) override; void setmiterlimit (std::vector<double> &p) override {_miterlimit = p[0];} void setopacityalpha (std::vector<double> &p) override {_opacityalpha = p[0];} + void setshapealpha (std::vector<double> &p) override {_shapealpha = p[0];} void setpagedevice (std::vector<double> &p) override; void setpattern (std::vector<double> &p) override; void setrgbcolor (std::vector<double> &rgb) override; @@ -166,6 +170,8 @@ class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, prote double _linewidth; ///< current line width in bp units double _miterlimit; ///< current miter limit in bp units double _opacityalpha; ///< opacity level (0=fully transparent, ..., 1=opaque) + double _shapealpha; ///< shape opacity level (0=fully transparent, ..., 1=opaque) + int _blendmode; ///< blend mode used when overlaying colored areas uint8_t _linecap : 2; ///< current line cap (0=butt, 1=round, 2=projecting square) uint8_t _linejoin : 2; ///< current line join (0=miter, 1=round, 2=bevel) double _dashoffset; ///< current dash offset @@ -173,6 +179,7 @@ class PsSpecialHandler : public SpecialHandler, public DVIEndPageListener, prote ClippingStack _clipStack; std::unordered_map<int, std::unique_ptr<PSPattern>> _patterns; PSTilingPattern *_pattern; ///< current pattern + BoundingBox _pdfpagebox; }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp index ea5f8d64a6e..c96aa1029bf 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/RangeMap.cpp @@ -125,11 +125,11 @@ void RangeMap::addRange (uint32_t cmin, uint32_t cmax, uint32_t vmin) { void RangeMap::adaptNeighbors (Ranges::iterator it) { if (it != _ranges.end()) { // adapt left neighbor - if (it != _ranges.begin() && it->min() <= (it-1)->max()) { - Ranges::iterator lit = it-1; // points to left neighbor + Ranges::iterator lit = it-1; // points to left neighbor + if (it != _ranges.begin() && it->min() <= lit->max()) { bool left_neighbor_valid = (it->min() > 0 && it->min()-1 >= lit->min()); - if (left_neighbor_valid) // is adapted left neighbor valid? - lit->max(it->min()-1); // => assign new max value + if (left_neighbor_valid) // is adapted left neighbor valid? + lit->max(it->min()-1); // => assign new max value if (!left_neighbor_valid || it->join(*lit)) it = _ranges.erase(lit); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp index f65d4e85181..a13cc775728 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp @@ -33,8 +33,9 @@ using namespace std; -SVGOutput::SVGOutput (const char *base, const string &pattern, int zipLevel) - : _path(base ? base : ""), _pattern(pattern), _stdout(base == 0), _zipLevel(zipLevel), _page(-1) + +SVGOutput::SVGOutput (const string &base, const string &pattern, int zipLevel) + : _path(base), _pattern(pattern), _stdout(base.empty()), _zipLevel(zipLevel), _page(-1) { } @@ -46,17 +47,24 @@ SVGOutput::SVGOutput (const char *base, const string &pattern, int zipLevel) ostream& SVGOutput::getPageStream (int page, int numPages) const { string fname = filename(page, numPages); if (fname.empty()) { - _osptr.reset(); - return cout; + if (_zipLevel == 0) { + _osptr.reset(); + return cout; + } +#ifdef _WIN32 + if (_setmode(_fileno(stdout), _O_BINARY) == -1) + throw MessageException("can't open stdout in binary mode"); +#endif + return *(_osptr = util::make_unique<ZLibOutputStream>(cout, ZLIB_GZIP, _zipLevel)); } if (page == _page) return *_osptr; _page = page; if (_zipLevel > 0) - _osptr = util::make_unique<ZLibOutputStream>(fname, _zipLevel); + _osptr = util::make_unique<ZLibOutputFileStream>(fname, ZLIB_GZIP, _zipLevel); else - _osptr = util::make_unique<ofstream>(fname.c_str()); + _osptr = util::make_unique<ofstream>(fname); if (!_osptr) throw MessageException("can't open file "+fname+" for writing"); return *_osptr; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp index a24f09821e6..a19501e5523 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp @@ -31,20 +31,17 @@ struct SVGOutputBase { virtual ~SVGOutputBase () =default; virtual std::ostream& getPageStream (int page, int numPages) const =0; virtual std::string filename (int page, int numPages) const =0; -// virtual std::string outpath (int page, int numPages) const =0; }; -class SVGOutput : public SVGOutputBase -{ +class SVGOutput : public SVGOutputBase { public: - SVGOutput () : SVGOutput(0, "", 0) {} - SVGOutput (const char *base) : SVGOutput(base, "", 0) {} - SVGOutput (const char *base, const std::string &pattern) : SVGOutput(base, pattern, 0) {} - SVGOutput (const char *base, const std::string &pattern, int zipLevel); + SVGOutput () : SVGOutput("", "", 0) {} + SVGOutput (const std::string &base) : SVGOutput(base, "", 0) {} + SVGOutput (const std::string &base, const std::string &pattern) : SVGOutput(base, pattern, 0) {} + SVGOutput (const std::string &base, const std::string &pattern, int zipLevel); std::ostream& getPageStream (int page, int numPages) const override; std::string filename (int page, int numPages) const override; -// std::string outpath (int page, int numPages) const override; protected: std::string expandFormatString (std::string str, int page, int numPages) const; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp new file mode 100644 index 00000000000..96efb50a875 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.cpp @@ -0,0 +1,123 @@ +/************************************************************************* +** SourceInput.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** 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 ** +** 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/>. ** +*************************************************************************/ + +#include <fstream> +#include <iostream> +#include "FileSystem.hpp" +#include "Message.hpp" +#include "MessageException.hpp" +#include "SourceInput.hpp" +#include "utility.hpp" + +#ifdef _WIN32 +#include <fcntl.h> +#include <sys/stat.h> +#include <windows.h> +#endif + +#ifdef _MSC_VER +#include <io.h> +#else +#include <cstdlib> +#include <unistd.h> +#endif + +using namespace std; + +#ifdef _WIN32 +static int fdwrite (int fd, const char *buf, size_t len) {return _write(fd, buf, len);} +static int fdclose (int fd) {return _close(fd);} +#else +static int fdwrite (int fd, const char *buf, size_t len) {return write(fd, buf, len);} +static int fdclose (int fd) {return close(fd);} +#endif + + +SourceInput::~SourceInput () { + // remove temporary file created for reading from stdin + if (!_tmpfilepath.empty()) + FileSystem::remove(_tmpfilepath); +} + + +/** Creates a temporary file in the configured tmp folder. + * @param[out] path path of the created file + * @return file descriptor (>= 0 on success) */ +static int create_tmp_file (string &path) { + path = FileSystem::tmpdir(); +#ifndef _WIN32 + path += "stdinXXXXXX"; + int fd = mkstemp(&path[0]); +#else + int fd = -1; + char fname[MAX_PATH]; + std::replace(path.begin(), path.end(), '/', '\\'); + if (GetTempFileName(path.c_str(), "stdin", 0, fname)) { + fd = _open(fname, _O_CREAT | _O_WRONLY | _O_BINARY, _S_IWRITE); + path = fname; + } +#endif + return fd; +} + + +istream& SourceInput::getInputStream (bool showMessages) { + if (!_ifs.is_open()) { + if (!_fname.empty()) + _ifs.open(_fname, ios::binary); + else { + int fd = create_tmp_file(_tmpfilepath); + if (fd < 0) + throw MessageException("can't create temporary file for writing"); +#ifdef _WIN32 + if (_setmode(_fileno(stdin), _O_BINARY) == -1) + throw MessageException("can't open stdin in binary mode"); +#endif + if (showMessages) + Message::mstream() << "reading from " << getMessageFileName() << '\n'; + char buf[1024]; + while (cin) { + cin.read(buf, 1024); + size_t count = cin.gcount(); + if (fdwrite(fd, buf, count) < 0) + throw MessageException("failed to write data to temporary file"); + } + if (fdclose(fd) < 0) + throw MessageException("failed to close temporary file"); + _ifs.open(_tmpfilepath, ios::binary); + } + } + return _ifs; +} + + +string SourceInput::getFileName () const { + return _fname.empty() ? "stdin" : _fname; +} + + +string SourceInput::getMessageFileName () const { + return _fname.empty() ? "<stdin>" : _fname; +} + + +string SourceInput::getFilePath () const { + return _tmpfilepath.empty() ? _fname : _tmpfilepath; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp new file mode 100644 index 00000000000..95f496a60a2 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SourceInput.hpp @@ -0,0 +1,42 @@ +/************************************************************************* +** SourceInput.hpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** 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 ** +** 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 DVIINPUT_HPP +#define DVIINPUT_HPP + +#include <fstream> +#include <string> + +class SourceInput { + public: + SourceInput (const std::string &fname) : _fname(fname) {} + ~SourceInput (); + std::istream& getInputStream (bool showMessages=false); + std::string getFileName () const; + std::string getMessageFileName () const; + std::string getFilePath () const; + + private: + const std::string &_fname; ///< name of file to read from + std::string _tmpfilepath; ///< path of temporary file used when reading from stdin + std::ifstream _ifs; +}; + +#endif
\ No newline at end of file diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp index e08bcd6092d..e121e16ef61 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialHandler.hpp @@ -36,41 +36,20 @@ struct SpecialException : public MessageException { }; -struct DVIPreprocessingListener { - virtual ~DVIPreprocessingListener () =default; - virtual void dviPreprocessingFinished () =0; -}; - - -struct DVIBeginPageListener { - virtual ~DVIBeginPageListener () =default; - virtual void dviBeginPage (unsigned pageno, SpecialActions &actions) =0; -}; - - -struct DVIEndPageListener { - virtual ~DVIEndPageListener () =default; - virtual void dviEndPage (unsigned pageno, SpecialActions &actions) =0; -}; - - -struct DVIPositionListener { - virtual ~DVIPositionListener () =default; - virtual void dviMovedTo (double x, double y, SpecialActions &actions) =0; -}; - - class SpecialHandler { friend class SpecialManager; public: virtual ~SpecialHandler () =default; virtual const char* info () const=0; virtual const char* name () const=0; - virtual const std::vector<const char*> prefixes () const=0; + virtual std::vector<const char*> prefixes() const =0; virtual void setDviScaleFactor (double dvi2bp) {} - virtual void preprocess (const char *prefix, std::istream &is, SpecialActions &actions) {} - virtual bool process (const char *prefix, std::istream &is, SpecialActions &actions)=0; + virtual void preprocess (const std::string &prefix, std::istream &is, SpecialActions &actions) {} + virtual bool process (const std::string &prefix, std::istream &is, SpecialActions &actions)=0; + virtual void dviPreprocessingFinished () {} + virtual void dviBeginPage (unsigned pageno, SpecialActions &actions) {} + virtual void dviEndPage (unsigned pageno, SpecialActions &actions) {} + virtual void dviMovedTo (double x, double y, SpecialActions &actions) {} }; - #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp index 7b0c66c9b5b..632065de31a 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.cpp @@ -40,10 +40,6 @@ SpecialManager& SpecialManager::instance() { void SpecialManager::unregisterHandlers () { _handlerPool.clear(); _handlersByPrefix.clear(); - _beginPageListeners.clear(); - _endPageListeners.clear(); - _preprocListeners.clear(); - _positionListeners.clear(); } @@ -55,15 +51,6 @@ void SpecialManager::registerHandler (unique_ptr<SpecialHandler> &&handler) { // get array of prefixes this handler is responsible for for (const char *prefix : handler->prefixes()) _handlersByPrefix[prefix] = handler.get(); - // initialize listener vectors - if (auto listener = dynamic_cast<DVIPreprocessingListener*>(handler.get())) - _preprocListeners.push_back(listener); - if (auto listener = dynamic_cast<DVIBeginPageListener*>(handler.get())) - _beginPageListeners.push_back(listener); - if (auto listener = dynamic_cast<DVIEndPageListener*>(handler.get())) - _endPageListeners.push_back(listener); - if (auto listener = dynamic_cast<DVIPositionListener*>(handler.get())) - _positionListeners.push_back(listener); _handlerPool.emplace_back(std::move(handler)); } } @@ -128,9 +115,9 @@ static string extract_prefix (istream &is) { void SpecialManager::preprocess (const string &special, SpecialActions &actions) const { istringstream iss(special); - string prefix = extract_prefix(iss); + const string prefix = extract_prefix(iss); if (SpecialHandler *handler = findHandlerByPrefix(prefix)) - handler->preprocess(prefix.c_str(), iss, actions); + handler->preprocess(prefix, iss, actions); } @@ -142,37 +129,37 @@ void SpecialManager::preprocess (const string &special, SpecialActions &actions) * @throw SpecialException in case of errors during special processing */ bool SpecialManager::process (const string &special, double dvi2bp, SpecialActions &actions) const { istringstream iss(special); - string prefix = extract_prefix(iss); + const string prefix = extract_prefix(iss); bool success=false; if (SpecialHandler *handler = findHandlerByPrefix(prefix)) { handler->setDviScaleFactor(dvi2bp); - success = handler->process(prefix.c_str(), iss, actions); + success = handler->process(prefix, iss, actions); } return success; } void SpecialManager::notifyPreprocessingFinished () const { - for (auto *listener : _preprocListeners) - listener->dviPreprocessingFinished(); + for (auto &handler : _handlerPool) + handler->dviPreprocessingFinished(); } void SpecialManager::notifyBeginPage (unsigned pageno, SpecialActions &actions) const { - for (auto *listener : _beginPageListeners) - listener->dviBeginPage(pageno, actions); + for (auto &handler : _handlerPool) + handler->dviBeginPage(pageno, actions); } void SpecialManager::notifyEndPage (unsigned pageno, SpecialActions &actions) const { - for (auto *listener : _endPageListeners) - listener->dviEndPage(pageno, actions); + for (auto &handler : _handlerPool) + handler->dviEndPage(pageno, actions); } void SpecialManager::notifyPositionChange (double x, double y, SpecialActions &actions) const { - for (auto *listener : _positionListeners) - listener->dviMovedTo(x, y, actions); + for (auto &handler : _handlerPool) + handler->dviMovedTo(x, y, actions); } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp index 250ebef082b..207a0a2e548 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SpecialManager.hpp @@ -57,10 +57,6 @@ class SpecialManager { private: HandlerPool _handlerPool; ///< stores pointers to all handlers HandlerMap _handlersByPrefix; ///< pointers to handlers for corresponding prefixes - std::vector<DVIPreprocessingListener*> _preprocListeners; - std::vector<DVIBeginPageListener*> _beginPageListeners; - std::vector<DVIEndPageListener*> _endPageListeners; - std::vector<DVIPositionListener*> _positionListeners; }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp index 9b5baf9ef12..5cd1dc7315c 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.cpp @@ -272,14 +272,14 @@ constexpr int cmd_id (const char *cmd) { }; -bool TpicSpecialHandler::process (const char *prefix, istream &is, SpecialActions &actions) { - if (!prefix || strlen(prefix) != 2) +bool TpicSpecialHandler::process (const string &prefix, istream &is, SpecialActions &actions) { + if (prefix.length() != 2) return false; _dviColor = actions.getColor(); const double mi2bp=0.072; // factor for milli-inch to PS points StreamInputBuffer ib(is); BufferInputReader ir(ib); - switch (cmd_id(prefix)) { + switch (cmd_id(prefix.c_str())) { case cmd_id("pn"): // set pen width in milli-inches _penwidth = max(0.0, ir.getDouble()*mi2bp); break; @@ -358,7 +358,7 @@ bool TpicSpecialHandler::process (const char *prefix, istream &is, SpecialAction } -const vector<const char*> TpicSpecialHandler::prefixes () const { - const vector<const char*> pfx {"ar", "bk", "da", "dt", "fp", "ia", "ip", "pa", "pn", "sh", "sp", "tx", "wh"}; +vector<const char*> TpicSpecialHandler::prefixes() const { + vector<const char*> pfx {"ar", "bk", "da", "dt", "fp", "ia", "ip", "pa", "pn", "sh", "sp", "tx", "wh"}; return pfx; } diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp index 2bbc8182b12..a9772b3f398 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/TpicSpecialHandler.hpp @@ -25,14 +25,13 @@ #include "Pair.hpp" #include "SpecialHandler.hpp" -class TpicSpecialHandler : public SpecialHandler, public DVIEndPageListener -{ +class TpicSpecialHandler : public SpecialHandler { public: TpicSpecialHandler (); const char* info () const override {return "TPIC specials";} const char* name () const override {return "tpic";} - const std::vector<const char*> prefixes () const override; - bool process (const char *prefix, std::istream &is, SpecialActions &actions) override; + std::vector<const char*> prefixes() const override; + bool process (const std::string &prefix, std::istream &is, SpecialActions &actions) override; double penwidth () const {return _penwidth;} double grayLevel () const {return _grayLevel;} Color fillColor (bool grayOnly) const; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp index 4a0b2fa52e2..c03db71742d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/ZLibOutputStream.hpp @@ -21,100 +21,161 @@ #ifndef ZLIBOUTPUTSTREAM_HPP #define ZLIBOUTPUTSTREAM_HPP +#include <fstream> #include <ostream> +#include <vector> #include <zlib.h> +#include "MessageException.hpp" -class ZLibOutputStream; +#ifdef _WIN32 +# include <fcntl.h> +# include <io.h> +#endif + +struct ZLibException : public MessageException { + ZLibException (const std::string &msg) : MessageException(msg) {} +}; -class ZLibOutputBuffer : public std::streambuf -{ - friend class ZLibOutputStream; +enum ZLibCompressionFormat {ZLIB_DEFLATE=0, ZLIB_GZIP=16}; + +class ZLibOutputBuffer : public std::streambuf { public: - ~ZLibOutputBuffer () {close();} + ZLibOutputBuffer () {} + + ZLibOutputBuffer (std::streambuf *sbuf, ZLibCompressionFormat format, int zipLevel) { + open(sbuf, format, zipLevel); + } - /** Opens the buffer object for writing. - * @param[in] fname name of gzip file + ~ZLibOutputBuffer () { + close(); + } + + /** Opens the buffer for writing. + * @param[in] sink stream buffer taking the compressed data + * @param[in] format compression format (deflate or gzip) * @param[in] zipLevel compression level (1-9) - * @return true on success */ - bool open (const char *fname, int zipLevel) { - if (_opened) - return false; - zipLevel = std::max(1, std::min(9, zipLevel)); - std::string modestr = "wb0"; - modestr[2] += zipLevel; - _gzfile = gzopen(fname, modestr.c_str()); - return _opened = (_gzfile != nullptr); + * @return true if buffer is ready for writing */ + bool open (std::streambuf *sink, ZLibCompressionFormat format, int zipLevel) { + if (sink) { + _inbuf.reserve(4096); + _zbuf.resize(4096); + _zstream.zalloc = Z_NULL; + _zstream.zfree = Z_NULL; + _zstream.opaque = Z_NULL; + zipLevel = std::max(1, std::min(9, zipLevel)); + if (deflateInit2(&_zstream, zipLevel, Z_DEFLATED, 15+format, 8, Z_DEFAULT_STRATEGY) != Z_OK) + throw ZLibException("failed to initialize deflate compression"); + _sink = sink; + _opened = true; + } + return _opened; } - /** Closes the buffer object. */ - bool close () { - if (!_opened) - return false; - sync(); - _opened = false; - return gzclose(_gzfile) == Z_OK; + /** Flushes the remaining data, finishes the compression process, and + * closes the buffer so that further output doesn't reach the sink. */ + void close () { + close(true); } - int overflow (int c) override { - if (!_opened) - return EOF; - if (c != EOF) { - *pptr() = c; - pbump(1); + int_type overflow (int_type c) override { + if (c == traits_type::eof()) { + close(); + } + else { + if (_inbuf.size() == _inbuf.capacity()) + flush(Z_NO_FLUSH); + _inbuf.push_back(c); } - return (flush() == EOF) ? EOF : c; + return c; } int sync () override { - return (pptr() && pptr() > pbase() && flush() == EOF) ? -1 : 0; + flush(Z_NO_FLUSH); + return 0; } protected: - ZLibOutputBuffer () : _gzfile(nullptr), _opened(false) { - setp(_buffer, _buffer+SIZE-1); + /** Compresses the chunk of data present in the input buffer + * and writes it to the assigned output stream. + * @param[in] flushmode flush mode of deflate function (Z_NO_FLUSH or Z_FINISH) + * @throws ZLibException if compression failed */ + void flush (int flushmode) { + if (_opened) { + _zstream.avail_in = _inbuf.size(); + _zstream.next_in = _inbuf.data(); + do { + _zstream.avail_out = _zbuf.size(); + _zstream.next_out = _zbuf.data(); + int ret = deflate(&_zstream, flushmode); + if (ret == Z_STREAM_ERROR) { + close(false); + throw ZLibException("stream error during data compression"); + } + auto have = _zbuf.size()-_zstream.avail_out; + _sink->sputn(reinterpret_cast<char*>(_zbuf.data()), have); + } while (_zstream.avail_out == 0); + } + _inbuf.clear(); } - /** Forces to write the buffer data to the output file. */ - int flush () { - int w = pptr()-pbase(); - if (gzwrite(_gzfile, pbase(), w) != w) - return EOF; - pbump(-w); - return w; + /** Closes the buffer so that further output doesn't reach the sink. + * @param[in] finish if true, flushes the remaining data and finishes the compression process */ + void close (bool finish) { + if (_opened) { + if (finish) + flush(Z_FINISH); + deflateEnd(&_zstream); + _sink = nullptr; + _opened = false; + } } private: - static constexpr int SIZE = 512; - gzFile _gzfile; - char _buffer[SIZE]; - bool _opened; + z_stream _zstream; + std::streambuf *_sink = nullptr; ///< target buffer where the compressded data is flushed to + std::vector<Bytef> _inbuf; ///< buffer holding a chunk of data to be compressed + std::vector<Bytef> _zbuf; ///< buffer holding a chunk of compressed data + bool _opened = false; ///< true if ready to process the incoming data correctly }; -class ZLibOutputStream : public virtual std::ios, public std::ostream -{ +class ZLibOutputStream : private ZLibOutputBuffer, public std::ostream { public: - ZLibOutputStream () : std::ostream(&_buf) {init(&_buf);} - ZLibOutputStream (const char *fname, int zipLevel) : ZLibOutputStream() {open(fname, zipLevel);} - ZLibOutputStream (const std::string &fname, int zipLevel) : ZLibOutputStream(fname.c_str(), zipLevel) {} + ZLibOutputStream () : std::ostream(this) {} + + ZLibOutputStream (std::ostream &os, ZLibCompressionFormat format, int zipLevel) + : ZLibOutputBuffer(os.rdbuf(), format, zipLevel), std::ostream(this) {} + ~ZLibOutputStream () {close();} - ZLibOutputBuffer* rdbuf() {return &_buf;} - - /** Opens the output stream for writing. - * @param[in] fname name of gzip file - * @param[in] zipLevel compression level (1-9) */ - void open (const char *name, int zipLevel) { - if (!_buf.open(name, zipLevel)) - clear(rdstate()|std::ios::badbit); + + bool open (std::ostream &os, ZLibCompressionFormat format, int zipLevel) { + ZLibOutputBuffer::close(); + return ZLibOutputBuffer::open(os.rdbuf(), format, zipLevel); } void close () { - if (!_buf.close()) - clear(rdstate()|std::ios::badbit); + ZLibOutputBuffer::close(); } +}; + + +class ZLibOutputFileStream : public ZLibOutputStream { + public: + ZLibOutputFileStream (const std::string &fname, ZLibCompressionFormat format, int zipLevel) + : _ofs(fname, std::ios::binary) + { + if (_ofs) { + if (_ofs.rdbuf()) + open(_ofs, format, zipLevel); + else + _ofs.close(); + } + } + + ~ZLibOutputFileStream () {close();} private: - ZLibOutputBuffer _buf; + std::ofstream _ofs; }; #endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp index f333cbbdb90..d778c84c5f9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp @@ -40,9 +40,11 @@ #include "HyperlinkManager.hpp" #include "Message.hpp" #include "PageSize.hpp" +#include "PDFToSVG.hpp" #include "PSInterpreter.hpp" #include "PsSpecialHandler.hpp" #include "SignalHandler.hpp" +#include "SourceInput.hpp" #include "SVGOutput.hpp" #include "System.hpp" #include "utility.hpp" @@ -68,10 +70,12 @@ static string remove_path (string fname) { } -static string ensure_suffix (string fname, bool eps) { - size_t dotpos = remove_path(fname).rfind('.'); - if (dotpos == string::npos) - fname += (eps ? ".eps" : ".dvi"); +static string ensure_suffix (string fname, const string &suffix) { + if (!fname.empty()) { + size_t dotpos = remove_path(fname).rfind('.'); + if (dotpos == string::npos) + fname += "." + suffix; + } return fname; } @@ -143,30 +147,21 @@ static bool set_temp_dir (const CommandLine &args) { } -static bool check_bbox (const string &bboxstr) { +static void check_bbox (const string &bboxstr) { for (const char *fmt : {"none", "min", "preview", "papersize", "dvi"}) if (bboxstr == fmt) - return true; + return; if (isalpha(bboxstr[0])) { try { PageSize size(bboxstr); - return true; } catch (const PageSizeException &e) { - Message::estream(true) << "invalid bounding box format '" << bboxstr << "'\n"; - return false; + throw MessageException("invalid bounding box format '" + bboxstr + "'"); } } - try { - // check if given bbox argument is valid, i.e. doesn't throw an exception - BoundingBox bbox; - bbox.set(bboxstr); - return true; - } - catch (const MessageException &e) { - Message::estream(true) << e.what() << '\n'; - return false; - } + // check if given bbox argument is valid, i.e. doesn't throw an exception + BoundingBox bbox; + bbox.set(bboxstr); } @@ -254,7 +249,7 @@ static void print_version (bool extended) { versionInfo.add("potrace", strchr(potrace_version(), ' ')); versionInfo.add("xxhash", XXH_versionNumber(), 3, 100); versionInfo.add("zlib", zlibVersion()); - versionInfo.add("Ghostscript", Ghostscript().revision(true), true); + versionInfo.add("Ghostscript", Ghostscript().revisionstr(), true); #ifndef DISABLE_WOFF versionInfo.add("brotli", BrotliEncoderVersion(), 3, 0x1000); versionInfo.add("woff2", woff2::version, 3, 0x100); @@ -326,8 +321,8 @@ static void set_variables (const CommandLine &cmdline) { int main (int argc, char *argv[]) { - CommandLine cmdline; try { + CommandLine cmdline; cmdline.parse(argc, argv); if (argc == 1 || cmdline.helpOpt.given()) { cmdline.help(cout, cmdline.helpOpt.value()); @@ -346,47 +341,47 @@ int main (int argc, char *argv[]) { } if (!set_cache_dir(cmdline) || !set_temp_dir(cmdline)) return 0; - if (cmdline.stdoutOpt.given() && cmdline.zipOpt.given()) { - Message::estream(true) << "writing SVGZ files to stdout is not supported\n"; - return 1; - } - if (!check_bbox(cmdline.bboxOpt.value())) - return 1; + check_bbox(cmdline.bboxOpt.value()); if (!HyperlinkManager::setLinkMarker(cmdline.linkmarkOpt.value())) Message::wstream(true) << "invalid argument '"+cmdline.linkmarkOpt.value()+"' supplied for option --linkmark\n"; - if (argc > 1 && cmdline.filenames().size() < 1) { - Message::estream(true) << "no input file given\n"; - return 1; + if (cmdline.stdinOpt.given() || cmdline.singleDashGiven()) { + if (!cmdline.filenames().empty()) + throw MessageException("option - or --stdin can't be used together with a filename"); + cmdline.addFilename(""); // empty filename => read from stdin } - } - catch (MessageException &e) { - Message::estream() << e.what() << '\n'; - return 1; - } + if (argc > 1 && cmdline.filenames().empty()) + throw MessageException("no input file given"); + + SignalHandler::instance().start(); + string inputfile = ensure_suffix(cmdline.filenames()[0], + cmdline.epsOpt.given() ? "eps" : cmdline.pdfOpt.given() ? "pdf" : "dvi"); + SourceInput srcin(inputfile); + if (!srcin.getInputStream(true)) + throw MessageException("can't open file '" + srcin.getMessageFileName() + "' for reading"); - bool eps_given = cmdline.epsOpt.given(); - string inputfile = ensure_suffix(cmdline.filenames()[0], eps_given); - ifstream ifs(inputfile.c_str(), ios::binary|ios::in); - if (!ifs) { - Message::estream(true) << "can't open file '" << inputfile << "' for reading\n"; - return 0; - } - try { double start_time = System::time(); set_variables(cmdline); - SVGOutput out(cmdline.stdoutOpt.given() ? nullptr : inputfile.c_str(), + SVGOutput out(cmdline.stdoutOpt.given() ? "" : srcin.getFileName(), cmdline.outputOpt.value(), cmdline.zipOpt.given() ? cmdline.zipOpt.value() : 0); - SignalHandler::instance().start(); - if (cmdline.epsOpt.given()) { - EPSToSVG eps2svg(inputfile, out); - eps2svg.convert(); + if (cmdline.epsOpt.given() || cmdline.pdfOpt.given()) { + auto img2svg = unique_ptr<ImageToSVG>( + cmdline.epsOpt.given() + ? static_cast<ImageToSVG*>(new EPSToSVG(srcin.getFilePath(), out)) + : static_cast<ImageToSVG*>(new PDFToSVG(srcin.getFilePath(), out))); + img2svg->convert(); + Message::mstream().indent(0); + Message::mstream(false, Message::MC_PAGE_NUMBER) << "file converted in " << (System::time()-start_time) << " seconds\n"; + } + else if (cmdline.pdfOpt.given()) { + PDFToSVG pdf2svg(srcin.getFilePath(), out); + pdf2svg.convert(); Message::mstream().indent(0); Message::mstream(false, Message::MC_PAGE_NUMBER) << "file converted in " << (System::time()-start_time) << " seconds\n"; } else { init_fontmap(cmdline); - DVIToSVG dvi2svg(ifs, out); + DVIToSVG dvi2svg(srcin.getInputStream(), out); const char *ignore_specials=nullptr; if (cmdline.noSpecialsOpt.given()) ignore_specials = cmdline.noSpecialsOpt.value().empty() ? "*" : cmdline.noSpecialsOpt.value().c_str(); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml b/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml index 39659844307..b8b43fcd5f8 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml @@ -23,7 +23,8 @@ <cmdline class="CommandLine"> <program> <usage>[options] dvifile</usage> - <usage>-E [options] epsfile</usage> + <usage>--eps [options] epsfile</usage> + <usage>--pdf [options] pdffile</usage> <description>This program converts DVI files, as created by TeX/LaTeX, to\nthe XML-based scalable vector graphics format SVG.</description> <copyright>Copyright (C) 2005-2018 Martin Gieseking <martin.gieseking@uos.de></copyright> </program> @@ -38,7 +39,13 @@ <description>evaluate (additional) font map files</description> </option> <option long="eps" short="E" if="!defined(DISABLE_GS)"> - <description>convert an EPS file to SVG</description> + <description>convert EPS file to SVG</description> + </option> + <option long="pdf" short="P" if="!defined(DISABLE_GS)"> + <description>convert PDF file to SVG</description> + </option> + <option long="stdin"> + <description>read input file from stdin</description> </option> </section> <section title="SVG output options"> @@ -171,7 +178,7 @@ <option long="list-specials" short="l"> <description>print supported special sets and exit</description> </option> - <option long="progress" short="P"> + <option long="progress"> <arg name="delay" type="double" optional="yes" default="0.5"/> <description>enable progress indicator</description> </option> diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp index 4b17c9cd7e4..5efa9db4dc4 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/psdefs.cpp @@ -29,72 +29,82 @@ const char *PSInterpreter::PSDEFS = "/:stroke @SD/stroke get put @SD/:fill @SD/fill get put @SD/:eofill @SD/eofill " "get put @SD/:clip @SD/clip get put @SD/:eoclip @SD/eoclip get put @SD/:charpat" "h @SD/charpath get put @SD/:show @SD/show get put @SD/.setopacityalpha known n" -"ot{@SD/.setopacityalpha{pop}put}if @SD/prseq{-1 1{-1 roll =only( )print}for(\\" -"n)print}put @SD/prcmd{( )exch(\\ndvi.)3{print}repeat prseq}put @SD/cvxall{{cvx" -"}forall}put @SD/defpr{[exch[/copy @SD]cvxall 5 -1 roll dup 6 1 roll[/get/exec]" -"cvxall 6 -1 roll dup 7 1 roll 4 -1 roll dup 5 1 roll dup length string cvs/prc" -"md cvx]cvx def}put @SD/querypos{{currentpoint}stopped{$error/newerror false pu" -"t}{2(querypos)prcmd}ifelse}put @SD/applyscalevals{1 0 dtransform exch dup mul " -"exch dup mul add sqrt 0 1 dtransform exch dup mul exch dup mul add sqrt 1 0 dt" -"ransform dup mul exch dup dup mul 3 -1 roll add dup 0 eq{pop}{sqrt div}ifelse " -"3(applyscalevals)prcmd}put @SD/prpath{{2(moveto)prcmd}{2(lineto)prcmd}{6(curve" -"to)prcmd}{0(closepath)prcmd}pathforall}put @SD/charpath{/@dodraw false store :" -"charpath/@dodraw true store}put @SD/show{@dodraw{dup :gsave currentpoint 2{50 " -"mul exch}repeat :newpath moveto 50 50/scale sysexec true charpath eofill :gres" -"tore/@dodraw false store :show/@dodraw true store}{pop}ifelse}put @SD/awidthsh" -"ow{{1 string dup 0 5 index put :gsave show :grestore pop 0 rmoveto 3 index eq{" -"4 index 4 index rmoveto}if 1 index 1 index rmoveto}exch cshow 5{pop}repeat}put" -" @SD/widthshow{0 0 3 -1 roll pstack awidthshow}put @SD/ashow{0 0 0 6 3 roll aw" -"idthshow}put @SD/newpath{:newpath 0 1(newpath)prcmd}put @SD/stroke{@dodraw{1 1" -"(newpath)prcmd prpath 0(stroke)prcmd :newpath}{:stroke}ifelse}put @SD/fill{@do" -"draw{1 1(newpath)prcmd prpath 0(fill)prcmd :newpath}{:fill}ifelse}put @SD/eofi" -"ll{@dodraw{1 1(newpath)prcmd prpath 0(eofill)prcmd :newpath}{:eofill}ifelse}pu" -"t @SD/clip{:clip 0 1(newpath)prcmd prpath 0(clip)prcmd}put @SD/eoclip{:eoclip " -"1 1(newpath)prcmd prpath 0(eoclip)prcmd}put @SD/shfill{begin currentdict/Shadi" -"ngType known currentdict/ColorSpace known and currentdict/DataSource known and" -" currentdict/Function known not and ShadingType 4 ge and DataSource type/array" -"type eq and{<</DeviceGray 1/DeviceRGB 3/DeviceCMYK 4/bgknown currentdict/Backg" -"round known/bbknown currentdict/BBox known>>begin currentdict ColorSpace known" -"{ShadingType ColorSpace load bgknown{1 Background aload pop}{0}ifelse bbknown{" -"1 BBox aload pop}{0}ifelse ShadingType 5 eq{VerticesPerRow}if DataSource aload" -" length 4 add bgknown{ColorSpace load add}if bbknown{4 add}if ShadingType 5 eq" -"{1 add}if(shfill)prcmd}if end}if end}put/@rect{4 -2 roll moveto exch dup 0 rli" -"neto exch 0 exch rlineto neg 0 rlineto closepath}bind def/@rectcc{4 -2 roll mo" -"veto 2 copy 0 lt exch 0 lt xor{dup 0 exch rlineto exch 0 rlineto neg 0 exch rl" -"ineto}{exch dup 0 rlineto exch 0 exch rlineto neg 0 rlineto}ifelse closepath}b" -"ind def @SD/rectclip{:newpath dup type/arraytype eq{aload length 4 idiv{@rectc" -"c}repeat}{@rectcc}ifelse clip :newpath}put @SD/rectfill{gsave :newpath dup typ" -"e/arraytype eq{aload length 4 idiv{@rectcc}repeat}{@rectcc}ifelse fill grestor" -"e}put @SD/rectstroke{gsave :newpath dup type/arraytype eq{aload length 4 idiv{" -"@rect}repeat}{@rect}ifelse stroke grestore}put false setglobal @SD readonly po" -"p/initclip 0 defpr/clippath 0 defpr/sysexec{@SD exch get exec}def/adddot{dup l" -"ength 1 add string dup 0 46 put dup 3 -1 roll 1 exch putinterval}def/setlinewi" -"dth{dup/setlinewidth sysexec 1(setlinewidth)prcmd}def/setlinecap 1 defpr/setli" -"nejoin 1 defpr/setmiterlimit 1 defpr/setdash{mark 3 1 roll 2 copy/setdash syse" -"xec exch aload length 1 add -1 roll counttomark(setdash)prcmd pop}def/@setpage" -"device{pop<<>>/setpagedevice sysexec[1 0 0 -1 0 0]setmatrix newpath 0(setpaged" -"evice)prcmd}def/setgstate{currentlinewidth 1(setlinewidth)prcmd currentlinecap" -" 1(setlinecap)prcmd currentlinejoin 1(setlinejoin)prcmd currentmiterlimit 1(se" -"tmiterlimit)prcmd currentrgbcolor 3(setrgbcolor)prcmd matrix currentmatrix alo" -"ad pop 6(setmatrix)prcmd applyscalevals currentdash mark 3 1 roll exch aload l" -"ength 1 add -1 roll counttomark(setdash)prcmd pop}def/save{@UD begin/@saveID v" -"mstatus pop pop def end :save @saveID 1(save)prcmd}def/restore{:restore setgst" -"ate @UD/@saveID known{@UD begin @saveID end}{0}ifelse 1(restore)prcmd}def/gsav" -"e 0 defpr/grestore{:grestore setgstate 0(grestore)prcmd}def/grestoreall{:grest" -"oreall setstate 0(grestoreall)prcmd}def/rotate{dup type/arraytype ne{dup 1(rot" -"ate)prcmd}if/rotate sysexec applyscalevals}def/scale{dup type/arraytype ne{2 c" -"opy 2(scale)prcmd}if/scale sysexec applyscalevals}def/translate{dup type/array" -"type ne{2 copy 2(translate)prcmd}if/translate sysexec}def/setmatrix{dup/setmat" -"rix sysexec aload pop 6(setmatrix)prcmd applyscalevals}def/initmatrix{matrix s" -"etmatrix}def/concat{matrix currentmatrix matrix concatmatrix setmatrix}def/mak" -"epattern{gsave<</mx 3 -1 roll>>begin dup/XUID[1000000 @patcnt]put mx/makepatte" -"rn sysexec dup dup begin PatternType @patcnt BBox aload pop XStep YStep PaintT" -"ype mx aload pop 15(makepattern)prcmd :newpath matrix setmatrix PaintProc 0 1(" -"makepattern)prcmd end/@patcnt @patcnt 1 add store end grestore}def/setpattern{" -"begin PatternType 1 eq{PaintType 1 eq{XUID aload pop exch pop 1}{:gsave[curren" -"tcolorspace aload length -1 roll pop]setcolorspace/setcolor sysexec XUID aload" -" pop exch pop currentrgbcolor :grestore 4}ifelse(setpattern)prcmd}{/setpattern" -" sysexec}ifelse end}def/setcolor{dup type/dicttype eq{setpattern}{/setcolor sy" -"sexec/currentrgbcolor sysexec setrgbcolor}ifelse}def/setgray 1 defpr/setcmykco" -"lor 4 defpr/sethsbcolor 3 defpr/setrgbcolor 3 defpr/.setopacityalpha{dup/.seto" -"pacityalpha sysexec 1(setopacityalpha)prcmd}def "; +"ot{@SD/.setopacityalpha{pop}put}if @SD/.setshapealpha known not{@SD/.setshapea" +"lpha{pop}put}if @SD/.setblendmode known not{@SD/.setblendmode{pop}put}if @SD/p" +"rseq{-1 1{-1 roll =only( )print}for(\\n)print}put @SD/prcmd{( )exch(\\ndvi.)3{" +"print}repeat prseq}put @SD/cvxall{{cvx}forall}put @SD/defpr{[exch[/copy @SD]cv" +"xall 5 -1 roll dup 6 1 roll[/get/exec]cvxall 6 -1 roll dup 7 1 roll 4 -1 roll " +"dup 5 1 roll dup length string cvs/prcmd cvx]cvx def}put @SD/querypos{{current" +"point}stopped{$error/newerror false put}{2(querypos)prcmd}ifelse}put @SD/apply" +"scalevals{1 0 dtransform exch dup mul exch dup mul add sqrt 0 1 dtransform exc" +"h dup mul exch dup mul add sqrt 1 0 dtransform dup mul exch dup dup mul 3 -1 r" +"oll add dup 0 eq{pop}{sqrt div}ifelse 3(applyscalevals)prcmd}put @SD/prpath{{2" +"(moveto)prcmd}{2(lineto)prcmd}{6(curveto)prcmd}{0(closepath)prcmd}pathforall}p" +"ut @SD/charpath{/@dodraw false store :charpath/@dodraw true store}put @SD/show" +"{@dodraw{dup :gsave currentpoint 2{50 mul exch}repeat :newpath moveto 50 50/sc" +"ale sysexec true charpath eofill :grestore/@dodraw false store :show/@dodraw t" +"rue store}{pop}ifelse}put @SD/awidthshow{{1 string dup 0 5 index put :gsave sh" +"ow :grestore pop 0 rmoveto 3 index eq{4 index 4 index rmoveto}if 1 index 1 ind" +"ex rmoveto}exch cshow 5{pop}repeat}put @SD/widthshow{0 0 3 -1 roll pstack awid" +"thshow}put @SD/ashow{0 0 0 6 3 roll awidthshow}put @SD/newpath{:newpath 0 1(ne" +"wpath)prcmd}put @SD/stroke{@dodraw{prcolor 1 1(newpath)prcmd prpath 0(stroke)p" +"rcmd :newpath}{:stroke}ifelse}put @SD/fill{@dodraw{prcolor 1 1(newpath)prcmd p" +"rpath 0(fill)prcmd :newpath}{:fill}ifelse}put @SD/eofill{@dodraw{prcolor 1 1(n" +"ewpath)prcmd prpath 0(eofill)prcmd :newpath}{:eofill}ifelse}put @SD/clip{:clip" +" 0 1(newpath)prcmd prpath 0(clip)prcmd}put @SD/eoclip{:eoclip 1 1(newpath)prcm" +"d prpath 0(eoclip)prcmd}put @SD/shfill{begin currentdict/ShadingType known cur" +"rentdict/ColorSpace known and currentdict/DataSource known and currentdict/Fun" +"ction known not and ShadingType 4 ge and DataSource type/arraytype eq and{<</D" +"eviceGray 1/DeviceRGB 3/DeviceCMYK 4/bgknown currentdict/Background known/bbkn" +"own currentdict/BBox known>>begin currentdict ColorSpace known{ShadingType Col" +"orSpace load bgknown{1 Background aload pop}{0}ifelse bbknown{1 BBox aload pop" +"}{0}ifelse ShadingType 5 eq{VerticesPerRow}if DataSource aload length 4 add bg" +"known{ColorSpace load add}if bbknown{4 add}if ShadingType 5 eq{1 add}if(shfill" +")prcmd}if end}if end}put/@rect{4 -2 roll moveto exch dup 0 rlineto exch 0 exch" +" rlineto neg 0 rlineto closepath}bind def/@rectcc{4 -2 roll moveto 2 copy 0 lt" +" exch 0 lt xor{dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto}{exch dup " +"0 rlineto exch 0 exch rlineto neg 0 rlineto}ifelse closepath}bind def @SD/rect" +"clip{:newpath dup type/arraytype eq{aload length 4 idiv{@rectcc}repeat}{@rectc" +"c}ifelse clip :newpath}put @SD/rectfill{gsave :newpath dup type/arraytype eq{a" +"load length 4 idiv{@rectcc}repeat}{@rectcc}ifelse fill grestore}put @SD/rectst" +"roke{gsave :newpath dup type/arraytype eq{aload length 4 idiv{@rect}repeat}{@r" +"ect}ifelse stroke grestore}put false setglobal @SD readonly pop/initclip 0 def" +"pr/clippath 0 defpr/sysexec{@SD exch get exec}def/adddot{dup length 1 add stri" +"ng dup 0 46 put dup 3 -1 roll 1 exch putinterval}def/setlinewidth{dup/setlinew" +"idth sysexec 1(setlinewidth)prcmd}def/setlinecap 1 defpr/setlinejoin 1 defpr/s" +"etmiterlimit 1 defpr/setdash{mark 3 1 roll 2 copy/setdash sysexec exch aload l" +"ength 1 add -1 roll counttomark(setdash)prcmd pop}def/@setpagedevice{pop<<>>/s" +"etpagedevice sysexec[1 0 0 -1 0 0]setmatrix newpath 0(setpagedevice)prcmd}def/" +"prcolor{currentrgbcolor 3(setrgbcolor)prcmd}def/printgstate{currentlinewidth 1" +"(setlinewidth)prcmd currentlinecap 1(setlinecap)prcmd currentlinejoin 1(setlin" +"ejoin)prcmd currentmiterlimit 1(setmiterlimit)prcmd currentrgbcolor 3(setrgbco" +"lor)prcmd matrix currentmatrix aload pop 6(setmatrix)prcmd applyscalevals curr" +"entdash mark 3 1 roll exch aload length 1 add -1 roll counttomark(setdash)prcm" +"d pop}def/setgstate{/setgstate sysexec printgstate}def/save{@UD begin/@saveID " +"vmstatus pop pop def end :save @saveID 1(save)prcmd}def/restore{:restore print" +"gstate @UD/@saveID known{@UD begin @saveID end}{0}ifelse 1(restore)prcmd}def/g" +"save 0 defpr/grestore{:grestore printgstate 0(grestore)prcmd}def/grestoreall{:" +"grestoreall setstate 0(grestoreall)prcmd}def/rotate{dup type/arraytype ne{dup " +"1(rotate)prcmd}if/rotate sysexec applyscalevals}def/scale{dup type/arraytype n" +"e{2 copy 2(scale)prcmd}if/scale sysexec applyscalevals}def/translate{dup type/" +"arraytype ne{2 copy 2(translate)prcmd}if/translate sysexec}def/setmatrix{dup/s" +"etmatrix sysexec aload pop 6(setmatrix)prcmd applyscalevals}def/initmatrix{mat" +"rix setmatrix}def/concat{matrix currentmatrix matrix concatmatrix setmatrix}de" +"f/makepattern{gsave<</mx 3 -1 roll>>begin dup/XUID[1000000 @patcnt]put mx/make" +"pattern sysexec dup dup begin PatternType @patcnt BBox aload pop XStep YStep P" +"aintType mx aload pop 15(makepattern)prcmd :newpath matrix setmatrix PaintProc" +" 0 1(makepattern)prcmd end/@patcnt @patcnt 1 add store end grestore}def/setpat" +"tern{begin PatternType 1 eq{PaintType 1 eq{XUID aload pop exch pop 1}{:gsave[c" +"urrentcolorspace aload length -1 roll pop]setcolorspace/setcolor sysexec XUID " +"aload pop exch pop currentrgbcolor :grestore 4}ifelse(setpattern)prcmd}{/setpa" +"ttern sysexec}ifelse end}def/setcolor{dup type/dicttype eq{setpattern}{/setcol" +"or sysexec/currentrgbcolor sysexec setrgbcolor}ifelse}def/setgray 1 defpr/setc" +"mykcolor 4 defpr/sethsbcolor 3 defpr/setrgbcolor 3 defpr/.setopacityalpha{dup/" +".setopacityalpha sysexec 1(setopacityalpha)prcmd}def/.setshapealpha{dup/.setsh" +"apealpha sysexec 1(setshapealpha)prcmd}def/.setblendmode{dup/.setblendmode sys" +"exec<</Normal 0/Compatible 0/Multiply 1/Screen 2/Overlay 3/SoftLight 4/HardLig" +"ht 5/ColorDodge 6/ColorBurn 7/Darken 8/Lighten 9/Difference 10/Exclusion 11/Hu" +"e 12/Saturation 13/Color 14/Luminosity 15/CompatibleOverprint 16>>exch get 1(s" +"etblendmode)prcmd}def/@getpdfpagebox{GS_PDF_ProcSet begin pdfdict begin(r)file" +" pdfopen begin 1 pdfgetpage/MediaBox pget pop aload pop 4(pdfpagebox)prcmd cur" +"rentdict pdfclose end end end}def DELAYBIND{.bindnow}if "; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp index 95200e15cf9..bbcd4cf0dbb 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp @@ -22,7 +22,7 @@ #define VERSION_HPP constexpr const char *PROGRAM_NAME = "dvisvgm"; -constexpr const char *PROGRAM_VERSION = "2.3.5"; +constexpr const char *PROGRAM_VERSION = "2.4"; #endif |