From 968b8b6ec6e1adfb9d4dc239af2326b03c8d3c52 Mon Sep 17 00:00:00 2001 From: Kulikova Svetlana Date: Mon, 24 Oct 2022 18:02:09 +0300 Subject: [PATCH] create DictToCDictObject --- PdfFile/PdfFile.cpp | 146 ++++++++++++++++++++++++++++++++++++- PdfWriter/PdfRenderer.cpp | 8 -- PdfWriter/PdfRenderer.h | 1 - PdfWriter/Src/Document.cpp | 36 ++++----- PdfWriter/Src/Document.h | 2 +- PdfWriter/Src/Pages.cpp | 7 +- PdfWriter/Src/Pages.h | 2 +- 7 files changed, 160 insertions(+), 42 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index bf26ea31e6..6e0cc8f8fd 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -6,6 +6,120 @@ #include "../PdfReader/lib/xpdf/PDFDoc.h" #include "../PdfReader/lib/xpdf/AcroForm.h" +#include "../PdfReader/lib/xpdf/TextString.h" + +#include "../PdfWriter/Src/Objects.h" +#include "../PdfWriter/Src/Document.h" +#include "../PdfWriter/Src/Pages.h" + +#define AddToObject(oVal)\ +{\ + if (pObj->GetType() == PdfWriter::object_type_DICT)\ + ((PdfWriter::CDictObject*)pObj)->Add(sKey, oVal);\ + else if (pObj->GetType() == PdfWriter::object_type_ARRAY)\ + ((PdfWriter::CArrayObject*)pObj)->Add(oVal);\ +} + +void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, const std::string& sKey) +{ + Object oTemp; + switch (obj->getType()) + { + case objBool: + { + AddToObject(obj->getBool()) + break; + } + case objInt: + { + AddToObject(obj->getInt()) + break; + } + case objReal: + { + AddToObject(obj->getReal()) + break; + } + case objString: + { + if (bBinary) + { + GString* str = obj->getString(); + int nLength = str->getLength(); + BYTE* arrId = new BYTE[nLength]; + for (int nIndex = 0; nIndex < nLength; ++nIndex) + arrId[nIndex] = str->getChar(nIndex); + AddToObject(new PdfWriter::CBinaryObject(arrId, nLength)); + RELEASEARRAYOBJECTS(arrId); + } + else + { + TextString* s = new TextString(obj->getString()); + std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + AddToObject(new PdfWriter::CStringObject(sValue.c_str())) + delete s; + } + break; + } + case objName: + { + AddToObject(obj->getName()) + break; + } + case objNull: + { + AddToObject(new PdfWriter::CNullObject()) + break; + } + case objArray: + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + AddToObject(pArray) + + for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) + { + obj->arrayGetNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pArray, bBinary, ""); + oTemp.free(); + } + break; + } + case objDict: + { + PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + AddToObject(pDict); + + for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) + { + char* chKey = obj->dictGetKey(nIndex); + if (strcmp("Resources", chKey) == 0 || strcmp("AcroForm", chKey) == 0) + obj->dictGetVal(nIndex, &oTemp); + else + obj->dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pDict, bBinary, chKey); + oTemp.free(); + } + break; + } + case objRef: + { + PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); + pBase->SetRef(obj->getRefNum(), obj->getRefGen()); + AddToObject(new PdfWriter::CProxyObject(pBase, true)) + break; + } + case objNone: + { + AddToObject("None") + break; + } + case objStream: + case objCmd: + case objError: + case objEOF: + break; + } +} class CPdfFile_Private { @@ -17,7 +131,8 @@ public: void GetPageTree(XRef* xref, Object* pPagesRefObj) { - if (!pPagesRefObj || !xref) + PdfWriter::CDocument* pDoc = pWriter->GetPDFDocument(); + if (!pPagesRefObj || !xref || !pDoc) return; Object typeDict, pagesObj; @@ -32,9 +147,34 @@ public: typeDict.free(); Ref topPagesRef = pPagesRefObj->getRef(); - std::wstring sPageTree = XMLConverter::DictToXml(L"PageTree", &pagesObj, topPagesRef.num, topPagesRef.gen); - pWriter->CreatePageTree(sPageTree, topPagesRef.num); + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, topPagesRef.num); + if (!pXref) + { + pagesObj.free(); + return; + } + + PdfWriter::CPageTree* pPageT = new PdfWriter::CPageTree(pXref); + if (!pPageT) + { + pagesObj.free(); + RELEASEOBJECT(pXref); + return; + } + + for (int nIndex = 0; nIndex < pagesObj.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = pagesObj.dictGetKey(nIndex); + pagesObj.dictGetValNF(nIndex, &oTemp); + DictToCDictObject(&oTemp, pPageT, false, chKey); + oTemp.free(); + } + + pDoc->CreatePageTree(pXref, pPageT); + pPageT->SetRef(topPagesRef.num, topPagesRef.gen); + pPageT->Fix(); Object kidsArrObj; if (!pagesObj.dictLookup("Kids", &kidsArrObj) || !kidsArrObj.isArray()) diff --git a/PdfWriter/PdfRenderer.cpp b/PdfWriter/PdfRenderer.cpp index 412196277d..c76dd712c5 100644 --- a/PdfWriter/PdfRenderer.cpp +++ b/PdfWriter/PdfRenderer.cpp @@ -2116,14 +2116,6 @@ bool CPdfRenderer::EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSi } return bRes; } -bool CPdfRenderer::CreatePageTree(const std::wstring& sPageTree, int nPageTree) -{ - if (!m_bEdit) - { - return false; - } - return m_pDocument->CreatePageTree(sPageTree, nPageTree); -} std::pair CPdfRenderer::GetPageRef(int nPageIndex) { return m_pDocument->GetPageRef(nPageIndex); diff --git a/PdfWriter/PdfRenderer.h b/PdfWriter/PdfRenderer.h index 79bcea2248..16ba044140 100644 --- a/PdfWriter/PdfRenderer.h +++ b/PdfWriter/PdfRenderer.h @@ -247,7 +247,6 @@ public: // Дополнительные функции для дозаписи Pdf //---------------------------------------------------------------------------------------- bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, const std::wstring& sCatalog, int nCatalog, const std::wstring& sEncrypt, const std::wstring& sPassword, int nCryptAlgorithm, int nFormField); - bool CreatePageTree(const std::wstring& sPageTree, int nPageTree); std::pair GetPageRef(int nPageIndex); bool EditPage(const std::wstring& sPage, int nPage); bool AddPage(int nPageIndex); diff --git a/PdfWriter/Src/Document.cpp b/PdfWriter/Src/Document.cpp index ad6578fbb3..efad5c773a 100644 --- a/PdfWriter/Src/Document.cpp +++ b/PdfWriter/Src/Document.cpp @@ -1090,6 +1090,20 @@ namespace PdfWriter return (!!m_pAcroForm); } + bool CDocument::CreatePageTree(CXref* pXref, CPageTree* pPageTree) + { + if (!pXref || !pPageTree) + return false; + + if (!m_pPageTree) + m_pPageTree = pPageTree; + else + m_pPageTree->Join(pPageTree); + pXref->SetPrev(m_pLastXref); + m_pLastXref = pXref; + + return true; + } bool CDocument::EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, const std::wstring& sCatalog, int nCatalog, const std::wstring& sEncrypt, const std::wstring& sPassword, int nCryptAlgorithm, int nFormField) { Close(); @@ -1143,28 +1157,6 @@ namespace PdfWriter m_wsFilePath = wsPath; return true; } - bool CDocument::CreatePageTree(const std::wstring& sPageTree, int nPageTree) - { - CXref* pXref = new CXref(this, nPageTree); - if (!pXref) - return false; - - CPageTree* pPageT = new CPageTree(pXref, sPageTree); - if (!pPageT) - { - RELEASEOBJECT(pXref); - return false; - } - - if (!m_pPageTree) - m_pPageTree = pPageT; - else - m_pPageTree->Join(pPageT); - pXref->SetPrev(m_pLastXref); - m_pLastXref = pXref; - - return true; - } std::pair CDocument::GetPageRef(int nPageIndex) { std::pair pRes = std::make_pair(0, 0); diff --git a/PdfWriter/Src/Document.h b/PdfWriter/Src/Document.h index 6663ea5c65..d415b78dad 100644 --- a/PdfWriter/Src/Document.h +++ b/PdfWriter/Src/Document.h @@ -152,8 +152,8 @@ namespace PdfWriter CSignatureField* CreateSignatureField(); bool CheckFieldName(CFieldBase* pField, const std::string& sName); + bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, const std::wstring& sCatalog, int nCatalog, const std::wstring& sEncrypt, const std::wstring& sPassword, int nCryptAlgorithm, int nFormField); - bool CreatePageTree(const std::wstring& sPageTree, int nPageTree); std::pair GetPageRef(int nPageIndex); CPage* EditPage(const std::wstring& sPage, int nPage); CPage* AddPage(int nPageIndex); diff --git a/PdfWriter/Src/Pages.cpp b/PdfWriter/Src/Pages.cpp index f9c7af26b6..f53b26a15c 100644 --- a/PdfWriter/Src/Pages.cpp +++ b/PdfWriter/Src/Pages.cpp @@ -193,13 +193,8 @@ namespace PdfWriter Add("Kids", m_pPages); Add("Count", m_pCount); } - CPageTree::CPageTree(CXref* pXref, const std::wstring& sPageTree) + void CPageTree::Fix() { - m_pXref = pXref; - pXref->Add(this); - - FromXml(sPageTree); - // Инициализация текущего m_pPages CObjectBase* pPages = Get("Kids"); if (pPages && pPages->GetType() == object_type_ARRAY) diff --git a/PdfWriter/Src/Pages.h b/PdfWriter/Src/Pages.h index 6dd1eb6876..718ae3de3d 100644 --- a/PdfWriter/Src/Pages.h +++ b/PdfWriter/Src/Pages.h @@ -62,7 +62,7 @@ namespace PdfWriter { public: CPageTree(CXref* pXref); - CPageTree(CXref* pXref, const std::wstring& sPageTree); + void Fix(); void AddPage(CDictObject* pPage); CObjectBase* GetObj(int nPageIndex); CPage* GetPage(int nPageIndex);