From f739e9f544ebab02724c3ef7920cd7ca10d9213b Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Thu, 4 Nov 2021 20:01:30 +0100 Subject: [PATCH] XFA: xfa engine parsing template --- Pdf4QtLib/Pdf4QtLib.pro | 2 +- Pdf4QtLib/sources/pdfform.cpp | 2 + Pdf4QtLib/sources/pdfform.h | 3 ++ Pdf4QtLib/sources/pdfxfaengine.cpp | 83 +++++++++++++++++++++++++++++- Pdf4QtLib/sources/pdfxfaengine.h | 4 ++ 5 files changed, 92 insertions(+), 2 deletions(-) diff --git a/Pdf4QtLib/Pdf4QtLib.pro b/Pdf4QtLib/Pdf4QtLib.pro index 218002a..3ba04c8 100644 --- a/Pdf4QtLib/Pdf4QtLib.pro +++ b/Pdf4QtLib/Pdf4QtLib.pro @@ -242,7 +242,7 @@ DEPENDPATH += $$Pdf4Qt_DEPENDENCIES_PATH/lcms2/include # ensure debug info even for RELEASE build CONFIG += force_debug_info -QMAKE_CXXFLAGS += /std:c++latest /utf-8 +QMAKE_CXXFLAGS += /std:c++latest /utf-8 /bigobj QMAKE_RESOURCE_FLAGS += -threshold 0 -compress 9 PdfforQt_library.files = $$DESTDIR/Pdf4QtLib.dll diff --git a/Pdf4QtLib/sources/pdfform.cpp b/Pdf4QtLib/sources/pdfform.cpp index 64d9e3c..8d4c854 100644 --- a/Pdf4QtLib/sources/pdfform.cpp +++ b/Pdf4QtLib/sources/pdfform.cpp @@ -1161,6 +1161,8 @@ void PDFFormManager::setDocument(const PDFModifiedDocument& document) // Just update field values updateFieldValues(); } + + m_xfaEngine.setDocument(document, &m_form); } } diff --git a/Pdf4QtLib/sources/pdfform.h b/Pdf4QtLib/sources/pdfform.h index 9d05f9d..0449db8 100644 --- a/Pdf4QtLib/sources/pdfform.h +++ b/Pdf4QtLib/sources/pdfform.h @@ -23,6 +23,7 @@ #include "pdfannotation.h" #include "pdfdocumentdrawinterface.h" #include "pdfsignaturehandler.h" +#include "pdfxfaengine.h" #include @@ -720,6 +721,8 @@ private: PDFForm m_form; bool m_isCommitDisabled; + PDFXFAEngine m_xfaEngine; + std::vector m_widgetEditors; PDFFormFieldWidgetEditor* m_focusedEditor; MouseGrabInfo m_mouseGrabInfo; diff --git a/Pdf4QtLib/sources/pdfxfaengine.cpp b/Pdf4QtLib/sources/pdfxfaengine.cpp index f2e7409..28e7ffa 100644 --- a/Pdf4QtLib/sources/pdfxfaengine.cpp +++ b/Pdf4QtLib/sources/pdfxfaengine.cpp @@ -16,8 +16,10 @@ // along with PDF4QT. If not, see . #include "pdfxfaengine.h" +#include "pdfform.h" #include +#include #include @@ -8887,10 +8889,16 @@ std::optional XFA_variables::parse(const QDomElement& element) class PDFXFAEngineImpl { public: - PDFXFAEngineImpl() = default; + PDFXFAEngineImpl(); + + void setDocument(const PDFModifiedDocument& document, PDFForm* form); private: + void clear(); + xfa::XFA_Node m_template; + const PDFDocument* m_document; + PDFForm* m_form; }; PDFXFAEngine::PDFXFAEngine() : @@ -8904,4 +8912,77 @@ PDFXFAEngine::~PDFXFAEngine() } +void PDFXFAEngine::setDocument(const PDFModifiedDocument& document, PDFForm* form) +{ + m_impl->setDocument(document, form); +} + +PDFXFAEngineImpl::PDFXFAEngineImpl() : + m_document(nullptr), + m_form(nullptr) +{ + +} + +void PDFXFAEngineImpl::setDocument(const PDFModifiedDocument& document, PDFForm* form) +{ + if (m_document != document || document.hasReset()) + { + m_document = document; + + if (document.hasReset()) + { + clear(); + + if (form->getFormType() == PDFForm::FormType::XFAForm) + { + try + { + const PDFObject& xfaObject = m_document->getObject(form->getXFA()); + + std::map xfaData; + if (xfaObject.isArray()) + { + const PDFArray* xfaArrayData = xfaObject.getArray(); + const size_t pairCount = xfaArrayData->getCount() / 2; + + for (size_t i = 0; i < pairCount; ++i) + { + const PDFObject& itemName = m_document->getObject(xfaArrayData->getItem(2 * i + 0)); + const PDFObject& streamObject = m_document->getObject(xfaArrayData->getItem(2 * i + 1)); + + if (itemName.isString() && streamObject.isStream()) + { + xfaData[itemName.getString()] = m_document->getDecodedStream(streamObject.getStream()); + } + } + } + else if (xfaObject.isStream()) + { + xfaData["template"] = m_document->getDecodedStream(xfaObject.getStream()); + } + + QDomDocument document; + if (document.setContent(xfaData["template"])) + { + m_template = xfa::XFA_template::parse(document.firstChildElement("template")); + } + } + catch (PDFException) + { + // Just clear once again - if some errorneous data + // were read, we want to clear them. + clear(); + } + } + } + } +} + +void PDFXFAEngineImpl::clear() +{ + // Clear the template + m_template = xfa::XFA_Node(); +} + } // namespace pdf diff --git a/Pdf4QtLib/sources/pdfxfaengine.h b/Pdf4QtLib/sources/pdfxfaengine.h index aec10fd..7b74b6d 100644 --- a/Pdf4QtLib/sources/pdfxfaengine.h +++ b/Pdf4QtLib/sources/pdfxfaengine.h @@ -19,12 +19,14 @@ #define PDFXFAENGINE_H #include "pdfglobal.h" +#include "pdfdocument.h" #include namespace pdf { +class PDFForm; class PDFXFAEngineImpl; class PDFXFAEngine @@ -33,6 +35,8 @@ public: PDFXFAEngine(); ~PDFXFAEngine(); + void setDocument(const PDFModifiedDocument& document, PDFForm* form); + private: std::unique_ptr m_impl; };