Redaction bugfixing

This commit is contained in:
Jakub Melka 2020-12-31 15:51:03 +01:00
parent 00e67ec2b1
commit b29791b890
6 changed files with 84 additions and 4 deletions

View File

@ -710,4 +710,14 @@ QString PDFActionURI::getURIString() const
return QString::fromUtf8(m_URI);
}
void PDFActionGoTo::setDestination(const PDFDestination& destination)
{
m_destination = destination;
}
void PDFActionGoTo::setStructureDestination(const PDFDestination& structureDestination)
{
m_structureDestination = structureDestination;
}
} // namespace pdf

View File

@ -191,6 +191,9 @@ public:
const PDFDestination& getDestination() const { return m_destination; }
const PDFDestination& getStructureDestination() const { return m_structureDestination; }
void setDestination(const PDFDestination& destination);
void setStructureDestination(const PDFDestination& structureDestination);
private:
PDFDestination m_destination;
PDFDestination m_structureDestination;

View File

@ -367,6 +367,20 @@ bool PDFOptimizer::performMergeIdenticalObjects()
auto processEntry = [this, &counter, &objects, &mutex, &replacementMap](size_t index)
{
const PDFObjectStorage::Entry& entry = objects[index];
// We do not merge special objects, such as pages
if (const PDFDictionary* dictionary = m_storage.getDictionaryFromObject(entry.object))
{
PDFObject nameObject = m_storage.getObject(dictionary->get("Type"));
if (nameObject.isName())
{
if (nameObject.getString() == "Page")
{
return;
}
}
}
for (size_t i = 0; i < index; ++i)
{
if (objects[i].object.isNull())

View File

@ -136,6 +136,16 @@ void PDFOutlineItem::setStructureElement(PDFObjectReference structureElement)
m_structureElement = structureElement;
}
void PDFOutlineItem::apply(const std::function<void (PDFOutlineItem*)>& functor)
{
functor(this);
for (const auto& item : m_children)
{
item->apply(functor);
}
}
bool PDFOutlineItem::isFontBold() const
{
return m_fontBold;
@ -171,6 +181,11 @@ const PDFAction* PDFOutlineItem::getAction() const
return m_action.get();
}
PDFAction* PDFOutlineItem::getAction()
{
return m_action.get();
}
void PDFOutlineItem::setAction(const PDFActionPtr& action)
{
m_action = action;

View File

@ -48,6 +48,7 @@ public:
static QSharedPointer<PDFOutlineItem> parse(const PDFDocument* document, const PDFObject& root);
const PDFAction* getAction() const;
PDFAction* getAction();
void setAction(const PDFActionPtr& action);
QColor getTextColor() const;
@ -62,6 +63,8 @@ public:
PDFObjectReference getStructureElement() const;
void setStructureElement(PDFObjectReference structureElement);
void apply(const std::function<void(PDFOutlineItem*)>& functor);
private:
static void parseImpl(const PDFDocument* document,
PDFOutlineItem* parent,

View File

@ -51,6 +51,8 @@ PDFDocument PDFRedact::perform(Options options)
PDFRenderer::None,
*m_meshQualitySettings);
std::map<PDFObjectReference, PDFObjectReference> mapOldPageRefToNewPageRef;
for (size_t i = 0; i < m_document->getCatalog()->getPageCount(); ++i)
{
const PDFPage* page = m_document->getCatalog()->getPage(i);
@ -59,6 +61,7 @@ PDFDocument PDFRedact::perform(Options options)
renderer.compile(&compiledPage, i);
PDFObjectReference newPageReference = builder.appendPage(page->getMediaBox());
mapOldPageRefToNewPageRef[page->getPageReference()] = newPageReference;
if (!page->getCropBox().isEmpty())
{
@ -127,11 +130,43 @@ PDFDocument PDFRedact::perform(Options options)
if (options.testFlag(CopyOutline))
{
const PDFOutlineItem* outlineItem = m_document->getCatalog()->getOutlineRootPtr().data();
if (outlineItem)
PDFObject catalog = m_document->getObject(m_document->getTrailerDictionary()->get("Root"));
if (const PDFDictionary* catalogDictionary = m_document->getDictionaryFromObject(catalog))
{
builder.setOutline(outlineItem);
if (catalogDictionary->hasKey("Outlines"))
{
QSharedPointer<PDFOutlineItem> outlineRoot = PDFOutlineItem::parse(m_document, catalogDictionary->get("Outlines"));
if (outlineRoot)
{
auto resolveNamedDestination = [this, &mapOldPageRefToNewPageRef](PDFOutlineItem* item)
{
PDFActionGoTo* action = dynamic_cast<PDFActionGoTo*>(item->getAction());
if (action)
{
if (action->getDestination().isNamedDestination())
{
const PDFDestination* destination = m_document->getCatalog()->getNamedDestination(action->getDestination().getName());
if (destination)
{
action->setDestination(*destination);
}
}
PDFDestination destination = action->getDestination();
auto it = mapOldPageRefToNewPageRef.find(destination.getPageReference());
if (it != mapOldPageRefToNewPageRef.cend())
{
destination.setPageReference(it->second);
action->setDestination(destination);
}
}
};
outlineRoot->apply(resolveNamedDestination);
builder.setOutline(outlineRoot.data());
}
}
}
}