blob: a8447ce7305b065f8ab8b5f563afb39c802cd9dd [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
Tom Sepez1ed8a212015-05-11 15:25:39 -07007#include "../../public/fpdf_edit.h"
8#include "../../public/fpdf_formfill.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07009#include "../include/fsdk_define.h"
Bo Xufdc00a72014-10-28 23:03:33 -070010#include "../include/fpdfxfa/fpdfxfa_doc.h"
11#include "../include/fpdfxfa/fpdfxfa_app.h"
12#include "../include/fpdfxfa/fpdfxfa_page.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070013
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070014#if _FX_OS_ == _FX_ANDROID_
15#include "time.h"
16#else
17#include <ctime>
18#endif
19
Nico Weber9d8ec5a2015-08-04 13:00:21 -070020DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() {
21 CPDF_Document* pDoc = FX_NEW CPDF_Document;
22 if (!pDoc)
23 return NULL;
24 pDoc->CreateNewDoc();
25 time_t currentTime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027 CFX_ByteString DateStr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029 if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) {
30 if (-1 != time(&currentTime)) {
31 tm* pTM = localtime(&currentTime);
32 if (pTM) {
33 DateStr.Format("D:%04d%02d%02d%02d%02d%02d", pTM->tm_year + 1900,
34 pTM->tm_mon + 1, pTM->tm_mday, pTM->tm_hour, pTM->tm_min,
35 pTM->tm_sec);
36 }
37 }
38 }
Tom Sepezbdeeb8a2015-05-27 12:25:00 -070039
Nico Weber9d8ec5a2015-08-04 13:00:21 -070040 CPDF_Dictionary* pInfoDict = NULL;
41 pInfoDict = pDoc->GetInfo();
42 if (pInfoDict) {
43 if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
44 pInfoDict->SetAt("CreationDate", new CPDF_String(DateStr));
45 pInfoDict->SetAt("Creator", FX_NEW CPDF_String(L"PDFium"));
46 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070047
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 CPDFXFA_App* pApp = CPDFXFA_App::GetInstance();
49 CPDFXFA_Document* document = FX_NEW CPDFXFA_Document(pDoc, pApp);
50 return document;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070051}
52
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index) {
54 CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
55 if (pDoc == NULL)
56 return;
57 if (page_index < 0 || page_index >= pDoc->GetPageCount())
58 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 pDoc->DeletePage(page_index);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061}
62
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document,
64 int page_index,
65 double width,
66 double height) {
67 if (!document)
68 return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070 // CPDF_Parser* pParser = (CPDF_Parser*)document;
71 CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
72 if (page_index < 0)
73 page_index = 0;
74 if (pDoc->GetPageCount() < page_index)
75 page_index = pDoc->GetPageCount();
76 // if (page_index < 0 || page_index >= pDoc->GetPageCount())
77 // return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070078
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079 CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index);
80 if (!pPageDict)
81 return NULL;
82 CPDF_Array* pMediaBoxArray = FX_NEW CPDF_Array;
83 pMediaBoxArray->Add(FX_NEW CPDF_Number(0));
84 pMediaBoxArray->Add(FX_NEW CPDF_Number(0));
85 pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(width)));
86 pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(height)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070087
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088 pPageDict->SetAt("MediaBox", pMediaBoxArray);
89 pPageDict->SetAt("Rotate", FX_NEW CPDF_Number(0));
90 pPageDict->SetAt("Resources", FX_NEW CPDF_Dictionary);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070091
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 // CPDF_Page* pPage = FX_NEW CPDF_Page;
93 // pPage->Load(pDoc,pPageDict);
94 // pPage->ParseContent();
Bo Xufdc00a72014-10-28 23:03:33 -070095
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096 CPDFXFA_Page* pPage =
97 FX_NEW CPDFXFA_Page((CPDFXFA_Document*)document, page_index);
98 pPage->LoadPDFPage(pPageDict);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070099
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100 return pPage;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700101}
102
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700103DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page) {
104 CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
105 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
106 !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
107 pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
108 "Page")) {
109 return -1;
110 }
111 CPDF_Dictionary* pDict = pPage->m_pFormDict;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700112
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113 int rotate = 0;
114 if (pDict != NULL) {
115 if (pDict->KeyExist("Rotate"))
116 rotate = pDict->GetElement("Rotate")->GetDirect()
117 ? pDict->GetElement("Rotate")->GetDirect()->GetInteger() / 90
118 : 0;
119 else {
120 if (pDict->KeyExist("Parent")) {
121 CPDF_Dictionary* pPages =
122 (CPDF_Dictionary*)pDict->GetElement("Parent")->GetDirect();
123 while (pPages) {
124 if (pPages->KeyExist("Rotate")) {
125 rotate =
126 pPages->GetElement("Rotate")->GetDirect()
127 ? pPages->GetElement("Rotate")->GetDirect()->GetInteger() /
128 90
129 : 0;
130 break;
131 } else if (pPages->KeyExist("Parent"))
132 pPages =
133 (CPDF_Dictionary*)pPages->GetElement("Parent")->GetDirect();
134 else
135 break;
136 }
137 }
138 }
139 } else {
140 return -1;
141 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700142
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143 return rotate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700144}
145
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page,
147 FPDF_PAGEOBJECT page_obj) {
148 CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
149 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
150 !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
151 pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
152 "Page")) {
153 return;
154 }
155 CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj;
156 if (pPageObj == NULL)
157 return;
158 FX_POSITION LastPersition = pPage->GetLastObjectPosition();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700159
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700160 pPage->InsertObject(LastPersition, pPageObj);
161 switch (pPageObj->m_Type) {
162 case FPDF_PAGEOBJ_PATH: {
163 CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
164 pPathObj->CalcBoundingBox();
165 break;
166 }
167 case FPDF_PAGEOBJ_TEXT: {
168 // CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
169 // pPathObj->CalcBoundingBox();
170 break;
171 }
172 case FPDF_PAGEOBJ_IMAGE: {
173 CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pPageObj;
174 pImageObj->CalcBoundingBox();
175 break;
176 }
177 case FPDF_PAGEOBJ_SHADING: {
178 CPDF_ShadingObject* pShadingObj = (CPDF_ShadingObject*)pPageObj;
179 pShadingObj->CalcBoundingBox();
180 break;
181 }
182 case FPDF_PAGEOBJ_FORM: {
183 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
184 pFormObj->CalcBoundingBox();
185 break;
186 }
187 default:
188 break;
189 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 // pPage->ParseContent();
192 // pPage->GenerateContent();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700193}
194
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page) {
196 CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
197 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
198 !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
199 pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
200 "Page")) {
201 return -1;
202 }
203 return pPage->CountObjects();
204 // return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700205}
206
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page,
208 int index) {
209 CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
210 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
211 pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
212 "Page")) {
213 return NULL;
214 }
215 return pPage->GetObjectByIndex(index);
216 // return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700217}
218
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page) {
220 if (!page)
221 return FALSE;
222 CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
223 if (!pPage)
224 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 return pPage->BackgroundAlphaNeeded();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700227}
228
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229DLLEXPORT FPDF_BOOL STDCALL
230FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) {
231 if (!pageObject)
232 return FALSE;
233 CPDF_PageObject* pPageObj = (CPDF_PageObject*)pageObject;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700234
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
236 int blend_type =
237 pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
238 if (blend_type != FXDIB_BLEND_NORMAL)
239 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700240
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 CPDF_Dictionary* pSMaskDict =
242 pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL;
243 if (pSMaskDict)
244 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700245
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 if (pGeneralState && pGeneralState->m_FillAlpha != 1.0f)
247 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700248
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 if (pPageObj->m_Type == PDFPAGE_PATH) {
250 if (pGeneralState && pGeneralState->m_StrokeAlpha != 1.0f)
251 return TRUE;
252 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 if (pPageObj->m_Type == PDFPAGE_FORM) {
255 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
256 if (pFormObj->m_pForm &&
257 (pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED))
258 return TRUE;
259 if (pFormObj->m_pForm &&
260 (!(pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED) &&
261 (pFormObj->m_pForm->m_Transparency & PDFTRANS_GROUP)))
262 return TRUE;
263 }
264 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700265}
266
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page) {
268 CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
269 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
270 !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
271 pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
272 "Page")) {
273 return FALSE;
274 }
275 CPDF_PageContentGenerate CG(pPage);
276 CG.GenerateContent();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700277
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700279}
280
281DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 double a,
283 double b,
284 double c,
285 double d,
286 double e,
287 double f) {
288 CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
289 if (pPageObj == NULL)
290 return;
291 // PDF_ImageObject* pImageObj = FX_NEW CPDF_ImageObject;
292 CFX_AffineMatrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d,
293 (FX_FLOAT)e, (FX_FLOAT)f);
294 pPageObj->Transform(matrix);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700295}
296DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700297 double a,
298 double b,
299 double c,
300 double d,
301 double e,
302 double f) {
303 if (page == NULL)
304 return;
305 CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
306 if (!pPage)
307 return;
308 CPDF_AnnotList AnnotList(pPage);
309 for (int i = 0; i < AnnotList.Count(); i++) {
310 CPDF_Annot* pAnnot = AnnotList.GetAt(i);
311 // transformAnnots Rectangle
312 CPDF_Rect rect;
313 pAnnot->GetRect(rect);
314 CFX_AffineMatrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d,
315 (FX_FLOAT)e, (FX_FLOAT)f);
316 rect.Transform(&matrix);
317 CPDF_Array* pRectArray = NULL;
318 pRectArray = pAnnot->GetAnnotDict()->GetArray("Rect");
319 if (!pRectArray)
320 pRectArray = CPDF_Array::Create();
321 pRectArray->SetAt(0, new CPDF_Number(rect.left));
322 pRectArray->SetAt(1, new CPDF_Number(rect.bottom));
323 pRectArray->SetAt(2, new CPDF_Number(rect.right));
324 pRectArray->SetAt(3, new CPDF_Number(rect.top));
325 pAnnot->GetAnnotDict()->SetAt("Rect", pRectArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700326
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700327 // Transform AP's rectangle
328 // To Do
329 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330}
Bo Xu394010d2014-06-12 13:41:50 -0700331
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate) {
333 if (page == NULL)
334 return;
335 CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
336 if (!pPage)
337 return;
Bo Xufdc00a72014-10-28 23:03:33 -0700338
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") ||
340 !pPage->m_pFormDict->GetElement("Type")->GetDirect() ||
341 pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare(
342 "Page")) {
343 return;
344 }
345 CPDF_Dictionary* pDict = pPage->m_pFormDict;
346 rotate %= 4;
Bo Xu394010d2014-06-12 13:41:50 -0700347
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700348 pDict->SetAt("Rotate", FX_NEW CPDF_Number(rotate * 90));
Nico Weber0ce77e32014-07-16 13:19:08 -0700349}