For bug 77407

This commit is contained in:
Svetlana Kulikova
2025-10-09 15:15:26 +03:00
parent 992f6616e0
commit 5b5a1d461c
5 changed files with 110 additions and 13 deletions

View File

@ -1311,11 +1311,6 @@ void CPdfEditor::Close()
} }
} }
// TODO нужна проверка полных имён
// Если имя совпадает, то: переименование с удалением действий или преобразование типа
// Если другие поля - тип, флаг и т.д. совпадает, то выносим общее в общего родителя
// Иначе переименовываем, action обрубаем
if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray())
{ {
if (!pFields) if (!pFields)
@ -2340,11 +2335,6 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD
} }
} }
// TODO нужна проверка полных имён
// Если имя совпадает, то: переименование с удалением действий или преобразование типа
// Если другие поля - тип, флаг и т.д. совпадает, то выносим общее в общего родителя
// Иначе переименовываем, action обрубаем
if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray())
{ {
if (!pFields) if (!pFields)
@ -2648,7 +2638,37 @@ void CreateOutlines(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, OutlineItem* pOu
} }
pOutlineItem->close(); pOutlineItem->close();
} }
bool CPdfEditor::MergePages(const std::wstring& wsPath, const std::wstring& wsPrefixForm) bool CPdfEditor::ChangeFullNameParent(int nParent, const std::string& sPrefix, std::vector<int>& arrRename)
{
std::vector<int>::const_iterator it2 = std::find(arrRename.begin(), arrRename.end(), nParent);
if (it2 != arrRename.end())
return true;
PdfWriter::CObjectBase* pObjBase = m_mObjManager.GetObj(nParent);
if (pObjBase->GetType() != PdfWriter::object_type_DICT)
return false;
PdfWriter::CDictObject* pDict = (PdfWriter::CDictObject*)pObjBase;
pObjBase = pDict->Get("Parent");
if (!pObjBase || !ChangeFullNameParent(pObjBase->GetObjId(), sPrefix, arrRename))
{
pObjBase = pDict->Get("T");
if (pObjBase && pObjBase->GetType() == PdfWriter::object_type_STRING)
{
PdfWriter::CStringObject* pStr = (PdfWriter::CStringObject*)pObjBase;
pStr->Add(sPrefix.c_str());
}
else if (pObjBase && pObjBase->GetType() == PdfWriter::object_type_BINARY)
{
PdfWriter::CBinaryObject* pBin = (PdfWriter::CBinaryObject*)pObjBase;
pBin->Add((BYTE*)sPrefix.c_str(), sPrefix.length());
}
}
arrRename.push_back(nParent);
return true;
}
bool CPdfEditor::MergePages(const std::wstring& wsPath, int nMaxID, const std::wstring& wsPrefixForm)
{ {
if (m_nMode == Mode::Unknown && !IncrementalUpdates()) if (m_nMode == Mode::Unknown && !IncrementalUpdates())
return false; return false;
@ -2660,6 +2680,38 @@ bool CPdfEditor::MergePages(const std::wstring& wsPath, const std::wstring& wsPr
if (!bRes) if (!bRes)
return false; return false;
// Переименование полей
std::string sPrefix = "_" + U_TO_UTF8(wsPrefixForm);
std::vector<int> arrRename; // Вектор переименованных полей
std::map<int, PdfWriter::CAnnotation*> mAnnots = m_pWriter->GetDocument()->GetAnnots();
for (auto it = mAnnots.begin(); it != mAnnots.end(); it++)
{
PdfWriter::CAnnotation* pAnnot = it->second;
if (pAnnot->GetAnnotationType() != PdfWriter::AnnotWidget || it->first < nMaxID)
continue;
std::vector<int>::iterator it2 = std::find(arrRename.begin(), arrRename.end(), it->first);
if (it2 != arrRename.end())
continue;
PdfWriter::CObjectBase* pObjBase = pAnnot->Get("Parent");
if (!pObjBase || !ChangeFullNameParent(pObjBase->GetObjId(), sPrefix, arrRename))
{
pObjBase = pAnnot->Get("T");
if (pObjBase && pObjBase->GetType() == PdfWriter::object_type_STRING)
{
PdfWriter::CStringObject* pStr = (PdfWriter::CStringObject*)pObjBase;
pStr->Add(sPrefix.c_str());
}
else if (pObjBase && pObjBase->GetType() == PdfWriter::object_type_BINARY)
{
PdfWriter::CBinaryObject* pBin = (PdfWriter::CBinaryObject*)pObjBase;
pBin->Add((BYTE*)sPrefix.c_str(), sPrefix.length());
}
}
arrRename.push_back(it->first);
}
Outline* pOutlineAdd = pDocument->getOutline(); Outline* pOutlineAdd = pDocument->getOutline();
GList* pListAdd = NULL; GList* pListAdd = NULL;
if (pOutlineAdd) if (pOutlineAdd)

View File

@ -105,11 +105,12 @@ public:
bool SplitPages(const int* arrPageIndex, unsigned int unLength); bool SplitPages(const int* arrPageIndex, unsigned int unLength);
void AfterSplitPages(); void AfterSplitPages();
bool MergePages(const std::wstring& wsPath, const std::wstring& wsPrefixForm); bool MergePages(const std::wstring& wsPath, int nMaxID, const std::wstring& wsPrefixForm);
private: private:
void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL);
bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc, int nStartRefID); bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc, int nStartRefID);
bool ChangeFullNameParent(int nParent, const std::string& sPrefixForm, std::vector<int>& arrRename);
struct CRedactData struct CRedactData
{ {

View File

@ -148,7 +148,7 @@ bool CPdfFile::MergePages(const std::wstring& wsPath, int nMaxID, const std::wst
if (!m_pInternal->pEditor) if (!m_pInternal->pEditor)
return false; return false;
if (m_pInternal->pReader->MergePages(wsPath, L"", nMaxID)) if (m_pInternal->pReader->MergePages(wsPath, L"", nMaxID))
return m_pInternal->pEditor->MergePages(wsPath, wsPrefixForm); return m_pInternal->pEditor->MergePages(wsPath, nMaxID, wsPrefixForm);
return false; return false;
} }
bool CPdfFile::MovePage(int nPageIndex, int nPos) bool CPdfFile::MovePage(int nPageIndex, int nPos)

View File

@ -179,6 +179,22 @@ namespace PdfWriter
m_bUTF16 = isUTF16; m_bUTF16 = isUTF16;
m_bDictValue = isDictValue; m_bDictValue = isDictValue;
} }
void CStringObject::Add(const char* sValue)
{
if (!sValue || !*sValue)
return;
unsigned int unAppendLen = StrLen(sValue, LIMIT_MAX_STRING_LEN);
BYTE* pNewValue = new BYTE[m_unLen + unAppendLen + 1];
if (m_unLen > 0)
StrCpy((char*)pNewValue, (char*)m_pValue, (char*)(pNewValue + m_unLen));
StrCpy((char*)(pNewValue + m_unLen), (char*)sValue, (char*)(pNewValue + m_unLen + unAppendLen));
if (m_pValue)
delete[] m_pValue;
m_pValue = pNewValue;
m_unLen += unAppendLen;
}
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// CBinaryObject // CBinaryObject
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
@ -215,6 +231,32 @@ namespace PdfWriter
else else
m_pValue = pValue; m_pValue = pValue;
} }
void CBinaryObject::Add(BYTE* pValue, unsigned int unLen)
{
if (!pValue || !unLen)
return;
unLen = std::min((unsigned int)LIMIT_MAX_STRING_LEN, unLen);
if (!m_pValue || m_unLen == 0)
{
Set(pValue, unLen, true);
return;
}
if (m_unLen + unLen > (unsigned int)LIMIT_MAX_STRING_LEN)
{
unLen = (unsigned int)LIMIT_MAX_STRING_LEN - m_unLen;
if (unLen == 0)
return;
}
BYTE* pNewValue = new BYTE[m_unLen + unLen];
MemCpy(pNewValue, m_pValue, m_unLen);
MemCpy(pNewValue + m_unLen, pValue, unLen);
if (m_pValue)
delete[] m_pValue;
m_pValue = pNewValue;
m_unLen += unLen;
}
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// CProxyObject // CProxyObject
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------

View File

@ -304,6 +304,7 @@ namespace PdfWriter
CStringObject(); CStringObject();
virtual ~CStringObject(); virtual ~CStringObject();
void Set(const char* sValue, bool isUTF16, bool isDictValue, int nMax = LIMIT_MAX_STRING_LEN); void Set(const char* sValue, bool isUTF16, bool isDictValue, int nMax = LIMIT_MAX_STRING_LEN);
void Add(const char* sValue);
const BYTE* GetString() const const BYTE* GetString() const
{ {
return (const BYTE*)m_pValue; return (const BYTE*)m_pValue;
@ -346,6 +347,7 @@ namespace PdfWriter
CBinaryObject(BYTE* pValue, unsigned int unLen, bool bCopy = true); CBinaryObject(BYTE* pValue, unsigned int unLen, bool bCopy = true);
~CBinaryObject(); ~CBinaryObject();
void Set(BYTE* pValue, unsigned int unLen, bool bCopy = true); void Set(BYTE* pValue, unsigned int unLen, bool bCopy = true);
void Add(BYTE* pValue, unsigned int unLen);
BYTE* GetValue() const BYTE* GetValue() const
{ {
return m_pValue; return m_pValue;