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