diff options
Diffstat (limited to 'fpdfsdk/fpdfxfa/cpdfxfa_document.cpp')
-rw-r--r-- | fpdfsdk/fpdfxfa/cpdfxfa_document.cpp | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_document.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_document.cpp new file mode 100644 index 0000000000..e49cfde8c4 --- /dev/null +++ b/fpdfsdk/fpdfxfa/cpdfxfa_document.cpp @@ -0,0 +1,201 @@ +// 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_document.h" + +#include "core/fpdfapi/parser/cpdf_document.h" +#include "fpdfsdk/cpdfsdk_document.h" +#include "fpdfsdk/cpdfsdk_environment.h" +#include "fpdfsdk/cpdfsdk_interform.h" +#include "fpdfsdk/cpdfsdk_pageview.h" +#include "fpdfsdk/fpdfxfa/cpdfxfa_app.h" +#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h" +#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h" +#include "fpdfsdk/fsdk_define.h" +#include "fpdfsdk/javascript/ijs_runtime.h" +#include "public/fpdf_formfill.h" +#include "xfa/fxfa/cxfa_eventparam.h" +#include "xfa/fxfa/xfa_ffapp.h" +#include "xfa/fxfa/xfa_ffdoc.h" +#include "xfa/fxfa/xfa_ffdocview.h" +#include "xfa/fxfa/xfa_ffpageview.h" +#include "xfa/fxfa/xfa_ffwidgethandler.h" + +#ifndef _WIN32 +extern void SetLastError(int err); +extern int GetLastError(); +#endif + +CPDFXFA_Document::CPDFXFA_Document(std::unique_ptr<CPDF_Document> pPDFDoc, + CPDFXFA_App* pProvider) + : m_iDocType(DOCTYPE_PDF), + m_pPDFDoc(std::move(pPDFDoc)), + m_pXFADocView(nullptr), + m_pApp(pProvider), + m_nLoadStatus(FXFA_LOADSTATUS_PRELOAD), + m_nPageCount(0), + m_DocEnv(this) {} + +CPDFXFA_Document::~CPDFXFA_Document() { + m_nLoadStatus = FXFA_LOADSTATUS_CLOSING; + + if (m_pXFADoc) { + CXFA_FFApp* pApp = m_pApp->GetXFAApp(); + if (pApp) { + CXFA_FFDocHandler* pDocHandler = pApp->GetDocHandler(); + if (pDocHandler) + CloseXFADoc(pDocHandler); + } + m_pXFADoc.reset(); + } + + m_nLoadStatus = FXFA_LOADSTATUS_CLOSED; +} + +FX_BOOL CPDFXFA_Document::LoadXFADoc() { + m_nLoadStatus = FXFA_LOADSTATUS_LOADING; + + if (!m_pPDFDoc) + return FALSE; + + m_XFAPageList.RemoveAll(); + + CXFA_FFApp* pApp = m_pApp->GetXFAApp(); + if (!pApp) + return FALSE; + + m_pXFADoc.reset(pApp->CreateDoc(&m_DocEnv, m_pPDFDoc.get())); + if (!m_pXFADoc) { + SetLastError(FPDF_ERR_XFALOAD); + return FALSE; + } + + CXFA_FFDocHandler* pDocHandler = pApp->GetDocHandler(); + if (!pDocHandler) { + SetLastError(FPDF_ERR_XFALOAD); + return FALSE; + } + + m_pXFADoc->StartLoad(); + int iStatus = m_pXFADoc->DoLoad(nullptr); + if (iStatus != XFA_PARSESTATUS_Done) { + CloseXFADoc(pDocHandler); + SetLastError(FPDF_ERR_XFALOAD); + return FALSE; + } + m_pXFADoc->StopLoad(); + m_pXFADoc->GetXFADoc()->InitScriptContext(m_pApp->GetJSERuntime()); + + if (m_pXFADoc->GetDocType() == XFA_DOCTYPE_Dynamic) + m_iDocType = DOCTYPE_DYNAMIC_XFA; + else + m_iDocType = DOCTYPE_STATIC_XFA; + + m_pXFADocView = m_pXFADoc->CreateDocView(XFA_DOCVIEW_View); + if (m_pXFADocView->StartLayout() < 0) { + CloseXFADoc(pDocHandler); + SetLastError(FPDF_ERR_XFALAYOUT); + return FALSE; + } + + m_pXFADocView->DoLayout(nullptr); + m_pXFADocView->StopLayout(); + m_nLoadStatus = FXFA_LOADSTATUS_LOADED; + + return TRUE; +} + +int CPDFXFA_Document::GetPageCount() const { + if (!m_pPDFDoc && !m_pXFADoc) + return 0; + + switch (m_iDocType) { + case DOCTYPE_PDF: + case DOCTYPE_STATIC_XFA: + if (m_pPDFDoc) + return m_pPDFDoc->GetPageCount(); + case DOCTYPE_DYNAMIC_XFA: + if (m_pXFADoc) + return m_pXFADocView->CountPageViews(); + default: + return 0; + } +} + +CPDFXFA_Page* CPDFXFA_Document::GetXFAPage(int page_index) { + if (page_index < 0) + return nullptr; + + CPDFXFA_Page* pPage = nullptr; + int nCount = m_XFAPageList.GetSize(); + if (nCount > 0 && page_index < nCount) { + pPage = m_XFAPageList.GetAt(page_index); + if (pPage) + pPage->Retain(); + } else { + m_nPageCount = GetPageCount(); + m_XFAPageList.SetSize(m_nPageCount); + } + if (pPage) + return pPage; + + pPage = new CPDFXFA_Page(this, page_index); + if (!pPage->LoadPage()) { + pPage->Release(); + return nullptr; + } + m_XFAPageList.SetAt(page_index, pPage); + return pPage; +} + +CPDFXFA_Page* CPDFXFA_Document::GetXFAPage(CXFA_FFPageView* pPage) const { + if (!pPage) + return nullptr; + + if (!m_pXFADoc) + return nullptr; + + if (m_iDocType != DOCTYPE_DYNAMIC_XFA) + return nullptr; + + int nSize = m_XFAPageList.GetSize(); + for (int i = 0; i < nSize; i++) { + CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i); + if (!pTempPage) + continue; + if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage) + return pTempPage; + } + + return nullptr; +} + +void CPDFXFA_Document::DeletePage(int page_index) { + // Delete from the document first because, if GetPage was never called for + // this |page_index| then |m_XFAPageList| may have size < |page_index| even + // if it's a valid page in the document. + if (m_pPDFDoc) + m_pPDFDoc->DeletePage(page_index); + + if (page_index < 0 || page_index >= m_XFAPageList.GetSize()) + return; + + if (CPDFXFA_Page* pPage = m_XFAPageList.GetAt(page_index)) + pPage->Release(); +} + +void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) { + m_XFAPageList.SetAt(page->GetPageIndex(), nullptr); +} + +void CPDFXFA_Document::SetSDKDoc(std::unique_ptr<CPDFSDK_Document> pSDKDoc) { + m_pSDKDoc.reset(pSDKDoc.release()); +} + +void CPDFXFA_Document::ClearChangeMark() { + if (m_pSDKDoc) + m_pSDKDoc->ClearChangeMark(); +} |