Fix bug 74294

This commit is contained in:
Svetlana Kulikova
2025-05-14 16:45:35 +03:00
parent 84de7e98be
commit 923f39fada
7 changed files with 82 additions and 16 deletions

View File

@ -1555,6 +1555,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD
PDFDoc* pPDFDocument = _pDoc; PDFDoc* pPDFDocument = _pDoc;
XRef* xref = pPDFDocument->getXRef(); XRef* xref = pPDFDocument->getXRef();
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree();
int nPagesBefore = m_pReader->GetNumPagesBefore(pPDFDocument); int nPagesBefore = m_pReader->GetNumPagesBefore(pPDFDocument);
if (unLength == 0) if (unLength == 0)
@ -1570,7 +1571,10 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD
PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc);
pDoc->AddObject(pPage); pDoc->AddObject(pPage);
pDoc->AddPage(pDoc->GetPagesCount(), pPage); if (m_nMode == Mode::WriteAppend)
pDoc->AddPage(pDoc->GetPagesCount(), pPage);
else
pPageTree->ReplacePage(nPagesBefore + (arrPageIndex ? arrPageIndex[i] : i), pPage);
pDoc->AddEditPage(pPage, nPagesBefore + (arrPageIndex ? arrPageIndex[i] : i)); pDoc->AddEditPage(pPage, nPagesBefore + (arrPageIndex ? arrPageIndex[i] : i));
// Получение объекта страницы // Получение объекта страницы
@ -1920,12 +1924,18 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength)
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
if (!pDoc) if (!pDoc)
return false; return false;
PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree();
if (!pPageTree)
return false;
int nPages = m_pReader->GetNumPages();
pPageTree->CreateFakePages(nPages);
int nTotalPages = 0; int nTotalPages = 0;
int nPDFIndex = 0; int nPDFIndex = 0;
std::map<int, std::vector<int>> mFileToPages; std::map<int, std::vector<int>> mFileToPages;
PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex); PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex);
int nPages = pPDFDocument->getNumPages(); nPages = pPDFDocument->getNumPages();
for (unsigned int i = 0; i < unLength; ++i) for (unsigned int i = 0; i < unLength; ++i)
{ {
if (arrPageIndex[i] < nTotalPages + nPages) if (arrPageIndex[i] < nTotalPages + nPages)
@ -1953,6 +1963,16 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength)
} }
return true; return true;
} }
void CPdfEditor::AfterSplitPages()
{
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
if (!pDoc)
return;
PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree();
if (!pPageTree)
return;
pPageTree->ClearFakePages();
}
void CreateOutlines(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, OutlineItem* pOutlineItem, PdfWriter::COutline* pParent) void CreateOutlines(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, OutlineItem* pOutlineItem, PdfWriter::COutline* pParent)
{ {
std::string sTitle = NSStringExt::CConverter::GetUtf8FromUTF32(pOutlineItem->getTitle(), pOutlineItem->getTitleLength()); std::string sTitle = NSStringExt::CConverter::GetUtf8FromUTF32(pOutlineItem->getTitle(), pOutlineItem->getTitleLength());
@ -2100,7 +2120,7 @@ bool CPdfEditor::MergePages(const std::wstring& wsPath, const std::wstring& wsPr
} }
bool CPdfEditor::DeletePage(int nPageIndex) bool CPdfEditor::DeletePage(int nPageIndex)
{ {
if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) if (m_nMode == Mode::Unknown && !IncrementalUpdates())
return false; return false;
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
@ -2131,7 +2151,12 @@ bool CPdfEditor::AddPage(int nPageIndex)
{ {
std::vector<int>::iterator it = std::find(m_mObjManager.m_arrSplitAddPages.begin(), m_mObjManager.m_arrSplitAddPages.end(), m_nOriginIndex++); std::vector<int>::iterator it = std::find(m_mObjManager.m_arrSplitAddPages.begin(), m_mObjManager.m_arrSplitAddPages.end(), m_nOriginIndex++);
if (it == m_mObjManager.m_arrSplitAddPages.end()) if (it == m_mObjManager.m_arrSplitAddPages.end())
{
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree();
pPageTree->CreateFakePages(1, nPageIndex);
return false; return false;
}
m_mObjManager.m_arrSplitAddPages.erase(it); m_mObjManager.m_arrSplitAddPages.erase(it);
} }
@ -2153,7 +2178,7 @@ bool CPdfEditor::AddPage(int nPageIndex)
} }
bool CPdfEditor::MovePage(int nPageIndex, int nPos) bool CPdfEditor::MovePage(int nPageIndex, int nPos)
{ {
if (EditPage(nPageIndex, true, true)) if (EditPage(nPageIndex, true, true) || m_nMode == Mode::WriteNew)
return m_pWriter->GetDocument()->MovePage(nPageIndex, nPos); return m_pWriter->GetDocument()->MovePage(nPageIndex, nPos);
return false; return false;
} }

