OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "public/fpdf_save.h" | 7 #include "public/fpdf_save.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "core/fpdfapi/edit/cpdf_creator.h" | 11 #include "core/fpdfapi/edit/cpdf_creator.h" |
12 #include "core/fpdfapi/parser/cpdf_array.h" | 12 #include "core/fpdfapi/parser/cpdf_array.h" |
13 #include "core/fpdfapi/parser/cpdf_document.h" | 13 #include "core/fpdfapi/parser/cpdf_document.h" |
14 #include "core/fpdfapi/parser/cpdf_reference.h" | 14 #include "core/fpdfapi/parser/cpdf_reference.h" |
15 #include "core/fpdfapi/parser/cpdf_stream_acc.h" | 15 #include "core/fpdfapi/parser/cpdf_stream_acc.h" |
16 #include "core/fpdfapi/parser/cpdf_string.h" | 16 #include "core/fpdfapi/parser/cpdf_string.h" |
17 #include "core/fxcrt/fx_ext.h" | 17 #include "core/fxcrt/fx_ext.h" |
18 #include "fpdfsdk/fsdk_define.h" | 18 #include "fpdfsdk/fsdk_define.h" |
19 #include "public/fpdf_edit.h" | 19 #include "public/fpdf_edit.h" |
20 | 20 |
21 #ifdef PDF_ENABLE_XFA | 21 #ifdef PDF_ENABLE_XFA |
22 #include "fpdfsdk/fpdfxfa/cpdfxfa_document.h" | 22 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h" |
23 #include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h" | 23 #include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h" |
24 #include "public/fpdf_formfill.h" | 24 #include "public/fpdf_formfill.h" |
25 #include "xfa/fxfa/cxfa_eventparam.h" | 25 #include "xfa/fxfa/cxfa_eventparam.h" |
26 #include "xfa/fxfa/xfa_checksum.h" | 26 #include "xfa/fxfa/xfa_checksum.h" |
27 #include "xfa/fxfa/xfa_ffapp.h" | 27 #include "xfa/fxfa/xfa_ffapp.h" |
28 #include "xfa/fxfa/xfa_ffdocview.h" | 28 #include "xfa/fxfa/xfa_ffdocview.h" |
29 #include "xfa/fxfa/xfa_ffwidgethandler.h" | 29 #include "xfa/fxfa/xfa_ffwidgethandler.h" |
30 #endif | 30 #endif |
31 | 31 |
32 #if _FX_OS_ == _FX_ANDROID_ | 32 #if _FX_OS_ == _FX_ANDROID_ |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 return true; | 68 return true; |
69 } | 69 } |
70 | 70 |
71 void CFX_IFileWrite::Release() { | 71 void CFX_IFileWrite::Release() { |
72 delete this; | 72 delete this; |
73 } | 73 } |
74 | 74 |
75 namespace { | 75 namespace { |
76 | 76 |
77 #ifdef PDF_ENABLE_XFA | 77 #ifdef PDF_ENABLE_XFA |
78 bool SaveXFADocumentData(CPDFXFA_Document* pDocument, | 78 bool SaveXFADocumentData(CPDFXFA_Context* pContext, |
79 std::vector<ScopedFileStream>* fileList) { | 79 std::vector<ScopedFileStream>* fileList) { |
80 if (!pDocument) | 80 if (!pContext) |
81 return false; | 81 return false; |
82 | 82 |
83 if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA && | 83 if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && |
84 pDocument->GetDocType() != DOCTYPE_STATIC_XFA) | 84 pContext->GetDocType() != DOCTYPE_STATIC_XFA) |
85 return true; | 85 return true; |
86 | 86 |
87 CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView(); | 87 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); |
88 if (!pXFADocView) | 88 if (!pXFADocView) |
89 return true; | 89 return true; |
90 | 90 |
91 CPDF_Document* pPDFDocument = pDocument->GetPDFDoc(); | 91 CPDF_Document* pPDFDocument = pContext->GetPDFDoc(); |
92 if (!pDocument) | 92 if (!pPDFDocument) |
93 return false; | 93 return false; |
94 | 94 |
95 CPDF_Dictionary* pRoot = pPDFDocument->GetRoot(); | 95 CPDF_Dictionary* pRoot = pPDFDocument->GetRoot(); |
96 if (!pRoot) | 96 if (!pRoot) |
97 return false; | 97 return false; |
98 | 98 |
99 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm"); | 99 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm"); |
100 if (!pAcroForm) | 100 if (!pAcroForm) |
101 return false; | 101 return false; |
102 | 102 |
(...skipping 14 matching lines...) Expand all Loading... |
117 CPDF_Object* pPDFObj = pArray->GetObjectAt(i); | 117 CPDF_Object* pPDFObj = pArray->GetObjectAt(i); |
118 if (!pPDFObj->IsString()) | 118 if (!pPDFObj->IsString()) |
119 continue; | 119 continue; |
120 if (pPDFObj->GetString() == "form") | 120 if (pPDFObj->GetString() == "form") |
121 iFormIndex = i + 1; | 121 iFormIndex = i + 1; |
122 else if (pPDFObj->GetString() == "datasets") | 122 else if (pPDFObj->GetString() == "datasets") |
123 iDataSetsIndex = i + 1; | 123 iDataSetsIndex = i + 1; |
124 else if (pPDFObj->GetString() == "template") | 124 else if (pPDFObj->GetString() == "template") |
125 iTemplate = i + 1; | 125 iTemplate = i + 1; |
126 } | 126 } |
127 std::unique_ptr<CXFA_ChecksumContext> pContext(new CXFA_ChecksumContext); | 127 std::unique_ptr<CXFA_ChecksumContext> pChecksum(new CXFA_ChecksumContext); |
128 pContext->StartChecksum(); | 128 pChecksum->StartChecksum(); |
129 | 129 |
130 // template | 130 // template |
131 if (iTemplate > -1) { | 131 if (iTemplate > -1) { |
132 CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate); | 132 CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate); |
133 CPDF_StreamAcc streamAcc; | 133 CPDF_StreamAcc streamAcc; |
134 streamAcc.LoadAllData(pTemplateStream); | 134 streamAcc.LoadAllData(pTemplateStream); |
135 uint8_t* pData = (uint8_t*)streamAcc.GetData(); | 135 uint8_t* pData = (uint8_t*)streamAcc.GetData(); |
136 uint32_t dwSize2 = streamAcc.GetSize(); | 136 uint32_t dwSize2 = streamAcc.GetSize(); |
137 ScopedFileStream pTemplate(FX_CreateMemoryStream(pData, dwSize2)); | 137 ScopedFileStream pTemplate(FX_CreateMemoryStream(pData, dwSize2)); |
138 pContext->UpdateChecksum(pTemplate.get()); | 138 pChecksum->UpdateChecksum(pTemplate.get()); |
139 } | 139 } |
140 CPDF_Stream* pFormStream = nullptr; | 140 CPDF_Stream* pFormStream = nullptr; |
141 CPDF_Stream* pDataSetsStream = nullptr; | 141 CPDF_Stream* pDataSetsStream = nullptr; |
142 if (iFormIndex != -1) { | 142 if (iFormIndex != -1) { |
143 // Get form CPDF_Stream | 143 // Get form CPDF_Stream |
144 CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex); | 144 CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex); |
145 if (pFormPDFObj->IsReference()) { | 145 if (pFormPDFObj->IsReference()) { |
146 CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect(); | 146 CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect(); |
147 if (pFormDirectObj && pFormDirectObj->IsStream()) { | 147 if (pFormDirectObj && pFormDirectObj->IsStream()) { |
148 pFormStream = (CPDF_Stream*)pFormDirectObj; | 148 pFormStream = (CPDF_Stream*)pFormDirectObj; |
(...skipping 16 matching lines...) Expand all Loading... |
165 pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj; | 165 pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj; |
166 } | 166 } |
167 } | 167 } |
168 // L"datasets" | 168 // L"datasets" |
169 { | 169 { |
170 ScopedFileStream pDsfileWrite(FX_CreateMemoryStream()); | 170 ScopedFileStream pDsfileWrite(FX_CreateMemoryStream()); |
171 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, | 171 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, |
172 pDsfileWrite.get(), nullptr) && | 172 pDsfileWrite.get(), nullptr) && |
173 pDsfileWrite->GetSize() > 0) { | 173 pDsfileWrite->GetSize() > 0) { |
174 // Datasets | 174 // Datasets |
175 pContext->UpdateChecksum(pDsfileWrite.get()); | 175 pChecksum->UpdateChecksum(pDsfileWrite.get()); |
176 pContext->FinishChecksum(); | 176 pChecksum->FinishChecksum(); |
177 CPDF_Dictionary* pDataDict = | 177 CPDF_Dictionary* pDataDict = |
178 new CPDF_Dictionary(pPDFDocument->GetByteStringPool()); | 178 new CPDF_Dictionary(pPDFDocument->GetByteStringPool()); |
179 if (iDataSetsIndex != -1) { | 179 if (iDataSetsIndex != -1) { |
180 if (pDataSetsStream) | 180 if (pDataSetsStream) |
181 pDataSetsStream->InitStreamFromFile(pDsfileWrite.get(), pDataDict); | 181 pDataSetsStream->InitStreamFromFile(pDsfileWrite.get(), pDataDict); |
182 } else { | 182 } else { |
183 CPDF_Stream* pData = new CPDF_Stream; | 183 CPDF_Stream* pData = new CPDF_Stream; |
184 pData->InitStreamFromFile(pDsfileWrite.get(), pDataDict); | 184 pData->InitStreamFromFile(pDsfileWrite.get(), pDataDict); |
185 iLast = pArray->GetCount() - 2; | 185 iLast = pArray->GetCount() - 2; |
186 pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE)); | 186 pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE)); |
187 pArray->InsertAt( | 187 pArray->InsertAt( |
188 iLast + 1, | 188 iLast + 1, |
189 new CPDF_Reference(pPDFDocument, | 189 new CPDF_Reference(pPDFDocument, |
190 pPDFDocument->AddIndirectObject(pData))); | 190 pPDFDocument->AddIndirectObject(pData))); |
191 } | 191 } |
192 fileList->push_back(std::move(pDsfileWrite)); | 192 fileList->push_back(std::move(pDsfileWrite)); |
193 } | 193 } |
194 } | 194 } |
195 // L"form" | 195 // L"form" |
196 { | 196 { |
197 ScopedFileStream pfileWrite(FX_CreateMemoryStream()); | 197 ScopedFileStream pfileWrite(FX_CreateMemoryStream()); |
198 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite.get(), | 198 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite.get(), |
199 pContext.get()) && | 199 pChecksum.get()) && |
200 pfileWrite->GetSize() > 0) { | 200 pfileWrite->GetSize() > 0) { |
201 CPDF_Dictionary* pDataDict = | 201 CPDF_Dictionary* pDataDict = |
202 new CPDF_Dictionary(pPDFDocument->GetByteStringPool()); | 202 new CPDF_Dictionary(pPDFDocument->GetByteStringPool()); |
203 if (iFormIndex != -1) { | 203 if (iFormIndex != -1) { |
204 if (pFormStream) | 204 if (pFormStream) |
205 pFormStream->InitStreamFromFile(pfileWrite.get(), pDataDict); | 205 pFormStream->InitStreamFromFile(pfileWrite.get(), pDataDict); |
206 } else { | 206 } else { |
207 CPDF_Stream* pData = new CPDF_Stream; | 207 CPDF_Stream* pData = new CPDF_Stream; |
208 pData->InitStreamFromFile(pfileWrite.get(), pDataDict); | 208 pData->InitStreamFromFile(pfileWrite.get(), pDataDict); |
209 iLast = pArray->GetCount() - 2; | 209 iLast = pArray->GetCount() - 2; |
210 pArray->InsertAt(iLast, new CPDF_String("form", FALSE)); | 210 pArray->InsertAt(iLast, new CPDF_String("form", FALSE)); |
211 pArray->InsertAt( | 211 pArray->InsertAt( |
212 iLast + 1, | 212 iLast + 1, |
213 new CPDF_Reference(pPDFDocument, | 213 new CPDF_Reference(pPDFDocument, |
214 pPDFDocument->AddIndirectObject(pData))); | 214 pPDFDocument->AddIndirectObject(pData))); |
215 } | 215 } |
216 fileList->push_back(std::move(pfileWrite)); | 216 fileList->push_back(std::move(pfileWrite)); |
217 } | 217 } |
218 } | 218 } |
219 return true; | 219 return true; |
220 } | 220 } |
221 | 221 |
222 bool SendPostSaveToXFADoc(CPDFXFA_Document* pDocument) { | 222 bool SendPostSaveToXFADoc(CPDFXFA_Context* pContext) { |
223 if (!pDocument) | 223 if (!pContext) |
224 return false; | 224 return false; |
225 | 225 |
226 if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA && | 226 if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && |
227 pDocument->GetDocType() != DOCTYPE_STATIC_XFA) | 227 pContext->GetDocType() != DOCTYPE_STATIC_XFA) |
228 return true; | 228 return true; |
229 | 229 |
230 CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView(); | 230 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); |
231 if (!pXFADocView) | 231 if (!pXFADocView) |
232 return false; | 232 return false; |
233 | 233 |
234 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler(); | 234 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler(); |
235 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator( | 235 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator( |
236 pXFADocView->CreateWidgetAccIterator()); | 236 pXFADocView->CreateWidgetAccIterator()); |
237 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) { | 237 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) { |
238 CXFA_EventParam preParam; | 238 CXFA_EventParam preParam; |
239 preParam.m_eType = XFA_EVENT_PostSave; | 239 preParam.m_eType = XFA_EVENT_PostSave; |
240 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam); | 240 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam); |
241 } | 241 } |
242 pXFADocView->UpdateDocView(); | 242 pXFADocView->UpdateDocView(); |
243 pDocument->ClearChangeMark(); | 243 pContext->ClearChangeMark(); |
244 return true; | 244 return true; |
245 } | 245 } |
246 | 246 |
247 bool SendPreSaveToXFADoc(CPDFXFA_Document* pDocument, | 247 bool SendPreSaveToXFADoc(CPDFXFA_Context* pContext, |
248 std::vector<ScopedFileStream>* fileList) { | 248 std::vector<ScopedFileStream>* fileList) { |
249 if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA && | 249 if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && |
250 pDocument->GetDocType() != DOCTYPE_STATIC_XFA) | 250 pContext->GetDocType() != DOCTYPE_STATIC_XFA) |
251 return true; | 251 return true; |
252 | 252 |
253 CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView(); | 253 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); |
254 if (!pXFADocView) | 254 if (!pXFADocView) |
255 return true; | 255 return true; |
256 | 256 |
257 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler(); | 257 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler(); |
258 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator( | 258 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator( |
259 pXFADocView->CreateWidgetAccIterator()); | 259 pXFADocView->CreateWidgetAccIterator()); |
260 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) { | 260 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) { |
261 CXFA_EventParam preParam; | 261 CXFA_EventParam preParam; |
262 preParam.m_eType = XFA_EVENT_PreSave; | 262 preParam.m_eType = XFA_EVENT_PreSave; |
263 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam); | 263 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam); |
264 } | 264 } |
265 pXFADocView->UpdateDocView(); | 265 pXFADocView->UpdateDocView(); |
266 return SaveXFADocumentData(pDocument, fileList); | 266 return SaveXFADocumentData(pContext, fileList); |
267 } | 267 } |
268 #endif // PDF_ENABLE_XFA | 268 #endif // PDF_ENABLE_XFA |
269 | 269 |
270 bool FPDF_Doc_Save(FPDF_DOCUMENT document, | 270 bool FPDF_Doc_Save(FPDF_DOCUMENT document, |
271 FPDF_FILEWRITE* pFileWrite, | 271 FPDF_FILEWRITE* pFileWrite, |
272 FPDF_DWORD flags, | 272 FPDF_DWORD flags, |
273 FPDF_BOOL bSetVersion, | 273 FPDF_BOOL bSetVersion, |
274 int fileVerion) { | 274 int fileVerion) { |
275 CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document); | 275 CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document); |
276 if (!pPDFDoc) | 276 if (!pPDFDoc) |
277 return 0; | 277 return 0; |
278 | 278 |
279 #ifdef PDF_ENABLE_XFA | 279 #ifdef PDF_ENABLE_XFA |
280 CPDFXFA_Document* pDoc = static_cast<CPDFXFA_Document*>(document); | 280 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); |
281 std::vector<ScopedFileStream> fileList; | 281 std::vector<ScopedFileStream> fileList; |
282 SendPreSaveToXFADoc(pDoc, &fileList); | 282 SendPreSaveToXFADoc(pContext, &fileList); |
283 #endif // PDF_ENABLE_XFA | 283 #endif // PDF_ENABLE_XFA |
284 | 284 |
285 if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY) | 285 if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY) |
286 flags = 0; | 286 flags = 0; |
287 | 287 |
288 CPDF_Creator FileMaker(pPDFDoc); | 288 CPDF_Creator FileMaker(pPDFDoc); |
289 if (bSetVersion) | 289 if (bSetVersion) |
290 FileMaker.SetFileVersion(fileVerion); | 290 FileMaker.SetFileVersion(fileVerion); |
291 if (flags == FPDF_REMOVE_SECURITY) { | 291 if (flags == FPDF_REMOVE_SECURITY) { |
292 flags = 0; | 292 flags = 0; |
293 FileMaker.RemoveSecurity(); | 293 FileMaker.RemoveSecurity(); |
294 } | 294 } |
295 | 295 |
296 CFX_IFileWrite* pStreamWrite = new CFX_IFileWrite; | 296 CFX_IFileWrite* pStreamWrite = new CFX_IFileWrite; |
297 pStreamWrite->Init(pFileWrite); | 297 pStreamWrite->Init(pFileWrite); |
298 bool bRet = FileMaker.Create(pStreamWrite, flags); | 298 bool bRet = FileMaker.Create(pStreamWrite, flags); |
299 #ifdef PDF_ENABLE_XFA | 299 #ifdef PDF_ENABLE_XFA |
300 SendPostSaveToXFADoc(pDoc); | 300 SendPostSaveToXFADoc(pContext); |
301 #endif // PDF_ENABLE_XFA | 301 #endif // PDF_ENABLE_XFA |
302 pStreamWrite->Release(); | 302 pStreamWrite->Release(); |
303 return bRet; | 303 return bRet; |
304 } | 304 } |
305 | 305 |
306 } // namespace | 306 } // namespace |
307 | 307 |
308 DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document, | 308 DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document, |
309 FPDF_FILEWRITE* pFileWrite, | 309 FPDF_FILEWRITE* pFileWrite, |
310 FPDF_DWORD flags) { | 310 FPDF_DWORD flags) { |
311 return FPDF_Doc_Save(document, pFileWrite, flags, FALSE, 0); | 311 return FPDF_Doc_Save(document, pFileWrite, flags, FALSE, 0); |
312 } | 312 } |
313 | 313 |
314 DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document, | 314 DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document, |
315 FPDF_FILEWRITE* pFileWrite, | 315 FPDF_FILEWRITE* pFileWrite, |
316 FPDF_DWORD flags, | 316 FPDF_DWORD flags, |
317 int fileVersion) { | 317 int fileVersion) { |
318 return FPDF_Doc_Save(document, pFileWrite, flags, TRUE, fileVersion); | 318 return FPDF_Doc_Save(document, pFileWrite, flags, TRUE, fileVersion); |
319 } | 319 } |
OLD | NEW |