diff --git a/PdfTool/PdfTool.pro b/PdfTool/PdfTool.pro index 7ab3ae7..6fc6041 100644 --- a/PdfTool/PdfTool.pro +++ b/PdfTool/PdfTool.pro @@ -52,11 +52,13 @@ SOURCES += \ pdftoolfetchtext.cpp \ pdftoolinfo.cpp \ pdftoolinfofonts.cpp \ + pdftoolinfoinks.cpp \ pdftoolinfojavascript.cpp \ pdftoolinfometadata.cpp \ pdftoolinfonameddestinations.cpp \ pdftoolinfopageboxes.cpp \ pdftoolinfostructuretree.cpp \ + pdftoolinkcoverage.cpp \ pdftooloptimize.cpp \ pdftoolrender.cpp \ pdftoolseparate.cpp \ @@ -87,11 +89,13 @@ HEADERS += \ pdftoolfetchtext.h \ pdftoolinfo.h \ pdftoolinfofonts.h \ + pdftoolinfoinks.h \ pdftoolinfojavascript.h \ pdftoolinfometadata.h \ pdftoolinfonameddestinations.h \ pdftoolinfopageboxes.h \ pdftoolinfostructuretree.h \ + pdftoolinkcoverage.h \ pdftooloptimize.h \ pdftoolrender.h \ pdftoolseparate.h \ diff --git a/PdfTool/pdftoolinfoinks.cpp b/PdfTool/pdftoolinfoinks.cpp new file mode 100644 index 0000000..afbd653 --- /dev/null +++ b/PdfTool/pdftoolinfoinks.cpp @@ -0,0 +1,106 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of Pdf4Qt. +// +// Pdf4Qt 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 +// with the written consent of the copyright owner, any later version. +// +// Pdf4Qt 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 Pdf4Qt. If not, see . + +#include "pdftoolinfoinks.h" +#include "pdftransparencyrenderer.h" + +namespace pdftool +{ + +static PDFToolInfoInksApplication s_infoInksApplication; + +QString PDFToolInfoInksApplication::getStandardString(StandardString standardString) const +{ + switch (standardString) + { + case Command: + return "info-inks"; + + case Name: + return PDFToolTranslationContext::tr("Info about used inks"); + + case Description: + return PDFToolTranslationContext::tr("Retrieve information about inks used in a document."); + + default: + Q_ASSERT(false); + break; + } + + return QString(); +} + +int PDFToolInfoInksApplication::execute(const PDFToolOptions& options) +{ + pdf::PDFDocument document; + QByteArray sourceData; + if (!readDocument(options, document, &sourceData, false)) + { + return ErrorDocumentReading; + } + + pdf::PDFCMSManager cmsManager(nullptr); + cmsManager.setDocument(&document); + cmsManager.setSettings(options.cmsSettings); + + PDFOutputFormatter formatter(options.outputStyle, options.outputCodec); + formatter.beginDocument("info-inks", PDFToolTranslationContext::tr("Inks")); + formatter.endl(); + + formatter.beginTable("inks", PDFToolTranslationContext::tr("Ink list")); + + formatter.beginTableHeaderRow("header"); + formatter.writeTableHeaderColumn("index", PDFToolTranslationContext::tr("No."), Qt::AlignLeft); + formatter.writeTableHeaderColumn("id", PDFToolTranslationContext::tr("Identifier"), Qt::AlignLeft); + formatter.writeTableHeaderColumn("name", PDFToolTranslationContext::tr("Name"), Qt::AlignLeft); + formatter.writeTableHeaderColumn("is-spot", PDFToolTranslationContext::tr("Spot"), Qt::AlignLeft); + formatter.writeTableHeaderColumn("color", PDFToolTranslationContext::tr("Color"), Qt::AlignLeft); + formatter.endTableHeaderRow(); + + pdf::PDFInkMapper mapper(&cmsManager, &document); + mapper.createSpotColors(true); + std::vector colorInfos = mapper.getSeparations(4, true); + + QLocale locale; + + int colorIndex = 0; + for (const pdf::PDFInkMapper::ColorInfo& colorInfo : colorInfos) + { + formatter.beginTableRow("ink", ++colorIndex); + formatter.writeTableColumn("index", locale.toString(colorIndex), Qt::AlignRight); + formatter.writeTableColumn("id", colorInfo.name.toPercentEncoding(" ")); + formatter.writeTableColumn("name", colorInfo.textName); + formatter.writeTableColumn("is-spot", colorInfo.isSpot ? PDFToolTranslationContext::tr("Yes") : PDFToolTranslationContext::tr("No"), Qt::AlignCenter); + formatter.writeTableColumn("color", colorInfo.color.name(), Qt::AlignLeft); + formatter.endTableRow(); + }; + + formatter.endTable(); + + formatter.endDocument(); + PDFConsole::writeText(formatter.getString(), options.outputCodec); + + return ExitSuccess; +} + +PDFToolAbstractApplication::Options PDFToolInfoInksApplication::getOptionsFlags() const +{ + return ConsoleFormat | OpenDocument | ColorManagementSystem; +} + + +} // namespace pdf diff --git a/PdfTool/pdftoolinfoinks.h b/PdfTool/pdftoolinfoinks.h new file mode 100644 index 0000000..c3fc4d1 --- /dev/null +++ b/PdfTool/pdftoolinfoinks.h @@ -0,0 +1,36 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of Pdf4Qt. +// +// Pdf4Qt 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 +// with the written consent of the copyright owner, any later version. +// +// Pdf4Qt 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 Pdf4Qt. If not, see . + +#ifndef PDFTOOLINFOINKS_H +#define PDFTOOLINFOINKS_H + +#include "pdftoolabstractapplication.h" + +namespace pdftool +{ + +class PDFToolInfoInksApplication : 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 // PDFTOOLINFOINKS_H diff --git a/PdfTool/pdftoolinkcoverage.cpp b/PdfTool/pdftoolinkcoverage.cpp new file mode 100644 index 0000000..9b36754 --- /dev/null +++ b/PdfTool/pdftoolinkcoverage.cpp @@ -0,0 +1,149 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of Pdf4Qt. +// +// Pdf4Qt 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 +// with the written consent of the copyright owner, any later version. +// +// Pdf4Qt 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 Pdf4Qt. If not, see . + +#include "pdftoolinkcoverage.h" +#include "pdftransparencyrenderer.h" + +namespace pdftool +{ + +static PDFToolInkCoverageApplication s_toolInkCoverageApplication; + +QString PDFToolInkCoverageApplication::getStandardString(PDFToolAbstractApplication::StandardString standardString) const +{ + switch (standardString) + { + case Command: + return "ink-coverage"; + + case Name: + return PDFToolTranslationContext::tr("Ink coverage"); + + case Description: + return PDFToolTranslationContext::tr("Calculate ink coverage of the selected pages, or a whole document."); + + default: + Q_ASSERT(false); + break; + } + + return QString(); +} + +int PDFToolInkCoverageApplication::execute(const PDFToolOptions& options) +{ + pdf::PDFDocument document; + QByteArray sourceData; + if (!readDocument(options, document, &sourceData, false)) + { + return ErrorDocumentReading; + } + + QString parseError; + std::vector pageIndices = options.getPageRange(document.getCatalog()->getPageCount(), parseError, true); + + if (!parseError.isEmpty() || pageIndices.empty()) + { + PDFConsole::writeError(parseError, options.outputCodec); + return ErrorInvalidArguments; + } + + // We are ready to calculate the document's ink coverage + pdf::PDFOptionalContentActivity optionalContentActivity(&document, pdf::OCUsage::Print, nullptr); + pdf::PDFCMSManager cmsManager(nullptr); + cmsManager.setDocument(&document); + cmsManager.setSettings(options.cmsSettings); + + pdf::PDFFontCache fontCache(pdf::DEFAULT_FONT_CACHE_LIMIT, pdf::DEFAULT_REALIZED_FONT_CACHE_LIMIT); + pdf::PDFModifiedDocument md(&document, &optionalContentActivity); + fontCache.setDocument(md); + fontCache.setCacheShrinkEnabled(nullptr, false); + + pdf::PDFInkMapper inkMapper(&cmsManager, &document); + inkMapper.createSpotColors(true); + + pdf::PDFInkCoverageCalculator calculator(&document, + &fontCache, + &cmsManager, + &optionalContentActivity, + &inkMapper, + nullptr, + pdf::PDFTransparencyRendererSettings()); + calculator.perform(QSize(1920, 1920), pageIndices); + + fontCache.setCacheShrinkEnabled(nullptr, true); + + PDFOutputFormatter formatter(options.outputStyle, options.outputCodec); + formatter.beginDocument("ink-coverage", PDFToolTranslationContext::tr("Ink Coverage")); + formatter.endl(); + + formatter.beginTable("ink-coverage-by-page", PDFToolTranslationContext::tr("Ink Coverage by Page")); + + bool isHeaderProcessed = false; + std::vector headerCoverage; + for (const pdf::PDFInteger pageIndex : pageIndices) + { + const std::vector* coverage = calculator.getInkCoverage(pageIndex); + + if (!coverage) + { + // Jakub Melka: Something bad happened? + continue; + } + + if (!isHeaderProcessed) + { + formatter.beginTableHeaderRow("header"); + formatter.writeTableHeaderColumn("page-no", PDFToolTranslationContext::tr("Page No."), Qt::AlignLeft); + for (const pdf::PDFInkCoverageCalculator::InkCoverageChannelInfo& info : *coverage) + { + formatter.writeTableHeaderColumn(QString("%1-ratio").arg(QString::fromLatin1(info.name)), PDFToolTranslationContext::tr("%1 Ratio [%]").arg(info.textName), Qt::AlignLeft); + formatter.writeTableHeaderColumn(QString("%1-area").arg(QString::fromLatin1(info.name)), PDFToolTranslationContext::tr("%1 Covered [mm^2]").arg(info.textName), Qt::AlignLeft); + } + headerCoverage = *coverage; + formatter.endTableHeaderRow(); + + isHeaderProcessed = true; + } + + for (const auto& info : *headerCoverage) + { + pdf::PDFInkCoverageCalculator::InkCoverageChannelInfo* channelInfo = pdf::PDFInkCoverageCalculator::findCoverageInfoByName(*coverage, info.name); + pdf::PDFInkCoverageCalculator::InkCoverageChannelInfo* sumChannelInfo = pdf::PDFInkCoverageCalculator::findCoverageInfoByName(headerCoverage, info.name); + + if (sumChannelInfo && channelInfo) + { + sumChannelInfo->coveredArea += channelInfo->coveredArea; + } + + } + } + + formatter.endTable(); + + formatter.endDocument(); + PDFConsole::writeText(formatter.getString(), options.outputCodec); + + return ExitSuccess; +} + +PDFToolAbstractApplication::Options PDFToolInkCoverageApplication::getOptionsFlags() const +{ + return ConsoleFormat | OpenDocument | PageSelector | ColorManagementSystem; +} + +} // namespace pdftool diff --git a/PdfTool/pdftoolinkcoverage.h b/PdfTool/pdftoolinkcoverage.h new file mode 100644 index 0000000..bf6f3ed --- /dev/null +++ b/PdfTool/pdftoolinkcoverage.h @@ -0,0 +1,35 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of Pdf4Qt. +// +// Pdf4Qt 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 +// with the written consent of the copyright owner, any later version. +// +// Pdf4Qt 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 Pdf4Qt. If not, see . + +#ifndef PDFTOOLINKCOVERAGE_H +#define PDFTOOLINKCOVERAGE_H + +#include "pdftoolabstractapplication.h" + +namespace pdftool +{ + +class PDFToolInkCoverageApplication : 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 // PDFTOOLINKCOVERAGE_H