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 19 CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Context* pContext, int page_index) 20 : m_pXFAPageView(nullptr), m_pContext(pContext), m_iPageIndex(page_index) {} 21 22 CPDFXFA_Page::~CPDFXFA_Page() {} 23 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 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 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 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 88 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 106 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 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 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 167 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