зеркало из https://github.com/mozilla/gecko-dev.git
252 строки
7.5 KiB
C++
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
|