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;
XRef* xref = pPDFDocument->getXRef();
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree();
int nPagesBefore = m_pReader->GetNumPagesBefore(pPDFDocument);
if (unLength == 0)
@ -1570,7 +1571,10 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD
PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc);
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));
// Получение объекта страницы
@ -1920,12 +1924,18 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength)
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
if (!pDoc)
return false;
PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree();
if (!pPageTree)
return false;
int nPages = m_pReader->GetNumPages();
pPageTree->CreateFakePages(nPages);
int nTotalPages = 0;
int nPDFIndex = 0;
std::map<int, std::vector<int>> mFileToPages;
PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex);
int nPages = pPDFDocument->getNumPages();
nPages = pPDFDocument->getNumPages();
for (unsigned int i = 0; i < unLength; ++i)
{
if (arrPageIndex[i] < nTotalPages + nPages)
@ -1953,6 +1963,16 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength)
}
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)
{
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)
{
if (m_nMode != Mode::WriteAppend && !IncrementalUpdates())
if (m_nMode == Mode::Unknown && !IncrementalUpdates())
return false;
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++);
if (it == m_mObjManager.m_arrSplitAddPages.end())
{
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree();
pPageTree->CreateFakePages(1, nPageIndex);
return false;
}
m_mObjManager.m_arrSplitAddPages.erase(it);
}
@ -2153,7 +2178,7 @@ bool CPdfEditor::AddPage(int nPageIndex)
}
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 false;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -224,9 +224,9 @@ namespace PdfWriter
if (pResources)
pResources->Fix();
}
void CPageTree::AddPage(CPage* pPage)
void CPageTree::AddPage(CObjectBase* pObj)
{
m_pPages->Add(pPage);
m_pPages->Add(pObj);
(*m_pCount)++;
}
CObjectBase* CPageTree::GetObj(int nPageIndex)
@ -247,12 +247,13 @@ namespace PdfWriter
int nI = 0;
return GetFromPageTree(nPageIndex, nI, true);
}
bool CPageTree::InsertPage(int nPageIndex, CPage* pPage)
bool CPageTree::InsertPage(int nPageIndex, CObjectBase* pPage)
{
if (nPageIndex >= m_pCount->Get())
{
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;
}
int nI = 0;
@ -287,7 +288,7 @@ namespace PdfWriter
}
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)
{
@ -303,14 +304,16 @@ namespace PdfWriter
if (bRemove && bInsert)
{
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)
pRes = m_pPages->Remove(i);
else if (bInsert)
{
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++;
@ -343,6 +346,31 @@ namespace PdfWriter
}
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
//----------------------------------------------------------------------------------------

View File

@ -65,14 +65,16 @@ namespace PdfWriter
CPageTree(CXref* pXref);
CPageTree();
void Fix();
void AddPage(CPage* pPage);
void AddPage(CObjectBase* pPage);
CObjectBase* GetObj(int nPageIndex);
CPage* GetPage(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 Join(CPageTree* pPageTree);
bool Find(CPage* pPage, int& nI);
void CreateFakePages(int nPages, int nPageIndex = 0);
void ClearFakePages();
unsigned int GetCount()
{
return m_pCount ? m_pCount->Get() : 0;
@ -82,7 +84,7 @@ namespace PdfWriter
return dict_type_PAGES;
}
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;
CArrayObject* m_pPages;