1 // 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.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../public/fpdf_edit.h"
8 #include "../include/fsdk_define.h"
9
10
11 #if _FX_OS_ == _FX_ANDROID_
12 #include "time.h"
13 #else
14 #include <ctime>
15 #endif
16
FPDF_CreateNewDocument()17 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument()
18 {
19 CPDF_Document* pDoc = new CPDF_Document;
20 pDoc->CreateNewDoc();
21 time_t currentTime;
22
23 CFX_ByteString DateStr;
24
25 if(FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
26 {
27 if ( -1 != time( ¤tTime ) )
28 {
29 tm * pTM = localtime( ¤tTime );
30 if ( pTM )
31 {
32 DateStr.Format( "D:%04d%02d%02d%02d%02d%02d", pTM->tm_year+1900, pTM->tm_mon+1,
33 pTM->tm_mday, pTM->tm_hour, pTM->tm_min, pTM->tm_sec );
34 }
35 }
36 }
37
38 CPDF_Dictionary* pInfoDict = NULL;
39 pInfoDict = pDoc->GetInfo();
40 if (pInfoDict)
41 {
42 if(FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
43 pInfoDict->SetAt("CreationDate", new CPDF_String(DateStr));
44 pInfoDict->SetAt("Creator", new CPDF_String(L"PDFium"));
45 }
46
47 return pDoc;
48 }
49
FPDFPage_Delete(FPDF_DOCUMENT document,int page_index)50 DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index)
51 {
52 CPDF_Document* pDoc = (CPDF_Document*)document;
53 if (pDoc == NULL)
54 return;
55 if (page_index < 0 || page_index >= pDoc->GetPageCount())
56 return;
57
58 pDoc->DeletePage(page_index);
59 }
60
FPDFPage_New(FPDF_DOCUMENT document,int page_index,double width,double height)61 DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height)
62 {
63 if (!document)
64 return NULL;
65
66 // CPDF_Parser* pParser = (CPDF_Parser*)document;
67 CPDF_Document* pDoc = (CPDF_Document*)document;
68 if(page_index < 0)
69 page_index = 0;
70 if(pDoc->GetPageCount()<page_index)
71 page_index = pDoc->GetPageCount();
72 // if (page_index < 0 || page_index >= pDoc->GetPageCount())
73 // return NULL;
74
75 CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index);
76 if(!pPageDict)
77 return NULL;
78 CPDF_Array* pMediaBoxArray = new CPDF_Array;
79 pMediaBoxArray->Add(new CPDF_Number(0));
80 pMediaBoxArray->Add(new CPDF_Number(0));
81 pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width)));
82 pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height)));
83
84 pPageDict->SetAt("MediaBox", pMediaBoxArray);
85 pPageDict->SetAt("Rotate", new CPDF_Number(0));
86 pPageDict->SetAt("Resources", new CPDF_Dictionary);
87
88 CPDF_Page* pPage = new CPDF_Page;
89 pPage->Load(pDoc,pPageDict);
90 pPage->ParseContent();
91
92 return pPage;
93 }
94
FPDFPage_GetRotation(FPDF_PAGE page)95 DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page)
96 {
97 CPDF_Page* pPage = (CPDF_Page*)page;
98 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
99 || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
100 {
101 return -1;
102 }
103 CPDF_Dictionary* pDict = pPage->m_pFormDict;
104
105 int rotate = 0;
106 if(pDict != NULL)
107 {
108 if (pDict->KeyExist("Rotate"))
109 rotate = pDict->GetElement("Rotate")->GetDirect()? pDict->GetElement("Rotate")->GetDirect()->GetInteger() / 90 : 0;
110 else
111 {
112 if(pDict->KeyExist("Parent"))
113 {
114 CPDF_Dictionary* pPages = (CPDF_Dictionary*)pDict->GetElement("Parent")->GetDirect();
115 while(pPages)
116 {
117 if(pPages->KeyExist("Rotate"))
118 {
119 rotate = pPages->GetElement("Rotate")->GetDirect()? pPages->GetElement("Rotate")->GetDirect()->GetInteger() / 90 : 0;
120 break;
121 }
122 else if(pPages->KeyExist("Parent"))
123 pPages = (CPDF_Dictionary*)pPages->GetElement("Parent")->GetDirect();
124 else break;
125 }
126 }
127 }
128 }
129 else
130 {
131 return -1;
132 }
133
134 return rotate;
135 }
136
FPDFPage_InsertObject(FPDF_PAGE page,FPDF_PAGEOBJECT page_obj)137 DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_obj)
138 {
139 CPDF_Page* pPage = (CPDF_Page*)page;
140 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
141 || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
142 {
143 return;
144 }
145 CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_obj;
146 if(pPageObj == NULL)
147 return;
148 FX_POSITION LastPersition = pPage->GetLastObjectPosition();
149
150 pPage->InsertObject(LastPersition, pPageObj);
151 switch(pPageObj->m_Type)
152 {
153 case FPDF_PAGEOBJ_PATH:
154 {
155 CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
156 pPathObj->CalcBoundingBox();
157 break;
158 }
159 case FPDF_PAGEOBJ_TEXT:
160 {
161 // CPDF_PathObject* pPathObj = (CPDF_PathObject*)pPageObj;
162 // pPathObj->CalcBoundingBox();
163 break;
164 }
165 case FPDF_PAGEOBJ_IMAGE:
166 {
167 CPDF_ImageObject* pImageObj = (CPDF_ImageObject*)pPageObj;
168 pImageObj->CalcBoundingBox();
169 break;
170 }
171 case FPDF_PAGEOBJ_SHADING:
172 {
173 CPDF_ShadingObject* pShadingObj = (CPDF_ShadingObject*)pPageObj;
174 pShadingObj->CalcBoundingBox();
175 break;
176 }
177 case FPDF_PAGEOBJ_FORM:
178 {
179 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
180 pFormObj->CalcBoundingBox();
181 break;
182 }
183 default:
184 break;
185 }
186
187 // pPage->ParseContent();
188 //pPage->GenerateContent();
189
190 }
191
FPDFPage_CountObject(FPDF_PAGE page)192 DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page)
193 {
194 CPDF_Page* pPage = (CPDF_Page*)page;
195 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
196 || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
197 {
198 return -1;
199 }
200 return pPage->CountObjects();
201 // return 0;
202 }
203
FPDFPage_GetObject(FPDF_PAGE page,int index)204 DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, int index)
205 {
206 CPDF_Page* pPage = (CPDF_Page*)page;
207 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type")
208 || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
209 {
210 return NULL;
211 }
212 return pPage->GetObjectByIndex(index);
213 // return NULL;
214 }
215
FPDFPage_HasTransparency(FPDF_PAGE page)216 DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page)
217 {
218 if(!page) return FALSE;
219 CPDF_Page* pPage = (CPDF_Page*)page;
220
221 return pPage->BackgroundAlphaNeeded();
222 }
223
FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject)224 DLLEXPORT FPDF_BOOL STDCALL FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject)
225 {
226 if(!pageObject) return FALSE;
227 CPDF_PageObject* pPageObj = (CPDF_PageObject*)pageObject;
228
229 const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
230 int blend_type = pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
231 if (blend_type != FXDIB_BLEND_NORMAL) return TRUE;
232
233 CPDF_Dictionary* pSMaskDict = pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL;
234 if(pSMaskDict) return TRUE;
235
236 if(pGeneralState && pGeneralState->m_FillAlpha != 1.0f)
237 return TRUE;
238
239 if(pPageObj->m_Type == PDFPAGE_PATH)
240 {
241 if(pGeneralState && pGeneralState->m_StrokeAlpha != 1.0f)
242 return TRUE;
243 }
244
245 if(pPageObj->m_Type == PDFPAGE_FORM)
246 {
247 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
248 if(pFormObj->m_pForm && (pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED))
249 return TRUE;
250 if(pFormObj->m_pForm && (!(pFormObj->m_pForm->m_Transparency & PDFTRANS_ISOLATED) && (pFormObj->m_pForm->m_Transparency & PDFTRANS_GROUP)))
251 return TRUE;
252 }
253 return FALSE;
254 }
255
FPDFPage_GenerateContent(FPDF_PAGE page)256 DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page)
257 {
258 CPDF_Page* pPage = (CPDF_Page*)page;
259 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
260 || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
261 {
262 return FALSE;
263 }
264 CPDF_PageContentGenerate CG(pPage);
265 CG.GenerateContent();
266
267 return TRUE;
268 }
269
FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,double a,double b,double c,double d,double e,double f)270 DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
271 double a, double b, double c, double d, double e, double f)
272 {
273 CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
274 if(pPageObj == NULL)
275 return;
276 CFX_AffineMatrix matrix((FX_FLOAT)a,(FX_FLOAT)b,(FX_FLOAT)c,(FX_FLOAT)d,(FX_FLOAT)e,(FX_FLOAT)f);
277 pPageObj->Transform(matrix);
278 }
FPDFPage_TransformAnnots(FPDF_PAGE page,double a,double b,double c,double d,double e,double f)279 DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
280 double a, double b, double c, double d, double e, double f)
281 {
282 if(page == NULL)
283 return;
284 CPDF_Page* pPage = (CPDF_Page*)page;
285 CPDF_AnnotList AnnotList(pPage);
286 for (int i=0; i<AnnotList.Count();i++)
287 {
288 CPDF_Annot* pAnnot = AnnotList.GetAt(i);
289 // transformAnnots Rectangle
290 CPDF_Rect rect;
291 pAnnot->GetRect(rect);
292 CFX_AffineMatrix matrix((FX_FLOAT)a,(FX_FLOAT)b,(FX_FLOAT)c,(FX_FLOAT)d,(FX_FLOAT)e,(FX_FLOAT)f);
293 rect.Transform(&matrix);
294 CPDF_Array *pRectArray = NULL;
295 pRectArray = pAnnot->m_pAnnotDict->GetArray("Rect");
296 if (!pRectArray) pRectArray=CPDF_Array::Create();
297 pRectArray->SetAt(0, new CPDF_Number(rect.left));
298 pRectArray->SetAt(1, new CPDF_Number(rect.bottom));
299 pRectArray->SetAt(2, new CPDF_Number(rect.right));
300 pRectArray->SetAt(3, new CPDF_Number(rect.top));
301 pAnnot->m_pAnnotDict->SetAt("Rect",pRectArray);
302
303 //Transform AP's rectangle
304 //To Do
305 }
306
307 }
308
FPDFPage_SetRotation(FPDF_PAGE page,int rotate)309 DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate)
310 {
311 CPDF_Page* pPage = (CPDF_Page*)page;
312 if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
313 || pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
314 {
315 return;
316 }
317 CPDF_Dictionary* pDict = pPage->m_pFormDict;
318 rotate %=4;
319
320 pDict->SetAt("Rotate", new CPDF_Number(rotate * 90));
321 }
322