diff options
Diffstat (limited to 'fpdfsdk/src/fpdfsave.cpp')
-rw-r--r-- | fpdfsdk/src/fpdfsave.cpp | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/fpdfsdk/src/fpdfsave.cpp b/fpdfsdk/src/fpdfsave.cpp index f786396632..b8e9c6e25c 100644 --- a/fpdfsdk/src/fpdfsave.cpp +++ b/fpdfsdk/src/fpdfsave.cpp @@ -10,6 +10,13 @@ #include "fpdfsdk/include/fsdk_define.h" #include "public/fpdf_edit.h" +#ifdef PDF_ENABLE_XFA +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" +#include "public/fpdf_formfill.h" +#endif + #if _FX_OS_ == _FX_ANDROID_ #include "time.h" #else @@ -53,6 +60,218 @@ void CFX_IFileWrite::Release() { delete this; } +#ifdef PDF_ENABLE_XFA +FX_BOOL _SaveXFADocumentData(CPDFXFA_Document* pDocument, + CFX_PtrArray& fileList) { + if (!pDocument) + return FALSE; + if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA && + pDocument->GetDocType() != DOCTYPE_STATIC_XFA) + return TRUE; + if (!CPDFXFA_App::GetInstance()->GetXFAApp()) + return TRUE; + + IXFA_DocView* pXFADocView = pDocument->GetXFADocView(); + if (NULL == pXFADocView) + return TRUE; + + IXFA_DocHandler* pXFADocHandler = + CPDFXFA_App::GetInstance()->GetXFAApp()->GetDocHandler(); + CPDF_Document* pPDFDocument = pDocument->GetPDFDoc(); + if (pDocument == NULL) + return FALSE; + + CPDF_Dictionary* pRoot = pPDFDocument->GetRoot(); + if (pRoot == NULL) + return FALSE; + CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm"); + if (NULL == pAcroForm) + return FALSE; + CPDF_Object* pXFA = pAcroForm->GetElement("XFA"); + if (pXFA == NULL) + return TRUE; + if (!pXFA->IsArray()) + return FALSE; + CPDF_Array* pArray = pXFA->GetArray(); + if (NULL == pArray) + return FALSE; + int size = pArray->GetCount(); + int iFormIndex = -1; + int iDataSetsIndex = -1; + int iTemplate = -1; + int iLast = size - 2; + for (int i = 0; i < size - 1; i++) { + CPDF_Object* pPDFObj = pArray->GetElement(i); + if (!pPDFObj->IsString()) + continue; + if (pPDFObj->GetString() == "form") + iFormIndex = i + 1; + else if (pPDFObj->GetString() == "datasets") + iDataSetsIndex = i + 1; + else if (pPDFObj->GetString() == "template") + iTemplate = i + 1; + } + IXFA_ChecksumContext* pContext = NULL; + // Checksum + pContext = XFA_Checksum_Create(); + FXSYS_assert(pContext); + pContext->StartChecksum(); + + // template + if (iTemplate > -1) { + CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate); + CPDF_StreamAcc streamAcc; + streamAcc.LoadAllData(pTemplateStream); + uint8_t* pData = (uint8_t*)streamAcc.GetData(); + FX_DWORD dwSize2 = streamAcc.GetSize(); + IFX_FileStream* pTemplate = FX_CreateMemoryStream(pData, dwSize2); + pContext->UpdateChecksum((IFX_FileRead*)pTemplate); + pTemplate->Release(); + } + CPDF_Stream* pFormStream = NULL; + CPDF_Stream* pDataSetsStream = NULL; + if (iFormIndex != -1) { + // Get form CPDF_Stream + CPDF_Object* pFormPDFObj = pArray->GetElement(iFormIndex); + if (pFormPDFObj->IsReference()) { + CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect(); + if (pFormDirectObj && pFormDirectObj->IsStream()) { + pFormStream = (CPDF_Stream*)pFormDirectObj; + } + } else if (pFormPDFObj->IsStream()) { + pFormStream = (CPDF_Stream*)pFormPDFObj; + } + } + + if (iDataSetsIndex != -1) { + // Get datasets CPDF_Stream + CPDF_Object* pDataSetsPDFObj = pArray->GetElement(iDataSetsIndex); + if (pDataSetsPDFObj->IsReference()) { + CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj; + CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect(); + if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) { + pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj; + } + } else if (pDataSetsPDFObj->IsStream()) { + pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj; + } + } + // end + // L"datasets" + { + IFX_FileStream* pDsfileWrite = FX_CreateMemoryStream(); + if (NULL == pDsfileWrite) { + pContext->Release(); + pDsfileWrite->Release(); + return FALSE; + } + if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(), + CFX_WideStringC(L"datasets"), + pDsfileWrite) && + pDsfileWrite->GetSize() > 0) { + // Datasets + pContext->UpdateChecksum((IFX_FileRead*)pDsfileWrite); + pContext->FinishChecksum(); + CPDF_Dictionary* pDataDict = new CPDF_Dictionary; + if (iDataSetsIndex != -1) { + if (pDataSetsStream) + pDataSetsStream->InitStreamFromFile(pDsfileWrite, pDataDict); + } else { + CPDF_Stream* pData = new CPDF_Stream(NULL, 0, NULL); + pData->InitStreamFromFile(pDsfileWrite, pDataDict); + pPDFDocument->AddIndirectObject(pData); + iLast = pArray->GetCount() - 2; + pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE)); + pArray->InsertAt(iLast + 1, pData, pPDFDocument); + } + fileList.Add(pDsfileWrite); + } + } + + // L"form" + { + IFX_FileStream* pfileWrite = FX_CreateMemoryStream(); + if (NULL == pfileWrite) { + pContext->Release(); + return FALSE; + } + if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(), + CFX_WideStringC(L"form"), pfileWrite, + pContext) && + pfileWrite > 0) { + CPDF_Dictionary* pDataDict = new CPDF_Dictionary; + if (iFormIndex != -1) { + if (pFormStream) + pFormStream->InitStreamFromFile(pfileWrite, pDataDict); + } else { + CPDF_Stream* pData = new CPDF_Stream(NULL, 0, NULL); + pData->InitStreamFromFile(pfileWrite, pDataDict); + pPDFDocument->AddIndirectObject(pData); + iLast = pArray->GetCount() - 2; + pArray->InsertAt(iLast, new CPDF_String("form", FALSE)); + pArray->InsertAt(iLast + 1, pData, pPDFDocument); + } + fileList.Add(pfileWrite); + } + } + pContext->Release(); + return TRUE; +} + +FX_BOOL _SendPostSaveToXFADoc(CPDFXFA_Document* pDocument) { + if (!pDocument) + return FALSE; + + if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA && + pDocument->GetDocType() != DOCTYPE_STATIC_XFA) + return TRUE; + + IXFA_DocView* pXFADocView = pDocument->GetXFADocView(); + if (NULL == pXFADocView) + return FALSE; + IXFA_WidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler(); + + CXFA_WidgetAcc* pWidgetAcc = NULL; + IXFA_WidgetAccIterator* pWidgetAccIterator = + pXFADocView->CreateWidgetAccIterator(); + pWidgetAcc = pWidgetAccIterator->MoveToNext(); + while (pWidgetAcc) { + CXFA_EventParam preParam; + preParam.m_eType = XFA_EVENT_PostSave; + pWidgetHander->ProcessEvent(pWidgetAcc, &preParam); + pWidgetAcc = pWidgetAccIterator->MoveToNext(); + } + pWidgetAccIterator->Release(); + pXFADocView->UpdateDocView(); + pDocument->_ClearChangeMark(); + return TRUE; +} + +FX_BOOL _SendPreSaveToXFADoc(CPDFXFA_Document* pDocument, + CFX_PtrArray& fileList) { + if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA && + pDocument->GetDocType() != DOCTYPE_STATIC_XFA) + return TRUE; + IXFA_DocView* pXFADocView = pDocument->GetXFADocView(); + if (NULL == pXFADocView) + return TRUE; + IXFA_WidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler(); + CXFA_WidgetAcc* pWidgetAcc = NULL; + IXFA_WidgetAccIterator* pWidgetAccIterator = + pXFADocView->CreateWidgetAccIterator(); + pWidgetAcc = pWidgetAccIterator->MoveToNext(); + while (pWidgetAcc) { + CXFA_EventParam preParam; + preParam.m_eType = XFA_EVENT_PreSave; + pWidgetHander->ProcessEvent(pWidgetAcc, &preParam); + pWidgetAcc = pWidgetAccIterator->MoveToNext(); + } + pWidgetAccIterator->Release(); + pXFADocView->UpdateDocView(); + return _SaveXFADocumentData(pDocument, fileList); +} +#endif // PDF_ENABLE_XFA + FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document, FPDF_FILEWRITE* pFileWrite, FPDF_DWORD flags, @@ -62,6 +281,12 @@ FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document, if (!pPDFDoc) return 0; +#ifdef PDF_ENABLE_XFA + CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document; + CFX_PtrArray fileList; + _SendPreSaveToXFADoc(pDoc, fileList); +#endif // PDF_ENABLE_XFA + if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY) { flags = 0; } @@ -79,6 +304,14 @@ FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document, pStreamWrite = new CFX_IFileWrite; pStreamWrite->Init(pFileWrite); bRet = FileMaker.Create(pStreamWrite, flags); +#ifdef PDF_ENABLE_XFA + _SendPostSaveToXFADoc(pDoc); + for (int i = 0; i < fileList.GetSize(); i++) { + IFX_FileStream* pFile = (IFX_FileStream*)fileList.GetAt(i); + pFile->Release(); + } + fileList.RemoveAll(); +#endif // PDF_ENABLE_XFA pStreamWrite->Release(); return bRet; } |