Bug 1359713 - Stop loading the contents of PDF files into memory in PDFViaEMFPrintHelper r=jwatt draft
authorFarmer Tseng <fatseng@mozilla.com>
Fri, 12 May 2017 12:42:20 +0800
changeset 584319 a59925542b6c075cd14c67577653163cc2d49c0f
parent 576805 d0bc87fc8a0a4ad9a1bf60453c10e76045e4ed5d
child 630330 c6ab750c9d5fae9bcac46cc53ff3b476e081da2e
push id60685
push userbmo:fatseng@mozilla.com
push dateThu, 25 May 2017 08:27:34 +0000
reviewersjwatt
bugs1359713
milestone55.0a1
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
widget/windows/PDFViaEMFPrintHelper.cpp
widget/windows/PDFViaEMFPrintHelper.h
widget/windows/PDFiumEngineShim.cpp
widget/windows/PDFiumEngineShim.h
--- 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;