diff options
Diffstat (limited to 'fpdfsdk/src/fpdfview.cpp')
-rw-r--r-- | fpdfsdk/src/fpdfview.cpp | 297 |
1 files changed, 288 insertions, 9 deletions
diff --git a/fpdfsdk/src/fpdfview.cpp b/fpdfsdk/src/fpdfview.cpp index c1feb51434..418d35d720 100644 --- a/fpdfsdk/src/fpdfview.cpp +++ b/fpdfsdk/src/fpdfview.cpp @@ -18,6 +18,15 @@ #include "public/fpdf_progressive.h" #include "third_party/base/numerics/safe_conversions_impl.h" +#ifdef PDF_ENABLE_XFA +#include "core/include/fpdfapi/fpdf_module.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_page.h" +#include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h" +#include "public/fpdf_formfill.h" +#endif // PDF_ENABLE_XFA + UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc) { return static_cast<UnderlyingDocumentType*>(doc); } @@ -31,21 +40,147 @@ UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page) { } CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc) { +#ifdef PDF_ENABLE_XFA + return doc ? UnderlyingFromFPDFDocument(doc)->GetPDFDoc() : nullptr; +#else // PDF_ENABLE_XFA return UnderlyingFromFPDFDocument(doc); +#endif // PDF_ENABLE_XFA } FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc) { +#ifdef PDF_ENABLE_XFA + return doc ? FPDFDocumentFromUnderlying( + new CPDFXFA_Document(doc, CPDFXFA_App::GetInstance())) + : nullptr; +#else // PDF_ENABLE_XFA return FPDFDocumentFromUnderlying(doc); +#endif // PDF_ENABLE_XFA } CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) { +#ifdef PDF_ENABLE_XFA + return page ? UnderlyingFromFPDFPage(page)->GetPDFPage() : nullptr; +#else // PDF_ENABLE_XFA return UnderlyingFromFPDFPage(page); +#endif // PDF_ENABLE_XFA +} + +#ifdef PDF_ENABLE_XFA +CFPDF_FileStream::CFPDF_FileStream(FPDF_FILEHANDLER* pFS) { + m_pFS = pFS; + m_nCurPos = 0; +} + +IFX_FileStream* CFPDF_FileStream::Retain() { + return this; +} + +void CFPDF_FileStream::Release() { + if (m_pFS && m_pFS->Release) + m_pFS->Release(m_pFS->clientData); + delete this; +} + +FX_FILESIZE CFPDF_FileStream::GetSize() { + if (m_pFS && m_pFS->GetSize) + return (FX_FILESIZE)m_pFS->GetSize(m_pFS->clientData); + return 0; +} + +FX_BOOL CFPDF_FileStream::IsEOF() { + return m_nCurPos >= GetSize(); +} + +FX_BOOL CFPDF_FileStream::ReadBlock(void* buffer, + FX_FILESIZE offset, + size_t size) { + if (!buffer || !size || !m_pFS->ReadBlock) + return FALSE; + + if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer, + (FPDF_DWORD)size) == 0) { + m_nCurPos = offset + size; + return TRUE; + } + return FALSE; +} + +size_t CFPDF_FileStream::ReadBlock(void* buffer, size_t size) { + if (!buffer || !size || !m_pFS->ReadBlock) + return 0; + + FX_FILESIZE nSize = GetSize(); + if (m_nCurPos >= nSize) + return 0; + FX_FILESIZE dwAvail = nSize - m_nCurPos; + if (dwAvail < (FX_FILESIZE)size) + size = (size_t)dwAvail; + if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer, + (FPDF_DWORD)size) == 0) { + m_nCurPos += size; + return size; + } + + return 0; +} + +FX_BOOL CFPDF_FileStream::WriteBlock(const void* buffer, + FX_FILESIZE offset, + size_t size) { + if (!m_pFS || !m_pFS->WriteBlock) + return FALSE; + + if (m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer, + (FPDF_DWORD)size) == 0) { + m_nCurPos = offset + size; + return TRUE; + } + return FALSE; } +FX_BOOL CFPDF_FileStream::Flush() { + if (!m_pFS || !m_pFS->Flush) + return TRUE; + + return m_pFS->Flush(m_pFS->clientData) == 0; +} +#endif // PDF_ENABLE_XFA + CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess) { m_FileAccess = *pFileAccess; +#ifdef PDF_ENABLE_XFA + m_BufferOffset = (FX_DWORD)-1; +#endif // PDF_ENABLE_XFA } +#ifdef PDF_ENABLE_XFA +FX_BOOL CPDF_CustomAccess::GetByte(FX_DWORD pos, uint8_t& ch) { + if (pos >= m_FileAccess.m_FileLen) + return FALSE; + if (m_BufferOffset == (FX_DWORD)-1 || pos < m_BufferOffset || + pos >= m_BufferOffset + 512) { + // Need to read from file access + m_BufferOffset = pos; + int size = 512; + if (pos + 512 > m_FileAccess.m_FileLen) + size = m_FileAccess.m_FileLen - pos; + if (!m_FileAccess.m_GetBlock(m_FileAccess.m_Param, m_BufferOffset, m_Buffer, + size)) + return FALSE; + } + ch = m_Buffer[pos - m_BufferOffset]; + return TRUE; +} + +FX_BOOL CPDF_CustomAccess::GetBlock(FX_DWORD pos, + uint8_t* pBuf, + FX_DWORD size) { + if (pos + size > m_FileAccess.m_FileLen) + return FALSE; + return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, pos, pBuf, size); +} +#endif // PDF_ENABLE_XFA + FX_BOOL CPDF_CustomAccess::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) { @@ -105,15 +240,25 @@ DLLEXPORT void STDCALL FPDF_InitLibraryWithConfig( pModuleMgr->SetCodecModule(g_pCodecModule); pModuleMgr->InitPageModule(); pModuleMgr->InitRenderModule(); +#ifdef PDF_ENABLE_XFA + CPDFXFA_App::GetInstance()->Initialize( + (cfg && cfg->version >= 2) + ? reinterpret_cast<FXJSE_HRUNTIME>(cfg->m_pIsolate) + : nullptr); +#else // PDF_ENABLE_XFA pModuleMgr->LoadEmbeddedGB1CMaps(); pModuleMgr->LoadEmbeddedJapan1CMaps(); pModuleMgr->LoadEmbeddedCNS1CMaps(); pModuleMgr->LoadEmbeddedKorea1CMaps(); +#endif // PDF_ENABLE_XFA if (cfg && cfg->version >= 2) IJS_Runtime::Initialize(cfg->m_v8EmbedderSlot, cfg->m_pIsolate); } DLLEXPORT void STDCALL FPDF_DestroyLibrary() { +#ifdef PDF_ENABLE_XFA + CPDFXFA_App::ReleaseInstance(); +#endif // PDF_ENABLE_XFA CPDF_ModuleMgr::Destroy(); CFX_GEModule::Destroy(); @@ -130,7 +275,7 @@ void SetLastError(int err) { int GetLastError() { return g_LastError; } -#endif +#endif // _WIN32 void ProcessParseError(CPDF_Parser::Error err) { FX_DWORD err_code; @@ -178,8 +323,55 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path, ProcessParseError(error); return NULL; } +#ifdef PDF_ENABLE_XFA + CPDF_Document* pPDFDoc = pParser->GetDocument(); + if (!pPDFDoc) + return NULL; + + CPDFXFA_App* pProvider = CPDFXFA_App::GetInstance(); + return new CPDFXFA_Document(pPDFDoc, pProvider); +#else // PDF_ENABLE_XFA return pParser->GetDocument(); +#endif // PDF_ENABLE_XFA +} + +#ifdef PDF_ENABLE_XFA +DLLEXPORT FPDF_BOOL STDCALL FPDF_HasXFAField(FPDF_DOCUMENT document, + int* docType) { + if (!document) + return FALSE; + + CPDF_Document* pdfDoc = + (static_cast<CPDFXFA_Document*>(document))->GetPDFDoc(); + if (!pdfDoc) + return FALSE; + + CPDF_Dictionary* pRoot = pdfDoc->GetRoot(); + if (!pRoot) + return FALSE; + + CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm"); + if (!pAcroForm) + return FALSE; + + CPDF_Object* pXFA = pAcroForm->GetElement("XFA"); + if (!pXFA) + return FALSE; + + FX_BOOL bDynamicXFA = pRoot->GetBooleanBy("NeedsRendering", FALSE); + + if (bDynamicXFA) + *docType = DOCTYPE_DYNAMIC_XFA; + else + *docType = DOCTYPE_STATIC_XFA; + + return TRUE; +} + +DLLEXPORT FPDF_BOOL STDCALL FPDF_LoadXFA(FPDF_DOCUMENT document) { + return document && (static_cast<CPDFXFA_Document*>(document))->LoadXFADoc(); } +#endif // PDF_ENABLE_XFA class CMemFile final : public IFX_FileRead { public: @@ -267,7 +459,11 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc, DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) +#ifndef PDF_ENABLE_XFA return 0; +#else // PDF_ENABLE_XFA + return (FX_DWORD)-1; +#endif // PDF_ENABLE_XFA CPDF_Dictionary* pDict = pDoc->GetParser()->GetEncryptDict(); return pDict ? pDict->GetIntegerBy("P") : (FX_DWORD)-1; @@ -296,6 +492,9 @@ DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document, if (page_index < 0 || page_index >= pDoc->GetPageCount()) return nullptr; +#ifdef PDF_ENABLE_XFA + return pDoc->GetPage(page_index); +#else // PDF_ENABLE_XFA CPDF_Dictionary* pDict = pDoc->GetPage(page_index); if (!pDict) return NULL; @@ -303,6 +502,7 @@ DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document, pPage->Load(pDoc, pDict); pPage->ParseContent(nullptr); return pPage; +#endif // PDF_ENABLE_XFA } DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page) { @@ -528,6 +728,10 @@ DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap, DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) { if (!page) return; +#ifdef PDF_ENABLE_XFA + CPDFXFA_Page* pPage = (CPDFXFA_Page*)page; + pPage->Release(); +#else // PDF_ENABLE_XFA CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)(((CPDF_Page*)page))->GetPrivateData((void*)page); if (pPageView && pPageView->IsLocked()) { @@ -535,19 +739,23 @@ DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page) { return; } delete (CPDF_Page*)page; +#endif // PDF_ENABLE_XFA } DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document) { +#ifdef PDF_ENABLE_XFA + delete UnderlyingFromFPDFDocument(document); +#else // PDF_ENABLE_XFA CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return; - - CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser(); + CPDF_Parser* pParser = pDoc->GetParser(); if (!pParser) { delete pDoc; return; } delete pParser; +#endif // PDF_ENABLE_XFA } DLLEXPORT unsigned long STDCALL FPDF_GetLastError() { @@ -567,19 +775,21 @@ DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page, if (!page || !page_x || !page_y) return; UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); - +#ifdef PDF_ENABLE_XFA + pPage->DeviceToPage(start_x, start_y, size_x, size_y, rotate, device_x, + device_y, page_x, page_y); +#else // PDF_ENABLE_XFA CFX_Matrix page2device; pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); CFX_Matrix device2page; device2page.SetReverse(page2device); - FX_FLOAT page_x_f, page_y_f; device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, page_y_f); - *page_x = (page_x_f); *page_y = (page_y_f); +#endif // PDF_ENABLE_XFA } DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page, @@ -597,16 +807,19 @@ DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page, UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page); if (!pPage) return; +#ifdef PDF_ENABLE_XFA + pPage->PageToDevice(start_x, start_y, size_x, size_y, rotate, page_x, page_y, + device_x, device_y); +#else // PDF_ENABLE_XFA CFX_Matrix page2device; pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); - FX_FLOAT device_x_f, device_y_f; page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, device_y_f); - *device_x = FXSYS_round(device_x_f); *device_y = FXSYS_round(device_y_f); +#endif // PDF_ENABLE_XFA } DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width, @@ -713,12 +926,14 @@ void FPDF_RenderPage_Retail(CRenderContext* pContext, pContext->m_pOptions->m_Flags |= RENDER_LIMITEDIMAGECACHE; if (flags & FPDF_RENDER_FORCEHALFTONE) pContext->m_pOptions->m_Flags |= RENDER_FORCE_HALFTONE; +#ifndef PDF_ENABLE_XFA if (flags & FPDF_RENDER_NO_SMOOTHTEXT) pContext->m_pOptions->m_Flags |= RENDER_NOTEXTSMOOTH; if (flags & FPDF_RENDER_NO_SMOOTHIMAGE) pContext->m_pOptions->m_Flags |= RENDER_NOIMAGESMOOTH; if (flags & FPDF_RENDER_NO_SMOOTHPATH) pContext->m_pOptions->m_Flags |= RENDER_NOPATHSMOOTH; +#endif // PDF_ENABLE_XFA // Grayscale output if (flags & FPDF_GRAYSCALE) { pContext->m_pOptions->m_ColorMode = RENDER_COLOR_GRAY; @@ -767,14 +982,24 @@ DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document, if (!pDoc) return FALSE; +#ifdef PDF_ENABLE_XFA + int count = pDoc->GetPageCount(); + if (page_index < 0 || page_index >= count) + return FALSE; + CPDFXFA_Page* pPage = pDoc->GetPage(page_index); + if (!pPage) + return FALSE; + *width = pPage->GetPageWidth(); + *height = pPage->GetPageHeight(); +#else // PDF_ENABLE_XFA CPDF_Dictionary* pDict = pDoc->GetPage(page_index); if (!pDict) return FALSE; - CPDF_Page page; page.Load(pDoc, pDict); *width = page.GetPageWidth(); *height = page.GetPageHeight(); +#endif // PDF_ENABLE_XFA return TRUE; } @@ -855,6 +1080,60 @@ DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document, return name_tree.LookupNamedDest(pDoc, name); } +#ifdef PDF_ENABLE_XFA +FPDF_RESULT FPDF_BStr_Init(FPDF_BSTR* str) { + if (!str) + return -1; + + FXSYS_memset(str, 0, sizeof(FPDF_BSTR)); + return 0; +} + +FPDF_RESULT FPDF_BStr_Set(FPDF_BSTR* str, FPDF_LPCSTR bstr, int length) { + if (!str) + return -1; + if (!bstr || !length) + return -1; + if (length == -1) + length = FXSYS_strlen(bstr); + + if (length == 0) { + if (str->str) { + FX_Free(str->str); + str->str = NULL; + } + str->len = 0; + return 0; + } + + if (str->str && str->len < length) + str->str = FX_Realloc(char, str->str, length + 1); + else if (!str->str) + str->str = FX_Alloc(char, length + 1); + + str->str[length] = 0; + if (str->str == NULL) + return -1; + + FXSYS_memcpy(str->str, bstr, length); + str->len = length; + + return 0; +} + +FPDF_RESULT FPDF_BStr_Clear(FPDF_BSTR* str) { + if (!str) + return -1; + + if (str->str) { + FX_Free(str->str); + str->str = NULL; + } + str->len = 0; + return 0; +} +#endif // PDF_ENABLE_XFA + DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document, int index, void* buffer, |