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