diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src')
18 files changed, 684 insertions, 138 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp index 82b9ee0dade..77130b218f9 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp @@ -46,8 +46,8 @@ class BasicDVIReader : public StreamReader { protected: using CommandHandler = void (BasicDVIReader::*)(int); enum DVIVersion {DVI_NONE=0, DVI_STANDARD=2, DVI_PTEX=3, DVI_XDV5=5, DVI_XDV6=6, DVI_XDV7=7}; - const uint8_t OP_SETCHAR0=0, OP_SETCHAR127=127, OP_SET1=128, OP_EOP=140, OP_FNTNUM0=171, OP_FNTNUM63=234, - OP_PRE=247, OP_POST=248, OP_POSTPOST=249, OP_DIR=255, DVI_FILL=223; + const uint8_t OP_SETCHAR0=0, OP_SETCHAR127=127, OP_SET1=128, OP_BOP=139, OP_EOP=140, OP_FNTNUM0=171, + OP_FNTNUM63=234, OP_PRE=247, OP_POST=248, OP_POSTPOST=249, OP_DIR=255, DVI_FILL=223; public: explicit BasicDVIReader (std::istream &is); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp index 1ae9f188d30..f98985ee0d6 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp @@ -54,6 +54,7 @@ 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"}; + TypedOption<std::string, Option::ArgMode::OPTIONAL> pageHashesOpt {"page-hashes", 'H', "params", "xxh64", "activate usage of page hashes"}; 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", '\0', "delay", 0.5, "enable progress indicator"}; @@ -136,6 +137,7 @@ class CommandLine : public CL::CommandLine { {&magOpt, 3}, {&noMktexmfOpt, 3}, {&noSpecialsOpt, 3}, + {&pageHashesOpt, 3}, {&traceAllOpt, 3}, {&colorOpt, 4}, {&helpOpt, 4}, diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp index d3aab868cc2..950d8ec024f 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp @@ -27,6 +27,7 @@ #include "DVIReader.hpp" #include "Font.hpp" #include "FontManager.hpp" +#include "HashFunction.hpp" #include "VectorStream.hpp" using namespace std; @@ -68,7 +69,7 @@ void DVIReader::executeAll () { /** Reads and executes the commands of a single page. * This methods stops reading after the page's eop command has been executed. - * @param[in] n number of page to be executed + * @param[in] n number of page to be executed (1-based) * @returns true if page was read successfully */ bool DVIReader::executePage (unsigned n) { clearStream(); // reset all status bits @@ -132,14 +133,46 @@ void DVIReader::collectBopOffsets () { _bopOffsets.push_back(tell()); // also add offset of postamble readByte(); // skip post command uint32_t offset = readUnsigned(4); // offset of final bop - while ((int32_t)offset > 0) { // not yet on first bop? + while (int32_t(offset) != -1) { // not yet on first bop? _bopOffsets.push_back(offset); // record offset - seek(offset+41); // skip bop command and the 10 \count values => now on offset of previous bop - offset = readUnsigned(4); + seek(offset); // now on previous bop + if (readByte() != OP_BOP) + throw DVIException("bop offset at "+to_string(offset)+" doesn't point to bop command" ); + seek(40, ios::cur); // skip the 10 \count values => now on offset of previous bop + uint32_t prevOffset = readUnsigned(4); + if ((prevOffset >= offset && int32_t(prevOffset) != -1)) + throw DVIException("invalid bop offset at "+to_string(tell()-static_cast<streamoff>(4))); + offset = prevOffset; } reverse(_bopOffsets.begin(), _bopOffsets.end()); } + +/** Computes a hash value for a given page. The hash algorithm is selected by + * a HashFunction object which will also contain the resulting hash value if + * this function returns true. + * @param[in] pageno number of page to process (1-based) + * @param[in,out] hashFunc hash function to use + * @return true on success, hashFunc contains the resulting hash value */ +bool DVIReader::computePageHash (size_t pageno, HashFunction &hashFunc) { + if (pageno == 0 || pageno > numberOfPages()) + return false; + + hashFunc.reset(); + clearStream(); + seek(_bopOffsets[pageno-1]+45); // now on first command after bop of selected page + const size_t BUFSIZE = 4096; + char buf[BUFSIZE]; + size_t numBytes = numberOfPageBytes(pageno-1)-46; // number of bytes excluding bop and eop + while (numBytes > 0) { + getInputStream().read(buf, min(numBytes, BUFSIZE)); + hashFunc.update(buf, getInputStream().gcount()); + numBytes -= getInputStream().gcount(); + } + return true; +} + + ///////////////////////////////////// /** Reads and executes DVI preamble command. @@ -174,7 +207,7 @@ void DVIReader::cmdPost (int) { uint32_t pageWidth = readUnsigned(4); // width of widest page in dvi units uint16_t stackDepth = readUnsigned(2); // max. stack depth required uint16_t numPages = readUnsigned(2); - if (numPages != numberOfPages()) + if (numPages != (numberOfPages() & 0xffff)) throw DVIException("page count in postamble doesn't match actual number of pages"); // 1 dviunit * num/den == multiples of 0.0000001m diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp index a17b98a5f2d..48ac1759776 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp @@ -31,6 +31,7 @@ class Font; class FontStyle; +class HashFunction; class NativeFont; class VirtualFont; @@ -67,6 +68,7 @@ class DVIReader : public BasicDVIReader, public VFActions { int executeCommand () override; void collectBopOffsets (); size_t numberOfPageBytes (int n) const {return _bopOffsets.size() > 1 ? _bopOffsets[n+1]-_bopOffsets[n] : 0;} + bool computePageHash (size_t pageno, HashFunction &hashFunc); void goToPostamble (); virtual void moveRight (double dx, MoveMode mode); virtual void moveDown (double dy, MoveMode mode); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp index 9a0ff50bf82..cb14c96a408 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp @@ -22,11 +22,13 @@ #include <cstdlib> #include <ctime> #include <fstream> +#include <iomanip> #include <set> #include <sstream> #include "Calculator.hpp" #include "DVIToSVG.hpp" #include "DVIToSVGActions.hpp" +#include "FileSystem.hpp" #include "Font.hpp" #include "FontManager.hpp" #include "GlyphTracerMessages.hpp" @@ -39,6 +41,7 @@ #include "SVGOutput.hpp" #include "utility.hpp" #include "version.hpp" +#include "XXHashFunction.hpp" /////////////////////////////////// // special handlers @@ -67,6 +70,7 @@ using namespace std; * 0 : only trace actually required glyphs */ char DVIToSVG::TRACE_MODE = 0; bool DVIToSVG::COMPUTE_PROGRESS = false; +DVIToSVG::HashSettings DVIToSVG::PAGE_HASH_SETTINGS; DVIToSVG::DVIToSVG (istream &is, SVGOutputBase &out) : DVIReader(is), _out(out) @@ -83,8 +87,8 @@ DVIToSVG::DVIToSVG (istream &is, SVGOutputBase &out) : DVIReader(is), _out(out) /** Starts the conversion process. * @param[in] first number of first page to convert * @param[in] last number of last page to convert - * @param[out] pageinfo (number of converted pages, number of total pages) */ -void DVIToSVG::convert (unsigned first, unsigned last, pair<int,int> *pageinfo) { + * @param[in] hashFunc pointer to function to be used to compute page hashes */ +void DVIToSVG::convert (unsigned first, unsigned last, HashFunction *hashFunc) { if (first > last) swap(first, last); if (first > numberOfPages()) { @@ -95,28 +99,59 @@ void DVIToSVG::convert (unsigned first, unsigned last, pair<int,int> *pageinfo) throw DVIException(oss.str()); } last = min(last, numberOfPages()); + bool computeHashes = (hashFunc && !_out.ignoresHashes()); + string shortenedOptHash = XXH32HashFunction(PAGE_HASH_SETTINGS.optionsHash()).digestString(); for (unsigned i=first; i <= last; ++i) { - executePage(i); - _svg.removeRedundantElements(); - embedFonts(_svg.rootNode()); - bool success = _svg.write(_out.getPageStream(currentPageNumber(), numberOfPages())); - string fname = _out.filename(i, numberOfPages()); - if (fname.empty()) - fname = "<stdout>"; - if (success) - Message::mstream(false, Message::MC_PAGE_WRITTEN) << "\noutput written to " << fname << '\n'; - else - Message::wstream(true) << "failed to write output to " << fname << '\n'; - _svg.reset(); - _actions->reset(); - } - if (pageinfo) { - pageinfo->first = last-first+1; - pageinfo->second = numberOfPages(); + string dviHash, combinedHash; + if (computeHashes) { + computePageHash(i, *hashFunc); + dviHash = hashFunc->digestString(); + hashFunc->update(PAGE_HASH_SETTINGS.optionsHash()); + combinedHash = hashFunc->digestString(); + } + const SVGOutput::HashTriple hashTriple(dviHash, shortenedOptHash, combinedHash); + string fname = _out.filename(i, numberOfPages(), hashTriple); + if (!dviHash.empty() && !PAGE_HASH_SETTINGS.isSet(HashSettings::P_REPLACE) && FileSystem::exists(fname)) { + Message::mstream(false, Message::MC_PAGE_NUMBER) << "skipping page " << i; + Message::mstream().indent(1); + Message::mstream(false, Message::MC_PAGE_WRITTEN) << "\nfile " << fname << " exists\n"; + Message::mstream().indent(0); + } + else { + executePage(i); + _svg.removeRedundantElements(); + embedFonts(_svg.rootNode()); + bool success = _svg.write(_out.getPageStream(currentPageNumber(), numberOfPages(), hashTriple)); + if (fname.empty()) + fname = "<stdout>"; + if (success) + Message::mstream(false, Message::MC_PAGE_WRITTEN) << "\noutput written to " << fname << '\n'; + else + Message::wstream(true) << "failed to write output to " << fname << '\n'; + _svg.reset(); + _actions->reset(); + } } } +/** Creates a HashFunction object for a given algorithm name. + * @param[in] algo name of hash algorithm + * @return pointer to hash function + * @throw MessageException if algorithm name is invalid or not supported */ +static unique_ptr<HashFunction> create_hash_function (const string &algo) { + if (auto hashFunc = HashFunction::create(algo)) + return hashFunc; + + string msg = "unknown hash algorithm '"+algo+"' (supported algorithms: "; + for (const string &name : HashFunction::supportedAlgorithms()) + msg += name + ", "; + msg.pop_back(); + msg.back() = ')'; + throw MessageException(msg); +} + + /** Convert DVI pages specified by a page range string. * @param[in] rangestr string describing the pages to convert * @param[out] pageinfo (number of converted pages, number of total pages) */ @@ -134,8 +169,12 @@ void DVIToSVG::convert (const string &rangestr, pair<int,int> *pageinfo) { SpecialManager::instance().notifyPreprocessingFinished(); } + unique_ptr<HashFunction> hashFunc; + if (!PAGE_HASH_SETTINGS.algorithm().empty()) // name of hash algorithm present? + hashFunc = create_hash_function(PAGE_HASH_SETTINGS.algorithm()); + for (const auto &range : ranges) - convert(range.first, range.second); + convert(range.first, range.second, hashFunc.get()); if (pageinfo) { pageinfo->first = ranges.numberOfPages(); pageinfo->second = numberOfPages(); @@ -143,6 +182,37 @@ void DVIToSVG::convert (const string &rangestr, pair<int,int> *pageinfo) { } +/** Writes the hash values of a selected set of pages to an output stream. + * @param[in] rangestr string describing the pages to convert + * @param[in,out] os stream the output is written to */ +void DVIToSVG::listHashes (const string &rangestr, std::ostream &os) { + PageRanges ranges; + if (!ranges.parse(rangestr, numberOfPages())) + throw MessageException("invalid page range format"); + + XXH32HashFunction xxh32; + auto hashFunc = create_hash_function(PAGE_HASH_SETTINGS.algorithm()); + int width1 = util::ilog10(numberOfPages())+1; + int width2 = hashFunc->digestSize()*2; + int spaces1 = width1+2+(width2-3)/2; + int spaces2 = width1+2+width2+2-spaces1-3+(width2-7)/2; + string shortenedOptHash = XXH32HashFunction(PAGE_HASH_SETTINGS.optionsHash()).digestString(); + os << string(spaces1, ' ') << "DVI" + << string(spaces2, ' ') << "DVI+opt\n"; + for (const auto &range : ranges) { + for (int i=range.first; i <= range.second; i++) { + computePageHash(i, *hashFunc); + os << setw(width1) << i; + os << ": " << hashFunc->digestString(); + hashFunc->update(PAGE_HASH_SETTINGS.optionsHash()); + os << ", " << hashFunc->digestString() << '\n'; + } + } + os << "hash algorithm: " << PAGE_HASH_SETTINGS.algorithm() + << ", options hash: " << shortenedOptHash << '\n'; +} + + int DVIToSVG::executeCommand () { SignalHandler::instance().check(); const streampos cmdpos = tell(); @@ -479,3 +549,26 @@ void DVIToSVG::dviXGlyphString (vector<double> &dx, vector<uint16_t> &glyphs, co void DVIToSVG::dviXTextAndGlyphs (vector<double> &dx, vector<double> &dy, vector<uint16_t>&, vector<uint16_t> &glyphs, const Font &font) { dviXGlyphArray(dx, dy, glyphs, font); } + +/////////////////////////////////////////////////////////////// + +/** Parses a string consisting of comma-separated words, and assigns + * the values to the hash settings. */ +void DVIToSVG::HashSettings::setParameters (const string ¶mstr) { + auto paramnames = util::split(paramstr, ","); + map<string, Parameter> paramMap = { + {"list", P_LIST}, + {"replace", P_REPLACE} + }; + for (string &name : paramnames) { + name = util::trim(name); + auto it = paramMap.find(name); + if (it != paramMap.end()) + _params.insert(it->second); + else if (_algo.empty() && HashFunction::isSupportedAlgorithm(name)) + _algo = name; + } + // set default hash algorithm if none is given + if (_algo.empty()) + _algo = "xxh64"; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp index 3c9100a0ec7..b0380e69239 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp @@ -21,6 +21,7 @@ #ifndef DVITOSVG_HPP #define DVITOSVG_HPP +#include <set> #include <string> #include <utility> #include "DVIReader.hpp" @@ -28,9 +29,26 @@ struct DVIActions; struct SVGOutputBase; +class HashFunction; class DVIToSVG : public DVIReader { public: + class HashSettings { + public: + enum Parameter {P_LIST, P_REPLACE}; + void setParameters (const std::string ¶mstr); + void setOptionHash (const std::string &optHash) {_optHash = optHash;} + std::string algorithm () const {return _algo;} + std::string optionsHash () const {return _optHash;} + bool isSet (Parameter param) {return _params.find(param) != _params.end();} + + private: + std::string _algo; + std::string _optHash; + std::set<Parameter> _params; + }; + + public: explicit DVIToSVG (std::istream &is, SVGOutputBase &out); void convert (const std::string &range, std::pair<int,int> *pageinfo=0); void setPageSize (const std::string &format) {_bboxFormatString = format;} @@ -41,6 +59,7 @@ class DVIToSVG : public DVIReader { double getXPos() const override {return dviState().h+_tx;} double getYPos() const override {return dviState().v+_ty;} void finishLine () override {_prevYPos = std::numeric_limits<double>::min();} + void listHashes (const std::string &rangestr, std::ostream &os); std::string getSVGFilename (unsigned pageno) const; std::string getUserBBoxString () const {return _bboxFormatString;} @@ -49,10 +68,11 @@ class DVIToSVG : public DVIReader { public: static bool COMPUTE_PROGRESS; ///< if true, an action to handle the progress ratio of a page is triggered static char TRACE_MODE; + static HashSettings PAGE_HASH_SETTINGS; protected: DVIToSVG (const DVIToSVG&) =delete; - void convert (unsigned firstPage, unsigned lastPage, std::pair<int,int> *pageinfo=0); + void convert (unsigned firstPage, unsigned lastPage, HashFunction *hashFunc); int executeCommand () override; void enterBeginPage (unsigned pageno, const std::vector<int32_t> &c); void leaveEndPage (unsigned pageno); diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp index cbb3589efc8..4d64fc6996b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp @@ -64,8 +64,8 @@ static string get_path_from_registry () { int major_version; iss >> major_version; if (major_version >= 7) { - char dll_path[256]; // path to Ghostscript DLL stored in the registry - DWORD length; + char dll_path[512]; // path to Ghostscript DLL stored in the registry + DWORD length = 512; if (RegGetValueA(hkey, subkey, "GS_DLL", RRF_RT_REG_SZ, 0, dll_path, &length) == ERROR_SUCCESS) { RegCloseKey(hkey); return dll_path; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp new file mode 100644 index 00000000000..828ed5ac1e0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp @@ -0,0 +1,84 @@ +/************************************************************************* +** HashFunction.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 <algorithm> +#include <iomanip> +#include <sstream> +#include "HashFunction.hpp" +#include "utility.hpp" +#include "MD5HashFunction.hpp" +#include "XXHashFunction.hpp" + +using namespace std; + + +/** Returns a vector containing the names of the currently supported hash algorithms. */ +vector<string> HashFunction::supportedAlgorithms () { + return vector<string> {"md5", "xxh32", "xxh64"}; +} + + +/** Returns true if 'algo' is the name of a supported hash algorithm. */ +bool HashFunction::isSupportedAlgorithm (const std::string &algo) { + auto algos = supportedAlgorithms(); + return find(algos.begin(), algos.end(), algo) != algos.end(); +} + + +/** Creates a hash function for a given algorithm name/identifier. + * The following names are currently supported: md5, xxh32, xxh64. */ +unique_ptr<HashFunction> HashFunction::create (const string &name) { + string lowerName = util::tolower(name); + if (lowerName == "md5") + return util::make_unique<MD5HashFunction>(); + if (lowerName == "xxh32") + return util::make_unique<XXH32HashFunction>(); + if (lowerName == "xxh64") + return util::make_unique<XXH64HashFunction>(); + return nullptr; +} + + +std::unique_ptr<HashFunction> HashFunction::create (const string &name, const char *data, size_t length) { + auto hashfunc = create(name); + if (hashfunc) + hashfunc->update(data, length); + return hashfunc; +} + + +std::unique_ptr<HashFunction> HashFunction::create (const string &name, const string &data) { + return create(name, data.data(), data.length()); +} + + +std::unique_ptr<HashFunction> HashFunction::create (const string &name, const vector<uint8_t> &data) { + return create(name, reinterpret_cast<const char*>(data.data()), data.size()); +} + + +/** Returns the current digest as hexadecimal value. */ +string HashFunction::digestString () const { + ostringstream oss; + oss << hex << setfill('0'); + for (int byte : digestValue()) + oss << setw(2) << byte; + return oss.str(); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp new file mode 100644 index 00000000000..02318786309 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp @@ -0,0 +1,47 @@ +/************************************************************************* +** HashFunction.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 HASHFUNCTION_HPP +#define HASHFUNCTION_HPP + +#include <memory> +#include <string> +#include <vector> + +/** Common base class for all hash functions. */ +class HashFunction { + public: + virtual ~HashFunction () =default; + virtual int digestSize () const =0; + virtual void reset () =0; + virtual void update (const char *data, size_t length) =0; + virtual void update (const std::string &data) =0; + virtual void update (const std::vector<uint8_t> &data) =0; + virtual std::vector<uint8_t> digestValue () const =0; + std::string digestString () const; + static std::vector<std::string> supportedAlgorithms (); + static bool isSupportedAlgorithm (const std::string &algo); + static std::unique_ptr<HashFunction> create (const std::string &name); + static std::unique_ptr<HashFunction> create (const std::string &name, const char *data, size_t length); + static std::unique_ptr<HashFunction> create (const std::string &name, const std::string &data); + static std::unique_ptr<HashFunction> create (const std::string &name, const std::vector<uint8_t> &data); +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp new file mode 100644 index 00000000000..2bf812dafd7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp @@ -0,0 +1,58 @@ +/************************************************************************* +** MD5HashFunction.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 MD5HASHFUNCTION_HPP +#define MD5HASHFUNCTION_HPP + +#include <config.h> +#ifdef HAVE_OPENSSL_MD5_H +# include <openssl/md5.h> +#else +# include <md5.h> +#endif + +#include "HashFunction.hpp" + +class MD5HashFunction : public HashFunction { + public: + MD5HashFunction () {MD5_Init(&_context);} + MD5HashFunction (const char *data, size_t length) : MD5HashFunction() {update(data, length);} + MD5HashFunction (const std::string &data) : MD5HashFunction() {update(data);} + MD5HashFunction (const std::vector<uint8_t> &data) : MD5HashFunction() {update(data);} + int digestSize () const override {return 16;} + void reset () override {MD5_Init(&_context);} + void update (const char *data, size_t length) override {MD5_Update(&_context, data, length);} + void update (const std::string &data) override {update(data.data(), data.length());} + void update (const std::vector<uint8_t> &data) override {update(reinterpret_cast<const char*>(data.data()), data.size());} + + std::vector<uint8_t> digestValue () const override { + std::vector<uint8_t> hash(16); + MD5_CTX savedContext = _context; + MD5_Final(hash.data(), &_context); // also erases the context structure + _context = savedContext; + return hash; + } + + private: + mutable MD5_CTX _context; +}; + +#endif + diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am index cd668737062..2ba46e25c9d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am @@ -38,6 +38,12 @@ dvisvgm_LDADD += \ endif endif +if USE_BUNDLED_MD5 +dvisvgm_LDADD += ../libs/md5/libmd5.a +else +dvisvgm_LDADD += $(LIBCRYPTO_LIBS) +endif + dvisvgm_LDADD += \ $(KPATHSEA_LIBS) \ $(FREETYPE2_LIBS) \ @@ -136,6 +142,8 @@ libdvisvgm_a_SOURCES = \ Glyph.hpp \ GlyphTracerMessages.hpp \ GraphicsPath.hpp \ + HashFunction.cpp \ + HashFunction.hpp \ HtmlSpecialHandler.cpp \ HtmlSpecialHandler.hpp \ HyperlinkManager.cpp \ @@ -155,6 +163,7 @@ libdvisvgm_a_SOURCES = \ MapLine.hpp \ Matrix.cpp \ Matrix.hpp \ + MD5HashFunction.hpp \ Message.cpp \ Message.hpp \ MessageException.hpp \ @@ -258,6 +267,7 @@ libdvisvgm_a_SOURCES = \ XMLNode.hpp \ XMLString.cpp \ XMLString.hpp \ + XXHashFunction.hpp \ ZLibOutputStream.hpp if ENABLE_WOFF @@ -307,6 +317,13 @@ AM_CXXFLAGS += \ $(WOFF2_CFLAGS) endif +if USE_BUNDLED_MD5 +AM_CXXFLAGS += -I$(dvisvgm_srcdir)/libs/md5 +else +AM_CXXFLAGS += $(LIBCRYPTO_CFLAGS) +endif + + AM_LDFLAGS += $(TTFAUTOHINT_LIBS) endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in index f886c02f8c6..a31480fee0b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in @@ -108,30 +108,34 @@ bin_PROGRAMS = dvisvgm$(EXEEXT) @ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_FALSE@ $(WOFF2_LIBS) \ @ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_FALSE@ $(BROTLI_LIBS) -@ENABLE_WOFF_TRUE@am__append_5 = ffwrapper.c ffwrapper.h -@USE_BUNDLED_LIBS_TRUE@am__append_6 = \ +@USE_BUNDLED_MD5_TRUE@am__append_5 = ../libs/md5/libmd5.a +@USE_BUNDLED_MD5_FALSE@am__append_6 = $(LIBCRYPTO_LIBS) +@ENABLE_WOFF_TRUE@am__append_7 = ffwrapper.c ffwrapper.h +@USE_BUNDLED_LIBS_TRUE@am__append_8 = \ @USE_BUNDLED_LIBS_TRUE@ -I$(dvisvgm_srcdir)/libs/potrace \ @USE_BUNDLED_LIBS_TRUE@ -I$(dvisvgm_srcdir)/libs/xxHash -@USE_BUNDLED_LIBS_FALSE@am__append_7 = \ +@USE_BUNDLED_LIBS_FALSE@am__append_9 = \ @USE_BUNDLED_LIBS_FALSE@ $(POTRACE_CFLAGS) \ @USE_BUNDLED_LIBS_FALSE@ $(XXHASH_CFLAGS) -@ENABLE_WOFF_TRUE@am__append_8 = \ +@ENABLE_WOFF_TRUE@am__append_10 = \ @ENABLE_WOFF_TRUE@ -I$(dvisvgm_srcdir)/libs/ff-woff/fontforge \ @ENABLE_WOFF_TRUE@ -I$(dvisvgm_srcdir)/libs/ff-woff/inc -@ENABLE_WOFF_TRUE@am__append_9 = $(TTFAUTOHINT_CFLAGS) -@ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_TRUE@am__append_10 = \ +@ENABLE_WOFF_TRUE@am__append_11 = $(TTFAUTOHINT_CFLAGS) +@ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_TRUE@am__append_12 = \ @ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_TRUE@ -I$(dvisvgm_srcdir)/libs/brotli/include \ @ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_TRUE@ -I$(dvisvgm_srcdir)/libs/woff2/include -@ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_FALSE@am__append_11 = \ +@ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_FALSE@am__append_13 = \ @ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_FALSE@ $(BROTLI_CFLAGS) \ @ENABLE_WOFF_TRUE@@USE_BUNDLED_LIBS_FALSE@ $(WOFF2_CFLAGS) -@ENABLE_WOFF_TRUE@am__append_12 = $(TTFAUTOHINT_LIBS) -@WIN32_TRUE@am__append_13 = -DTEXLIVEWIN32 +@ENABLE_WOFF_TRUE@@USE_BUNDLED_MD5_TRUE@am__append_14 = -I$(dvisvgm_srcdir)/libs/md5 +@ENABLE_WOFF_TRUE@@USE_BUNDLED_MD5_FALSE@am__append_15 = $(LIBCRYPTO_CFLAGS) +@ENABLE_WOFF_TRUE@am__append_16 = $(TTFAUTOHINT_LIBS) +@WIN32_TRUE@am__append_17 = -DTEXLIVEWIN32 subdir = dvisvgm-src/src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../../m4/ax_cxx_compile_stdcxx.m4 \ @@ -188,30 +192,30 @@ am__libdvisvgm_a_SOURCES_DIST = AGLTable.hpp BasicDVIReader.cpp \ 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 \ + GlyphTracerMessages.hpp GraphicsPath.hpp HashFunction.cpp \ + HashFunction.hpp HtmlSpecialHandler.cpp HtmlSpecialHandler.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 \ + MD5HashFunction.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 \ @@ -227,7 +231,8 @@ am__libdvisvgm_a_SOURCES_DIST = AGLTable.hpp BasicDVIReader.cpp \ VectorStream.hpp version.hpp VFActions.hpp VFReader.cpp \ VFReader.hpp windows.hpp XMLDocument.cpp XMLDocument.hpp \ XMLNode.cpp XMLNode.hpp XMLString.cpp XMLString.hpp \ - ZLibOutputStream.hpp ffwrapper.c ffwrapper.h + XXHashFunction.hpp ZLibOutputStream.hpp ffwrapper.c \ + ffwrapper.h @ENABLE_WOFF_TRUE@am__objects_1 = ffwrapper.$(OBJEXT) am_libdvisvgm_a_OBJECTS = BasicDVIReader.$(OBJEXT) Bezier.$(OBJEXT) \ BgColorSpecialHandler.$(OBJEXT) Bitmap.$(OBJEXT) \ @@ -244,31 +249,32 @@ am_libdvisvgm_a_OBJECTS = BasicDVIReader.$(OBJEXT) Bezier.$(OBJEXT) \ FontEngine.$(OBJEXT) FontManager.$(OBJEXT) FontMap.$(OBJEXT) \ FontMetrics.$(OBJEXT) FontWriter.$(OBJEXT) \ GFGlyphTracer.$(OBJEXT) GFReader.$(OBJEXT) GFTracer.$(OBJEXT) \ - Ghostscript.$(OBJEXT) HtmlSpecialHandler.$(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) \ - SVGCharTspanTextHandler.$(OBJEXT) SVGOutput.$(OBJEXT) \ - SVGSingleCharTextHandler.$(OBJEXT) SVGTree.$(OBJEXT) \ - System.$(OBJEXT) TensorProductPatch.$(OBJEXT) \ - Terminal.$(OBJEXT) TFM.$(OBJEXT) ToUnicodeMap.$(OBJEXT) \ - TpicSpecialHandler.$(OBJEXT) TriangularPatch.$(OBJEXT) \ - TrueTypeFont.$(OBJEXT) TTFAutohint.$(OBJEXT) Unicode.$(OBJEXT) \ - utility.$(OBJEXT) VFReader.$(OBJEXT) XMLDocument.$(OBJEXT) \ - XMLNode.$(OBJEXT) XMLString.$(OBJEXT) $(am__objects_1) + Ghostscript.$(OBJEXT) HashFunction.$(OBJEXT) \ + HtmlSpecialHandler.$(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) SVGCharTspanTextHandler.$(OBJEXT) \ + SVGOutput.$(OBJEXT) SVGSingleCharTextHandler.$(OBJEXT) \ + SVGTree.$(OBJEXT) System.$(OBJEXT) \ + TensorProductPatch.$(OBJEXT) Terminal.$(OBJEXT) TFM.$(OBJEXT) \ + ToUnicodeMap.$(OBJEXT) TpicSpecialHandler.$(OBJEXT) \ + TriangularPatch.$(OBJEXT) TrueTypeFont.$(OBJEXT) \ + TTFAutohint.$(OBJEXT) Unicode.$(OBJEXT) utility.$(OBJEXT) \ + VFReader.$(OBJEXT) XMLDocument.$(OBJEXT) XMLNode.$(OBJEXT) \ + XMLString.$(OBJEXT) $(am__objects_1) libdvisvgm_a_OBJECTS = $(am_libdvisvgm_a_OBJECTS) am_dvisvgm_OBJECTS = dvisvgm.$(OBJEXT) dvisvgm_OBJECTS = $(am_dvisvgm_OBJECTS) @@ -312,7 +318,8 @@ am__depfiles_remade = ./$(DEPDIR)/BasicDVIReader.Po \ ./$(DEPDIR)/FontMap.Po ./$(DEPDIR)/FontMetrics.Po \ ./$(DEPDIR)/FontWriter.Po ./$(DEPDIR)/GFGlyphTracer.Po \ ./$(DEPDIR)/GFReader.Po ./$(DEPDIR)/GFTracer.Po \ - ./$(DEPDIR)/Ghostscript.Po ./$(DEPDIR)/HtmlSpecialHandler.Po \ + ./$(DEPDIR)/Ghostscript.Po ./$(DEPDIR)/HashFunction.Po \ + ./$(DEPDIR)/HtmlSpecialHandler.Po \ ./$(DEPDIR)/HyperlinkManager.Po ./$(DEPDIR)/ImageToSVG.Po \ ./$(DEPDIR)/InputBuffer.Po ./$(DEPDIR)/InputReader.Po \ ./$(DEPDIR)/JFM.Po ./$(DEPDIR)/Length.Po \ @@ -413,7 +420,7 @@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AM_LDFLAGS = $(KPSE_LIBS) $(CODE_COVERAGE_LDFLAGS) $(am__append_12) +AM_LDFLAGS = $(KPSE_LIBS) $(CODE_COVERAGE_LDFLAGS) $(am__append_16) AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ @@ -560,8 +567,9 @@ dvisvgm_SOURCES = \ dvisvgm_LDADD = $(noinst_LIBRARIES) ../libs/clipper/libclipper.a \ $(am__append_1) $(am__append_2) $(am__append_3) \ - $(am__append_4) $(KPATHSEA_LIBS) $(FREETYPE2_LIBS) \ - $(FONTFORGE_LIBS) $(ZLIB_LIBS) $(LIBGS_LIBS) + $(am__append_4) $(am__append_5) $(am__append_6) \ + $(KPATHSEA_LIBS) $(FREETYPE2_LIBS) $(FONTFORGE_LIBS) \ + $(ZLIB_LIBS) $(LIBGS_LIBS) dvisvgm_DEPENDENCIES = $(noinst_LIBRARIES) $(KPATHSEA_DEPEND) \ $(ZLIB_DEPEND) $(FREETYPE2_DEPEND) libdvisvgm_a_SOURCES = AGLTable.hpp BasicDVIReader.cpp \ @@ -587,30 +595,30 @@ libdvisvgm_a_SOURCES = AGLTable.hpp BasicDVIReader.cpp \ 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 \ + GlyphTracerMessages.hpp GraphicsPath.hpp HashFunction.cpp \ + HashFunction.hpp HtmlSpecialHandler.cpp HtmlSpecialHandler.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 \ + MD5HashFunction.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 \ @@ -626,18 +634,19 @@ libdvisvgm_a_SOURCES = AGLTable.hpp BasicDVIReader.cpp \ VectorStream.hpp version.hpp VFActions.hpp VFReader.cpp \ VFReader.hpp windows.hpp XMLDocument.cpp XMLDocument.hpp \ XMLNode.cpp XMLNode.hpp XMLString.cpp XMLString.hpp \ - ZLibOutputStream.hpp $(am__append_5) + XXHashFunction.hpp ZLibOutputStream.hpp $(am__append_7) EXTRA_DIST = options.xml options.dtd iapi.h ierrors.h MiKTeXCom.hpp MiKTeXCom.cpp dvisvgm_srcdir = $(top_srcdir)/dvisvgm-src AM_CFLAGS = $(WARNING_CFLAGS) $(ZLIB_INCLUDES) $(CODE_COVERAGE_CFLAGS) \ - $(am__append_8) + $(am__append_10) AM_CXXFLAGS = $(WARNING_CFLAGS) -Wnon-virtual-dtor \ -Wno-mismatched-tags -I$(dvisvgm_srcdir)/libs/clipper \ - -I$(dvisvgm_srcdir)/libs/variant/include $(am__append_6) \ - $(am__append_7) $(am__append_9) $(am__append_10) \ - $(am__append_11) $(KPATHSEA_INCLUDES) $(POTRACE_INCLUDES) \ - $(FREETYPE2_INCLUDES) $(ZLIB_INCLUDES) $(LIBGS_INCLUDES) \ - $(CODE_COVERAGE_CFLAGS) $(am__append_13) + -I$(dvisvgm_srcdir)/libs/variant/include $(am__append_8) \ + $(am__append_9) $(am__append_11) $(am__append_12) \ + $(am__append_13) $(am__append_14) $(am__append_15) \ + $(KPATHSEA_INCLUDES) $(POTRACE_INCLUDES) $(FREETYPE2_INCLUDES) \ + $(ZLIB_INCLUDES) $(LIBGS_INCLUDES) $(CODE_COVERAGE_CFLAGS) \ + $(am__append_17) CLEANFILES = *.gcda *.gcno all: all-am @@ -780,6 +789,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GFReader.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GFTracer.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Ghostscript.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HashFunction.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HtmlSpecialHandler.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HyperlinkManager.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ImageToSVG.Po@am__quote@ # am--include-marker @@ -1065,6 +1075,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/GFReader.Po -rm -f ./$(DEPDIR)/GFTracer.Po -rm -f ./$(DEPDIR)/Ghostscript.Po + -rm -f ./$(DEPDIR)/HashFunction.Po -rm -f ./$(DEPDIR)/HtmlSpecialHandler.Po -rm -f ./$(DEPDIR)/HyperlinkManager.Po -rm -f ./$(DEPDIR)/ImageToSVG.Po @@ -1205,6 +1216,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/GFReader.Po -rm -f ./$(DEPDIR)/GFTracer.Po -rm -f ./$(DEPDIR)/Ghostscript.Po + -rm -f ./$(DEPDIR)/HashFunction.Po -rm -f ./$(DEPDIR)/HtmlSpecialHandler.Po -rm -f ./$(DEPDIR)/HyperlinkManager.Po -rm -f ./$(DEPDIR)/ImageToSVG.Po diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp index a13cc775728..a57cc20fc9b 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp @@ -43,9 +43,10 @@ SVGOutput::SVGOutput (const string &base, const string &pattern, int zipLevel) /** Returns an output stream for the given page. * @param[in] page number of current page * @param[in] numPages total number of pages in the DVI file + * @param[in] hash hash value of the current page * @return output stream for the given page */ -ostream& SVGOutput::getPageStream (int page, int numPages) const { - string fname = filename(page, numPages); +ostream& SVGOutput::getPageStream (int page, int numPages, const HashTriple &hashes) const { + string fname = filename(page, numPages, hashes); if (fname.empty()) { if (_zipLevel == 0) { _osptr.reset(); @@ -73,14 +74,18 @@ ostream& SVGOutput::getPageStream (int page, int numPages) const { /** Returns the name of the SVG file containing the given page. * @param[in] page number of current page - * @param[in] numPages total number of pages */ -string SVGOutput::filename (int page, int numPages) const { + * @param[in] numPages total number of pages + * @param[in] hash hash value of current page */ +string SVGOutput::filename (int page, int numPages, const HashTriple &hashes) const { if (_stdout) return ""; - string expanded_pattern = util::trim(expandFormatString(_pattern, page, numPages)); + + string expanded_pattern = util::trim(expandFormatString(_pattern, page, numPages, hashes)); // set and expand default pattern if necessary - if (expanded_pattern.empty()) - expanded_pattern = expandFormatString(numPages > 1 ? "%f-%p" : "%f", page, numPages); + if (expanded_pattern.empty()) { + string pattern = hashes.empty() ? (numPages > 1 ? "%f-%p" : "%f") : "%f-%hd"; + expanded_pattern = expandFormatString(pattern, page, numPages, hashes); + } // append suffix if necessary FilePath outpath(expanded_pattern, true); if (outpath.suffix().empty()) @@ -109,10 +114,15 @@ string SVGOutput::outpath (int page, int numPages) const { /** Replaces expressions in a given string by the corresponding values and returns the result. * Supported constructs: * %f: basename of the current file (filename without suffix) + * %h: hash value of current page * %[0-9]?p: current page number * %[0-9]?P: number of pages in DVI file - * %[0-9]?(expr): arithmetic expression */ -string SVGOutput::expandFormatString (string str, int page, int numPages) const { + * %[0-9]?(expr): arithmetic expression + * @param[in] str string to expand + * @param[in] page number of current page + * @param[in] numPages total number of pages + * @param[in] hash hash value of current page (skipped if empty) */ +string SVGOutput::expandFormatString (string str, int page, int numPages, const HashTriple &hashes) const { string result; while (!str.empty()) { size_t pos = str.find('%'); @@ -125,17 +135,27 @@ string SVGOutput::expandFormatString (string str, int page, int numPages) const str = str.substr(pos); pos = 1; ostringstream oss; - if (isdigit(str[pos])) { + if (!isdigit(str[pos])) + oss << setw(util::ilog10(numPages)+1) << setfill('0'); + else { oss << setw(str[pos]-'0') << setfill('0'); pos++; } - else { - oss << setw(util::ilog10(numPages)+1) << setfill('0'); - } switch (str[pos]) { case 'f': result += _path.basename(); break; + case 'h': { + char variant = pos+1 < str.length() ? str[++pos] : '\0'; + switch (variant) { + case 'd': result += hashes.dviHash(); break; + case 'c': result += hashes.cmbHash(); break; + case 'o': result += hashes.optHash(); break; + default: + throw MessageException("hash type 'd', 'c', or 'o' expected after '%h' in filename pattern"); + } + break; + } case 'p': case 'P': oss << (str[pos] == 'p' ? page : numPages); @@ -168,3 +188,10 @@ string SVGOutput::expandFormatString (string str, int page, int numPages) const } return result; } + + +/** Returns true if methods 'filename' and 'getPageStream' ignore the hash + * parameter because it's not requested in the filename pattern. */ +bool SVGOutput::ignoresHashes () const { + return _stdout || (!_pattern.empty() && _pattern.find("%h") == string::npos); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp index a19501e5523..5b06577a4f3 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp @@ -28,9 +28,26 @@ struct SVGOutputBase { + class HashTriple { + public: + HashTriple () =default; + HashTriple (const std::string &dviHash, const std::string &optHash, const std::string &cmbHash) + : _dviHash(dviHash), _optHash(optHash), _cmbHash(cmbHash) {} + std::string dviHash () const {return _dviHash;} + std::string optHash () const {return _optHash;} + std::string cmbHash () const {return _cmbHash;} + bool empty () const {return _dviHash.empty();} + + private: + std::string _dviHash; ///< hash of plain DVI data + std::string _optHash; ///< hash of options affecting the SVG document + std::string _cmbHash; ///< combined hash of DVI data and options + }; + 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::ostream& getPageStream (int page, int numPages, const HashTriple &hashes=HashTriple()) const =0; + virtual std::string filename (int page, int numPages, const HashTriple &hashes=HashTriple()) const =0; + virtual bool ignoresHashes () const {return true;} }; @@ -40,11 +57,12 @@ class SVGOutput : public SVGOutputBase { 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::ostream& getPageStream (int page, int numPages, const HashTriple &hash=HashTriple()) const override; + std::string filename (int page, int numPages, const HashTriple &hash=HashTriple()) const override; + bool ignoresHashes () const override; protected: - std::string expandFormatString (std::string str, int page, int numPages) const; + std::string expandFormatString (std::string str, int page, int numPages, const HashTriple &hashes) const; private: FilePath _path; diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp new file mode 100644 index 00000000000..231eec9eb9b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp @@ -0,0 +1,88 @@ +/************************************************************************* +** XXHashFunction.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 XXHASHFUNCTION_HPP +#define XXHASHFUNCTION_HPP + +#include <xxhash.h> +#include "HashFunction.hpp" + + +template <int HASH_SIZE> +struct XXHInterface { +}; + +template<> +struct XXHInterface<4> { + using State = XXH32_state_t; + static constexpr auto createState = &XXH32_createState; + static constexpr auto freeState = &XXH32_freeState; + static constexpr auto reset = &XXH32_reset; + static constexpr auto update = &XXH32_update; + static constexpr auto digest = &XXH32_digest; +}; + +template<> +struct XXHInterface<8> { + using State = XXH64_state_t; + static constexpr auto createState = &XXH64_createState; + static constexpr auto freeState = &XXH64_freeState; + static constexpr auto reset = &XXH64_reset; + static constexpr auto update = &XXH64_update; + static constexpr auto digest = &XXH64_digest; +}; + + +/** Implements the HashFunction class for the xxHash algorithms. */ +template <int HASH_BYTES> +class XXHashFunction : public HashFunction { + using Interface = XXHInterface<HASH_BYTES>; + public: + XXHashFunction () : _state(Interface::createState()) {Interface::reset(_state, 0);} + XXHashFunction(const char *data, size_t length) : XXHashFunction() {update(data, length);} + XXHashFunction(const std::string &data) : XXHashFunction() {update(data);} + XXHashFunction(const std::vector<uint8_t> &data) : XXHashFunction() {update(data);} + ~XXHashFunction () {Interface::freeState(_state);} + int digestSize () const override {return HASH_BYTES;} + void reset () override {Interface::reset(_state, 0);} + void update (const char *data, size_t length) override {Interface::update(_state, data, length);} + void update (const std::string &data) override {update(data.data(), data.length());} + void update (const std::vector<uint8_t> &data) override {update(reinterpret_cast<const char*>(data.data()), data.size());} + + std::vector<uint8_t> digestValue () const override { + std::vector<uint8_t> hash(HASH_BYTES); + auto digest = Interface::digest(_state); + for (int i=HASH_BYTES-1; i >= 0; i--) { + hash[i] = digest & 0xff; + digest >>= 8; + } + return hash; + } + + static unsigned version () {return XXH_versionNumber();} + + private: + typename Interface::State *_state; +}; + +using XXH32HashFunction = XXHashFunction<4>; +using XXH64HashFunction = XXHashFunction<8>; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp index 297844cb21d..f9aae6963a5 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp @@ -26,7 +26,6 @@ #include <potracelib.h> #include <sstream> #include <vector> -#include <xxhash.h> #include <zlib.h> #include "CommandLine.hpp" #include "DVIToSVG.hpp" @@ -37,6 +36,7 @@ #include "Font.hpp" #include "FontEngine.hpp" #include "Ghostscript.hpp" +#include "HashFunction.hpp" #include "HyperlinkManager.hpp" #include "Message.hpp" #include "PageSize.hpp" @@ -47,6 +47,7 @@ #include "SourceInput.hpp" #include "SVGOutput.hpp" #include "System.hpp" +#include "XXHashFunction.hpp" #include "utility.hpp" #include "version.hpp" @@ -114,7 +115,12 @@ static bool set_cache_dir (const CommandLine &args) { Message::wstream(true) << "cache directory '" << args.cacheOpt.value() << "' does not exist (caching disabled)\n"; } else if (const char *userdir = FileSystem::userdir()) { - static string cachepath = userdir + string("/.dvisvgm/cache"); +#ifdef _WIN32 + string cachedir = "\\.dvisvgm\\cache"; +#else + string cachedir = "/.dvisvgm/cache"; +#endif + static string cachepath = userdir + cachedir; if (!FileSystem::exists(cachepath)) FileSystem::mkdir(cachepath); PhysicalFont::CACHE_PATH = cachepath.c_str(); @@ -247,7 +253,7 @@ static void print_version (bool extended) { versionInfo.add("clipper", CLIPPER_VERSION); versionInfo.add("freetype", FontEngine::version()); versionInfo.add("potrace", strchr(potrace_version(), ' ')); - versionInfo.add("xxhash", XXH_versionNumber(), 3, 100); + versionInfo.add("xxhash", XXH64HashFunction::version(), 3, 100); versionInfo.add("zlib", zlibVersion()); versionInfo.add("Ghostscript", Ghostscript().revisionstr(), true); #ifndef DISABLE_WOFF @@ -285,6 +291,39 @@ static void init_fontmap (const CommandLine &cmdline) { } +/** Returns a unique string for the current state of the command-line + * options affecting the SVG output. */ +static string svg_options_hash (const CommandLine &cmdline) { + // options affecting the SVG output + vector<const CL::Option*> svg_options = { + &cmdline.bboxOpt, &cmdline.clipjoinOpt, &cmdline.colornamesOpt, &cmdline.commentsOpt, + &cmdline.exactOpt, &cmdline.fontFormatOpt, &cmdline.fontmapOpt, &cmdline.gradOverlapOpt, + &cmdline.gradSegmentsOpt, &cmdline.gradSimplifyOpt, &cmdline.linkmarkOpt, &cmdline.magOpt, + &cmdline.noFontsOpt, &cmdline.noMergeOpt, &cmdline.noSpecialsOpt, &cmdline.noStylesOpt, + &cmdline.precisionOpt, &cmdline.relativeOpt, &cmdline.zoomOpt + }; + string idString = get_transformation_string(cmdline); + for (const CL::Option *opt : svg_options) { + idString += opt->given(); + idString += opt->valueString(); + } + return XXH64HashFunction(idString).digestString(); +} + + +static bool list_page_hashes (const CommandLine &cmdline, DVIToSVG &dvisvg) { + if (cmdline.pageHashesOpt.given()) { + DVIToSVG::PAGE_HASH_SETTINGS.setParameters(cmdline.pageHashesOpt.value()); + DVIToSVG::PAGE_HASH_SETTINGS.setOptionHash(svg_options_hash(cmdline)); + if (DVIToSVG::PAGE_HASH_SETTINGS.isSet(DVIToSVG::HashSettings::P_LIST)) { + dvisvg.listHashes(cmdline.pageOpt.value(), cout); + return true; + } + } + return false; +} + + static void set_variables (const CommandLine &cmdline) { Message::COLORIZE = cmdline.colorOpt.given(); if (cmdline.progressOpt.given()) { @@ -390,6 +429,8 @@ int main (int argc, char *argv[]) { else { init_fontmap(cmdline); DVIToSVG dvi2svg(srcin.getInputStream(), out); + if (list_page_hashes(cmdline, dvi2svg)) + return 0; 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 b8b43fcd5f8..c221bcdacd0 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml @@ -162,6 +162,10 @@ <arg type="string" name="prefixes" optional="yes"/> <description>don't process [selected] specials</description> </option> + <option long="page-hashes" short="H"> + <arg type="string" name="params" optional="yes" default="xxh64"/> + <description>activate usage of page hashes</description> + </option> <option long="trace-all" short="a"> <arg name="retrace" type="bool" optional="yes" default="false"/> <description>trace all glyphs of bitmap fonts</description> diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp index cf86d2ca2d4..2245a2bef1c 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.5"; +constexpr const char *PROGRAM_VERSION = "2.6"; #endif |