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 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 25 CPDFXFA_Page::~CPDFXFA_Page() { 26 if (m_pContext) 27 m_pContext->RemovePage(this); 28 } 29 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 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 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 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 97 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 121 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 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 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 190 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