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/include/fsdk_define.h"
      8 #include "fpdfsdk/include/fsdk_mgr.h"
      9 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
     10 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
     11 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h"
     12 
     13 CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index)
     14     : m_pPDFPage(NULL),
     15       m_pXFAPageView(NULL),
     16       m_iPageIndex(page_index),
     17       m_pDocument(pDoc),
     18       m_iRef(1) {}
     19 
     20 CPDFXFA_Page::~CPDFXFA_Page() {
     21   if (m_pPDFPage)
     22     delete m_pPDFPage;
     23   m_pPDFPage = NULL;
     24   m_pXFAPageView = NULL;
     25 }
     26 
     27 void CPDFXFA_Page::Release() {
     28   m_iRef--;
     29   if (m_iRef > 0)
     30     return;
     31 
     32   if (m_pDocument)
     33     m_pDocument->RemovePage(this);
     34 
     35   delete this;
     36 }
     37 
     38 FX_BOOL CPDFXFA_Page::LoadPDFPage() {
     39   if (!m_pDocument)
     40     return FALSE;
     41   CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc();
     42   if (pPDFDoc) {
     43     CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);
     44     if (pDict == NULL)
     45       return FALSE;
     46     if (m_pPDFPage) {
     47       if (m_pPDFPage->m_pFormDict == pDict)
     48         return TRUE;
     49 
     50       delete m_pPDFPage;
     51       m_pPDFPage = NULL;
     52     }
     53 
     54     m_pPDFPage = new CPDF_Page;
     55     m_pPDFPage->Load(pPDFDoc, pDict);
     56     m_pPDFPage->ParseContent();
     57     return TRUE;
     58   }
     59 
     60   return FALSE;
     61 }
     62 
     63 FX_BOOL CPDFXFA_Page::LoadXFAPageView() {
     64   if (!m_pDocument)
     65     return FALSE;
     66   IXFA_Doc* pXFADoc = m_pDocument->GetXFADoc();
     67   if (!pXFADoc)
     68     return FALSE;
     69 
     70   IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView();
     71   if (!pXFADocView)
     72     return FALSE;
     73 
     74   IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);
     75   if (!pPageView)
     76     return FALSE;
     77 
     78   if (m_pXFAPageView == pPageView)
     79     return TRUE;
     80 
     81   m_pXFAPageView = pPageView;
     82   (void)m_pXFAPageView->LoadPageView(nullptr);
     83   return TRUE;
     84 }
     85 
     86 FX_BOOL CPDFXFA_Page::LoadPage() {
     87   if (!m_pDocument || m_iPageIndex < 0)
     88     return FALSE;
     89 
     90   int iDocType = m_pDocument->GetDocType();
     91   switch (iDocType) {
     92     case DOCTYPE_PDF:
     93     case DOCTYPE_STATIC_XFA: {
     94       return LoadPDFPage();
     95     }
     96     case DOCTYPE_DYNAMIC_XFA: {
     97       return LoadXFAPageView();
     98     }
     99     default:
    100       return FALSE;
    101   }
    102 
    103   return FALSE;
    104 }
    105 
    106 FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict) {
    107   if (!m_pDocument || m_iPageIndex < 0 || !pageDict)
    108     return FALSE;
    109 
    110   if (m_pPDFPage)
    111     delete m_pPDFPage;
    112 
    113   m_pPDFPage = new CPDF_Page();
    114   m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict);
    115   m_pPDFPage->ParseContent();
    116 
    117   return TRUE;
    118 }
    119 
    120 FX_FLOAT CPDFXFA_Page::GetPageWidth() {
    121   ASSERT(m_pDocument != NULL);
    122 
    123   if (!m_pPDFPage && !m_pXFAPageView)
    124     return 0.0f;
    125 
    126   int nDocType = m_pDocument->GetDocType();
    127   switch (nDocType) {
    128     case DOCTYPE_DYNAMIC_XFA: {
    129       if (m_pXFAPageView) {
    130         CFX_RectF rect;
    131         m_pXFAPageView->GetPageViewRect(rect);
    132         return rect.width;
    133       }
    134     } break;
    135     case DOCTYPE_STATIC_XFA:
    136     case DOCTYPE_PDF: {
    137       if (m_pPDFPage)
    138         return m_pPDFPage->GetPageWidth();
    139     } break;
    140     default:
    141       return 0.0f;
    142   }
    143 
    144   return 0.0f;
    145 }
    146 
    147 FX_FLOAT CPDFXFA_Page::GetPageHeight() {
    148   ASSERT(m_pDocument != NULL);
    149 
    150   if (!m_pPDFPage && !m_pXFAPageView)
    151     return 0.0f;
    152 
    153   int nDocType = m_pDocument->GetDocType();
    154   switch (nDocType) {
    155     case DOCTYPE_PDF:
    156     case DOCTYPE_STATIC_XFA: {
    157       if (m_pPDFPage)
    158         return m_pPDFPage->GetPageHeight();
    159     } break;
    160     case DOCTYPE_DYNAMIC_XFA: {
    161       if (m_pXFAPageView) {
    162         CFX_RectF rect;
    163         m_pXFAPageView->GetPageViewRect(rect);
    164         return rect.height;
    165       }
    166     } break;
    167     default:
    168       return 0.0f;
    169   }
    170 
    171   return 0.0f;
    172 }
    173 
    174 void CPDFXFA_Page::DeviceToPage(int start_x,
    175                                 int start_y,
    176                                 int size_x,
    177                                 int size_y,
    178                                 int rotate,
    179                                 int device_x,
    180                                 int device_y,
    181                                 double* page_x,
    182                                 double* page_y) {
    183   ASSERT(m_pDocument != NULL);
    184 
    185   if (!m_pPDFPage && !m_pXFAPageView)
    186     return;
    187 
    188   CFX_Matrix page2device;
    189   CFX_Matrix device2page;
    190   FX_FLOAT page_x_f, page_y_f;
    191 
    192   GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
    193 
    194   device2page.SetReverse(page2device);
    195   device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f,
    196                         page_y_f);
    197 
    198   *page_x = (page_x_f);
    199   *page_y = (page_y_f);
    200 }
    201 
    202 void CPDFXFA_Page::PageToDevice(int start_x,
    203                                 int start_y,
    204                                 int size_x,
    205                                 int size_y,
    206                                 int rotate,
    207                                 double page_x,
    208                                 double page_y,
    209                                 int* device_x,
    210                                 int* device_y) {
    211   if (!m_pPDFPage && !m_pXFAPageView)
    212     return;
    213 
    214   CFX_Matrix page2device;
    215   FX_FLOAT device_x_f, device_y_f;
    216 
    217   GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
    218 
    219   page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f,
    220                         device_y_f);
    221 
    222   *device_x = FXSYS_round(device_x_f);
    223   *device_y = FXSYS_round(device_y_f);
    224 }
    225 
    226 void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix,
    227                                     int xPos,
    228                                     int yPos,
    229                                     int xSize,
    230                                     int ySize,
    231                                     int iRotate) const {
    232   ASSERT(m_pDocument != NULL);
    233 
    234   if (!m_pPDFPage && !m_pXFAPageView)
    235     return;
    236 
    237   int nDocType = m_pDocument->GetDocType();
    238   switch (nDocType) {
    239     case DOCTYPE_DYNAMIC_XFA: {
    240       if (m_pXFAPageView) {
    241         CFX_Rect rect;
    242         rect.Set(xPos, yPos, xSize, ySize);
    243         m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate);
    244       }
    245     } break;
    246     case DOCTYPE_PDF:
    247     case DOCTYPE_STATIC_XFA: {
    248       if (m_pPDFPage) {
    249         m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate);
    250       }
    251     } break;
    252     default:
    253       return;
    254   }
    255 }
    256