Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / fpdfsdk / src / fpdfxfa / fpdfxfa_page.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 "../../include/fsdk_define.h"\r
8 #include "../../include/fsdk_mgr.h"\r
9 #include "../../include/fpdfxfa/fpdfxfa_util.h"\r
10 #include "../../include/fpdfxfa/fpdfxfa_doc.h"\r
11 #include "../../include/fpdfxfa/fpdfxfa_page.h"\r
12 \r
13 CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index) :\r
14         m_pPDFPage(NULL),\r
15         m_pXFAPageView(NULL),\r
16         m_iPageIndex(page_index),\r
17         m_pDocument(pDoc),\r
18         m_iRef(1)\r
19 {\r
20 \r
21 }\r
22 \r
23 CPDFXFA_Page::~CPDFXFA_Page()\r
24 {\r
25         if (m_pPDFPage)\r
26                 delete m_pPDFPage;\r
27         m_pPDFPage = NULL;\r
28         m_pXFAPageView = NULL;\r
29 }\r
30 \r
31 void CPDFXFA_Page::Release()\r
32 {\r
33         m_iRef--;\r
34         if (m_iRef > 0)\r
35                 return;\r
36         \r
37         if (m_pDocument)\r
38                 m_pDocument->RemovePage(this);\r
39 \r
40         delete this;\r
41 }\r
42 \r
43 FX_BOOL CPDFXFA_Page::LoadPDFPage()\r
44 {\r
45         if (!m_pDocument) return FALSE;\r
46         CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc();\r
47         if (pPDFDoc)\r
48         {\r
49                 CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);\r
50                 if (pDict == NULL) return FALSE;\r
51                 if (m_pPDFPage) {\r
52                         if (m_pPDFPage->m_pFormDict == pDict)\r
53                                 return TRUE;\r
54 \r
55                         delete m_pPDFPage;\r
56                         m_pPDFPage = NULL;\r
57                 }\r
58 \r
59                 m_pPDFPage = FX_NEW CPDF_Page;\r
60                 m_pPDFPage->Load(pPDFDoc, pDict);\r
61                 m_pPDFPage->ParseContent();\r
62                 return TRUE;\r
63         }\r
64 \r
65         return FALSE;\r
66 }\r
67 \r
68 FX_BOOL CPDFXFA_Page::LoadXFAPageView()\r
69 {\r
70         if (!m_pDocument)\r
71                 return FALSE;\r
72         XFA_HDOC pXFADoc = m_pDocument->GetXFADoc();\r
73         if (pXFADoc)\r
74         {\r
75                 IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView();\r
76                 if (!pXFADocView) \r
77                         return FALSE;\r
78 \r
79                 IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);\r
80                 if (!pPageView)\r
81                         return FALSE;\r
82 \r
83                 if (m_pXFAPageView)\r
84                         if (m_pXFAPageView == pPageView)\r
85                                 return TRUE;\r
86 \r
87                 m_pXFAPageView = pPageView;\r
88                 int iStatus = m_pXFAPageView->LoadPageView(NULL);\r
89 \r
90                 return TRUE;\r
91         }\r
92 \r
93         return FALSE;\r
94 }\r
95 \r
96 FX_BOOL CPDFXFA_Page::LoadPage()\r
97 {\r
98         if (!m_pDocument || m_iPageIndex < 0)\r
99                 return FALSE;\r
100 \r
101         int iDocType = m_pDocument->GetDocType();\r
102         CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc();\r
103         XFA_HDOC pXFADoc = m_pDocument->GetXFADoc();\r
104 \r
105         switch (iDocType)\r
106         {\r
107         case DOCTYPE_PDF:\r
108         case DOCTYPE_STATIC_XFA:\r
109                 {\r
110                         return LoadPDFPage();\r
111                 }\r
112         case DOCTYPE_DYNIMIC_XFA:\r
113                 {\r
114                         return LoadXFAPageView();\r
115                 }\r
116         default:\r
117                 return FALSE;\r
118         }\r
119 \r
120         return FALSE;\r
121 }\r
122 \r
123 FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict)\r
124 {\r
125         if (!m_pDocument || m_iPageIndex < 0 || !pageDict)\r
126                 return FALSE;\r
127 \r
128         if (m_pPDFPage)\r
129                 delete m_pPDFPage;\r
130 \r
131         m_pPDFPage = FX_NEW CPDF_Page();\r
132         m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict);\r
133         m_pPDFPage->ParseContent();\r
134 \r
135         return TRUE;\r
136 }\r
137 \r
138 FX_FLOAT CPDFXFA_Page::GetPageWidth()\r
139 {\r
140         ASSERT(m_pDocument != NULL);\r
141 \r
142         if (!m_pPDFPage && !m_pXFAPageView)\r
143                 return 0.0f;\r
144 \r
145         int nDocType = m_pDocument->GetDocType();\r
146         switch (nDocType)\r
147         {\r
148         case DOCTYPE_DYNIMIC_XFA:\r
149                 {\r
150                         if (m_pXFAPageView)\r
151                         {\r
152                                 CFX_RectF rect;\r
153                                 m_pXFAPageView->GetPageViewRect(rect);\r
154                                 return rect.width;\r
155                         }\r
156                 }\r
157                 break;\r
158         case DOCTYPE_STATIC_XFA:\r
159         case DOCTYPE_PDF:\r
160                 {\r
161                         if (m_pPDFPage)\r
162                                 return m_pPDFPage->GetPageWidth();\r
163                 }\r
164                 break;\r
165         default:\r
166                 return 0.0f;\r
167         }\r
168 \r
169         return 0.0f;\r
170 }\r
171 \r
172 FX_FLOAT CPDFXFA_Page::GetPageHeight()\r
173 {\r
174         ASSERT(m_pDocument != NULL);\r
175 \r
176         if (!m_pPDFPage && !m_pXFAPageView)\r
177                 return 0.0f;\r
178 \r
179         int nDocType = m_pDocument->GetDocType();\r
180         switch (nDocType)\r
181         {\r
182         case DOCTYPE_PDF:\r
183         case DOCTYPE_STATIC_XFA:\r
184                 {\r
185                         if (m_pPDFPage)\r
186                                 return m_pPDFPage->GetPageHeight();\r
187                 }\r
188                 break;\r
189         case DOCTYPE_DYNIMIC_XFA:\r
190                 {\r
191                         if (m_pXFAPageView)\r
192                         {\r
193                                 CFX_RectF rect;\r
194                                 m_pXFAPageView->GetPageViewRect(rect);\r
195                                 return rect.height;\r
196                         }\r
197                 }\r
198                 break;\r
199         default:\r
200                 return 0.0f;\r
201         }\r
202 \r
203         return 0.0f;\r
204 }\r
205 \r
206 void CPDFXFA_Page::DeviceToPage(int start_x, int start_y, int size_x, int size_y, int rotate, int device_x, int device_y, double* page_x, double* page_y)\r
207 {\r
208         ASSERT(m_pDocument != NULL);\r
209 \r
210         if (!m_pPDFPage && !m_pXFAPageView)\r
211                 return;\r
212 \r
213         CPDF_Matrix page2device;\r
214         CPDF_Matrix device2page;\r
215         FX_FLOAT page_x_f, page_y_f;\r
216 \r
217         GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);\r
218 \r
219         device2page.SetReverse(page2device);\r
220         device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, page_y_f);\r
221 \r
222         *page_x = (page_x_f);\r
223         *page_y = (page_y_f);\r
224 }\r
225 \r
226 void CPDFXFA_Page::PageToDevice(int start_x, int start_y, int size_x, int size_y, int rotate, double page_x, double page_y, int* device_x, int* device_y)\r
227 {\r
228         if (!m_pPDFPage && !m_pXFAPageView)\r
229                 return;\r
230 \r
231         CPDF_Matrix page2device;\r
232         FX_FLOAT device_x_f, device_y_f;\r
233 \r
234         GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);\r
235 \r
236         page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, device_y_f);\r
237 \r
238         *device_x = FXSYS_round(device_x_f);\r
239         *device_y = FXSYS_round(device_y_f);\r
240 }\r
241 \r
242 void CPDFXFA_Page::GetDisplayMatrix(CFX_AffineMatrix& matrix, int xPos, int yPos, \r
243         int xSize, int ySize, int iRotate) const\r
244 {\r
245         ASSERT(m_pDocument != NULL);\r
246 \r
247         if (!m_pPDFPage && !m_pXFAPageView)\r
248                 return;\r
249 \r
250         int nDocType = m_pDocument->GetDocType();\r
251         switch (nDocType)\r
252         {\r
253         case DOCTYPE_DYNIMIC_XFA:\r
254                 {\r
255                         if (m_pXFAPageView)\r
256                         {\r
257                                 CFX_Rect rect;\r
258                                 rect.Set(xPos, yPos, xSize, ySize);\r
259                                 m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate);\r
260                         }\r
261                 }\r
262                 break;\r
263         case DOCTYPE_PDF:\r
264         case DOCTYPE_STATIC_XFA:\r
265                 {\r
266                         if (m_pPDFPage) \r
267                         {\r
268                                 m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate);\r
269                         }\r
270                 }\r
271                 break;\r
272         default:\r
273                 return;\r
274         }\r
275 \r
276 }\r