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/cxfa_ffdocview.h"
17 #include "xfa/fxfa/cxfa_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), m_pContext(pContext), m_iPageIndex(page_index) {}
21
~CPDFXFA_Page()22 CPDFXFA_Page::~CPDFXFA_Page() {}
23
LoadPDFPage()24 bool CPDFXFA_Page::LoadPDFPage() {
25 if (!m_pContext)
26 return false;
27
28 CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc();
29 if (!pPDFDoc)
30 return false;
31
32 CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);
33 if (!pDict)
34 return false;
35
36 if (!m_pPDFPage || m_pPDFPage->m_pFormDict != pDict) {
37 m_pPDFPage = pdfium::MakeUnique<CPDF_Page>(pPDFDoc, pDict, true);
38 m_pPDFPage->ParseContent();
39 }
40 return true;
41 }
42
LoadXFAPageView()43 bool CPDFXFA_Page::LoadXFAPageView() {
44 if (!m_pContext)
45 return false;
46
47 CXFA_FFDoc* pXFADoc = m_pContext->GetXFADoc();
48 if (!pXFADoc)
49 return false;
50
51 CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView();
52 if (!pXFADocView)
53 return false;
54
55 CXFA_FFPageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);
56 if (!pPageView)
57 return false;
58
59 m_pXFAPageView = pPageView;
60 return true;
61 }
62
LoadPage()63 bool CPDFXFA_Page::LoadPage() {
64 if (!m_pContext || m_iPageIndex < 0)
65 return false;
66
67 switch (m_pContext->GetFormType()) {
68 case FormType::kNone:
69 case FormType::kAcroForm:
70 case FormType::kXFAForeground:
71 return LoadPDFPage();
72 case FormType::kXFAFull:
73 return LoadXFAPageView();
74 }
75 return false;
76 }
77
LoadPDFPage(CPDF_Dictionary * pageDict)78 bool CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) {
79 if (!m_pContext || m_iPageIndex < 0 || !pageDict)
80 return false;
81
82 m_pPDFPage =
83 pdfium::MakeUnique<CPDF_Page>(m_pContext->GetPDFDoc(), pageDict, true);
84 m_pPDFPage->ParseContent();
85 return true;
86 }
87
GetPageWidth() const88 float CPDFXFA_Page::GetPageWidth() const {
89 if (!m_pPDFPage && !m_pXFAPageView)
90 return 0.0f;
91
92 switch (m_pContext->GetFormType()) {
93 case FormType::kNone:
94 case FormType::kAcroForm:
95 case FormType::kXFAForeground:
96 if (m_pPDFPage)
97 return m_pPDFPage->GetPageWidth();
98 case FormType::kXFAFull:
99 if (m_pXFAPageView)
100 return m_pXFAPageView->GetPageViewRect().width;
101 }
102
103 return 0.0f;
104 }
105
GetPageHeight() const106 float CPDFXFA_Page::GetPageHeight() const {
107 if (!m_pPDFPage && !m_pXFAPageView)
108 return 0.0f;
109
110 switch (m_pContext->GetFormType()) {
111 case FormType::kNone:
112 case FormType::kAcroForm:
113 case FormType::kXFAForeground:
114 if (m_pPDFPage)
115 return m_pPDFPage->GetPageHeight();
116 case FormType::kXFAFull:
117 if (m_pXFAPageView)
118 return m_pXFAPageView->GetPageViewRect().height;
119 }
120
121 return 0.0f;
122 }
123
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)124 void CPDFXFA_Page::DeviceToPage(int start_x,
125 int start_y,
126 int size_x,
127 int size_y,
128 int rotate,
129 int device_x,
130 int device_y,
131 double* page_x,
132 double* page_y) {
133 if (!m_pPDFPage && !m_pXFAPageView)
134 return;
135
136 CFX_PointF pos = GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate)
137 .GetInverse()
138 .Transform(CFX_PointF(static_cast<float>(device_x),
139 static_cast<float>(device_y)));
140
141 *page_x = pos.x;
142 *page_y = pos.y;
143 }
144
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)145 void CPDFXFA_Page::PageToDevice(int start_x,
146 int start_y,
147 int size_x,
148 int size_y,
149 int rotate,
150 double page_x,
151 double page_y,
152 int* device_x,
153 int* device_y) {
154 if (!m_pPDFPage && !m_pXFAPageView)
155 return;
156
157 CFX_Matrix page2device =
158 GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate);
159
160 CFX_PointF pos = page2device.Transform(
161 CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)));
162
163 *device_x = FXSYS_round(pos.x);
164 *device_y = FXSYS_round(pos.y);
165 }
166
GetDisplayMatrix(int xPos,int yPos,int xSize,int ySize,int iRotate) const167 CFX_Matrix CPDFXFA_Page::GetDisplayMatrix(int xPos,
168 int yPos,
169 int xSize,
170 int ySize,
171 int iRotate) const {
172 if (!m_pPDFPage && !m_pXFAPageView)
173 return CFX_Matrix();
174
175 switch (m_pContext->GetFormType()) {
176 case FormType::kNone:
177 case FormType::kAcroForm:
178 case FormType::kXFAForeground:
179 if (m_pPDFPage)
180 return m_pPDFPage->GetDisplayMatrix(xPos, yPos, xSize, ySize, iRotate);
181 case FormType::kXFAFull:
182 if (m_pXFAPageView)
183 return m_pXFAPageView->GetDisplayMatrix(
184 CFX_Rect(xPos, yPos, xSize, ySize), iRotate);
185 }
186
187 return CFX_Matrix();
188 }
189