blob: 87e003e1473e3733273c55fe02f4976a1ec441e3 [file] [log] [blame]
// 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();
}