• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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