blob: 5acdef0a60a3c464882428f80ee1df3627676352 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangb4e7f302015-11-06 15:52:32 -08007#include "public/fpdf_save.h"
8
Dan Sinclair85c8e7f2016-11-21 13:50:32 -05009#include <memory>
10#include <utility>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050011#include <vector>
12
dsinclair24154352016-10-04 11:01:48 -070013#include "core/fpdfapi/edit/cpdf_creator.h"
dsinclair488b7ad2016-10-04 11:55:50 -070014#include "core/fpdfapi/parser/cpdf_array.h"
15#include "core/fpdfapi/parser/cpdf_document.h"
16#include "core/fpdfapi/parser/cpdf_reference.h"
17#include "core/fpdfapi/parser/cpdf_stream_acc.h"
18#include "core/fpdfapi/parser/cpdf_string.h"
Dan Sinclair283a0432017-04-20 14:11:21 -040019#include "core/fxcrt/cfx_memorystream.h"
Dan Sinclaircfb19442017-04-20 13:13:04 -040020#include "core/fxcrt/fx_extension.h"
dsinclair114e46a2016-09-29 17:18:21 -070021#include "fpdfsdk/fsdk_define.h"
Dan Sinclairae4656e2017-05-09 12:36:41 -040022#include "fpdfsdk/fsdk_filewriteadapter.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080023#include "public/fpdf_edit.h"
24
Tom Sepez51da0932015-11-25 16:05:49 -080025#ifdef PDF_ENABLE_XFA
Dan Sinclairddb70162017-03-30 14:01:31 -040026#include "core/fxcrt/cfx_checksumcontext.h"
dsinclair521b7502016-11-02 13:02:28 -070027#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
dsinclair4d29e782016-10-04 14:02:47 -070028#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -080029#include "public/fpdf_formfill.h"
dsinclair5b493092016-09-29 20:20:24 -070030#include "xfa/fxfa/cxfa_eventparam.h"
Dan Sinclair80c48782017-03-23 12:11:20 -040031#include "xfa/fxfa/cxfa_ffapp.h"
32#include "xfa/fxfa/cxfa_ffdocview.h"
33#include "xfa/fxfa/cxfa_ffwidgethandler.h"
34#include "xfa/fxfa/cxfa_widgetacciterator.h"
Tom Sepez51da0932015-11-25 16:05:49 -080035#endif
Tom Sepez1ed8a212015-05-11 15:25:39 -070036
Dan Sinclair698aed72017-09-26 16:24:49 -040037#if _FX_OS_ == _FX_OS_ANDROID_
Dan Sinclair85c8e7f2016-11-21 13:50:32 -050038#include <time.h>
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070039#else
40#include <ctime>
41#endif
42
Tom Sepez7a73eff2016-02-08 13:39:53 -080043namespace {
44
Tom Sepez51da0932015-11-25 16:05:49 -080045#ifdef PDF_ENABLE_XFA
Dan Sinclair0b950422017-09-21 15:49:49 -040046bool SaveXFADocumentData(CPDFXFA_Context* pContext,
47 std::vector<RetainPtr<IFX_SeekableStream>>* fileList) {
dsinclair521b7502016-11-02 13:02:28 -070048 if (!pContext)
Tom Sepez7a73eff2016-02-08 13:39:53 -080049 return false;
50
Ryan Harrison854d71c2017-10-18 12:28:14 -040051 if (!pContext->ContainsXFAForm())
Tom Sepez7a73eff2016-02-08 13:39:53 -080052 return true;
53
dsinclair521b7502016-11-02 13:02:28 -070054 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -080055 if (!pXFADocView)
56 return true;
Bo Xufdc00a72014-10-28 23:03:33 -070057
dsinclair521b7502016-11-02 13:02:28 -070058 CPDF_Document* pPDFDocument = pContext->GetPDFDoc();
59 if (!pPDFDocument)
Tom Sepez7a73eff2016-02-08 13:39:53 -080060 return false;
Bo Xufdc00a72014-10-28 23:03:33 -070061
Lei Zhang01581062017-08-30 14:19:26 -070062 const CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
Tom Sepez7a73eff2016-02-08 13:39:53 -080063 if (!pRoot)
64 return false;
65
dsinclair38fd8442016-09-15 10:15:32 -070066 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
Tom Sepez7a73eff2016-02-08 13:39:53 -080067 if (!pAcroForm)
68 return false;
69
dsinclair38fd8442016-09-15 10:15:32 -070070 CPDF_Object* pXFA = pAcroForm->GetObjectFor("XFA");
Tom Sepez7a73eff2016-02-08 13:39:53 -080071 if (!pXFA)
72 return true;
73
thestigb8bf55f2016-05-21 21:08:05 -070074 CPDF_Array* pArray = pXFA->AsArray();
Tom Sepez7a73eff2016-02-08 13:39:53 -080075 if (!pArray)
76 return false;
77
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078 int size = pArray->GetCount();
79 int iFormIndex = -1;
80 int iDataSetsIndex = -1;
81 int iTemplate = -1;
82 int iLast = size - 2;
83 for (int i = 0; i < size - 1; i++) {
tsepezbd567552016-03-29 14:51:50 -070084 CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
Tom Sepez8e5cd192016-01-26 13:20:26 -080085 if (!pPDFObj->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 continue;
87 if (pPDFObj->GetString() == "form")
88 iFormIndex = i + 1;
89 else if (pPDFObj->GetString() == "datasets")
90 iDataSetsIndex = i + 1;
Lei Zhangd983b092015-12-14 16:58:33 -080091 else if (pPDFObj->GetString() == "template")
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 iTemplate = i + 1;
93 }
Dan Sinclair0bb13332017-03-30 16:12:02 -040094 auto pChecksum = pdfium::MakeUnique<CFX_ChecksumContext>();
dsinclair521b7502016-11-02 13:02:28 -070095 pChecksum->StartChecksum();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070096
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097 // template
98 if (iTemplate > -1) {
Wei Li9b761132016-01-29 15:44:20 -080099 CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate);
Tom Sepezafd0d1f2017-04-04 14:37:18 -0700100 auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pTemplateStream);
101 pAcc->LoadAllData();
Dan Sinclair0b950422017-09-21 15:49:49 -0400102 RetainPtr<IFX_SeekableStream> pTemplate =
Dan Sinclair283a0432017-04-20 14:11:21 -0400103 pdfium::MakeRetain<CFX_MemoryStream>(
104 const_cast<uint8_t*>(pAcc->GetData()), pAcc->GetSize(), false);
tsepez833619b2016-12-07 09:21:17 -0800105 pChecksum->UpdateChecksum(pTemplate);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106 }
thestig1cd352e2016-06-07 17:53:06 -0700107 CPDF_Stream* pFormStream = nullptr;
108 CPDF_Stream* pDataSetsStream = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700109 if (iFormIndex != -1) {
110 // Get form CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700111 CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800112 if (pFormPDFObj->IsReference()) {
113 CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect();
114 if (pFormDirectObj && pFormDirectObj->IsStream()) {
115 pFormStream = (CPDF_Stream*)pFormDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800117 } else if (pFormPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700118 pFormStream = (CPDF_Stream*)pFormPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700119 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700121
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122 if (iDataSetsIndex != -1) {
123 // Get datasets CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700124 CPDF_Object* pDataSetsPDFObj = pArray->GetObjectAt(iDataSetsIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800125 if (pDataSetsPDFObj->IsReference()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
Tom Sepez8e5cd192016-01-26 13:20:26 -0800127 CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect();
128 if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) {
129 pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800131 } else if (pDataSetsPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700133 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 // L"datasets"
136 {
Dan Sinclair0b950422017-09-21 15:49:49 -0400137 RetainPtr<IFX_SeekableStream> pDsfileWrite =
Dan Sinclair283a0432017-04-20 14:11:21 -0400138 pdfium::MakeRetain<CFX_MemoryStream>(false);
tsepez833619b2016-12-07 09:21:17 -0800139 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, pDsfileWrite,
140 nullptr) &&
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 pDsfileWrite->GetSize() > 0) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700142 // Datasets
tsepez833619b2016-12-07 09:21:17 -0800143 pChecksum->UpdateChecksum(pDsfileWrite);
dsinclair521b7502016-11-02 13:02:28 -0700144 pChecksum->FinishChecksum();
tsepez9e05ee12016-11-21 13:19:10 -0800145 auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
146 pPDFDocument->GetByteStringPool());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147 if (iDataSetsIndex != -1) {
tsepez9e05ee12016-11-21 13:19:10 -0800148 if (pDataSetsStream) {
tsepez833619b2016-12-07 09:21:17 -0800149 pDataSetsStream->InitStreamFromFile(pDsfileWrite,
tsepez9e05ee12016-11-21 13:19:10 -0800150 std::move(pDataDict));
151 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 } else {
tsepez70c4afd2016-11-15 11:33:44 -0800153 CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
tsepez833619b2016-12-07 09:21:17 -0800154 pData->InitStreamFromFile(pDsfileWrite, std::move(pDataDict));
Tom Sepez3343d142015-11-02 09:54:54 -0800155 iLast = pArray->GetCount() - 2;
tsepez8a3aa452016-11-16 12:26:06 -0800156 pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false);
157 pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
158 pData->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800160 fileList->push_back(std::move(pDsfileWrite));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 }
162 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 // L"form"
164 {
Dan Sinclair0b950422017-09-21 15:49:49 -0400165 RetainPtr<IFX_SeekableStream> pfileWrite =
Dan Sinclair283a0432017-04-20 14:11:21 -0400166 pdfium::MakeRetain<CFX_MemoryStream>(false);
tsepez833619b2016-12-07 09:21:17 -0800167 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite,
dsinclair521b7502016-11-02 13:02:28 -0700168 pChecksum.get()) &&
Tom Sepez7a73eff2016-02-08 13:39:53 -0800169 pfileWrite->GetSize() > 0) {
tsepez9e05ee12016-11-21 13:19:10 -0800170 auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
171 pPDFDocument->GetByteStringPool());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 if (iFormIndex != -1) {
tsepez833619b2016-12-07 09:21:17 -0800173 if (pFormStream)
174 pFormStream->InitStreamFromFile(pfileWrite, std::move(pDataDict));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 } else {
tsepez70c4afd2016-11-15 11:33:44 -0800176 CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
tsepez833619b2016-12-07 09:21:17 -0800177 pData->InitStreamFromFile(pfileWrite, std::move(pDataDict));
Tom Sepez3343d142015-11-02 09:54:54 -0800178 iLast = pArray->GetCount() - 2;
tsepez8a3aa452016-11-16 12:26:06 -0800179 pArray->InsertNewAt<CPDF_String>(iLast, "form", false);
180 pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
181 pData->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800183 fileList->push_back(std::move(pfileWrite));
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700184 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800186 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187}
188
dsinclair521b7502016-11-02 13:02:28 -0700189bool SendPostSaveToXFADoc(CPDFXFA_Context* pContext) {
190 if (!pContext)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800191 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192
Ryan Harrison854d71c2017-10-18 12:28:14 -0400193 if (!pContext->ContainsXFAForm())
Tom Sepez7a73eff2016-02-08 13:39:53 -0800194 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195
dsinclair521b7502016-11-02 13:02:28 -0700196 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800197 if (!pXFADocView)
198 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199
Lei Zhangcddc8ed2017-06-20 17:26:44 -0700200 CXFA_FFWidgetHandler* pWidgetHandler = pXFADocView->GetWidgetHandler();
Tom Sepez40badde2017-05-01 13:21:39 -0700201 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator =
202 pXFADocView->CreateWidgetAccIterator();
tsepeze7b28532016-05-18 12:10:49 -0700203 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204 CXFA_EventParam preParam;
205 preParam.m_eType = XFA_EVENT_PostSave;
Lei Zhangcddc8ed2017-06-20 17:26:44 -0700206 pWidgetHandler->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 pXFADocView->UpdateDocView();
dsinclair521b7502016-11-02 13:02:28 -0700209 pContext->ClearChangeMark();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800210 return true;
Bo Xufdc00a72014-10-28 23:03:33 -0700211}
212
Dan Sinclair0b950422017-09-21 15:49:49 -0400213bool SendPreSaveToXFADoc(CPDFXFA_Context* pContext,
214 std::vector<RetainPtr<IFX_SeekableStream>>* fileList) {
Ryan Harrison854d71c2017-10-18 12:28:14 -0400215 if (!pContext->ContainsXFAForm())
Tom Sepez7a73eff2016-02-08 13:39:53 -0800216 return true;
217
dsinclair521b7502016-11-02 13:02:28 -0700218 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800219 if (!pXFADocView)
220 return true;
221
Lei Zhangcddc8ed2017-06-20 17:26:44 -0700222 CXFA_FFWidgetHandler* pWidgetHandler = pXFADocView->GetWidgetHandler();
Tom Sepez40badde2017-05-01 13:21:39 -0700223 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator =
224 pXFADocView->CreateWidgetAccIterator();
tsepeze7b28532016-05-18 12:10:49 -0700225 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 CXFA_EventParam preParam;
227 preParam.m_eType = XFA_EVENT_PreSave;
Lei Zhangcddc8ed2017-06-20 17:26:44 -0700228 pWidgetHandler->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230 pXFADocView->UpdateDocView();
dsinclair521b7502016-11-02 13:02:28 -0700231 return SaveXFADocumentData(pContext, fileList);
Bo Xufdc00a72014-10-28 23:03:33 -0700232}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800233#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700234
Tom Sepez7a73eff2016-02-08 13:39:53 -0800235bool FPDF_Doc_Save(FPDF_DOCUMENT document,
236 FPDF_FILEWRITE* pFileWrite,
237 FPDF_DWORD flags,
238 FPDF_BOOL bSetVersion,
239 int fileVerion) {
Tom Sepez1b246282015-11-25 15:15:31 -0800240 CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 if (!pPDFDoc)
242 return 0;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700243
Tom Sepez51da0932015-11-25 16:05:49 -0800244#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -0700245 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
Dan Sinclair0b950422017-09-21 15:49:49 -0400246 std::vector<RetainPtr<IFX_SeekableStream>> fileList;
dsinclair521b7502016-11-02 13:02:28 -0700247 SendPreSaveToXFADoc(pContext, &fileList);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800248#endif // PDF_ENABLE_XFA
Tom Sepez1b246282015-11-25 15:15:31 -0800249
Tom Sepez7a73eff2016-02-08 13:39:53 -0800250 if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 flags = 0;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700252
Dan Sinclairae4656e2017-05-09 12:36:41 -0400253 CPDF_Creator fileMaker(pPDFDoc,
254 pdfium::MakeRetain<FSDK_FileWriteAdapter>(pFileWrite));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255 if (bSetVersion)
Dan Sinclairae4656e2017-05-09 12:36:41 -0400256 fileMaker.SetFileVersion(fileVerion);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 if (flags == FPDF_REMOVE_SECURITY) {
258 flags = 0;
Dan Sinclairae4656e2017-05-09 12:36:41 -0400259 fileMaker.RemoveSecurity();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 }
Tom Sepez1b246282015-11-25 15:15:31 -0800261
Dan Sinclairae4656e2017-05-09 12:36:41 -0400262 bool bRet = fileMaker.Create(flags);
Tom Sepez51da0932015-11-25 16:05:49 -0800263#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -0700264 SendPostSaveToXFADoc(pContext);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800265#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 return bRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700267}
268
Tom Sepez7a73eff2016-02-08 13:39:53 -0800269} // namespace
270
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400271FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_SaveAsCopy(FPDF_DOCUMENT document,
272 FPDF_FILEWRITE* pFileWrite,
273 FPDF_DWORD flags) {
tsepez4cf55152016-11-02 14:37:54 -0700274 return FPDF_Doc_Save(document, pFileWrite, flags, false, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700275}
276
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400277FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
278FPDF_SaveWithVersion(FPDF_DOCUMENT document,
279 FPDF_FILEWRITE* pFileWrite,
280 FPDF_DWORD flags,
281 int fileVersion) {
tsepez4cf55152016-11-02 14:37:54 -0700282 return FPDF_Doc_Save(document, pFileWrite, flags, true, fileVersion);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700283}