Bug 1359713 - Stop loading the contents of PDF files into memory in PDFViaEMFPrintHelper r=jwatt
This change changes PDFViaEMFPrintHelper so that instead of loading the entire
contents of a PDF document into memory to pass to PDFium, it now simply passes
PDFium a file system path to load the PDF from. This should help us reduce
memory use (and potentially avoid running out of memory) when larger PDFs are
printed.
MozReview-Commit-ID: GISolZYC2GJ
--- a/widget/windows/PDFViaEMFPrintHelper.cpp
+++ b/widget/windows/PDFViaEMFPrintHelper.cpp
@@ -36,61 +36,37 @@ PDFViaEMFPrintHelper::PDFViaEMFPrintHelp
MOZ_ASSERT(mPDFiumLibrary);
}
PDFViaEMFPrintHelper::~PDFViaEMFPrintHelper()
{
CloseDocument();
}
-bool
-PDFViaEMFPrintHelper::LoadPDFDataToBuffer(nsIFile *aFile)
-{
- RefPtr<nsFileInputStream> inputStream = new nsFileInputStream();
- if (NS_FAILED(inputStream->Init(aFile, -1, -1, 0))) {
- return false;
- }
-
- int64_t size = 0;
- inputStream->GetSize(&size);
- NS_ENSURE_TRUE(size > 0, false);
-
- if (!mPDFFileContents.resize(size)) {
- return false;
- }
-
- uint32_t bytesRead = 0;
- inputStream->Read(mPDFFileContents.begin(), size, &bytesRead);
- MOZ_ASSERT(bytesRead == size);
- return true;
-}
-
nsresult
PDFViaEMFPrintHelper::OpenDocument(nsIFile *aFile)
{
MOZ_ASSERT(aFile);
if (mPDFDoc) {
MOZ_ASSERT_UNREACHABLE("We can only open one PDF at a time");
return NS_ERROR_FAILURE;
}
if (!mPDFiumEngine) {
mPDFiumEngine = MakeUnique<PDFiumEngineShim>(mPDFiumLibrary);
}
- if (!LoadPDFDataToBuffer(aFile)) {
- return NS_ERROR_FAILURE;
+ nsAutoCString nativePath;
+ nsresult rv = aFile->GetNativePath(nativePath);
+ if (NS_FAILED(rv)) {
+ return rv;
}
- // Create Bug 1359713 to implement loading document by path in
- // PDFiumEngineShim.
- mPDFDoc = mPDFiumEngine->LoadMemDocument(mPDFFileContents.begin(),
- mPDFFileContents.length(),
- nullptr);
+
+ mPDFDoc = mPDFiumEngine->LoadDocument(nativePath.get(), nullptr);
if (!mPDFDoc) {
- mPDFFileContents.clear();
return NS_ERROR_FAILURE;
}
if (mPDFiumEngine->GetPageCount(mPDFDoc) < 1) {
CloseDocument();
return NS_ERROR_FAILURE;
}
@@ -178,11 +154,10 @@ PDFViaEMFPrintHelper::DrawPageToFile(con
}
void
PDFViaEMFPrintHelper::CloseDocument()
{
if (mPDFDoc) {
mPDFiumEngine->CloseDocument(mPDFDoc);
mPDFDoc = nullptr;
- mPDFFileContents.clear();
}
}
\ No newline at end of file
--- a/widget/windows/PDFViaEMFPrintHelper.h
+++ b/widget/windows/PDFViaEMFPrintHelper.h
@@ -51,16 +51,15 @@ private:
bool LoadPDFDataToBuffer(nsIFile *aFile);
bool RenderPageToDC(HDC aDC, unsigned int aPageIndex,
int aPageWidth, int aPageHeight);
UniquePtr<PDFiumEngineShim> mPDFiumEngine;
FPDF_DOCUMENT mPDFDoc;
- Vector<char> mPDFFileContents;
PRLibrary* mPDFiumLibrary;
};
} // namespace widget
} // namespace mozilla
#endif /* PDFVIAEMFPRINTHELPER_H_ */
\ No newline at end of file
--- a/widget/windows/PDFiumEngineShim.cpp
+++ b/widget/windows/PDFiumEngineShim.cpp
@@ -47,16 +47,21 @@ PDFiumEngineShim::InitSymbolsAndLibrary(
if (!mFPDF_DestroyLibrary) {
return false;
}
mFPDF_LoadMemDocument = (FPDF_LoadMemDocument_Pfn)PR_FindFunctionSymbol(
mPRLibrary, "FPDF_LoadMemDocument");
if (!mFPDF_LoadMemDocument) {
return false;
}
+ mFPDF_LoadDocument = (FPDF_LoadDocument_Pfn)PR_FindFunctionSymbol(
+ mPRLibrary, "FPDF_LoadDocument");
+ if (!mFPDF_LoadDocument) {
+ return false;
+ }
mFPDF_CloseDocument = (FPDF_CloseDocument_Pfn)PR_FindFunctionSymbol(
mPRLibrary, "FPDF_CloseDocument");
if (!mFPDF_CloseDocument) {
return false;
}
mFPDF_GetPageCount = (FPDF_GetPageCount_Pfn)PR_FindFunctionSymbol(
mPRLibrary, "FPDF_GetPageCount");
if (!mFPDF_GetPageCount) {
@@ -114,16 +119,29 @@ PDFiumEngineShim::LoadMemDocument(const
if (!InitSymbolsAndLibrary()) {
return nullptr;
}
}
return mFPDF_LoadMemDocument(aDataBuf, aSize, aPassword);
}
+FPDF_DOCUMENT
+PDFiumEngineShim::LoadDocument(FPDF_STRING file_path,
+ FPDF_BYTESTRING aPassword)
+{
+ if (!mInitialized) {
+ if (!InitSymbolsAndLibrary()) {
+ return nullptr;
+ }
+ }
+
+ return mFPDF_LoadDocument(file_path, aPassword);
+}
+
void
PDFiumEngineShim::CloseDocument(FPDF_DOCUMENT aDocument)
{
MOZ_ASSERT(mInitialized);
mFPDF_CloseDocument(aDocument);
DestroyLibrary();
mInitialized = false;
}
--- a/widget/windows/PDFiumEngineShim.h
+++ b/widget/windows/PDFiumEngineShim.h
@@ -63,30 +63,34 @@ typedef void* FPDF_PAGELINK;
typedef void* FPDF_PAGEOBJECT; // Page object(text, path, etc)
typedef void* FPDF_PAGERANGE;
typedef void* FPDF_PATH;
typedef void* FPDF_RECORDER;
typedef void* FPDF_SCHHANDLE;
typedef void* FPDF_STRUCTELEMENT;
typedef void* FPDF_STRUCTTREE;
typedef void* FPDF_TEXTPAGE;
+typedef const char* FPDF_STRING;
// Basic data types
typedef int FPDF_BOOL;
typedef int FPDF_ERROR;
typedef unsigned long FPDF_DWORD;
typedef float FS_FLOAT;
typedef const char* FPDF_BYTESTRING;
typedef void (*FPDF_InitLibrary_Pfn)();
typedef void (*FPDF_DestroyLibrary_Pfn)();
typedef FPDF_DOCUMENT (*FPDF_LoadMemDocument_Pfn)(const void* aDataBuf,
int aSize,
FPDF_BYTESTRING aPassword);
+typedef FPDF_DOCUMENT (*FPDF_LoadDocument_Pfn)(FPDF_STRING file_path,
+ FPDF_BYTESTRING password);
+
typedef void(*FPDF_CloseDocument_Pfn)(FPDF_DOCUMENT aDocument);
typedef int (*FPDF_GetPageCount_Pfn)(FPDF_DOCUMENT aDocument);
typedef int (*FPDF_GetPageSizeByIndex_Pfn)(FPDF_DOCUMENT aDocument,
int aPageIndex,
double* aWidth,
double* aWeight);
@@ -98,30 +102,33 @@ typedef void (*FPDF_RenderPage_Pfn)(HDC
int aStartY,
int aSizeX,
int aSizeY,
int aRotate,
int aFlags);
typedef void (*FPDF_RenderPage_Close_Pfn) (FPDF_PAGE aPage);
+
/**
* This class exposes an interface to the PDFium library and
* takes care of loading and linking to the appropriate PDFium symbols.
*/
class PDFiumEngineShim
{
public:
explicit PDFiumEngineShim(PRLibrary* aLibrary);
~PDFiumEngineShim();
FPDF_DOCUMENT LoadMemDocument(const void* aDataBuf,
int aSize,
FPDF_BYTESTRING aPassword);
+ FPDF_DOCUMENT LoadDocument(FPDF_STRING file_path,
+ FPDF_BYTESTRING aPassword);
void CloseDocument(FPDF_DOCUMENT aDocument);
int GetPageCount(FPDF_DOCUMENT aDocument);
int GetPageSizeByIndex(FPDF_DOCUMENT aDocument, int aPageIndex,
double* aWidth, double* aHeight);
FPDF_PAGE LoadPage(FPDF_DOCUMENT aDocument, int aPageIndex);
void ClosePage(FPDF_PAGE aPage);
void RenderPage(HDC aDC, FPDF_PAGE aPage,
@@ -138,16 +145,17 @@ private:
void DestroyLibrary();
PRLibrary* mPRLibrary;
bool mInitialized ;
FPDF_InitLibrary_Pfn mFPDF_InitLibrary;
FPDF_DestroyLibrary_Pfn mFPDF_DestroyLibrary;
FPDF_LoadMemDocument_Pfn mFPDF_LoadMemDocument;
+ FPDF_LoadDocument_Pfn mFPDF_LoadDocument;
FPDF_CloseDocument_Pfn mFPDF_CloseDocument;
FPDF_GetPageCount_Pfn mFPDF_GetPageCount;
FPDF_GetPageSizeByIndex_Pfn mFPDF_GetPageSizeByIndex;
FPDF_LoadPage_Pfn mFPDF_LoadPage;
FPDF_ClosePage_Pfn mFPDF_ClosePage;
FPDF_RenderPage_Pfn mFPDF_RenderPage;
FPDF_RenderPage_Close_Pfn mFPDF_RenderPage_Close;