summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/src
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src')
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/BasicDVIReader.hpp4
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/CommandLine.hpp2
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.cpp43
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/DVIReader.hpp2
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.cpp133
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/DVIToSVG.hpp22
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/Ghostscript.cpp4
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.cpp84
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/HashFunction.hpp47
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/MD5HashFunction.hpp58
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.am17
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/Makefile.in184
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.cpp53
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/SVGOutput.hpp28
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/XXHashFunction.hpp88
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/dvisvgm.cpp47
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/options.xml4
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/version.hpp2
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 &paramstr) {
+ 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 &paramstr);
+ 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