summaryrefslogtreecommitdiff
path: root/fpdfsdk/src/fpdfsave.cpp
diff options
context:
space:
mode:
authorBo Xu <bo_xu@foxitsoftware.com>2014-10-28 23:03:33 -0700
committerBo Xu <bo_xu@foxitsoftware.com>2014-11-03 11:10:11 -0800
commitfdc00a7042d912aafaabddae4d9c84199921ef23 (patch)
tree32ab8ac91cc68d2cd15b9168782a71b3f3f5e7b9 /fpdfsdk/src/fpdfsave.cpp
parente9b38fa38de2c95d8260be31c57d9272c4d127ed (diff)
downloadpdfium-fdc00a7042d912aafaabddae4d9c84199921ef23.tar.xz
Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
Diffstat (limited to 'fpdfsdk/src/fpdfsave.cpp')
-rw-r--r--fpdfsdk/src/fpdfsave.cpp275
1 files changed, 268 insertions, 7 deletions
diff --git a/fpdfsdk/src/fpdfsave.cpp b/fpdfsdk/src/fpdfsave.cpp
index 45dfbf7214..229e580dec 100644
--- a/fpdfsdk/src/fpdfsave.cpp
+++ b/fpdfsdk/src/fpdfsave.cpp
@@ -7,6 +7,9 @@
#include "../include/fsdk_define.h"
#include "../include/fpdfsave.h"
#include "../include/fpdfedit.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_app.h"
+#include "../include/fpdfxfa/fpdfxfa_util.h"
#if _FX_OS_ == _FX_ANDROID_
#include "time.h"
#else
@@ -53,11 +56,258 @@ FX_BOOL CFX_IFileWrite::WriteBlock(const void* pData, size_t size)
return FALSE;
}
-FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document,FPDF_FILEWRITE * pFileWrite,FPDF_DWORD flags, FPDF_BOOL bSetVersion,
+#define XFA_DATASETS 0
+#define XFA_FORMS 1
+
+FX_BOOL _SaveXFADocumentData(CPDFXFA_Document* pDocument, CFX_PtrArray& fileList)
+{
+ if (!pDocument)
+ return FALSE;
+ if (pDocument->GetDocType() != DOCTYPE_DYNIMIC_XFA && pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
+ return TRUE;
+ if (!FPDFXFA_GetApp()->GetXFAApp())
+ return TRUE;
+
+ IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
+ if (NULL == pXFADocView)
+ return TRUE;
+ IXFA_DocHandler *pXFADocHandler = FPDFXFA_GetApp()->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->GetDict("AcroForm");
+ if (NULL == pAcroForm)
+ return FALSE;
+ CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
+ if (pXFA == NULL)
+ return TRUE;
+ if(pXFA->GetType() != PDFOBJ_ARRAY)
+ 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->GetType() != PDFOBJ_STRING)
+ continue;
+ if (pPDFObj->GetString() == "form")
+ iFormIndex = i+1;
+ else if (pPDFObj->GetString() == "datasets")
+ iDataSetsIndex = i+1;
+ else if (pPDFObj->GetString() == FX_BSTRC("template"))
+ iTemplate = i + 1;
+ }
+ IXFA_ChecksumContext* pContext = NULL;
+#define XFA_USECKSUM
+#ifdef XFA_USECKSUM
+ //Checksum
+ pContext = XFA_Checksum_Create();
+ FXSYS_assert(pContext);
+ pContext->StartChecksum();
+
+ //template
+ if (iTemplate > -1)
+ {
+ CPDF_Stream *pTemplateStream = pArray->GetStream(iTemplate);
+ CPDF_StreamAcc streamAcc;
+ streamAcc.LoadAllData(pTemplateStream);
+ FX_LPBYTE pData = (FX_LPBYTE)streamAcc.GetData();
+ FX_DWORD dwSize2 = streamAcc.GetSize();
+ IFX_FileStream *pTemplate = FX_CreateMemoryStream(pData, dwSize2);
+ pContext->UpdateChecksum((IFX_FileRead*)pTemplate);
+ pTemplate->Release();
+ }
+#endif
+ CPDF_Stream* pFormStream = NULL;
+ CPDF_Stream* pDataSetsStream = NULL;
+ if (iFormIndex != -1)
+ {
+ //Get form CPDF_Stream
+ CPDF_Object* pFormPDFObj = pArray->GetElement(iFormIndex);
+ if (pFormPDFObj->GetType() == PDFOBJ_REFERENCE)
+ {
+ CPDF_Reference* pFormRefObj = (CPDF_Reference*)pFormPDFObj;
+ CPDF_Object* pFormDircetObj = pFormPDFObj->GetDirect();
+ if (NULL != pFormDircetObj && pFormDircetObj->GetType() == PDFOBJ_STREAM)
+ {
+ pFormStream = (CPDF_Stream*)pFormDircetObj;
+ }
+ }
+ else if (pFormPDFObj->GetType() == PDFOBJ_STREAM)
+ {
+ pFormStream = (CPDF_Stream*)pFormPDFObj;
+ }
+ }
+
+ if (iDataSetsIndex != -1)
+ {
+ //Get datasets CPDF_Stream
+ CPDF_Object* pDataSetsPDFObj = pArray->GetElement(iDataSetsIndex);
+ if (pDataSetsPDFObj->GetType() == PDFOBJ_REFERENCE)
+ {
+ CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
+ CPDF_Object* pDataSetsDircetObj = pDataSetsRefObj->GetDirect();
+ if (NULL != pDataSetsDircetObj && pDataSetsDircetObj->GetType() == PDFOBJ_STREAM)
+ {
+ pDataSetsStream = (CPDF_Stream*)pDataSetsDircetObj;
+ }
+ }
+ else if (pDataSetsPDFObj->GetType() == PDFOBJ_STREAM)
+ {
+ 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)
+ {
+#ifdef XFA_USECKSUM
+ //Datasets
+ pContext->UpdateChecksum((IFX_FileRead*)pDsfileWrite);
+ pContext->FinishChecksum();
+#endif
+ CPDF_Dictionary* pDataDict = FX_NEW CPDF_Dictionary;
+ if (iDataSetsIndex != -1)
+ {
+ if (pDataSetsStream)
+ pDataSetsStream->InitStream(pDsfileWrite, pDataDict);
+ }
+ else
+ {
+ CPDF_Stream* pData = FX_NEW CPDF_Stream(NULL, 0, NULL);
+ pData->InitStream(pDsfileWrite, pDataDict);
+ FX_DWORD AppStreamobjnum = pPDFDocument->AddIndirectObject(pData);
+ CPDF_Reference* pRef = (CPDF_Reference*)pPDFDocument->GetIndirectObject(AppStreamobjnum);
+ {
+ iLast = pArray->GetCount() -2;
+ pArray->InsertAt(iLast,CPDF_String::Create("datasets"));
+ 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 = FX_NEW CPDF_Dictionary;
+ if (iFormIndex != -1)
+ {
+ if (pFormStream)
+ pFormStream->InitStream(pfileWrite, pDataDict);
+ }
+ else
+ {
+ CPDF_Stream* pData = FX_NEW CPDF_Stream(NULL, 0, NULL);
+ pData->InitStream(pfileWrite, pDataDict);
+ FX_DWORD AppStreamobjnum = pPDFDocument->AddIndirectObject(pData);
+ CPDF_Reference* pRef = (CPDF_Reference*)pPDFDocument->GetIndirectObject(AppStreamobjnum);
+ {
+ iLast = pArray->GetCount() -2;
+ pArray->InsertAt(iLast, CPDF_String::Create("form"));
+ 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_DYNIMIC_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_DYNIMIC_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);
+}
+
+FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document, FPDF_FILEWRITE * pFileWrite,FPDF_DWORD flags, FPDF_BOOL bSetVersion,
int fileVerion)
{
- CPDF_Document* pDoc = (CPDF_Document*)document;
- if (!pDoc)
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
+
+ CFX_PtrArray fileList;
+
+ _SendPreSaveToXFADoc(pDoc, fileList);
+
+ CPDF_Document* pPDFDoc = pDoc->GetPDFDoc();
+ if (!pPDFDoc)
return 0;
if ( flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY )
@@ -65,10 +315,10 @@ FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document,FPDF_FILEWRITE * pFileWrite,FPDF
flags = 0;
}
- CPDF_Creator FileMaker(pDoc);
- if(bSetVersion)
+ CPDF_Creator FileMaker(pPDFDoc);
+ if (bSetVersion)
FileMaker.SetFileVersion(fileVerion);
- if(flags == FPDF_REMOVE_SECURITY)
+ if (flags == FPDF_REMOVE_SECURITY)
{
flags = 0;
FileMaker.RemoveSecurity();
@@ -78,6 +328,17 @@ FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document,FPDF_FILEWRITE * pFileWrite,FPDF
pStreamWrite = new CFX_IFileWrite;
pStreamWrite->Init( pFileWrite );
bRet = FileMaker.Create(pStreamWrite, flags);
+
+ _SendPostSaveToXFADoc(pDoc);
+ //pDoc->_ClearChangeMark();
+
+ for (int i = 0; i < fileList.GetSize(); i++)
+ {
+ IFX_FileStream* pFile = (IFX_FileStream*)fileList.GetAt(i);
+ pFile->Release();
+ }
+ fileList.RemoveAll();
+
delete pStreamWrite;
return bRet;
}
@@ -88,9 +349,9 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy( FPDF_DOCUMENT document,FPDF_FILEWRI
return _FPDF_Doc_Save(document, pFileWrite, flags, FALSE , 0);
}
-
DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion( FPDF_DOCUMENT document,FPDF_FILEWRITE * pFileWrite,
FPDF_DWORD flags, int fileVersion)
{
return _FPDF_Doc_Save(document, pFileWrite, flags, TRUE , fileVersion);
}
+