| // 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/fpdfxfa/cpdfxfa_page.h" | |
| #include "core/fpdfapi/page/cpdf_page.h" | |
| #include "core/fpdfapi/parser/cpdf_document.h" | |
| #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h" | |
| #include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h" | |
| #include "fpdfsdk/fsdk_define.h" | |
| #include "public/fpdf_formfill.h" | |
| #include "third_party/base/ptr_util.h" | |
| #include "xfa/fxfa/cxfa_ffdocview.h" | |
| #include "xfa/fxfa/cxfa_ffpageview.h" | |
| CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Context* pContext, int page_index) | |
| : m_pXFAPageView(nullptr), m_pContext(pContext), m_iPageIndex(page_index) {} | |
| CPDFXFA_Page::~CPDFXFA_Page() {} | |
| bool CPDFXFA_Page::LoadPDFPage() { | |
| if (!m_pContext) | |
| return false; | |
| CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc(); | |
| if (!pPDFDoc) | |
| return false; | |
| CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex); | |
| if (!pDict) | |
| return false; | |
| if (!m_pPDFPage || m_pPDFPage->m_pFormDict != pDict) { | |
| m_pPDFPage = pdfium::MakeUnique<CPDF_Page>(pPDFDoc, pDict, true); | |
| m_pPDFPage->ParseContent(); | |
| } | |
| return true; | |
| } | |
| bool CPDFXFA_Page::LoadXFAPageView() { | |
| if (!m_pContext) | |
| return false; | |
| CXFA_FFDoc* pXFADoc = m_pContext->GetXFADoc(); | |
| if (!pXFADoc) | |
| return false; | |
| CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView(); | |
| if (!pXFADocView) | |
| return false; | |
| CXFA_FFPageView* pPageView = pXFADocView->GetPageView(m_iPageIndex); | |
| if (!pPageView) | |
| return false; | |
| m_pXFAPageView = pPageView; | |
| return true; | |
| } | |
| bool CPDFXFA_Page::LoadPage() { | |
| if (!m_pContext || m_iPageIndex < 0) | |
| return false; | |
| switch (m_pContext->GetDocType()) { | |
| case XFA_DocType::PDF: | |
| case XFA_DocType::Static: | |
| return LoadPDFPage(); | |
| case XFA_DocType::Dynamic: | |
| return LoadXFAPageView(); | |
| default: | |
| return false; | |
| } | |
| } | |
| bool CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) { | |
| if (!m_pContext || m_iPageIndex < 0 || !pageDict) | |
| return false; | |
| m_pPDFPage = | |
| pdfium::MakeUnique<CPDF_Page>(m_pContext->GetPDFDoc(), pageDict, true); | |
| m_pPDFPage->ParseContent(); | |
| return true; | |
| } | |
| float CPDFXFA_Page::GetPageWidth() const { | |
| if (!m_pPDFPage && !m_pXFAPageView) | |
| return 0.0f; | |
| switch (m_pContext->GetDocType()) { | |
| case XFA_DocType::Dynamic: { | |
| if (m_pXFAPageView) | |
| return m_pXFAPageView->GetPageViewRect().width; | |
| break; | |
| } | |
| case XFA_DocType::Static: | |
| case XFA_DocType::PDF: { | |
| if (m_pPDFPage) | |
| return m_pPDFPage->GetPageWidth(); | |
| break; | |
| } | |
| default: | |
| return 0.0f; | |
| } | |
| return 0.0f; | |
| } | |
| float CPDFXFA_Page::GetPageHeight() const { | |
| if (!m_pPDFPage && !m_pXFAPageView) | |
| return 0.0f; | |
| switch (m_pContext->GetDocType()) { | |
| case XFA_DocType::PDF: | |
| case XFA_DocType::Static: { | |
| if (m_pPDFPage) | |
| return m_pPDFPage->GetPageHeight(); | |
| break; | |
| } | |
| case XFA_DocType::Dynamic: { | |
| if (m_pXFAPageView) | |
| return m_pXFAPageView->GetPageViewRect().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_PointF pos = GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate) | |
| .GetInverse() | |
| .Transform(CFX_PointF(static_cast<float>(device_x), | |
| static_cast<float>(device_y))); | |
| *page_x = pos.x; | |
| *page_y = pos.y; | |
| } | |
| 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 = | |
| GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate); | |
| CFX_PointF pos = page2device.Transform( | |
| CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y))); | |
| *device_x = FXSYS_round(pos.x); | |
| *device_y = FXSYS_round(pos.y); | |
| } | |
| CFX_Matrix CPDFXFA_Page::GetDisplayMatrix(int xPos, | |
| int yPos, | |
| int xSize, | |
| int ySize, | |
| int iRotate) const { | |
| if (!m_pPDFPage && !m_pXFAPageView) | |
| return CFX_Matrix(); | |
| switch (m_pContext->GetDocType()) { | |
| case XFA_DocType::Dynamic: { | |
| if (m_pXFAPageView) { | |
| return m_pXFAPageView->GetDisplayMatrix( | |
| CFX_Rect(xPos, yPos, xSize, ySize), iRotate); | |
| } | |
| break; | |
| } | |
| case XFA_DocType::PDF: | |
| case XFA_DocType::Static: { | |
| if (m_pPDFPage) | |
| return m_pPDFPage->GetDisplayMatrix(xPos, yPos, xSize, ySize, iRotate); | |
| break; | |
| } | |
| default: | |
| return CFX_Matrix(); | |
| } | |
| return CFX_Matrix(); | |
| } |