Home | History | Annotate | Download | only in fpdfxfa
      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