mirror of https://github.com/JakubMelka/PDF4QT.git
Redaction bugfixing
This commit is contained in:
parent
00e67ec2b1
commit
b29791b890
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue