// Copyright 2014 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h" #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" #include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" #include "fpdfsdk/include/fsdk_define.h" #include "fpdfsdk/include/fsdk_mgr.h" CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index) : m_pPDFPage(NULL), m_pXFAPageView(NULL), m_iPageIndex(page_index), m_pDocument(pDoc), m_iRef(1) {} CPDFXFA_Page::~CPDFXFA_Page() { if (m_pPDFPage) delete m_pPDFPage; m_pPDFPage = NULL; m_pXFAPageView = NULL; } void CPDFXFA_Page::Release() { m_iRef--; if (m_iRef > 0) return; if (m_pDocument) m_pDocument->RemovePage(this); delete this; } FX_BOOL CPDFXFA_Page::LoadPDFPage() { if (!m_pDocument) return FALSE; CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc(); if (pPDFDoc) { CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex); if (pDict == NULL) return FALSE; if (m_pPDFPage) { if (m_pPDFPage->m_pFormDict == pDict) return TRUE; delete m_pPDFPage; m_pPDFPage = NULL; } m_pPDFPage = new CPDF_Page; m_pPDFPage->Load(pPDFDoc, pDict); m_pPDFPage->ParseContent(nullptr); return TRUE; } return FALSE; } FX_BOOL CPDFXFA_Page::LoadXFAPageView() { if (!m_pDocument) return FALSE; IXFA_Doc* pXFADoc = m_pDocument->GetXFADoc(); if (!pXFADoc) return FALSE; IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView(); if (!pXFADocView) return FALSE; IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex); if (!pPageView) return FALSE; if (m_pXFAPageView == pPageView) return TRUE; m_pXFAPageView = pPageView; (void)m_pXFAPageView->LoadPageView(nullptr); return TRUE; } FX_BOOL CPDFXFA_Page::LoadPage() { if (!m_pDocument || m_iPageIndex < 0) return FALSE; int iDocType = m_pDocument->GetDocType(); switch (iDocType) { case DOCTYPE_PDF: case DOCTYPE_STATIC_XFA: { return LoadPDFPage(); } case DOCTYPE_DYNAMIC_XFA: { return LoadXFAPageView(); } default: return FALSE; } return FALSE; } FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) { if (!m_pDocument || m_iPageIndex < 0 || !pageDict) return FALSE; if (m_pPDFPage) delete m_pPDFPage; m_pPDFPage = new CPDF_Page(); m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict); m_pPDFPage->ParseContent(nullptr); return TRUE; } FX_FLOAT CPDFXFA_Page::GetPageWidth() { if (!m_pPDFPage && !m_pXFAPageView) return 0.0f; int nDocType = m_pDocument->GetDocType(); switch (nDocType) { case DOCTYPE_DYNAMIC_XFA: { if (m_pXFAPageView) { CFX_RectF rect; m_pXFAPageView->GetPageViewRect(rect); return rect.width; } } break; case DOCTYPE_STATIC_XFA: case DOCTYPE_PDF: { if (m_pPDFPage) return m_pPDFPage->GetPageWidth(); } break; default: return 0.0f; } return 0.0f; } FX_FLOAT CPDFXFA_Page::GetPageHeight() { if (!m_pPDFPage && !m_pXFAPageView) return 0.0f; int nDocType = m_pDocument->GetDocType(); switch (nDocType) { case DOCTYPE_PDF: case DOCTYPE_STATIC_XFA: { if (m_pPDFPage) return m_pPDFPage->GetPageHeight(); } break; case DOCTYPE_DYNAMIC_XFA: { if (m_pXFAPageView) { CFX_RectF rect; m_pXFAPageView->GetPageViewRect(rect); return rect.height; } } break; default: return 0.0f; } return 0.0f; } void CPDFXFA_Page::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) { if (!m_pPDFPage && !m_pXFAPageView) return; CFX_Matrix page2device; CFX_Matrix device2page; FX_FLOAT page_x_f, page_y_f; GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); device2page.SetReverse(page2device); device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, page_y_f); *page_x = (page_x_f); *page_y = (page_y_f); } void CPDFXFA_Page::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) { if (!m_pPDFPage && !m_pXFAPageView) return; CFX_Matrix page2device; FX_FLOAT device_x_f, device_y_f; GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, device_y_f); *device_x = FXSYS_round(device_x_f); *device_y = FXSYS_round(device_y_f); } void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix, int xPos, int yPos, int xSize, int ySize, int iRotate) const { if (!m_pPDFPage && !m_pXFAPageView) return; int nDocType = m_pDocument->GetDocType(); switch (nDocType) { case DOCTYPE_DYNAMIC_XFA: { if (m_pXFAPageView) { CFX_Rect rect; rect.Set(xPos, yPos, xSize, ySize); m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate); } } break; case DOCTYPE_PDF: case DOCTYPE_STATIC_XFA: { if (m_pPDFPage) { m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate); } } break; default: return; } }