gecko-dev/widget/windows/PDFiumEngineShim.cpp

252 строки
7.5 KiB
C++

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PDFiumEngineShim.h"
#include "private/pprio.h"
typedef void (STDCALL *FPDF_InitLibrary_Pfn)();
typedef void (STDCALL *FPDF_DestroyLibrary_Pfn)();
typedef FPDF_DOCUMENT (STDCALL *FPDF_LoadDocument_Pfn)(FPDF_STRING file_path,
FPDF_BYTESTRING password);
typedef FPDF_DOCUMENT (STDCALL *FPDF_LoadCustomDocument_Pfn)(FPDF_FILEACCESS* pFileAccess,
FPDF_BYTESTRING password);
typedef void(STDCALL *FPDF_CloseDocument_Pfn)(FPDF_DOCUMENT aDocument);
typedef int (STDCALL *FPDF_GetPageCount_Pfn)(FPDF_DOCUMENT aDocument);
typedef FPDF_PAGE (STDCALL *FPDF_LoadPage_Pfn)(FPDF_DOCUMENT aDocument,
int aPageIndex);
typedef void (STDCALL *FPDF_ClosePage_Pfn)(FPDF_PAGE aPage);
typedef void (STDCALL *FPDF_RenderPage_Pfn)(HDC aDC,
FPDF_PAGE aPage,
int aStartX,
int aStartY,
int aSizeX,
int aSizeY,
int aRotate,
int aFlags);
namespace mozilla {
namespace widget {
static PDFiumEngineShim* sPDFiumEngineShim;
struct PDFFunctionPointerTable
{
PDFFunctionPointerTable()
: mFPDF_InitLibrary(nullptr)
, mFPDF_DestroyLibrary(nullptr)
, mFPDF_CloseDocument(nullptr)
, mFPDF_GetPageCount(nullptr)
, mFPDF_LoadPage(nullptr)
, mFPDF_ClosePage(nullptr)
, mFPDF_RenderPage(nullptr)
{
}
FPDF_InitLibrary_Pfn mFPDF_InitLibrary;
FPDF_DestroyLibrary_Pfn mFPDF_DestroyLibrary;
FPDF_LoadDocument_Pfn mFPDF_LoadDocument;
FPDF_LoadCustomDocument_Pfn mFPDF_LoadCustomDocument;
FPDF_CloseDocument_Pfn mFPDF_CloseDocument;
FPDF_GetPageCount_Pfn mFPDF_GetPageCount;
FPDF_LoadPage_Pfn mFPDF_LoadPage;
FPDF_ClosePage_Pfn mFPDF_ClosePage;
FPDF_RenderPage_Pfn mFPDF_RenderPage;
};
/* static */
already_AddRefed<PDFiumEngineShim>
PDFiumEngineShim::GetInstanceOrNull()
{
RefPtr<PDFiumEngineShim> inst = sPDFiumEngineShim;
if (!inst) {
inst = new PDFiumEngineShim();
if (!inst->Init(NS_LITERAL_STRING("pdfium.dll"))) {
inst = nullptr;
}
sPDFiumEngineShim = inst.get();
}
return inst.forget();
}
/* static */
already_AddRefed<PDFiumEngineShim>
PDFiumEngineShim::GetInstanceOrNull(const nsString& aLibrary)
{
RefPtr<PDFiumEngineShim> shim = new PDFiumEngineShim();
if (!shim->Init(aLibrary)) {
return nullptr;
}
return shim.forget();
}
PDFiumEngineShim::PDFiumEngineShim()
: mTable(MakeUnique<PDFFunctionPointerTable>())
, mInitialized(false)
, mPRLibrary(nullptr)
{
}
PDFiumEngineShim::~PDFiumEngineShim()
{
if (mInitialized) {
mTable->mFPDF_DestroyLibrary();
}
sPDFiumEngineShim = nullptr;
if (mPRLibrary) {
PR_UnloadLibrary(mPRLibrary);
}
}
bool
PDFiumEngineShim::Init(const nsString& aLibrary)
{
if (mInitialized) {
return true;
}
PRLibSpec libSpec;
libSpec.type = PR_LibSpec_PathnameU;
libSpec.value.pathname_u = aLibrary.get();
mPRLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
NS_ENSURE_TRUE(mPRLibrary, false);
mTable->mFPDF_InitLibrary =
(FPDF_InitLibrary_Pfn)PR_FindFunctionSymbol(mPRLibrary,
"FPDF_InitLibrary");
NS_ENSURE_TRUE(mTable->mFPDF_InitLibrary, false);
mTable->mFPDF_DestroyLibrary =
(FPDF_DestroyLibrary_Pfn)PR_FindFunctionSymbol(mPRLibrary,
"FPDF_DestroyLibrary");
NS_ENSURE_TRUE(mTable->mFPDF_DestroyLibrary, false);
mTable->mFPDF_LoadDocument =
(FPDF_LoadDocument_Pfn)PR_FindFunctionSymbol(mPRLibrary,
"FPDF_LoadDocument");
NS_ENSURE_TRUE(mTable->mFPDF_LoadDocument, false);
mTable->mFPDF_LoadCustomDocument =
(FPDF_LoadCustomDocument_Pfn)PR_FindFunctionSymbol(mPRLibrary,
"FPDF_LoadCustomDocument");
NS_ENSURE_TRUE(mTable->mFPDF_LoadCustomDocument, false);
mTable->mFPDF_CloseDocument =
(FPDF_CloseDocument_Pfn)PR_FindFunctionSymbol(mPRLibrary,
"FPDF_CloseDocument");
NS_ENSURE_TRUE(mTable->mFPDF_CloseDocument, false);
mTable->mFPDF_GetPageCount =
(FPDF_GetPageCount_Pfn)PR_FindFunctionSymbol(mPRLibrary,
"FPDF_GetPageCount");
NS_ENSURE_TRUE(mTable->mFPDF_GetPageCount, false);
mTable->mFPDF_LoadPage =
(FPDF_LoadPage_Pfn)PR_FindFunctionSymbol(mPRLibrary, "FPDF_LoadPage");
NS_ENSURE_TRUE(mTable->mFPDF_LoadPage, false);
mTable->mFPDF_ClosePage =
(FPDF_ClosePage_Pfn)PR_FindFunctionSymbol(mPRLibrary, "FPDF_ClosePage");
NS_ENSURE_TRUE(mTable->mFPDF_ClosePage, false);
mTable->mFPDF_RenderPage =
(FPDF_RenderPage_Pfn)PR_FindFunctionSymbol(mPRLibrary, "FPDF_RenderPage");
NS_ENSURE_TRUE(mTable->mFPDF_RenderPage, false);
mTable->mFPDF_InitLibrary();
mInitialized = true;
return true;
}
FPDF_DOCUMENT
PDFiumEngineShim::LoadDocument(FPDF_STRING file_path,
FPDF_BYTESTRING aPassword)
{
MOZ_ASSERT(mInitialized);
return mTable->mFPDF_LoadDocument(file_path, aPassword);
}
FPDF_DOCUMENT
PDFiumEngineShim::LoadDocument(PRFileDesc* aPrfile,
FPDF_BYTESTRING aPassword)
{
MOZ_ASSERT(mInitialized && aPrfile);
PROffset32 fileLength = PR_Seek64(aPrfile, 0, PR_SEEK_END);
if (fileLength == -1) {
NS_WARNING("Failed to access the given FD.");
return nullptr;
}
FPDF_FILEACCESS fileAccess;
fileAccess.m_FileLen = static_cast<unsigned long>(fileLength);
fileAccess.m_Param = reinterpret_cast<void*>(aPrfile);
fileAccess.m_GetBlock =
[](void* param, unsigned long pos, unsigned char* buf, unsigned long size)
{
PRFileDesc* prfile = reinterpret_cast<PRFileDesc*>(param);
if (PR_Seek64(prfile, pos, PR_SEEK_SET) != pos) {
return 0;
}
if (PR_Read(prfile, buf, size) <= 0) {
return 0;
}
return 1;
};
return mTable->mFPDF_LoadCustomDocument(&fileAccess, aPassword);
}
void
PDFiumEngineShim::CloseDocument(FPDF_DOCUMENT aDocument)
{
MOZ_ASSERT(mInitialized);
mTable->mFPDF_CloseDocument(aDocument);
}
int
PDFiumEngineShim::GetPageCount(FPDF_DOCUMENT aDocument)
{
MOZ_ASSERT(mInitialized);
return mTable->mFPDF_GetPageCount(aDocument);
}
FPDF_PAGE
PDFiumEngineShim::LoadPage(FPDF_DOCUMENT aDocument, int aPageIndex)
{
MOZ_ASSERT(mInitialized);
return mTable->mFPDF_LoadPage(aDocument, aPageIndex);
}
void
PDFiumEngineShim::ClosePage(FPDF_PAGE aPage)
{
MOZ_ASSERT(mInitialized);
mTable->mFPDF_ClosePage(aPage);
}
void
PDFiumEngineShim::RenderPage(HDC aDC, FPDF_PAGE aPage,
int aStartX, int aStartY,
int aSizeX, int aSizeY,
int aRotate, int aFlags)
{
MOZ_ASSERT(mInitialized);
mTable->mFPDF_RenderPage(aDC, aPage, aStartX, aStartY,
aSizeX, aSizeY, aRotate, aFlags);
}
} // namespace widget
} // namespace mozilla