View File

@ -96,6 +96,7 @@ public:
bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath);
bool SplitPages(const int* arrPageIndex, unsigned int unLength); bool SplitPages(const int* arrPageIndex, unsigned int unLength);
void AfterSplitPages();
bool MergePages(const std::wstring& wsPath, const std::wstring& wsPrefixForm); bool MergePages(const std::wstring& wsPath, const std::wstring& wsPrefixForm);
private: private:

View File

@ -450,6 +450,7 @@ BYTE* CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength, BYTE*
CConvertFromBinParams* pParams = new CConvertFromBinParams(); CConvertFromBinParams* pParams = new CConvertFromBinParams();
AddToPdfFromBinary(pChanges + 4, nLength - 4, pParams); AddToPdfFromBinary(pChanges + 4, nLength - 4, pParams);
} }
m_pInternal->pEditor->AfterSplitPages();
if (m_pInternal->pWriter->SaveToMemory(&pRes, &nLen) != 0) if (m_pInternal->pWriter->SaveToMemory(&pRes, &nLen) != 0)
{ {

View File

@ -1707,8 +1707,16 @@ namespace PdfWriter
if (m_pPageTree) if (m_pPageTree)
{ {
CObjectBase* pObj = m_pPageTree->RemovePage(nPageIndex); CObjectBase* pObj = m_pPageTree->RemovePage(nPageIndex);
if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGE) if (pObj)
return m_pPageTree->InsertPage(nPos, (CPage*)pObj); {
if (pObj->GetType() == object_type_UNKNOWN)
{
CObjectBase* pObjTemp = pObj->Copy();
delete pObj;
pObj = pObjTemp;
}
return m_pPageTree->InsertPage(nPos, pObj);
}
} }
return false; return false;
} }

View File

@ -202,6 +202,7 @@ namespace PdfWriter
std::string SetParentKids(int nParentID); std::string SetParentKids(int nParentID);
const std::map<int, CAnnotation*>& GetAnnots() { return m_mAnnotations; } const std::map<int, CAnnotation*>& GetAnnots() { return m_mAnnotations; }
const std::map<int, CDictObject*>& GetParents() { return m_mParents; } const std::map<int, CDictObject*>& GetParents() { return m_mParents; }
CPageTree* GetPageTree() { return m_pPageTree; }
void AddShapeXML(const std::string& sXML); void AddShapeXML(const std::string& sXML);
void EndShapeXML(); void EndShapeXML();
void ClearPage(); void ClearPage();

View File

