From fdc00a7042d912aafaabddae4d9c84199921ef23 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Tue, 28 Oct 2014 23:03:33 -0700 Subject: Merge XFA to PDFium master at 4dc95e7 on 10/28/2014 --- fpdfsdk/src/fpdfsave.cpp | 275 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 268 insertions(+), 7 deletions(-) (limited to 'fpdfsdk/src/fpdfsave.cpp') 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); } + -- cgit v1.2.3