From 1830a1103ae1168ddde42559f4c1cb990ae7e3da Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 5 Mar 2025 15:40:12 +0300 Subject: [PATCH] Fix SplitPages --- PdfFile/PdfEditor.cpp | 46 +++++++++++++++++++++++++++++----- PdfFile/PdfEditor.h | 3 ++- PdfFile/PdfFile.cpp | 8 ++++-- PdfFile/PdfWriter.cpp | 13 ++++++++++ PdfFile/PdfWriter.h | 1 + PdfFile/SrcWriter/Document.cpp | 16 ++++++++++++ PdfFile/SrcWriter/Document.h | 1 + PdfFile/SrcWriter/Streams.cpp | 11 ++++++++ PdfFile/SrcWriter/Streams.h | 2 ++ 9 files changed, 92 insertions(+), 9 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index c07e3eb969..ba4b479c6f 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1100,7 +1100,7 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet) return false; PDFDoc* pPDFDocument = NULL; - int nPageIndex = m_pReader->GetPageIndex(_nPageIndex - 1, &pPDFDocument); + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex, &pPDFDocument); if (nPageIndex < 0 || !pPDFDocument) return NULL; @@ -1581,11 +1581,45 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD return true; } -bool CPdfEditor::MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength) +BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) +{ + if (m_nMode != Mode::Unknown) + return NULL; + m_nMode = Mode::WriteNew; + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (!pDoc) + return NULL; + + for (unsigned int i = 0; i < unLength; ++i) + { + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(arrPageIndex[i], &pPDFDocument); + SplitPages(&nPageIndex, 1, pPDFDocument); + } + + BYTE* pRes = NULL; + int nLength = 0; + if (m_pWriter->SaveToMemory(&pRes, &nLength)) + { + NSWasm::CData oRes; + oRes.SkipLen(); + + oRes.Write(pRes, nLength); + RELEASEARRAYOBJECTS(pRes); + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; + } + RELEASEARRAYOBJECTS(pRes); + return NULL; +} +bool CPdfEditor::MergePages(PDFDoc* pDocument, const int* arrPageIndex, unsigned int unLength) { if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; - return SplitPages(arrPageIndex, unLength, pDoc); + return SplitPages(arrPageIndex, unLength, pDocument); } bool CPdfEditor::DeletePage(int nPageIndex) { @@ -1627,7 +1661,7 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) { PDFDoc* pPDFDocument = NULL; PdfReader::CPdfFontList* pFontList = NULL; - int nPageIndex = m_pReader->GetPageIndex(_nPageIndex - 1, &pPDFDocument, &pFontList); + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex, &pPDFDocument, &pFontList); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; @@ -1881,7 +1915,7 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { PDFDoc* pPDFDocument = NULL; - int nPageIndex = m_pReader->GetPageIndex(m_nEditPage - 1, &pPDFDocument); + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; @@ -2007,7 +2041,7 @@ bool CPdfEditor::IsEditPage() void CPdfEditor::ClearPage() { PDFDoc* pPDFDocument = NULL; - int nPageIndex = m_pReader->GetPageIndex(m_nEditPage - 1, &pPDFDocument); + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (nPageIndex < 0 || !pPDFDocument || !pDoc) return; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 39c98294d6..66bf114465 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -70,7 +70,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, PDFDoc* pDoc = NULL); + BYTE* SplitPages(const int* arrPageIndex, unsigned int unLength); + bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc); bool MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength); private: diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 855dbac63a..5ed2f52c69 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -434,14 +434,18 @@ BYTE* CPdfFile::GetAnnots(int nPageIndex) BYTE* CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) { if (!m_pInternal->pReader) - return false; + return NULL; RELEASEOBJECT(m_pInternal->pWriter); m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); RELEASEOBJECT(m_pInternal->pEditor); m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, L"", m_pInternal->pReader, m_pInternal->pWriter); - return m_pInternal->pReader->SplitPages(arrPageIndex, unLength); + BYTE* pRes = m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); + + RELEASEOBJECT(m_pInternal->pWriter); + RELEASEOBJECT(m_pInternal->pEditor); + return pRes; } BYTE* CPdfFile::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 32e002cd23..3db57e3013 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -207,6 +207,19 @@ int CPdfWriter::SaveToFile(const std::wstring& wsPath) return 0; } +int CPdfWriter::SaveToMemory(BYTE** pData, int* pLength) +{ + // TODO: Переделать на код ошибки + if (!IsValid()) + return 1; + + m_oCommandManager.Flush(); + + if (!m_pDocument->SaveToMemory(pData, pLength)) + return 1; + + return 0; +} void CPdfWriter::SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords) { if (!IsValid()) diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 297cc96434..445f7c63c1 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -67,6 +67,7 @@ public: CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false, IRenderer* pRenderer = NULL, bool bCreate = true); ~CPdfWriter(); int SaveToFile(const std::wstring& wsPath); + int SaveToMemory(BYTE** pData, int* pLength); void SetPassword(const std::wstring& wsPassword); void SetDocumentID(const std::wstring& wsDocumentID); void SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 1c43a08202..632f3938f7 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -236,6 +236,22 @@ namespace PdfWriter return true; } + bool CDocument::SaveToMemory(BYTE** pData, int* pLength) + { + CMemoryStream* pStream = new CMemoryStream(); + if (!pStream) + return false; + + if (m_pJbig2) + m_pJbig2->FlushStreams(); + + SaveToStream(pStream); + + *pData = pStream->GetBuffer(); + *pLength = pStream->Size(); + pStream->ClearWithoutAttack(); + return true; + } void CDocument::SaveToStream(CStream* pStream) { m_pCatalog->AddMetadata(m_pXref, m_pInfo); diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index e663425f7b..0fc429bf56 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -106,6 +106,7 @@ namespace PdfWriter bool CreateNew(); void Close(); bool SaveToFile(const std::wstring& wsPath); + bool SaveToMemory(BYTE** pData, int* pLength); bool SaveNewWithPassword(CXref* pXref, CXref* _pXref, const std::wstring& wsPath, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword, CDictObject* pTrailer); void SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword); diff --git a/PdfFile/SrcWriter/Streams.cpp b/PdfFile/SrcWriter/Streams.cpp index e5a873b2b5..6a3ab108ff 100644 --- a/PdfFile/SrcWriter/Streams.cpp +++ b/PdfFile/SrcWriter/Streams.cpp @@ -787,6 +787,17 @@ namespace PdfWriter { return m_unSize; } + BYTE* CMemoryStream::GetBuffer() + { + return m_pBuffer; + } + void CMemoryStream::ClearWithoutAttack() + { + m_nBufferSize = 0; + m_pBuffer = NULL; + m_pCur = NULL; + m_unSize = 0; + } void CMemoryStream::Shrink(unsigned int unSize) { if (m_pBuffer) diff --git a/PdfFile/SrcWriter/Streams.h b/PdfFile/SrcWriter/Streams.h index 471bbaa5f2..18c585da32 100644 --- a/PdfFile/SrcWriter/Streams.h +++ b/PdfFile/SrcWriter/Streams.h @@ -158,6 +158,8 @@ namespace PdfWriter { return StreamMemory; } + BYTE* GetBuffer(); + void ClearWithoutAttack(); private: