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/xfa_ffdocview.h"
     17 #include "xfa/fxfa/xfa_ffpageview.h"
     18 
     19 CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Context* pContext, int page_index)
     20     : m_pXFAPageView(nullptr),
     21       m_pContext(pContext),
     22       m_iPageIndex(page_index),
     23       m_iRef(1) {}
     24 
     25 CPDFXFA_Page::~CPDFXFA_Page() {
     26   if (m_pContext)
     27     m_pContext->RemovePage(this);
     28 }
     29 
     30 bool CPDFXFA_Page::LoadPDFPage() {
     31   if (!m_pContext)
     32     return false;
     33 
     34   CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc();
     35   if (!pPDFDoc)
     36     return false;
     37 
     38   CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);
     39   if (!pDict)
     40     return false;
     41 
     42   if (!m_pPDFPage || m_pPDFPage->m_pFormDict != pDict) {
     43     m_pPDFPage = pdfium::MakeUnique<CPDF_Page>(pPDFDoc, pDict, true);
     44     m_pPDFPage->ParseContent();
     45   }
     46   return true;
     47 }
     48 
     49 bool CPDFXFA_Page::LoadXFAPageView() {
     50   if (!m_pContext)
     51     return false;
     52 
     53   CXFA_FFDoc* pXFADoc = m_pContext->GetXFADoc();
     54   if (!pXFADoc)
     55     return false;
     56 
     57   CXFA_FFDocView* pXFADocView = m_pContext->GetXFADocView();
     58   if (!pXFADocView)
     59     return false;
     60 
     61   CXFA_FFPageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);
     62   if (!pPageView)
     63     return false;
     64 
     65   m_pXFAPageView = pPageView;
     66   return true;
     67 }
     68 
     69 bool CPDFXFA_Page::LoadPage() {
     70   if (!m_pContext || m_iPageIndex < 0)
     71     return false;
     72 
     73   int iDocType = m_pContext->GetDocType();
     74   switch (iDocType) {
     75     case DOCTYPE_PDF:
     76     case DOCTYPE_STATIC_XFA: {
     77       return LoadPDFPage();
     78     }
     79     case DOCTYPE_DYNAMIC_XFA: {
     80       return LoadXFAPageView();
     81     }
     82     default:
     83       return false;
     84   }
     85 }
     86 
     87 bool CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) {
     88   if (!m_pContext || m_iPageIndex < 0 || !pageDict)
     89     return false;
     90 
     91   m_pPDFPage =
     92       pdfium::MakeUnique<CPDF_Page>(m_pContext->GetPDFDoc(), pageDict, true);
     93   m_pPDFPage->ParseContent();
     94   return true;
     95 }
     96 
     97 FX_FLOAT CPDFXFA_Page::GetPageWidth() const {
     98   if (!m_pPDFPage && !m_pXFAPageView)
     99     return 0.0f;
    100 
    101   int nDocType = m_pContext->GetDocType();
    102   switch (nDocType) {
    103     case DOCTYPE_DYNAMIC_XFA: {
    104       if (m_pXFAPageView)
    105         return m_pXFAPageView->GetPageViewRect().width;
    106       break;
    107     }
    108     case DOCTYPE_STATIC_XFA:
    109     case DOCTYPE_PDF: {
    110       if (m_pPDFPage)
    111         return m_pPDFPage->GetPageWidth();
    112       break;
    113     }
    114     default:
    115       return 0.0f;
    116   }
    117 
    118   return 0.0f;
    119 }
    120 
    121 FX_FLOAT CPDFXFA_Page::GetPageHeight() const {
    122   if (!m_pPDFPage && !m_pXFAPageView)
    123     return 0.0f;
    124 
    125   int nDocType = m_pContext->GetDocType();
    126   switch (nDocType) {
    127     case DOCTYPE_PDF:
    128     case DOCTYPE_STATIC_XFA: {
    129       if (m_pPDFPage)
    130         return m_pPDFPage->GetPageHeight();
    131       break;
    132     }
    133     case DOCTYPE_DYNAMIC_XFA: {
    134       if (m_pXFAPageView)
    135         return m_pXFAPageView->GetPageViewRect().height;
    136       break;
    137     }
    138     default:
    139       return 0.0f;
    140   }
    141 
    142   return 0.0f;
    143 }
    144 
    145 void CPDFXFA_Page::DeviceToPage(int start_x,
    146                                 int start_y,
    147                                 int size_x,
    148                                 int size_y,
    149                                 int rotate,
    150                                 int device_x,
    151                                 int device_y,
    152                                 double* page_x,
    153                                 double* page_y) {
    154   if (!m_pPDFPage && !m_pXFAPageView)
    155     return;
    156 
    157   CFX_Matrix device2page;
    158   device2page.SetReverse(
    159       GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate));
    160 
    161   CFX_PointF pos = device2page.Transform(CFX_PointF(
    162       static_cast<FX_FLOAT>(device_x), static_cast<FX_FLOAT>(device_y)));
    163 
    164   *page_x = pos.x;
    165   *page_y = pos.y;
    166 }
    167 
    168 void CPDFXFA_Page::PageToDevice(int start_x,
    169                                 int start_y,
    170                                 int size_x,
    171                                 int size_y,
    172                                 int rotate,
    173                                 double page_x,
    174                                 double page_y,
    175                                 int* device_x,
    176                                 int* device_y) {
    177   if (!m_pPDFPage && !m_pXFAPageView)
    178     return;
    179 
    180   CFX_Matrix page2device =
    181       GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate);
    182 
    183   CFX_PointF pos = page2device.Transform(
    184       CFX_PointF(static_cast<FX_FLOAT>(page_x), static_cast<FX_FLOAT>(page_y)));
    185 
    186   *device_x = FXSYS_round(pos.x);
    187   *device_y = FXSYS_round(pos.y);
    188 }
    189 
    190 CFX_Matrix CPDFXFA_Page::GetDisplayMatrix(int xPos,
    191                                           int yPos,
    192                                           int xSize,
    193                                           int ySize,
    194                                           int iRotate) const {
    195   if (!m_pPDFPage && !m_pXFAPageView)
    196     return CFX_Matrix();
    197 
    198   int nDocType = m_pContext->GetDocType();
    199   switch (nDocType) {
    200     case DOCTYPE_DYNAMIC_XFA: {
    201       if (m_pXFAPageView) {
    202         return m_pXFAPageView->GetDisplayMatrix(
    203             CFX_Rect(xPos, yPos, xSize, ySize), iRotate);
    204       }
    205       break;
    206     }
    207     case DOCTYPE_PDF:
    208     case DOCTYPE_STATIC_XFA: {
    209       if (m_pPDFPage)
    210         return m_pPDFPage->GetDisplayMatrix(xPos, yPos, xSize, ySize, iRotate);
    211       break;
    212     }
    213     default:
    214       return CFX_Matrix();
    215   }
    216   return CFX_Matrix();
    217 }
    218