mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Redaction bugfixing
This commit is contained in:
		| @@ -710,4 +710,14 @@ QString PDFActionURI::getURIString() const | |||||||
|     return QString::fromUtf8(m_URI); |     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 | }   // namespace pdf | ||||||
|   | |||||||
| @@ -191,6 +191,9 @@ public: | |||||||
|     const PDFDestination& getDestination() const { return m_destination; } |     const PDFDestination& getDestination() const { return m_destination; } | ||||||
|     const PDFDestination& getStructureDestination() const { return m_structureDestination; } |     const PDFDestination& getStructureDestination() const { return m_structureDestination; } | ||||||
|  |  | ||||||
|  |     void setDestination(const PDFDestination& destination); | ||||||
|  |     void setStructureDestination(const PDFDestination& structureDestination); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     PDFDestination m_destination; |     PDFDestination m_destination; | ||||||
|     PDFDestination m_structureDestination; |     PDFDestination m_structureDestination; | ||||||
|   | |||||||
| @@ -367,6 +367,20 @@ bool PDFOptimizer::performMergeIdenticalObjects() | |||||||
|     auto processEntry = [this, &counter, &objects, &mutex, &replacementMap](size_t index) |     auto processEntry = [this, &counter, &objects, &mutex, &replacementMap](size_t index) | ||||||
|     { |     { | ||||||
|         const PDFObjectStorage::Entry& entry = objects[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) |         for (size_t i = 0; i < index; ++i) | ||||||
|         { |         { | ||||||
|             if (objects[i].object.isNull()) |             if (objects[i].object.isNull()) | ||||||
|   | |||||||
| @@ -136,6 +136,16 @@ void PDFOutlineItem::setStructureElement(PDFObjectReference structureElement) | |||||||
|     m_structureElement = 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 | bool PDFOutlineItem::isFontBold() const | ||||||
| { | { | ||||||
|     return m_fontBold; |     return m_fontBold; | ||||||
| @@ -171,6 +181,11 @@ const PDFAction* PDFOutlineItem::getAction() const | |||||||
|     return m_action.get(); |     return m_action.get(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | PDFAction* PDFOutlineItem::getAction() | ||||||
|  | { | ||||||
|  |     return m_action.get(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void PDFOutlineItem::setAction(const PDFActionPtr& action) | void PDFOutlineItem::setAction(const PDFActionPtr& action) | ||||||
| { | { | ||||||
|     m_action = action; |     m_action = action; | ||||||
|   | |||||||
| @@ -48,6 +48,7 @@ public: | |||||||
|     static QSharedPointer<PDFOutlineItem> parse(const PDFDocument* document, const PDFObject& root); |     static QSharedPointer<PDFOutlineItem> parse(const PDFDocument* document, const PDFObject& root); | ||||||
|  |  | ||||||
|     const PDFAction* getAction() const; |     const PDFAction* getAction() const; | ||||||
|  |     PDFAction* getAction(); | ||||||
|     void setAction(const PDFActionPtr& action); |     void setAction(const PDFActionPtr& action); | ||||||
|  |  | ||||||
|     QColor getTextColor() const; |     QColor getTextColor() const; | ||||||
| @@ -62,6 +63,8 @@ public: | |||||||
|     PDFObjectReference getStructureElement() const; |     PDFObjectReference getStructureElement() const; | ||||||
|     void setStructureElement(PDFObjectReference structureElement); |     void setStructureElement(PDFObjectReference structureElement); | ||||||
|  |  | ||||||
|  |     void apply(const std::function<void(PDFOutlineItem*)>& functor); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     static void parseImpl(const PDFDocument* document, |     static void parseImpl(const PDFDocument* document, | ||||||
|                           PDFOutlineItem* parent, |                           PDFOutlineItem* parent, | ||||||
|   | |||||||
| @@ -51,6 +51,8 @@ PDFDocument PDFRedact::perform(Options options) | |||||||
|                          PDFRenderer::None, |                          PDFRenderer::None, | ||||||
|                          *m_meshQualitySettings); |                          *m_meshQualitySettings); | ||||||
|  |  | ||||||
|  |     std::map<PDFObjectReference, PDFObjectReference> mapOldPageRefToNewPageRef; | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < m_document->getCatalog()->getPageCount(); ++i) |     for (size_t i = 0; i < m_document->getCatalog()->getPageCount(); ++i) | ||||||
|     { |     { | ||||||
|         const PDFPage* page = m_document->getCatalog()->getPage(i); |         const PDFPage* page = m_document->getCatalog()->getPage(i); | ||||||
| @@ -59,6 +61,7 @@ PDFDocument PDFRedact::perform(Options options) | |||||||
|         renderer.compile(&compiledPage, i); |         renderer.compile(&compiledPage, i); | ||||||
|  |  | ||||||
|         PDFObjectReference newPageReference = builder.appendPage(page->getMediaBox()); |         PDFObjectReference newPageReference = builder.appendPage(page->getMediaBox()); | ||||||
|  |         mapOldPageRefToNewPageRef[page->getPageReference()] = newPageReference; | ||||||
|  |  | ||||||
|         if (!page->getCropBox().isEmpty()) |         if (!page->getCropBox().isEmpty()) | ||||||
|         { |         { | ||||||
| @@ -127,11 +130,43 @@ PDFDocument PDFRedact::perform(Options options) | |||||||
|  |  | ||||||
|     if (options.testFlag(CopyOutline)) |     if (options.testFlag(CopyOutline)) | ||||||
|     { |     { | ||||||
|         const PDFOutlineItem* outlineItem = m_document->getCatalog()->getOutlineRootPtr().data(); |         PDFObject catalog = m_document->getObject(m_document->getTrailerDictionary()->get("Root")); | ||||||
|  |         if (const PDFDictionary* catalogDictionary = m_document->getDictionaryFromObject(catalog)) | ||||||
|         if (outlineItem) |  | ||||||
|         { |         { | ||||||
|             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()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user