mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
Merge remote-tracking branch 'origin/develop' into feature/pdf-link
This commit is contained in:
@ -1126,7 +1126,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// OWNER PASSWORD
|
||||
if (true)
|
||||
if (false)
|
||||
{
|
||||
std::string sPassword = "gfhjkmgfhjkm";
|
||||
std::cout << "CheckPerm 4 Edit " << CheckPerm(pGrFile, 4) << std::endl;
|
||||
@ -1176,7 +1176,7 @@ int main(int argc, char* argv[])
|
||||
free(pInfo);
|
||||
|
||||
// LINKS
|
||||
if (true && nPagesCount > 0)
|
||||
if (false && nPagesCount > 0)
|
||||
{
|
||||
BYTE* pLinks = GetLinks(pGrFile, nTestPage);
|
||||
nLength = READ_INT(pLinks);
|
||||
@ -1212,7 +1212,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// STRUCTURE
|
||||
if (true)
|
||||
if (false)
|
||||
{
|
||||
BYTE* pStructure = GetStructure(pGrFile);
|
||||
nLength = READ_INT(pStructure);
|
||||
@ -1242,7 +1242,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// GLYPHS
|
||||
if (true && nPagesCount > 0)
|
||||
if (false && nPagesCount > 0)
|
||||
{
|
||||
BYTE* pGlyphs = GetGlyphs(pGrFile, nTestPage);
|
||||
nLength = READ_INT(pGlyphs);
|
||||
|
||||
@ -713,12 +713,13 @@ namespace DocFileFormat
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 1; i < arField.size(); i++)
|
||||
//for (size_t i = 1; i < arField.size(); i++)
|
||||
if (arField.size() > 1)
|
||||
{
|
||||
std::wstring f1 = arField[1];
|
||||
int d = (int)f1.find(PAGEREF);
|
||||
size_t d = f1.find(PAGEREF);
|
||||
|
||||
if (d > 0)
|
||||
if (d != std::wstring::npos)
|
||||
{
|
||||
_writeWebHidden = true;
|
||||
std::wstring _writeTocLink =f1.substr(d + 9);
|
||||
@ -729,10 +730,8 @@ namespace DocFileFormat
|
||||
_writeAfterRun += XmlUtils::EncodeXmlString(_writeTocLink);
|
||||
_writeAfterRun += std::wstring (L"\" w:history=\"1\">");
|
||||
|
||||
break;
|
||||
//cp = cpFieldSep1;
|
||||
//break;
|
||||
}
|
||||
//cpFieldSep1 = cpFieldSep2;
|
||||
}
|
||||
_skipRuns = 5; //with separator
|
||||
}
|
||||
|
||||
@ -99,6 +99,7 @@ namespace DocFileFormat
|
||||
XMLTools::XMLElement pgNumType (L"w:pgNumType");
|
||||
|
||||
HeaderAndFooterTable* pTable = _ctx->_doc->headerAndFooterTable;
|
||||
bool bHasEndnoteNumFmt = false;
|
||||
|
||||
if (pTable)
|
||||
{
|
||||
@ -327,8 +328,11 @@ namespace DocFileFormat
|
||||
break;
|
||||
|
||||
case sprmSNfcEdnRef:
|
||||
{
|
||||
appendValueElement( &endnotePr, L"numFmt", NumberingMapping::GetNumberFormatWideString( FormatUtils::BytesToInt16( iter->Arguments, 0, iter->argumentsSize ) ), true );
|
||||
break;
|
||||
bHasEndnoteNumFmt = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case sprmSNFtn:
|
||||
appendValueElement( &footnotePr, L"numStart", FormatUtils::IntToWideString( FormatUtils::BytesToInt16( iter->Arguments, 0, iter->argumentsSize ) ), true );
|
||||
@ -488,6 +492,10 @@ namespace DocFileFormat
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bHasEndnoteNumFmt)
|
||||
{
|
||||
appendValueElement( &endnotePr, L"numFmt", L"decimal", true );
|
||||
}
|
||||
|
||||
if (bWasSprmSFPgnRestart && false == wsSprmSPgnStart.empty() )
|
||||
appendValueAttribute( &pgNumType, L"w:start", wsSprmSPgnStart );
|
||||
|
||||
@ -72,7 +72,14 @@ void AutoFilter::readFields(CFRecord& record)
|
||||
{
|
||||
size_t pos_record = record.getRdPtr();
|
||||
|
||||
if (size == 0xffffffff) size = record.getDataSize() - pos_record;
|
||||
|
||||
if (size == 0xffffffff)
|
||||
size = record.getDataSize() - pos_record;
|
||||
else if(record.getDataSize() < pos_record + size)
|
||||
{
|
||||
//size error
|
||||
return;
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
|
||||
@ -55,6 +55,8 @@ void DataFormat::readFields(CFRecord& record)
|
||||
unsigned short flags;
|
||||
record >> xi >> yi >> iss >> flags;
|
||||
fUnknown = GETBIT(flags, 0);
|
||||
if(iss > 1000)
|
||||
iss = 0;
|
||||
}
|
||||
|
||||
void DataFormat::writeFields(CFRecord& record)
|
||||
|
||||
@ -148,7 +148,7 @@ int MarkerFormat::serialize(std::wostream & _stream, int index, BaseObjectPtr _G
|
||||
{
|
||||
CP_XML_NODE(L"a:srgbClr")
|
||||
{
|
||||
CP_XML_ATTR(L"val", (false == fAuto || index < 0) ? rgbBack.strRGB : default_marker_color[index]);
|
||||
CP_XML_ATTR(L"val", (false == fAuto || index < 0 || index > default_marker_color->size()) ? rgbBack.strRGB : default_marker_color[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,7 +158,7 @@ int MarkerFormat::serialize(std::wostream & _stream, int index, BaseObjectPtr _G
|
||||
{
|
||||
CP_XML_NODE(L"a:srgbClr")
|
||||
{
|
||||
CP_XML_ATTR(L"val", (false == fAuto || index < 0) ? rgbFore.strRGB : default_marker_color[index]);
|
||||
CP_XML_ATTR(L"val", (false == fAuto || index < 0 || index > default_marker_color->size()) ? rgbFore.strRGB : default_marker_color[index]);
|
||||
}
|
||||
}
|
||||
CP_XML_NODE(L"a:prstDash") { CP_XML_ATTR(L"val", L"solid"); }
|
||||
|
||||
@ -53,7 +53,7 @@ void Feat11FdaAutoFilter::load(CFRecord& record)
|
||||
}
|
||||
record.skipNunBytes(2);
|
||||
|
||||
if (cbAutoFilter > 0 && cbAutoFilter < 2080)
|
||||
if (cbAutoFilter > 0 && cbAutoFilter < 2080 && (record.getDataSize() - record.getRdPtr()) >= cbAutoFilter)
|
||||
{
|
||||
recAutoFilter.size = cbAutoFilter;
|
||||
recAutoFilter.readFields(record);
|
||||
|
||||
@ -80,10 +80,11 @@ const bool LD::loadContent(BinProcessor& proc)
|
||||
elements_.pop_back();
|
||||
}
|
||||
|
||||
proc.mandatory<ATTACHEDLABEL>();
|
||||
|
||||
m_ATTACHEDLABEL = elements_.back();
|
||||
elements_.pop_back();
|
||||
if(proc.mandatory<ATTACHEDLABEL>())
|
||||
{
|
||||
m_ATTACHEDLABEL = elements_.back();
|
||||
elements_.pop_back();
|
||||
}
|
||||
|
||||
if (proc.optional<FRAME>())
|
||||
{
|
||||
@ -102,7 +103,8 @@ const bool LD::loadContent(BinProcessor& proc)
|
||||
elements_.pop_back();
|
||||
}
|
||||
proc.optional<CRTMLFRT>();
|
||||
proc.mandatory<End>(); elements_.pop_back();
|
||||
if(proc.mandatory<End>())
|
||||
elements_.pop_back();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -305,7 +305,7 @@ int SS::serialize_default(std::wostream & _stream, int series_type, int ind )
|
||||
if ((line) && (line->lns == (_UINT16)5)) ind = -1;
|
||||
}
|
||||
|
||||
if (ind >= 0 && m_isAutoLine)
|
||||
if (ind >= 0 && default_series_line_color->size() > ind && m_isAutoLine)
|
||||
{
|
||||
CP_XML_NODE(L"a:ln")
|
||||
{
|
||||
@ -444,7 +444,8 @@ int SS::serialize(std::wostream & _stream, int series_type, int indPt)
|
||||
{
|
||||
CP_XML_NODE(L"a:srgbClr")
|
||||
{
|
||||
CP_XML_ATTR(L"val", default_series_line_color[ind]);
|
||||
if(default_series_line_color->size() > ind)
|
||||
CP_XML_ATTR(L"val", default_series_line_color[ind]);
|
||||
}
|
||||
}
|
||||
CP_XML_NODE(L"a:prstDash")
|
||||
|
||||
@ -52,7 +52,7 @@ bool DigitReader::ReadDigit(const std::wstring &value, std::wstring &digit, std:
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((0 == *pEndPtr) || (pEndPtr != value.c_str() && (value.c_str() + length - pEndPtr) <= 4))
|
||||
if ((0 == *pEndPtr) || (pEndPtr != value.c_str() && (value.c_str() + length - pEndPtr) <= 1))
|
||||
{
|
||||
std::wstring postfix;
|
||||
auto length = value.length();
|
||||
@ -88,6 +88,9 @@ bool DigitReader::ReadDigit(const std::wstring &value, std::wstring &digit, std:
|
||||
format = DefaultPercentFormat;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
/*
|
||||
else if(currency.CheckPostfix(postfix))
|
||||
{
|
||||
digit = std::to_wstring(dValue);
|
||||
@ -116,6 +119,7 @@ bool DigitReader::ReadDigit(const std::wstring &value, std::wstring &digit, std:
|
||||
}
|
||||
format = data_format;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -80,7 +80,7 @@ void oox_data_labels::oox_serialize(std::wostream & _Wostream)
|
||||
case 6: CP_XML_ATTR(L"val", L"l"); break;
|
||||
case 7: CP_XML_ATTR(L"val", L"inBase"); break;
|
||||
case 9: CP_XML_ATTR(L"val", L"r"); break;
|
||||
case 10: CP_XML_ATTR(L"val", L"outEnd");break;
|
||||
case 10: CP_XML_ATTR(L"val", L"t"); break;
|
||||
case 11: CP_XML_ATTR(L"val", L"t"); break;
|
||||
case 12: CP_XML_ATTR(L"val", L"t"); break;
|
||||
case 5: //CP_XML_ATTR(L"val", L"inEnd"); break;
|
||||
|
||||
@ -999,6 +999,8 @@ void CPdfEditor::SetMode(Mode nMode)
|
||||
int nPages = m_pReader->GetNumPages();
|
||||
pPageTree->CreateFakePages(nPages);
|
||||
m_pWriter->SetNeedAddHelvetica(false);
|
||||
|
||||
NewFrom();
|
||||
}
|
||||
}
|
||||
bool CPdfEditor::IncrementalUpdates()
|
||||
@ -1233,6 +1235,257 @@ bool CPdfEditor::IncrementalUpdates()
|
||||
pagesRefObj.free();
|
||||
return bRes;
|
||||
}
|
||||
void CPdfEditor::NewFrom()
|
||||
{
|
||||
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
|
||||
Object oCatalog;
|
||||
PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0);
|
||||
int nStartRefID = 0;
|
||||
XRef* xref = pPDFDocument->getXRef();
|
||||
if (!xref->getCatalog(&oCatalog)->isDict())
|
||||
{
|
||||
oCatalog.free();
|
||||
return;
|
||||
}
|
||||
|
||||
Object oAcroForm;
|
||||
if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict())
|
||||
{
|
||||
PdfWriter::CDictObject* pAcroForm = pDoc->GetAcroForm();
|
||||
if (!pAcroForm)
|
||||
{
|
||||
pAcroForm = new PdfWriter::CDictObject();
|
||||
if (oAcroForm.isRef())
|
||||
pDoc->AddObject(pAcroForm);
|
||||
pDoc->SetAcroForm(pAcroForm);
|
||||
}
|
||||
else
|
||||
pAcroForm->Remove("NeedAppearances");
|
||||
|
||||
if (oAcroForm.isRef())
|
||||
{
|
||||
oAcroForm.free();
|
||||
if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict())
|
||||
{
|
||||
oAcroForm.free(); oCatalog.free();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex)
|
||||
{
|
||||
Object oTemp;
|
||||
char* chKey = oAcroForm.dictGetKey(nIndex);
|
||||
if (strcmp("Fields", chKey) == 0)
|
||||
{
|
||||
Ref oFieldsRef = { -1, -1 };
|
||||
if (oAcroForm.dictGetValNF(nIndex, &oTemp)->isRef())
|
||||
oFieldsRef = oTemp.getRef();
|
||||
oTemp.free();
|
||||
|
||||
PdfWriter::CArrayObject* pFields = dynamic_cast<PdfWriter::CArrayObject*>(pAcroForm->Get("Fields"));
|
||||
if (!pFields)
|
||||
{
|
||||
PdfWriter::CObjectBase* pObj = oFieldsRef.num > 0 ? m_mObjManager.GetObj(oFieldsRef.num + nStartRefID) : NULL;
|
||||
if (pObj)
|
||||
{
|
||||
pAcroForm->Add(chKey, pObj);
|
||||
m_mObjManager.IncRefCount(oFieldsRef.num + nStartRefID);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray())
|
||||
{
|
||||
if (!pFields)
|
||||
{
|
||||
pFields = new PdfWriter::CArrayObject();
|
||||
if (oFieldsRef.num > 0)
|
||||
{
|
||||
pDoc->AddObject(pFields);
|
||||
m_mObjManager.AddObj(oFieldsRef.num + nStartRefID, pFields);
|
||||
}
|
||||
pAcroForm->Add(chKey, pFields);
|
||||
}
|
||||
|
||||
for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex)
|
||||
{
|
||||
Object oRes;
|
||||
PdfWriter::CObjectBase* pObj = NULL;
|
||||
if (oTemp.arrayGetNF(nIndex, &oRes)->isRef())
|
||||
pObj = m_mObjManager.GetObj(oRes.getRefNum() + nStartRefID);
|
||||
if (pObj)
|
||||
{
|
||||
pFields->Add(pObj);
|
||||
m_mObjManager.IncRefCount(oRes.getRefNum() + nStartRefID);
|
||||
AddWidgetParent(pDoc, &m_mObjManager, pObj);
|
||||
oRes.free();
|
||||
continue;
|
||||
}
|
||||
oRes.free();
|
||||
}
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else if (!pFields)
|
||||
{
|
||||
oTemp.free();
|
||||
oAcroForm.dictGetValNF(nIndex, &oTemp);
|
||||
}
|
||||
else
|
||||
{
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (strcmp("SigFlags", chKey) == 0 || strcmp("XFA", chKey) == 0 || strcmp("DA", chKey) == 0 || strcmp("NeedAppearances", chKey) == 0)
|
||||
{ // Нельзя гарантировать их выполнение
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else if (strcmp("CO", chKey) == 0)
|
||||
{
|
||||
Ref oCORef = { -1, -1 };
|
||||
if (oAcroForm.dictGetValNF(nIndex, &oTemp)->isRef())
|
||||
oCORef = oTemp.getRef();
|
||||
oTemp.free();
|
||||
|
||||
PdfWriter::CArrayObject* pCO = dynamic_cast<PdfWriter::CArrayObject*>(pAcroForm->Get("CO"));
|
||||
if (!pCO)
|
||||
{
|
||||
PdfWriter::CObjectBase* pObj = oCORef.num > 0 ? m_mObjManager.GetObj(oCORef.num + nStartRefID) : NULL;
|
||||
if (pObj)
|
||||
{
|
||||
pAcroForm->Add(chKey, pObj);
|
||||
m_mObjManager.IncRefCount(oCORef.num + nStartRefID);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray())
|
||||
{
|
||||
if (!pCO)
|
||||
{
|
||||
pCO = new PdfWriter::CArrayObject();
|
||||
if (oCORef.num > 0)
|
||||
{
|
||||
pDoc->AddObject(pCO);
|
||||
m_mObjManager.AddObj(oCORef.num + nStartRefID, pCO);
|
||||
}
|
||||
pAcroForm->Add(chKey, pCO);
|
||||
}
|
||||
|
||||
for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex)
|
||||
{
|
||||
Object oRes;
|
||||
PdfWriter::CObjectBase* pObj = NULL;
|
||||
if (oTemp.arrayGetNF(nIndex, &oRes)->isRef())
|
||||
pObj = m_mObjManager.GetObj(oRes.getRefNum() + nStartRefID);
|
||||
if (pObj)
|
||||
{
|
||||
pCO->Add(pObj);
|
||||
m_mObjManager.IncRefCount(oRes.getRefNum() + nStartRefID);
|
||||
}
|
||||
oRes.free();
|
||||
}
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (strcmp("DR", chKey) == 0)
|
||||
{ // Добавляем только уникальные ключи
|
||||
PdfWriter::CResourcesDict* pDR = pDoc->GetFieldsResources();
|
||||
if (!pDR)
|
||||
{
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oAcroForm.dictGetVal(nIndex, &oTemp)->isDict())
|
||||
{
|
||||
Object oTemp2;
|
||||
for (int nIndex2 = 0; nIndex2 < oTemp.dictGetLength(); ++nIndex2)
|
||||
{
|
||||
char* chKey2 = oTemp.dictGetKey(nIndex2);
|
||||
if (strcmp("ProcSet", chKey2) == 0 || !oTemp.dictGetVal(nIndex2, &oTemp2)->isDict())
|
||||
{
|
||||
oTemp2.free();
|
||||
continue;
|
||||
}
|
||||
PdfWriter::CDictObject* pDict = dynamic_cast<PdfWriter::CDictObject*>(pDR->Get(chKey2));
|
||||
if (!pDict)
|
||||
{
|
||||
Object oTempRef;
|
||||
if (oTemp.dictGetValNF(nIndex2, &oTempRef)->isRef())
|
||||
{
|
||||
PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oTempRef.getRefNum() + nStartRefID);
|
||||
if (pObj)
|
||||
{
|
||||
pDR->Add(chKey2, pObj);
|
||||
m_mObjManager.IncRefCount(oTempRef.getRefNum() + nStartRefID);
|
||||
oTemp2.free(); oTempRef.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
if (oTempRef.isRef())
|
||||
pDoc->AddObject(pBase);
|
||||
pDR->Add(chKey2, pBase);
|
||||
oTemp2.free(); oTempRef.free();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int nIndex3 = 0; nIndex3 < oTemp2.dictGetLength(); ++nIndex3)
|
||||
{
|
||||
char* chKey3 = oTemp2.dictGetKey(nIndex3);
|
||||
if (pDict->Get(chKey3))
|
||||
continue;
|
||||
Object oTempRef;
|
||||
if (oTemp2.dictGetValNF(nIndex3, &oTempRef)->isRef())
|
||||
{
|
||||
PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oTempRef.getRefNum() + nStartRefID);
|
||||
if (pObj)
|
||||
{
|
||||
pDict->Add(chKey3, pObj);
|
||||
m_mObjManager.IncRefCount(oTempRef.getRefNum() + nStartRefID);
|
||||
oTemp2.free(); oTempRef.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
if (oTempRef.isRef())
|
||||
pDoc->AddObject(pBase);
|
||||
pDict->Add(chKey3, pBase);
|
||||
oTemp2.free(); oTempRef.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
oTemp2.free(); oTemp.free();
|
||||
pDR->Fix();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
oTemp.free();
|
||||
oAcroForm.dictGetValNF(nIndex, &oTemp);
|
||||
}
|
||||
}
|
||||
else
|
||||
oAcroForm.dictGetValNF(nIndex, &oTemp);
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
pAcroForm->Add(chKey, pBase);
|
||||
oTemp.free();
|
||||
}
|
||||
}
|
||||
oAcroForm.free(); oCatalog.free();
|
||||
}
|
||||
void CPdfEditor::Close()
|
||||
{
|
||||
if (m_wsDstFile.empty())
|
||||
@ -1262,208 +1515,11 @@ void CPdfEditor::Close()
|
||||
EditPage(i, false, true);
|
||||
}
|
||||
|
||||
Object oCatalog;
|
||||
NewFrom();
|
||||
|
||||
PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0);
|
||||
int nStartRefID = 0;
|
||||
XRef* xref = pPDFDocument->getXRef();
|
||||
if (!xref->getCatalog(&oCatalog)->isDict())
|
||||
{
|
||||
oCatalog.free();
|
||||
return;
|
||||
}
|
||||
|
||||
Object oAcroForm;
|
||||
if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict())
|
||||
{
|
||||
PdfWriter::CDictObject* pAcroForm = pDoc->GetAcroForm();
|
||||
if (!pAcroForm)
|
||||
{
|
||||
pAcroForm = new PdfWriter::CDictObject();
|
||||
if (oAcroForm.isRef())
|
||||
pDoc->AddObject(pAcroForm);
|
||||
pDoc->SetAcroForm(pAcroForm);
|
||||
}
|
||||
else
|
||||
pAcroForm->Remove("NeedAppearances");
|
||||
|
||||
if (oAcroForm.isRef())
|
||||
{
|
||||
oAcroForm.free();
|
||||
if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict())
|
||||
{
|
||||
oAcroForm.free(); oCatalog.free();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex)
|
||||
{
|
||||
Object oTemp;
|
||||
char* chKey = oAcroForm.dictGetKey(nIndex);
|
||||
if (strcmp("Fields", chKey) == 0)
|
||||
{
|
||||
Ref oFieldsRef = { -1, -1 };
|
||||
if (oAcroForm.dictGetValNF(nIndex, &oTemp)->isRef())
|
||||
oFieldsRef = oTemp.getRef();
|
||||
oTemp.free();
|
||||
|
||||
PdfWriter::CArrayObject* pFields = dynamic_cast<PdfWriter::CArrayObject*>(pAcroForm->Get("Fields"));
|
||||
if (!pFields)
|
||||
{
|
||||
PdfWriter::CObjectBase* pObj = oFieldsRef.num > 0 ? m_mObjManager.GetObj(oFieldsRef.num + nStartRefID) : NULL;
|
||||
if (pObj)
|
||||
{
|
||||
pAcroForm->Add(chKey, pObj);
|
||||
m_mObjManager.IncRefCount(oFieldsRef.num + nStartRefID);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray())
|
||||
{
|
||||
if (!pFields)
|
||||
{
|
||||
pFields = new PdfWriter::CArrayObject();
|
||||
if (oFieldsRef.num > 0)
|
||||
{
|
||||
pDoc->AddObject(pFields);
|
||||
m_mObjManager.AddObj(oFieldsRef.num + nStartRefID, pFields);
|
||||
}
|
||||
pAcroForm->Add(chKey, pFields);
|
||||
}
|
||||
|
||||
for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex)
|
||||
{
|
||||
Object oRes;
|
||||
PdfWriter::CObjectBase* pObj = NULL;
|
||||
if (oTemp.arrayGetNF(nIndex, &oRes)->isRef())
|
||||
pObj = m_mObjManager.GetObj(oRes.getRefNum() + nStartRefID);
|
||||
if (pObj)
|
||||
{
|
||||
pFields->Add(pObj);
|
||||
m_mObjManager.IncRefCount(oRes.getRefNum() + nStartRefID);
|
||||
AddWidgetParent(pDoc, &m_mObjManager, pObj);
|
||||
oRes.free();
|
||||
continue;
|
||||
}
|
||||
oRes.free();
|
||||
}
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else if (!pFields)
|
||||
{
|
||||
oTemp.free();
|
||||
oAcroForm.dictGetValNF(nIndex, &oTemp);
|
||||
}
|
||||
else
|
||||
{
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (strcmp("SigFlags", chKey) == 0 || strcmp("XFA", chKey) == 0 || (strcmp("DA", chKey) == 0 && pAcroForm->Get("DA")) || strcmp("NeedAppearances", chKey) == 0)
|
||||
{ // Нельзя гарантировать их выполнение
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else if (strcmp("DR", chKey) == 0)
|
||||
{ // Добавляем только уникальные ключи
|
||||
PdfWriter::CDictObject* pDR = dynamic_cast<PdfWriter::CDictObject*>(pAcroForm->Get("DR"));
|
||||
if (!pDR)
|
||||
{
|
||||
pDR = new PdfWriter::CDictObject();
|
||||
pDoc->AddObject(pDR);
|
||||
pAcroForm->Add(chKey, pDR);
|
||||
}
|
||||
|
||||
PdfWriter::CArrayObject* pProcset = new PdfWriter::CArrayObject();
|
||||
pDR->Add("ProcSet", pProcset);
|
||||
pProcset->Add(new PdfWriter::CNameObject("PDF"));
|
||||
pProcset->Add(new PdfWriter::CNameObject("Text"));
|
||||
pProcset->Add(new PdfWriter::CNameObject("ImageB"));
|
||||
pProcset->Add(new PdfWriter::CNameObject("ImageC"));
|
||||
pProcset->Add(new PdfWriter::CNameObject("ImageI"));
|
||||
|
||||
if (oAcroForm.dictGetVal(nIndex, &oTemp)->isDict())
|
||||
{
|
||||
Object oTemp2;
|
||||
for (int nIndex2 = 0; nIndex2 < oTemp.dictGetLength(); ++nIndex2)
|
||||
{
|
||||
char* chKey2 = oTemp.dictGetKey(nIndex2);
|
||||
if (strcmp("ProcSet", chKey2) == 0 || !oTemp.dictGetVal(nIndex2, &oTemp2)->isDict())
|
||||
{
|
||||
oTemp2.free();
|
||||
continue;
|
||||
}
|
||||
PdfWriter::CDictObject* pDict = dynamic_cast<PdfWriter::CDictObject*>(pDR->Get(chKey2));
|
||||
if (!pDict)
|
||||
{
|
||||
Object oTempRef;
|
||||
if (oTemp.dictGetValNF(nIndex2, &oTempRef)->isRef())
|
||||
{
|
||||
PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oTempRef.getRefNum() + nStartRefID);
|
||||
if (pObj)
|
||||
{
|
||||
pDR->Add(chKey2, pObj);
|
||||
m_mObjManager.IncRefCount(oTempRef.getRefNum() + nStartRefID);
|
||||
oTemp2.free(); oTempRef.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
if (oTempRef.isRef())
|
||||
pDoc->AddObject(pBase);
|
||||
pDR->Add(chKey2, pBase);
|
||||
oTemp2.free(); oTempRef.free();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int nIndex3 = 0; nIndex3 < oTemp2.dictGetLength(); ++nIndex3)
|
||||
{
|
||||
char* chKey3 = oTemp2.dictGetKey(nIndex3);
|
||||
if (pDict->Get(chKey3))
|
||||
continue;
|
||||
Object oTempRef;
|
||||
if (oTemp2.dictGetValNF(nIndex3, &oTempRef)->isRef())
|
||||
{
|
||||
PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oTempRef.getRefNum() + nStartRefID);
|
||||
if (pObj)
|
||||
{
|
||||
pDict->Add(chKey3, pObj);
|
||||
m_mObjManager.IncRefCount(oTempRef.getRefNum() + nStartRefID);
|
||||
oTemp2.free(); oTempRef.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
if (oTempRef.isRef())
|
||||
pDoc->AddObject(pBase);
|
||||
pDict->Add(chKey3, pBase);
|
||||
oTemp2.free(); oTempRef.free();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
oTemp2.free(); oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
oTemp.free();
|
||||
oAcroForm.dictGetValNF(nIndex, &oTemp);
|
||||
}
|
||||
}
|
||||
else
|
||||
oAcroForm.dictGetValNF(nIndex, &oTemp);
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
pAcroForm->Add(chKey, pBase);
|
||||
oTemp.free();
|
||||
}
|
||||
}
|
||||
oAcroForm.free(); oCatalog.free();
|
||||
|
||||
int nStartRefID = 0;
|
||||
if (xref->isEncrypted() && xref->getTrailerDict())
|
||||
{
|
||||
CryptAlgorithm encAlgorithm;
|
||||
|
||||
@ -82,7 +82,6 @@ public:
|
||||
CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, const std::wstring& _wsDstFile, CPdfReader* _pReader, CPdfWriter* _pWriter, Mode nMode = Mode::Unknown);
|
||||
|
||||
void SetMode(Mode nMode);
|
||||
bool IncrementalUpdates();
|
||||
|
||||
int GetError();
|
||||
void Close();
|
||||
@ -109,6 +108,8 @@ public:
|
||||
bool MergePages(const std::wstring& wsPath);
|
||||
|
||||
private:
|
||||
bool IncrementalUpdates();
|
||||
void NewFrom();
|
||||
void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL);
|
||||
bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc, int nStartRefID);
|
||||
bool ChangeFullNameParent(int nParent, const std::string& sPrefixForm, std::vector<int>& arrRename);
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
|
||||
#ifdef __linux__
|
||||
#include <string.h>
|
||||
#include <limits>
|
||||
#endif
|
||||
|
||||
namespace PdfWriter
|
||||
|
||||
Reference in New Issue
Block a user