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/include/fsdk_define.h" 8 #include "fpdfsdk/include/fsdk_mgr.h" 9 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" 10 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" 11 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h" 12 13 CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index) 14 : m_pPDFPage(NULL), 15 m_pXFAPageView(NULL), 16 m_iPageIndex(page_index), 17 m_pDocument(pDoc), 18 m_iRef(1) {} 19 20 CPDFXFA_Page::~CPDFXFA_Page() { 21 if (m_pPDFPage) 22 delete m_pPDFPage; 23 m_pPDFPage = NULL; 24 m_pXFAPageView = NULL; 25 } 26 27 void CPDFXFA_Page::Release() { 28 m_iRef--; 29 if (m_iRef > 0) 30 return; 31 32 if (m_pDocument) 33 m_pDocument->RemovePage(this); 34 35 delete this; 36 } 37 38 FX_BOOL CPDFXFA_Page::LoadPDFPage() { 39 if (!m_pDocument) 40 return FALSE; 41 CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc(); 42 if (pPDFDoc) { 43 CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex); 44 if (pDict == NULL) 45 return FALSE; 46 if (m_pPDFPage) { 47 if (m_pPDFPage->m_pFormDict == pDict) 48 return TRUE; 49 50 delete m_pPDFPage; 51 m_pPDFPage = NULL; 52 } 53 54 m_pPDFPage = new CPDF_Page; 55 m_pPDFPage->Load(pPDFDoc, pDict); 56 m_pPDFPage->ParseContent(); 57 return TRUE; 58 } 59 60 return FALSE; 61 } 62 63 FX_BOOL CPDFXFA_Page::LoadXFAPageView() { 64 if (!m_pDocument) 65 return FALSE; 66 IXFA_Doc* pXFADoc = m_pDocument->GetXFADoc(); 67 if (!pXFADoc) 68 return FALSE; 69 70 IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView(); 71 if (!pXFADocView) 72 return FALSE; 73 74 IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex); 75 if (!pPageView) 76 return FALSE; 77 78 if (m_pXFAPageView == pPageView) 79 return TRUE; 80 81 m_pXFAPageView = pPageView; 82 (void)m_pXFAPageView->LoadPageView(nullptr); 83 return TRUE; 84 } 85 86 FX_BOOL CPDFXFA_Page::LoadPage() { 87 if (!m_pDocument || m_iPageIndex < 0) 88 return FALSE; 89 90 int iDocType = m_pDocument->GetDocType(); 91 switch (iDocType) { 92 case DOCTYPE_PDF: 93 case DOCTYPE_STATIC_XFA: { 94 return LoadPDFPage(); 95 } 96 case DOCTYPE_DYNAMIC_XFA: { 97 return LoadXFAPageView(); 98 } 99 default: 100 return FALSE; 101 } 102 103 return FALSE; 104 } 105 106 FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) { 107 if (!m_pDocument || m_iPageIndex < 0 || !pageDict) 108 return FALSE; 109 110 if (m_pPDFPage) 111 delete m_pPDFPage; 112 113 m_pPDFPage = new CPDF_Page(); 114 m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict); 115 m_pPDFPage->ParseContent(); 116 117 return TRUE; 118 } 119 120 FX_FLOAT CPDFXFA_Page::GetPageWidth() { 121 ASSERT(m_pDocument != NULL); 122 123 if (!m_pPDFPage && !m_pXFAPageView) 124 return 0.0f; 125 126 int nDocType = m_pDocument->GetDocType(); 127 switch (nDocType) { 128 case DOCTYPE_DYNAMIC_XFA: { 129 if (m_pXFAPageView) { 130 CFX_RectF rect; 131 m_pXFAPageView->GetPageViewRect(rect); 132 return rect.width; 133 } 134 } break; 135 case DOCTYPE_STATIC_XFA: 136 case DOCTYPE_PDF: { 137 if (m_pPDFPage) 138 return m_pPDFPage->GetPageWidth(); 139 } break; 140 default: 141 return 0.0f; 142 } 143 144 return 0.0f; 145 } 146 147 FX_FLOAT CPDFXFA_Page::GetPageHeight() { 148 ASSERT(m_pDocument != NULL); 149 150 if (!m_pPDFPage && !m_pXFAPageView) 151 return 0.0f; 152 153 int nDocType = m_pDocument->GetDocType(); 154 switch (nDocType) { 155 case DOCTYPE_PDF: 156 case DOCTYPE_STATIC_XFA: { 157 if (m_pPDFPage) 158 return m_pPDFPage->GetPageHeight(); 159 } break; 160 case DOCTYPE_DYNAMIC_XFA: { 161 if (m_pXFAPageView) { 162 CFX_RectF rect; 163 m_pXFAPageView->GetPageViewRect(rect); 164 return rect.height; 165 } 166 } break; 167 default: 168 return 0.0f; 169 } 170 171 return 0.0f; 172 } 173 174 void CPDFXFA_Page::DeviceToPage(int start_x, 175 int start_y, 176 int size_x, 177 int size_y, 178 int rotate, 179 int device_x, 180 int device_y, 181 double* page_x, 182 double* page_y) { 183 ASSERT(m_pDocument != NULL); 184 185 if (!m_pPDFPage && !m_pXFAPageView) 186 return; 187 188 CFX_Matrix page2device; 189 CFX_Matrix device2page; 190 FX_FLOAT page_x_f, page_y_f; 191 192 GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); 193 194 device2page.SetReverse(page2device); 195 device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, 196 page_y_f); 197 198 *page_x = (page_x_f); 199 *page_y = (page_y_f); 200 } 201 202 void CPDFXFA_Page::PageToDevice(int start_x, 203 int start_y, 204 int size_x, 205 int size_y, 206 int rotate, 207 double page_x, 208 double page_y, 209 int* device_x, 210 int* device_y) { 211 if (!m_pPDFPage && !m_pXFAPageView) 212 return; 213 214 CFX_Matrix page2device; 215 FX_FLOAT device_x_f, device_y_f; 216 217 GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); 218 219 page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, 220 device_y_f); 221 222 *device_x = FXSYS_round(device_x_f); 223 *device_y = FXSYS_round(device_y_f); 224 } 225 226 void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix, 227 int xPos, 228 int yPos, 229 int xSize, 230 int ySize, 231 int iRotate) const { 232 ASSERT(m_pDocument != NULL); 233 234 if (!m_pPDFPage && !m_pXFAPageView) 235 return; 236 237 int nDocType = m_pDocument->GetDocType(); 238 switch (nDocType) { 239 case DOCTYPE_DYNAMIC_XFA: { 240 if (m_pXFAPageView) { 241 CFX_Rect rect; 242 rect.Set(xPos, yPos, xSize, ySize); 243 m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate); 244 } 245 } break; 246 case DOCTYPE_PDF: 247 case DOCTYPE_STATIC_XFA: { 248 if (m_pPDFPage) { 249 m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate); 250 } 251 } break; 252 default: 253 return; 254 } 255 } 256