@ -224,9 +224,9 @@ namespace PdfWriter
if (pResources) if (pResources)
pResources->Fix(); pResources->Fix();
} }
void CPageTree::AddPage(CPage* pPage) void CPageTree::AddPage(CObjectBase* pObj)
{ {
m_pPages->Add(pPage); m_pPages->Add(pObj);
(*m_pCount)++; (*m_pCount)++;
} }
CObjectBase* CPageTree::GetObj(int nPageIndex) CObjectBase* CPageTree::GetObj(int nPageIndex)
@ -247,12 +247,13 @@ namespace PdfWriter
int nI = 0; int nI = 0;
return GetFromPageTree(nPageIndex, nI, true); return GetFromPageTree(nPageIndex, nI, true);
} }
bool CPageTree::InsertPage(int nPageIndex, CPage* pPage) bool CPageTree::InsertPage(int nPageIndex, CObjectBase* pPage)
{ {
if (nPageIndex >= m_pCount->Get()) if (nPageIndex >= m_pCount->Get())
{ {
AddPage(pPage); AddPage(pPage);
pPage->Add("Parent", this); if (pPage->GetType() == object_type_DICT && ((CDictObject*)pPage)->GetDictType() == dict_type_PAGE)
((CPage*)pPage)->Add("Parent", this);
return true; return true;
} }
int nI = 0; int nI = 0;
@ -287,7 +288,7 @@ namespace PdfWriter
} }
return false; return false;
} }
CObjectBase* CPageTree::GetFromPageTree(int nPageIndex, int& nI, bool bRemove, bool bInsert, CPage* pPage) CObjectBase* CPageTree::GetFromPageTree(int nPageIndex, int& nI, bool bRemove, bool bInsert, CObjectBase* pPage)
{ {
for (int i = 0, count = m_pPages->GetCount(); i < count; ++i) for (int i = 0, count = m_pPages->GetCount(); i < count; ++i)
{ {
@ -303,14 +304,16 @@ namespace PdfWriter
if (bRemove && bInsert) if (bRemove && bInsert)
{ {
m_pPages->Insert(pObj, pPage, true); m_pPages->Insert(pObj, pPage, true);
pPage->Add("Parent", this); if (pPage->GetType() == object_type_DICT && ((CDictObject*)pPage)->GetDictType() == dict_type_PAGE)
((CPage*)pPage)->Add("Parent", this);
} }
else if (bRemove) else if (bRemove)
pRes = m_pPages->Remove(i); pRes = m_pPages->Remove(i);
else if (bInsert) else if (bInsert)
{ {
m_pPages->Insert(pObj, pPage); m_pPages->Insert(pObj, pPage);
pPage->Add("Parent", this); if (pPage->GetType() == object_type_DICT && ((CDictObject*)pPage)->GetDictType() == dict_type_PAGE)
((CPage*)pPage)->Add("Parent", this);
} }
} }
nI++; nI++;
@ -343,6 +346,31 @@ namespace PdfWriter
} }
return false; return false;
} }
void CPageTree::CreateFakePages(int nPages, int nPageIndex)
{
for (int i = 0; i < nPages; ++i)
{
CObjectBase* pTarget = GetObj(nPageIndex);
if (pTarget)
m_pPages->Insert(pTarget, new CObjectBase());
else
m_pPages->Add(new CObjectBase());
(*m_pCount)++;
}
}
void CPageTree::ClearFakePages()
{
for (int i = 0; i < GetCount(); ++i)
{
CObjectBase* pObj = GetObj(i);
if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGE)
continue;
pObj = m_pPages->Remove(i);
delete pObj;
(*m_pCount)--;
--i;
}
}
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// CPage // CPage
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------

View File

@ -65,14 +65,16 @@ namespace PdfWriter
CPageTree(CXref* pXref); CPageTree(CXref* pXref);
CPageTree(); CPageTree();
void Fix(); void Fix();
void AddPage(CPage* pPage); void AddPage(CObjectBase* pPage);
CObjectBase* GetObj(int nPageIndex); CObjectBase* GetObj(int nPageIndex);
CPage* GetPage(int nPageIndex); CPage* GetPage(int nPageIndex);
CObjectBase* RemovePage(int nPageIndex); CObjectBase* RemovePage(int nPageIndex);
bool InsertPage(int nPageIndex, CPage* pPage); bool InsertPage(int nPageIndex, CObjectBase* pPage);
bool ReplacePage(int nPageIndex, CPage* pPage); bool ReplacePage(int nPageIndex, CPage* pPage);
bool Join(CPageTree* pPageTree); bool Join(CPageTree* pPageTree);
bool Find(CPage* pPage, int& nI); bool Find(CPage* pPage, int& nI);
void CreateFakePages(int nPages, int nPageIndex = 0);
void ClearFakePages();
unsigned int GetCount() unsigned int GetCount()
{ {
return m_pCount ? m_pCount->Get() : 0; return m_pCount ? m_pCount->Get() : 0;
@ -82,7 +84,7 @@ namespace PdfWriter
return dict_type_PAGES; return dict_type_PAGES;
} }
private: private:
CObjectBase* GetFromPageTree(int nPageIndex, int& nI, bool bRemove = false, bool bInsert = false, CPage* pPage = NULL); CObjectBase* GetFromPageTree(int nPageIndex, int& nI, bool bRemove = false, bool bInsert = false, CObjectBase* pPage = NULL);
CNumberObject* m_pCount; CNumberObject* m_pCount;
CArrayObject* m_pPages; CArrayObject* m_pPages;