diff --git a/PdfForQtLib/sources/pdfutils.cpp b/PdfForQtLib/sources/pdfutils.cpp
index bcf2307..4e32120 100644
--- a/PdfForQtLib/sources/pdfutils.cpp
+++ b/PdfForQtLib/sources/pdfutils.cpp
@@ -284,6 +284,12 @@ void PDFClosedIntervalSet::addInterval(PDFInteger low, PDFInteger high)
normalize();
}
+void PDFClosedIntervalSet::merge(const PDFClosedIntervalSet& other)
+{
+ m_intervals.insert(m_intervals.end(), other.m_intervals.cbegin(), other.m_intervals.cend());
+ normalize();
+}
+
bool PDFClosedIntervalSet::isCovered(PDFInteger low, PDFInteger high)
{
PDFClosedIntervalSet temporary;
diff --git a/PdfForQtLib/sources/pdfutils.h b/PdfForQtLib/sources/pdfutils.h
index f2055c9..bb65382 100644
--- a/PdfForQtLib/sources/pdfutils.h
+++ b/PdfForQtLib/sources/pdfutils.h
@@ -604,6 +604,9 @@ public:
/// \param value Value
void addValue(PDFInteger value) { addInterval(value, value); }
+ /// Merge with other interval set
+ void merge(const PDFClosedIntervalSet& other);
+
/// Returns true, if given closed range is subset of
/// this interval set.
bool isCovered(PDFInteger low, PDFInteger high);
diff --git a/PdfTool/PdfTool.pro b/PdfTool/PdfTool.pro
index 06e0b6e..ad166f2 100644
--- a/PdfTool/PdfTool.pro
+++ b/PdfTool/PdfTool.pro
@@ -46,6 +46,7 @@ SOURCES += \
pdftoolinfo.cpp \
pdftoolinfojavascript.cpp \
pdftoolinfonameddestinations.cpp \
+ pdftoolinfopageboxes.cpp \
pdftoolverifysignatures.cpp \
pdftoolxml.cpp
@@ -65,5 +66,6 @@ HEADERS += \
pdftoolinfo.h \
pdftoolinfojavascript.h \
pdftoolinfonameddestinations.h \
+ pdftoolinfopageboxes.h \
pdftoolverifysignatures.h \
pdftoolxml.h
diff --git a/PdfTool/pdftoolinfopageboxes.cpp b/PdfTool/pdftoolinfopageboxes.cpp
new file mode 100644
index 0000000..e6c7d7b
--- /dev/null
+++ b/PdfTool/pdftoolinfopageboxes.cpp
@@ -0,0 +1,160 @@
+// Copyright (C) 2020 Jakub Melka
+//
+// This file is part of PdfForQt.
+//
+// PdfForQt is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// PdfForQt 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with PDFForQt. If not, see .
+
+#include "pdftoolinfopageboxes.h"
+#include "pdfutils.h"
+
+namespace pdftool
+{
+
+static PDFToolInfoPageBoxesApplication s_infoPageBoxesApplication;
+
+QString PDFToolInfoPageBoxesApplication::getStandardString(StandardString standardString) const
+{
+ switch (standardString)
+ {
+ case Command:
+ return "info-page-boxes";
+
+ case Name:
+ return PDFToolTranslationContext::tr("Info (page boxes)");
+
+ case Description:
+ return PDFToolTranslationContext::tr("Retrieve informations about page boxes in a document.");
+
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+
+ return QString();
+}
+
+struct PDFPageBoxInfo
+{
+ bool operator==(const PDFPageBoxInfo& other) const
+ {
+ return mediaBox == other.mediaBox &&
+ cropBox == other.cropBox &&
+ bleedBox == other.bleedBox &&
+ trimBox == other.trimBox &&
+ artBox == other.artBox;
+ }
+
+ pdf::PDFClosedIntervalSet pages;
+ QRectF mediaBox;
+ QRectF cropBox;
+ QRectF bleedBox;
+ QRectF trimBox;
+ QRectF artBox;
+};
+
+int PDFToolInfoPageBoxesApplication::execute(const PDFToolOptions& options)
+{
+ pdf::PDFDocument document;
+ QByteArray sourceData;
+ if (!readDocument(options, document, &sourceData))
+ {
+ return ErrorDocumentReading;
+ }
+
+ QString parseError;
+ std::vector pages = options.getPageRange(document.getCatalog()->getPageCount(), parseError, true);
+
+ if (!parseError.isEmpty())
+ {
+ PDFConsole::writeError(parseError, options.outputCodec);
+ return ErrorInvalidArguments;
+ }
+
+ std::vector infos;
+ for (const pdf::PDFInteger pageIndex : pages)
+ {
+ const pdf::PDFPage* page = document.getCatalog()->getPage(pageIndex);
+
+ PDFPageBoxInfo info;
+ info.mediaBox = page->getMediaBoxMM();
+ info.cropBox = page->getCropBoxMM();
+ info.bleedBox = page->getBleedBoxMM();
+ info.trimBox = page->getTrimBoxMM();
+ info.artBox = page->getArtBoxMM();
+
+ auto it = std::find(infos.begin(), infos.end(), info);
+ if (it != infos.end())
+ {
+ it->pages.addValue(pageIndex + 1);
+ }
+ else
+ {
+ info.pages.addValue(pageIndex + 1);
+ infos.emplace_back(qMove(info));
+ }
+ }
+
+ QLocale locale;
+
+ PDFOutputFormatter formatter(options.outputStyle, options.outputCodec);
+ formatter.beginDocument("info-page-boxes", PDFToolTranslationContext::tr("Page boxes in document %1").arg(options.document));
+
+ auto writeBox = [&formatter, &locale](const QString& name, const QString& title, const QRectF& rect)
+ {
+ formatter.beginTableRow(name);
+ formatter.writeTableColumn("title", title);
+
+ if (rect.isValid())
+ {
+ formatter.writeTableColumn("value", QString("[ %1 %2 %3 %4 ]").arg(locale.toString(rect.left()), locale.toString(rect.top()), locale.toString(rect.right()), locale.toString(rect.bottom())));
+ }
+ else
+ {
+ formatter.writeTableColumn("value", "null");
+ }
+
+ formatter.endTableRow();
+ };
+
+ for (const PDFPageBoxInfo& info : infos)
+ {
+ formatter.endl();
+ formatter.beginTable("page-range", PDFToolTranslationContext::tr("Pages %1").arg(info.pages.toText()));
+
+ formatter.beginTableHeaderRow("header");
+ formatter.writeTableHeaderColumn("box", PDFToolTranslationContext::tr("Box"), Qt::AlignLeft);
+ formatter.writeTableHeaderColumn("value", PDFToolTranslationContext::tr("Value"), Qt::AlignLeft);
+ formatter.endTableHeaderRow();
+
+ writeBox("media", PDFToolTranslationContext::tr("Media"), info.mediaBox);
+ writeBox("crop", PDFToolTranslationContext::tr("Crop"), info.cropBox);
+ writeBox("bleed", PDFToolTranslationContext::tr("Bleed"), info.bleedBox);
+ writeBox("trim", PDFToolTranslationContext::tr("Trim"), info.trimBox);
+ writeBox("art", PDFToolTranslationContext::tr("Art"), info.artBox);
+
+ formatter.endTable();
+ }
+
+ formatter.endDocument();
+ PDFConsole::writeText(formatter.getString(), options.outputCodec);
+
+ return ExitSuccess;
+}
+
+PDFToolAbstractApplication::Options PDFToolInfoPageBoxesApplication::getOptionsFlags() const
+{
+ return ConsoleFormat | OpenDocument | PageSelector;
+}
+
+} // namespace pdftool
diff --git a/PdfTool/pdftoolinfopageboxes.h b/PdfTool/pdftoolinfopageboxes.h
new file mode 100644
index 0000000..73d3f12
--- /dev/null
+++ b/PdfTool/pdftoolinfopageboxes.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2020 Jakub Melka
+//
+// This file is part of PdfForQt.
+//
+// PdfForQt is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// PdfForQt 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with PDFForQt. If not, see .
+
+#ifndef PDFTOOLINFOPAGEBOXES_H
+#define PDFTOOLINFOPAGEBOXES_H
+
+#include "pdftoolabstractapplication.h"
+
+namespace pdftool
+{
+
+class PDFToolInfoPageBoxesApplication : public PDFToolAbstractApplication
+{
+public:
+ virtual QString getStandardString(StandardString standardString) const override;
+ virtual int execute(const PDFToolOptions& options) override;
+ virtual Options getOptionsFlags() const override;
+};
+
+} // namespace pdftool
+
+
+#endif // PDFTOOLINFOPAGEBOXES_H