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/fpdfxfa/cpdfxfa_page.h"
8
9 #include "core/fpdfapi/page/cpdf_page.h"
10 #include "core/fpdfapi/parser/cpdf_document.h"
11 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
12 #include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
13 #include "fpdfsdk/fsdk_define.h"
14 #include "public/fpdf_formfill.h"
15 #include "third_party/base/ptr_util.h"
16 #include "xfa/fxfa/xfa_ffdocview.h"
17 #include "xfa/fxfa/xfa_ffpageview.h"
18
CPDFXFA_Page(CPDFXFA_Context * pContext,int page_index)19 CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Context* pContext, int page_index)
20 : m_pXFAPageView(nullptr),
21 m_pContext(pContext),
22 m_iPageIndex(page_index),
23 m_iRef(1) {}
24
~CPDFXFA_Page()25 CPDFXFA_Page::~CPDFXFA_Page() {
26 if (m_pContext)
27 m_pContext->RemovePage(this);
28 }
29
LoadPDFPage()30 bool CPDFXFA_Page::LoadPDFPage() {
31 if (!m_pContext)
32 return false;
33
34 CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc();
35 if (!pPDFDoc)
36 return false;
37
38 CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);
39 if (!pDict)
40 return false;
41
42 if (!m_pPDFPage || m_pPDFPage->m_pFormDict != pDict) {
43 m_pPDFPage = pdfium::MakeUnique<CPDF_Page>(pPDFDoc, pDict, true);
44 m_pPDFPage->ParseContent();
45 }
46 return true;
47 }
48
LoadXFAPageView()49 bool CPDFXFA_Page::LoadXFAPageView() {
50 if (!m_pContext)
51 return false;
52
53 CXFA_FFDoc* pXFADoc = m_pContext->GetXFADoc();
54 if (!pXFADoc)
55 return false;
56
57 CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView();
58 if (!pXFADocView)
59 return false;
60
61 CXFA_FFPageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);
62 if (!pPageView)
63 return false;
64
65 m_pXFAPageView = pPageView;
66 return true;
67 }
68
LoadPage()69 bool CPDFXFA_Page::LoadPage() {
70 if (!m_pContext || m_iPageIndex < 0)
71 return false;
72
73 int iDocType = m_pContext->GetDocType();
74 switch (iDocType) {
75 case DOCTYPE_PDF:
76 case DOCTYPE_STATIC_XFA: {
77 return LoadPDFPage();
78 }
79 case DOCTYPE_DYNAMIC_XFA: {
80 return LoadXFAPageView();
81 }
82 default:
83 return false;
84 }
85 }
86
LoadPDFPage(CPDF_Dictionary * pageDict)87 bool CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) {
88 if (!m_pContext || m_iPageIndex < 0 || !pageDict)
89 return false;
90
91 m_pPDFPage =
92 pdfium::MakeUnique<CPDF_Page>(m_pContext->GetPDFDoc(), pageDict, true);
93 m_pPDFPage->ParseContent();
94 return true;
95 }
96
GetPageWidth() const97 FX_FLOAT CPDFXFA_Page::GetPageWidth() const {
98 if (!m_pPDFPage && !m_pXFAPageView)
99 return 0.0f;
100
101 int nDocType = m_pContext->GetDocType();
102 switch (nDocType) {
103 case DOCTYPE_DYNAMIC_XFA: {
104 if (m_pXFAPageView)
105 return m_pXFAPageView->GetPageViewRect().width;
106 break;
107 }
108 case DOCTYPE_STATIC_XFA:
109 case DOCTYPE_PDF: {
110 if (m_pPDFPage)
111 return m_pPDFPage->GetPageWidth();
112 break;
113 }
114 default:
115 return 0.0f;
116 }
117
118 return 0.0f;
119 }
120
GetPageHeight() const121 FX_FLOAT CPDFXFA_Page::GetPageHeight() const {
122 if (!m_pPDFPage && !m_pXFAPageView)
123 return 0.0f;
124
125 int nDocType = m_pContext->GetDocType();
126 switch (nDocType) {
127 case DOCTYPE_PDF:
128 case DOCTYPE_STATIC_XFA: {
129 if (m_pPDFPage)
130 return m_pPDFPage->GetPageHeight();
131 break;
132 }
133 case DOCTYPE_DYNAMIC_XFA: {
134 if (m_pXFAPageView)
135 return m_pXFAPageView->GetPageViewRect().height;
136 break;
137 }
138 default:
139 return 0.0f;
140 }
141
142 return 0.0f;
143 }
144
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)145 void CPDFXFA_Page::DeviceToPage(int start_x,
146 int start_y,
147 int size_x,
148 int size_y,
149 int rotate,
150 int device_x,
151 int device_y,
152 double* page_x,
153 double* page_y) {
154 if (!m_pPDFPage && !m_pXFAPageView)
155 return;
156
157 CFX_Matrix device2page;
158 device2page.SetReverse(
159 GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate));
160
161 CFX_PointF pos = device2page.Transform(CFX_PointF(
162 static_cast<FX_FLOAT>(device_x), static_cast<FX_FLOAT>(device_y)));
163
164 *page_x = pos.x;
165 *page_y = pos.y;
166 }
167
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)168 void CPDFXFA_Page::PageToDevice(int start_x,
169 int start_y,
170 int size_x,
171 int size_y,
172 int rotate,
173 double page_x,
174 double page_y,
175 int* device_x,
176 int* device_y) {
177 if (!m_pPDFPage && !m_pXFAPageView)
178 return;
179
180 CFX_Matrix page2device =
181 GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate);
182
183 CFX_PointF pos = page2device.Transform(
184 CFX_PointF(static_cast<FX_FLOAT>(page_x), static_cast<FX_FLOAT>(page_y)));
185
186 *device_x = FXSYS_round(pos.x);
187 *device_y = FXSYS_round(pos.y);
188 }
189
GetDisplayMatrix(int xPos,int yPos,int xSize,int ySize,int iRotate) const190 CFX_Matrix CPDFXFA_Page::GetDisplayMatrix(int xPos,
191 int yPos,
192 int xSize,
193 int ySize,
194 int iRotate) const {
195 if (!m_pPDFPage && !m_pXFAPageView)
196 return CFX_Matrix();
197
198 int nDocType = m_pContext->GetDocType();
199 switch (nDocType) {
200 case DOCTYPE_DYNAMIC_XFA: {
201 if (m_pXFAPageView) {
202 return m_pXFAPageView->GetDisplayMatrix(
203 CFX_Rect(xPos, yPos, xSize, ySize), iRotate);
204 }
205 break;
206 }
207 case DOCTYPE_PDF:
208 case DOCTYPE_STATIC_XFA: {
209 if (m_pPDFPage)
210 return m_pPDFPage->GetDisplayMatrix(xPos, yPos, xSize, ySize, iRotate);
211 break;
212 }
213 default:
214 return CFX_Matrix();
215 }
216 return CFX_Matrix();
217 }
218