diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index cc47211257..09d5b85acf 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -1161,71 +1161,78 @@ CFile.prototype["getInteractiveFormsInfo"] = function() let reader = ptr.getReader(); if (!reader) return {}; - let res = {}; - let k = reader.readInt(); - if (k > 0) - res["CO"] = []; - for (let i = 0; i < k; ++i) - res["CO"].push(reader.readInt()); - - k = reader.readInt(); - if (k > 0) - res["Parents"] = []; - for (let i = 0; i < k; ++i) - { - let rec = {}; - rec["i"] = reader.readInt(); - let flags = reader.readInt(); - if (flags & (1 << 0)) - rec["name"] = reader.readString(); - if (flags & (1 << 1)) - rec["value"] = reader.readString(); - if (flags & (1 << 2)) - rec["defaultValue"] = reader.readString(); - if (flags & (1 << 3)) - { - let n = reader.readInt(); - rec["curIdxs"] = []; - for (let i = 0; i < n; ++i) - rec["curIdxs"].push(reader.readInt()); - } - if (flags & (1 << 4)) - rec["Parent"] = reader.readInt(); - if (flags & (1 << 5)) - { - let n = reader.readInt(); - rec["value"] = []; - for (let i = 0; i < n; ++i) - rec["value"].push(reader.readString()); - } - if (flags & (1 << 6)) - { - let n = reader.readInt(); - rec["Opt"] = []; - for (let i = 0; i < n; ++i) - rec["Opt"].push(reader.readString()); - } - res["Parents"].push(rec); - } + let arrRes = []; - res["Fields"] = []; - k = reader.readInt(); - for (let q = 0; reader.isValid() && q < k; ++q) + while (reader.isValid()) { - let rec = {}; - // Widget type - FT - // 26 - Unknown, 27 - button, 28 - radiobutton, 29 - checkbox, 30 - text, 31 - combobox, 32 - listbox, 33 - signature - rec["type"] = reader.readByte(); - // Annot - readAnnot(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); - // Widget type - readWidgetType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); + let res = {}; + let k = reader.readInt(); + if (k > 0) + res["CO"] = []; + for (let i = 0; i < k; ++i) + res["CO"].push(reader.readInt()); - res["Fields"].push(rec); + k = reader.readInt(); + if (k > 0) + res["Parents"] = []; + for (let i = 0; i < k; ++i) + { + let rec = {}; + rec["i"] = reader.readInt(); + let flags = reader.readInt(); + if (flags & (1 << 0)) + rec["name"] = reader.readString(); + if (flags & (1 << 1)) + rec["value"] = reader.readString(); + if (flags & (1 << 2)) + rec["defaultValue"] = reader.readString(); + if (flags & (1 << 3)) + { + let n = reader.readInt(); + rec["curIdxs"] = []; + for (let i = 0; i < n; ++i) + rec["curIdxs"].push(reader.readInt()); + } + if (flags & (1 << 4)) + rec["Parent"] = reader.readInt(); + if (flags & (1 << 5)) + { + let n = reader.readInt(); + rec["value"] = []; + for (let i = 0; i < n; ++i) + rec["value"].push(reader.readString()); + } + if (flags & (1 << 6)) + { + let n = reader.readInt(); + rec["Opt"] = []; + for (let i = 0; i < n; ++i) + rec["Opt"].push(reader.readString()); + } + res["Parents"].push(rec); + } + + res["Fields"] = []; + k = reader.readInt(); + for (let q = 0; reader.isValid() && q < k; ++q) + { + let rec = {}; + // Widget type - FT + // 26 - Unknown, 27 - button, 28 - radiobutton, 29 - checkbox, 30 - text, 31 - combobox, 32 - listbox, 33 - signature + rec["type"] = reader.readByte(); + // Annot + readAnnot(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); + // Widget type + readWidgetType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); + + res["Fields"].push(rec); + } + + arrRes.push(res); } ptr.free(); - return res; + return arrRes; }; // optional nWidget - rec["AP"]["i"] diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index 4ee10b03a5..bdc3663490 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -218,15 +218,10 @@ namespace NSOnlineOfficeBinToPdf std::wstring wsPassword = oReader.ReadString(); int nLength = oReader.ReadInt(); int* pPageIndex = new int[nLength]; - int* pPositions = new int[nLength]; for (int i = 0; i < nLength; ++i) - { pPageIndex[i] = oReader.ReadInt(); - pPositions[i] = oReader.ReadInt(); - } - pPdf->MergePages(wsPath, wsPassword, pPageIndex, nLength, pPositions); + pPdf->MergePages(wsPath, wsPassword, pPageIndex, nLength); delete[] pPageIndex; - delete[] pPositions; break; } case AddCommandType::SplitPages: diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 9e380d78b1..b6e7c9ff83 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -34,6 +34,7 @@ #include "../DesktopEditor/common/Path.h" #include "SrcReader/Adaptors.h" +#include "SrcReader/PdfAnnot.h" #include "lib/xpdf/PDFDoc.h" #include "lib/xpdf/AcroForm.h" #include "lib/xpdf/TextString.h" @@ -402,7 +403,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo { if (!_pReader || !_pWriter) return S_FALSE; - PDFDoc* pPDFDocument = _pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = _pReader->GetFirstPDFDocument(); if (!pPDFDocument) return S_FALSE; XRef* xref = pPDFDocument->getXRef(); @@ -658,7 +659,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa m_nError = 0; m_nMode = -1; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); if (!pPDFDocument) { m_nError = 1; @@ -679,7 +680,7 @@ bool CPdfEditor::IncrementalUpdates() return true; m_nMode = 0; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -909,7 +910,7 @@ void CPdfEditor::Close() return; } - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); XRef* xref = pPDFDocument->getXRef(); @@ -1093,25 +1094,31 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT } kidsArrObj.free(); } -bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) +bool CPdfEditor::EditPage(int _nPageIndex, bool bSet) { if (m_nMode != 0 && !IncrementalUpdates()) return false; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex - 1, &pPDFDocument); + if (nPageIndex < 0 || !pPDFDocument) + return NULL; + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; PdfWriter::CPage* pEditPage = NULL; - pEditPage = bActualPos ? pDoc->GetPage(nPageIndex) : pDoc->GetEditPage(nPageIndex); + pEditPage = pDoc->GetEditPage(_nPageIndex); + if (!pEditPage) + pEditPage = pDoc->GetPage(nPageIndex); if (pEditPage) { if (bSet) { pDoc->SetCurPage(pEditPage); m_pWriter->EditPage(pEditPage); - m_nEditPage = nPageIndex; + m_nEditPage = _nPageIndex; } return true; } @@ -1232,12 +1239,12 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) pageObj.free(); // Применение редактирования страницы для writer - if (pDoc->EditPage(pXref, pPage, nPageIndex)) + if (pDoc->EditPage(pXref, pPage, _nPageIndex)) { if (bSet) { m_pWriter->EditPage(pPage); - m_nEditPage = nPageIndex; + m_nEditPage = _nPageIndex; } pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); pPage->SetStrokeColor(0, 0, 0); @@ -1254,13 +1261,13 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) RELEASEOBJECT(pXref); return false; } -bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader, const int* arrPositions) +bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc) { - if (m_nMode == 1 || (m_nMode == 0 && !_pReader)) + if (m_nMode == 1 || (m_nMode == 0 && !_pDoc)) return false; if (m_nMode < 0) m_nMode = 1; - PDFDoc* pPDFDocument = _pReader ? _pReader->GetPDFDocument() : m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = _pDoc ? _pDoc : m_pReader->GetFirstPDFDocument(); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -1277,7 +1284,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); pDoc->AddObject(pPage); - pDoc->AddPage(arrPositions ? arrPositions[i] : pDoc->GetPagesCount(), pPage); + pDoc->AddPage(pDoc->GetPagesCount(), pPage); // Получение объекта страницы Object pageRefObj, pageObj; @@ -1574,11 +1581,11 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf return true; } -bool CPdfEditor::MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, const int* arrPositions) +bool CPdfEditor::MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength) { if (m_nMode != 0 && !IncrementalUpdates()) return false; - return SplitPages(arrPageIndex, unLength, _pReader, arrPositions); + return SplitPages(arrPageIndex, unLength, pDoc); } bool CPdfEditor::DeletePage(int nPageIndex) { @@ -1609,18 +1616,20 @@ bool CPdfEditor::AddPage(int nPageIndex) } bool CPdfEditor::MovePage(int nPageIndex, int nPos) { - if (EditPage(nPageIndex, true, true)) + if (EditPage(nPageIndex)) { m_nEditPage = nPos; return m_pWriter->GetDocument()->MovePage(nPageIndex, nPos); } return false; } -bool CPdfEditor::EditAnnot(int nPageIndex, int nID) +bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) { - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex - 1, &pPDFDocument, &pFontList); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) + if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; XRef* xref = pPDFDocument->getXRef(); @@ -1652,14 +1661,8 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) return false; } - PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); - if (!pEditPage) - { - pEditPage = pDoc->GetCurPage(); - EditPage(nPageIndex); - pDoc->SetCurPage(pEditPage); - m_pWriter->EditPage(pEditPage); - } + if (!pDoc->GetEditPage(_nPageIndex)) + EditPage(_nPageIndex, false); // Воспроизведение словаря аннотации из reader для writer PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum()); @@ -1685,7 +1688,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); else if (oType.isName("FreeText")) { - std::map mapFont = m_pReader->GetAnnotFonts(&oAnnotRef); + std::map mapFont = PdfReader::CAnnotFonts::GetAnnotFont(pPDFDocument, m_pReader->GetFontManager(), pFontList, &oAnnotRef); m_mFonts.insert(mapFont.begin(), mapFont.end()); pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); } @@ -1877,16 +1880,18 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage - 1, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) + if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; XRef* xref = pPDFDocument->getXRef(); bool bClear = false; if (!oAnnots) { - std::pair pPageRef = pDoc->GetPageRef(m_nEditPage); + PdfWriter::CPage* pPage = pDoc->GetCurPage(); + std::pair pPageRef = { pPage->GetObjId(), pPage->GetObjId() }; if (pPageRef.first == 0) return false; @@ -1944,7 +1949,7 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) return false; CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); std::vector arrParents = pFieldInfo->GetParents(); @@ -2001,10 +2006,14 @@ bool CPdfEditor::IsEditPage() } void CPdfEditor::ClearPage() { - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); - XRef* xref = pPDFDocument->getXRef(); + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage - 1, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - std::pair pPageRef = pDoc->GetPageRef(m_nEditPage); + if (nPageIndex < 0 || !pPDFDocument || !pDoc) + return; + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CPage* pPage = pDoc->GetCurPage(); + std::pair pPageRef = { pPage->GetObjId(), pPage->GetObjId() }; // Получение объекта страницы Object pageRefObj, pageObj; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 6c4eac58ec..bee40bc7c3 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -46,7 +46,7 @@ public: int GetError(); void Close(); - bool EditPage(int nPageIndex, bool bSet = true, bool bActualPos = false); + bool EditPage(int nPageIndex, bool bSet = true); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); bool MovePage(int nPageIndex, int nPos); @@ -62,8 +62,8 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); - bool SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader = NULL, const int* arrPositions = NULL); - bool MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, const int* arrPositions); + bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* pDoc = NULL); + bool MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength); private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 34f55ec4c0..663d7caf09 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -167,23 +167,13 @@ bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) return false; return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); } -bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength, const int* arrPosition) +bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength) { if (!m_pInternal->pEditor) return false; - CPdfFile* pMergeFile = new CPdfFile(m_pInternal->pAppFonts); - pMergeFile->SetTempDirectory(m_pInternal->wsTempFolder); - - if (!pMergeFile->LoadFromFile(wsPath, L"", wsPassword, wsPassword)) - { - RELEASEOBJECT(pMergeFile); - return false; - } - - bool bRes = m_pInternal->pEditor->MergePages(pMergeFile->m_pInternal->pReader, arrPageIndex, unLength, arrPosition); - RELEASEOBJECT(pMergeFile); - return bRes; + if (m_pInternal->pReader->AddFromFile(wsPath, wsPassword)) + return m_pInternal->pEditor->MergePages(m_pInternal->pReader->GetLastPDFDocument(), arrPageIndex, unLength); } bool CPdfFile::MovePage(int nPageIndex, int nPos) { @@ -367,15 +357,13 @@ int CPdfFile::GetPagesCount() { if (!m_pInternal->pReader) return 0; - PDFDoc* pPdfDoc = m_pInternal->pReader->GetPDFDocument(); - int nPages = pPdfDoc ? pPdfDoc->getNumPages() : 0; if (m_pInternal->pEditor) { int nWPages = m_pInternal->pEditor->GetPagesCount(); if (nWPages > 0) - nPages = nWPages; + return nWPages; } - return nPages; + return m_pInternal->pReader->GetNumPages(); } void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) { diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 05f13555f3..f744409604 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -99,7 +99,7 @@ public: bool AddPage (int nPageIndex); bool MovePage (int nPageIndex, int nPos); bool SplitPages(const int* arrPageIndex, unsigned int unLength); - bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0, const int* arrPosition = NULL); + bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 0175dbb23e..ab2d453661 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -446,6 +446,10 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat return true; } +bool CPdfReader::AddFromFile(const std::wstring& wsFile, const std::wstring& wsPassword) +{ + return true; +} bool CPdfReader::AddFromMemory(BYTE* pData, DWORD nLength, const std::wstring& wsPassword) { return true; @@ -548,6 +552,17 @@ int CPdfReader::GetMaxRefID() } return nMaxRefID; } +int CPdfReader::GetNumPages() +{ + int nNumPages = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + nNumPages += pPDFContext->m_pDocument->getNumPages(); + } + return nNumPages; +} bool CPdfReader::ValidMetaData() { if (m_vPDFContext.empty() || m_vPDFContext.size() != 1) @@ -641,6 +656,26 @@ std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStrea return wsXml; } +PDFDoc* CPdfReader::GetFirstPDFDocument() +{ + if (m_vPDFContext.empty()) + return NULL; + + CPdfReaderContext* pPDFContext = m_vPDFContext.front(); + if (pPDFContext) + return pPDFContext->m_pDocument; + return NULL; +} +PDFDoc* CPdfReader::GetLastPDFDocument() +{ + if (m_vPDFContext.empty()) + return NULL; + + CPdfReaderContext* pPDFContext = m_vPDFContext.back(); + if (pPDFContext) + return pPDFContext->m_pDocument; + return NULL; +} std::wstring CPdfReader::GetInfo() { @@ -749,17 +784,7 @@ std::wstring CPdfReader::GetInfo() sRes += L",\"PageHeight\":"; sRes += std::to_wstring((int)(nH * 100)); sRes += L",\"NumberOfPages\":"; - - int nNumPages = 0; - for (CPdfReaderContext* pPDFContext : m_vPDFContext) - { - if (!pPDFContext || !pPDFContext->m_pDocument) - continue; - PDFDoc* pDoc = pPDFContext->m_pDocument; - nNumPages += pDoc->getNumPages(); - } - - sRes += std::to_wstring(nNumPages); + sRes += std::to_wstring(GetNumPages()); sRes += L",\"FastWebView\":"; bool bLinearized = false; @@ -1003,7 +1028,7 @@ BYTE* CPdfReader::GetLinks(int _nPageIndex) int nRotate = 0; #ifdef BUILDING_WASM_MODULE - nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); + nRotate = -pDoc->getPageRotate(nPageIndex); #endif // Текст-ссылка @@ -1043,18 +1068,22 @@ BYTE* CPdfReader::GetLinks(int _nPageIndex) } BYTE* CPdfReader::GetWidgets() { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) - return NULL; - if (!m_pPDFDocument->getCatalog()->getForm() || !m_pPDFDocument->getXRef()) - return NULL; - NSWasm::CData oRes; oRes.SkipLen(); - PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(m_pPDFDocument, m_pFontManager, m_pFontList); - if (pAnnots) - pAnnots->ToWASM(oRes); - RELEASEOBJECT(pAnnots); + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (!pDoc || !pDoc->getCatalog()) + continue; + if (!pDoc->getCatalog()->getForm() || !pDoc->getXRef()) + continue; + + PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList); + if (pAnnots) + pAnnots->ToWASM(oRes); + RELEASEOBJECT(pAnnots); + } oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); @@ -1096,10 +1125,14 @@ BYTE* CPdfReader::GetFonts(bool bStandart) } BYTE* CPdfReader::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + if (m_vPDFContext.empty()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + CPdfReaderContext* pPDFContext = m_vPDFContext.front(); + if (!pPDFContext || !pPDFContext->m_pDocument || !pPDFContext->m_pDocument->getCatalog()) + return NULL; + + AcroForm* pAcroForms = pPDFContext->m_pDocument->getCatalog()->getForm(); if (!pAcroForms) return NULL; @@ -1175,12 +1208,15 @@ BYTE* CPdfReader::VerifySign(const std::wstring& sFile, ICertificate* pCertifica oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget, const char* sView, const char* sButtonView) +BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, int _nPageIndex, int nWidget, const char* sView, const char* sButtonView) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + AcroForm* pAcroForms = pDoc->getCatalog()->getForm(); if (!pAcroForms) return NULL; @@ -1191,14 +1227,14 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, { AcroFormField* pField = pAcroForms->getField(i); Object oRef; - if (pField->getPageNum() != nPageIndex + 1 || (nWidget >= 0 && pField->getFieldRef(&oRef) && oRef.getRefNum() != nWidget)) + if (pField->getPageNum() != nPageIndex || (nWidget >= 0 && pField->getFieldRef(&oRef) && oRef.getRefNum() != nWidget)) { oRef.free(); continue; } oRef.free(); - PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(m_pPDFDocument, m_pFontManager, m_pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex, sView, sButtonView, pField); + PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(pDoc, m_pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex, sView, sButtonView, pField); if (pAP) pAP->ToWASM(oRes); RELEASEOBJECT(pAP); @@ -1209,12 +1245,14 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) +BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + PDFDoc* pDoc = NULL; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc); + if (nPageIndex < 0 || !pDoc || !pDoc->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + AcroForm* pAcroForms = pDoc->getCatalog()->getForm(); if (!pAcroForms) return NULL; @@ -1225,7 +1263,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) { AcroFormField* pField = pAcroForms->getField(i); - if (pField->getPageNum() != nPageIndex + 1 || pField->getAcroFormFieldType() != acroFormFieldPushbutton || (nButtonWidget >= 0 && i != nButtonWidget)) + if (pField->getPageNum() != nPageIndex || pField->getAcroFormFieldType() != acroFormFieldPushbutton || (nButtonWidget >= 0 && i != nButtonWidget)) continue; Object oMK; @@ -1578,90 +1616,50 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReade oAnnots.free(); } -BYTE* CPdfReader::GetAnnots(int nPageIndex) +BYTE* CPdfReader::GetAnnots(int _nPageIndex) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + if (m_vPDFContext.empty()) return NULL; NSWasm::CData oRes; oRes.SkipLen(); - if (nPageIndex >= 0) - GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPageIndex); + if (_nPageIndex >= 0) + { + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) + return NULL; + GetPageAnnots(pDoc, m_pFontManager, pFontList, oRes, nPageIndex - 1); + } else - for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) - GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPage); - - oRes.WriteLen(); - BYTE* bRes = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return bRes; -} -BYTE* CPdfReader::GetShapes(int nPageIndex) -{ - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) - return NULL; - Dict* pResources = m_pPDFDocument->getCatalog()->getPage(nPageIndex + 1)->getResourceDict(); - if (!pResources) - return NULL; - - Object oProperties, oMetaOForm, oID; - XRef* xref = m_pPDFDocument->getXRef(); - if (!pResources->lookup("Properties", &oProperties)->isDict() || !oProperties.dictLookup("OShapes", &oMetaOForm)->isDict("OShapes") || !oMetaOForm.dictLookup("ID", &oID)->isString()) { - oProperties.free(); oMetaOForm.free(); oID.free(); - return NULL; - } - oProperties.free(); - - Object oTID, oID2; - Object* pTrailerDict = xref->getTrailerDict(); - if (!pTrailerDict->dictLookup("ID", &oTID)->isArray() || !oTID.arrayGet(1, &oID2)->isString() || oID2.getString()->cmp(oID.getString()) != 0) - { - oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); - return NULL; - } - oID.free(); oTID.free(); oID2.free(); - - Object oMetadata; - if (!oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray()) - { - oMetaOForm.free(); oMetadata.free(); - return NULL; - } - oMetaOForm.free(); - - NSWasm::CData oRes; - oRes.SkipLen(); - int nMetadataLength = oMetadata.arrayGetLength(); - oRes.AddInt(nMetadataLength); - - for (int i = 0; i < nMetadataLength; ++i) - { - Object oMetaStr; - std::string sStr; - if (oMetadata.arrayGet(i, &oMetaStr)->isString()) + for (CPdfReaderContext* pPDFContext : m_vPDFContext) { - TextString* s = new TextString(oMetaStr.getString()); - sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - delete s; + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (!pDoc || !pDoc->getCatalog() || !pPDFContext->m_pFontList) + continue; + for (int nPage = 0, nLastPage = pDoc->getNumPages(); nPage < nLastPage; ++nPage) + GetPageAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, oRes, nPage); } - oRes.WriteString(sStr); } - oMetadata.free(); oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot, const char* sView) +BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int _nPageIndex, int nAnnot, const char* sView) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; Object oAnnots; - Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPageIndex + 1); + Page* pPage = pDoc->getCatalog()->getPage(nPageIndex); if (!pPage || !pPage->getAnnots(&oAnnots)->isArray()) { oAnnots.free(); @@ -1693,7 +1691,7 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, continue; } - PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(m_pPDFDocument, m_pFontManager, m_pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex, sView, &oAnnotRef); + PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(pDoc, m_pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex - 1, sView, &oAnnotRef); if (pAP) pAP->ToWASM(oRes); RELEASEOBJECT(pAP); @@ -1708,7 +1706,3 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, oRes.ClearWithoutAttack(); return bRes; } -std::map CPdfReader::GetAnnotFonts(Object* pRefAnnot) -{ - return PdfReader::CAnnotFonts::GetAnnotFont(m_pPDFDocument, m_pFontManager, m_pFontList, pRefAnnot); -} diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 177758f512..66f79f2947 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -59,6 +59,7 @@ public: bool LoadFromFile (NSFonts::IApplicationFonts* pAppFonts, const std::wstring& file, const std::wstring& owner_password = L"", const std::wstring& user_password = L""); bool LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& owner_password = L"", const std::wstring& user_password = L""); + bool AddFromFile (const std::wstring& wsFile, const std::wstring& wsPassword = L""); bool AddFromMemory (BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L""); void Close(); @@ -75,32 +76,33 @@ public: int GetError(); int GetRotate(int nPageIndex); int GetMaxRefID(); + int GetNumPages(); bool ValidMetaData(); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); std::wstring GetInfo(); std::wstring GetFontPath(const std::wstring& wsFontName, bool bSave = true); std::wstring ToXml(const std::wstring& wsXmlPath, bool isPrintStreams = false); + void ChangeLength(DWORD nLength) { m_nFileLength = nLength; } NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } - // PDFDoc* GetPDFDocument() { return m_pPDFDocument; } + PDFDoc* GetFirstPDFDocument(); + PDFDoc* GetLastPDFDocument(); + int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL); BYTE* GetStructure(); BYTE* GetLinks(int nPageIndex); BYTE* GetWidgets(); BYTE* GetFonts(bool bStandart); BYTE* GetAnnots(int nPageIndex = -1); - BYTE* GetShapes(int nPageIndex); BYTE* VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); BYTE* GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nBWidget = -1, const char* sIView = NULL); - std::map GetAnnotFonts(Object* pRefAnnot); std::map GetFonts() { return m_mFonts; } private: void Clear(); - int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL); std::wstring m_wsTempFolder; NSFonts::IFontManager* m_pFontManager; diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index aca4e506e2..1c43a08202 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1466,7 +1466,7 @@ namespace PdfWriter pPage->SetFilter(STREAM_FILTER_FLATE_DECODE); #endif - m_pCurPage = pPage; + m_pCurPage = pPage; m_mEditPages[nPageIndex] = pPage; if (m_pPageTree)