mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-05 18:54:14 +02:00
Give a repeatable PDF the same document id however the project was made (#1178)
With SOURCE_DATE_EPOCH set, the document id came from the project's uuid and a hash of the .qet file. A project generated again from the same data has new uuids, so its PDF differed in the id alone (XMP DocumentID and trailer /ID, 120 bytes) although every page was the same. Qt now writes a fixed placeholder id, and once the file is written the placeholder is replaced with an id derived from the bytes of the PDF: the same pages give the same id. Same length, so no offset changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+11
-13
@@ -42,7 +42,6 @@
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QDomDocument>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDate>
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
@@ -63,7 +62,6 @@
|
||||
#include <QTextStream>
|
||||
#include <QTimeZone>
|
||||
#include <QTransform>
|
||||
#include <QUuid>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -189,18 +187,16 @@ int exportPdf(QETProject &project, const QString &output,
|
||||
|
||||
// SOURCE_DATE_EPOCH (reproducible-builds.org) asks for the same file
|
||||
// from the same input: the time it names instead of now, and a document
|
||||
// id from the project file instead of a random one. Qt has no setter for
|
||||
// the dates, so they are rewritten once the file is written. Before
|
||||
// Qt 6.8 there is no document id to set: it is only written for PDF/A.
|
||||
// id from what the PDF shows instead of a random one. Qt has no setter
|
||||
// for the dates, and the content is not known yet, so both are
|
||||
// rewritten once the file is written; Qt writes a fixed id until then.
|
||||
// The id does not come from the project file, whose uuids are new each
|
||||
// time a project is generated again from the same data. Before Qt 6.8
|
||||
// there is no document id to set: it is only written for PDF/A.
|
||||
const QDateTime sourceDate = sourceDateEpoch();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
if (sourceDate.isValid()) {
|
||||
QCryptographicHash hash(QCryptographicHash::Sha256);
|
||||
QFile file(project.filePath());
|
||||
if (file.open(QIODevice::ReadOnly))
|
||||
hash.addData(&file);
|
||||
writer.setDocumentId(QUuid::createUuidV5(project.uuid(), hash.result()));
|
||||
}
|
||||
if (sourceDate.isValid())
|
||||
writer.setDocumentId(PdfLinks::placeholderDocumentId());
|
||||
#endif
|
||||
|
||||
QPainter painter;
|
||||
@@ -277,8 +273,10 @@ int exportPdf(QETProject &project, const QString &output,
|
||||
// the cross-references jump inside the document in any PDF viewer.
|
||||
PdfLinks::convertUriToGoTo(output);
|
||||
PdfLinks::removeUnusedPdfxNamespace(output);
|
||||
if (sourceDate.isValid())
|
||||
if (sourceDate.isValid()) {
|
||||
PdfLinks::setDocumentDate(output, sourceDate);
|
||||
PdfLinks::setDocumentIdFromContent(output);
|
||||
}
|
||||
|
||||
out << "Exported " << diagrams.size() << " page(s) -> " << output << "\n";
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user