Bug 1372113 - Call PDFium function directly in PDFiumEngineShim r?jwatt draft
authorFarmer Tseng <fatseng@mozilla.com>
Thu, 06 Jul 2017 10:25:46 +0800
changeset 604544 25650284eb0108590a5c339ccaa46243a5f01389
parent 604170 211d4dd61025c0a40caea7a54c9066e051bdde8c
child 604545 7b5e718c7fe5dbeee13bbd7a0c958cd285d0833f
push id67114
push userbmo:fatseng@mozilla.com
push dateThu, 06 Jul 2017 03:11:20 +0000
reviewersjwatt
bugs1372113, 1368948
milestone56.0a1
Bug 1372113 - Call PDFium function directly in PDFiumEngineShim r?jwatt 1.PDfium would be built into the xul (bug 1368948) so PDFiumEngineShim could call functions directly. However, I still keep loading dynamic library for debugging purpose. Create a new preference for storing the library file path. 2.Remove redundant define and typedef which are written in PDFium head file. 3.Include an appropriate head file from PDFium. 4.Remove non-used PDFium APIs. 5.Use the singleton pattern to retrieve the instance of PDFiumEngineShim. 6.Don't destroy the library inside PDFiumEngineShim::CloseDocument because the library has to deal with multi-document. MozReview-Commit-ID: 97ZBFp1qU8V
widget/windows/PDFViaEMFPrintHelper.cpp
widget/windows/PDFViaEMFPrintHelper.h
widget/windows/PDFiumEngineShim.cpp
widget/windows/PDFiumEngineShim.h
widget/windows/moz.build
--- a/widget/windows/PDFViaEMFPrintHelper.cpp
+++ b/widget/windows/PDFViaEMFPrintHelper.cpp
@@ -24,21 +24,19 @@ float ComputeScaleFactor(int aDCWidth, i
       static_cast<float>(aDCWidth) / static_cast <float>(aPageWidth);
     float yFactor =
       static_cast<float>(aDCHeight) / static_cast <float>(aPageHeight);
     scaleFactor = std::min(xFactor, yFactor);
   }
   return scaleFactor;
 }
 
-PDFViaEMFPrintHelper::PDFViaEMFPrintHelper(PRLibrary* aPDFiumLibrary)
-  : mPDFiumLibrary(aPDFiumLibrary)
-  , mPDFDoc(nullptr)
+PDFViaEMFPrintHelper::PDFViaEMFPrintHelper()
+  : mPDFDoc(nullptr)
 {
-  MOZ_ASSERT(mPDFiumLibrary);
 }
 
 PDFViaEMFPrintHelper::~PDFViaEMFPrintHelper()
 {
   CloseDocument();
 }
 
 nsresult
@@ -46,17 +44,18 @@ PDFViaEMFPrintHelper::OpenDocument(nsIFi
 {
   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);
+    mPDFiumEngine = PDFiumEngineShim::GetInstanceOrNull();
+    NS_ENSURE_TRUE(mPDFiumEngine, NS_ERROR_FAILURE);
   }
 
   nsAutoCString nativePath;
   nsresult rv = aFile->GetNativePath(nativePath);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
--- a/widget/windows/PDFViaEMFPrintHelper.h
+++ b/widget/windows/PDFViaEMFPrintHelper.h
@@ -23,17 +23,17 @@ namespace widget {
  * This class helps draw a PDF file to a given Windows DC.
  * To do that it first converts the PDF file to EMF.
  * Windows EMF:
  * https://msdn.microsoft.com/en-us/windows/hardware/drivers/print/emf-data-type
  */
 class PDFViaEMFPrintHelper
 {
 public:
-  explicit PDFViaEMFPrintHelper(PRLibrary* aPDFiumLibrary);
+  PDFViaEMFPrintHelper();
   ~PDFViaEMFPrintHelper();
 
   /** Loads the specified PDF file. */
   NS_IMETHOD OpenDocument(nsIFile *aFile);
 
   /** Releases document buffer. */
   void CloseDocument();
 
@@ -49,17 +49,16 @@ public:
 
 private:
 
   bool LoadPDFDataToBuffer(nsIFile *aFile);
 
   bool RenderPageToDC(HDC aDC, unsigned int aPageIndex,
                       int aPageWidth, int aPageHeight);
 
-  UniquePtr<PDFiumEngineShim> mPDFiumEngine;
+  RefPtr<PDFiumEngineShim>    mPDFiumEngine;
   FPDF_DOCUMENT               mPDFDoc;
-  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
@@ -4,170 +4,150 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PDFiumEngineShim.h"
 
 
 namespace mozilla {
 namespace widget {
 
-PDFiumEngineShim::PDFiumEngineShim(PRLibrary* aLibrary)
-  : mPRLibrary(aLibrary)
-  , mFPDF_InitLibrary(nullptr)
+static PDFiumEngineShim* sPDFiumEngineShim;
+
+/* static */
+already_AddRefed<PDFiumEngineShim>
+PDFiumEngineShim::GetInstanceOrNull()
+{
+  RefPtr<PDFiumEngineShim> inst = sPDFiumEngineShim;
+  if (!inst) {
+    inst = new PDFiumEngineShim();
+    if (!inst->Init()) {
+      inst = nullptr;
+    }
+    sPDFiumEngineShim = inst.get();
+  }
+
+  return inst.forget();
+}
+
+PDFiumEngineShim::PDFiumEngineShim()
+  : mFPDF_InitLibrary(nullptr)
   , mFPDF_DestroyLibrary(nullptr)
-  , mFPDF_LoadMemDocument(nullptr)
   , mFPDF_CloseDocument(nullptr)
   , mFPDF_GetPageCount(nullptr)
-  , mFPDF_GetPageSizeByIndex(nullptr)
   , mFPDF_LoadPage(nullptr)
   , mFPDF_ClosePage(nullptr)
   , mFPDF_RenderPage(nullptr)
-  , mFPDF_RenderPage_Close(nullptr)
+#ifdef USE_EXTERNAL_PDFIUM
+  , mPRLibrary(nullptr)
+#endif
   , mInitialized(false)
 {
-  MOZ_ASSERT(mPRLibrary);
 }
 
 PDFiumEngineShim::~PDFiumEngineShim()
 {
+  if (mInitialized) {
+    mFPDF_DestroyLibrary();
+  }
+
+  sPDFiumEngineShim = nullptr;
+
+#ifdef USE_EXTERNAL_PDFIUM
+  if (mPRLibrary) {
+    PR_UnloadLibrary(mPRLibrary);
+  }
+#endif
 }
 
 bool
-PDFiumEngineShim::InitSymbolsAndLibrary()
+PDFiumEngineShim::Init()
 {
   if (mInitialized) {
     return true;
   }
 
+#ifdef USE_EXTERNAL_PDFIUM
+  const nsAdoptingString& PDFiumPath =
+    mozilla::Preferences::GetString("print.load_external_pdfium");
+  NS_ENSURE_FALSE(PDFiumPath.IsEmpty(), false);
+
+  nsAutoCString filePath = NS_ConvertUTF16toUTF8(PDFiumPath);
+  mPRLibrary = PR_LoadLibrary(filePath.get());
+  NS_ENSURE_TRUE(mPRLibrary, false);
+
   mFPDF_InitLibrary = (FPDF_InitLibrary_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_InitLibrary");
-  if (!mFPDF_InitLibrary) {
-    return false;
-  }
+  NS_ENSURE_TRUE(mFPDF_InitLibrary, false);
+
   mFPDF_DestroyLibrary = (FPDF_DestroyLibrary_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_DestroyLibrary");
-  if (!mFPDF_DestroyLibrary) {
-    return false;
-  }
-  mFPDF_LoadMemDocument = (FPDF_LoadMemDocument_Pfn)PR_FindFunctionSymbol(
-    mPRLibrary, "FPDF_LoadMemDocument");
-  if (!mFPDF_LoadMemDocument) {
-    return false;
-  }
+  NS_ENSURE_TRUE(mFPDF_DestroyLibrary, false);
+
   mFPDF_LoadDocument = (FPDF_LoadDocument_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_LoadDocument");
-  if (!mFPDF_LoadDocument) {
-    return false;
-  }
+  NS_ENSURE_TRUE(mFPDF_LoadDocument, false);
+
   mFPDF_CloseDocument = (FPDF_CloseDocument_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_CloseDocument");
-  if (!mFPDF_CloseDocument) {
-    return false;
-  }
+  NS_ENSURE_TRUE(mFPDF_CloseDocument, false);
+
   mFPDF_GetPageCount = (FPDF_GetPageCount_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_GetPageCount");
-  if (!mFPDF_GetPageCount) {
-    return false;
-  }
-  mFPDF_GetPageSizeByIndex = (FPDF_GetPageSizeByIndex_Pfn)PR_FindFunctionSymbol(
-    mPRLibrary, "FPDF_GetPageSizeByIndex");
-  if (!mFPDF_GetPageSizeByIndex) {
-    return false;
-  }
+  NS_ENSURE_TRUE(mFPDF_GetPageCount, false);
+
   mFPDF_LoadPage = (FPDF_LoadPage_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_LoadPage");
-  if (!mFPDF_LoadPage) {
-    return false;
-  }
+  NS_ENSURE_TRUE(mFPDF_LoadPage, false);
+
   mFPDF_ClosePage = (FPDF_ClosePage_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_ClosePage");
-  if (!mFPDF_ClosePage) {
-    return false;
-  }
+  NS_ENSURE_TRUE(mFPDF_ClosePage, false);
+
   mFPDF_RenderPage = (FPDF_RenderPage_Pfn)PR_FindFunctionSymbol(
     mPRLibrary, "FPDF_RenderPage");
-  if (!mFPDF_RenderPage) {
-    return false;
-  }
-  mFPDF_RenderPage_Close = (FPDF_RenderPage_Close_Pfn)PR_FindFunctionSymbol(
-    mPRLibrary, "FPDF_RenderPage_Close");
-  if (!mFPDF_RenderPage_Close) {
-    return false;
-  }
+  NS_ENSURE_TRUE(mFPDF_RenderPage, false);
 
-  InitLibrary();
+#else
+  mFPDF_InitLibrary = (FPDF_InitLibrary_Pfn) FPDF_InitLibrary;
+  mFPDF_DestroyLibrary = (FPDF_DestroyLibrary_Pfn) FPDF_DestroyLibrary;
+  mFPDF_LoadDocument = (FPDF_LoadDocument_Pfn) FPDF_LoadDocument;
+  mFPDF_CloseDocument = (FPDF_CloseDocument_Pfn) FPDF_CloseDocument;
+  mFPDF_GetPageCount = (FPDF_GetPageCount_Pfn) FPDF_GetPageCount;
+  mFPDF_LoadPage = (FPDF_LoadPage_Pfn) FPDF_LoadPage;
+  mFPDF_ClosePage = (FPDF_ClosePage_Pfn) FPDF_ClosePage;
+  mFPDF_RenderPage = (FPDF_RenderPage_Pfn) FPDF_RenderPage;
+#endif
+
+  mFPDF_InitLibrary();
   mInitialized = true;
   return true;
 }
 
-void
-PDFiumEngineShim::InitLibrary()
-{
-  mFPDF_InitLibrary();
-}
-
-void
-PDFiumEngineShim::DestroyLibrary()
-{
-  mFPDF_DestroyLibrary();
-}
-
-FPDF_DOCUMENT
-PDFiumEngineShim::LoadMemDocument(const void* aDataBuf,
-                                  int aSize,
-                                  FPDF_BYTESTRING aPassword)
-{
-  if (!mInitialized) {
-    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;
-    }
-  }
-
+  MOZ_ASSERT(mInitialized);
   return mFPDF_LoadDocument(file_path, aPassword);
 }
 
 void
 PDFiumEngineShim::CloseDocument(FPDF_DOCUMENT aDocument)
 {
   MOZ_ASSERT(mInitialized);
   mFPDF_CloseDocument(aDocument);
-  DestroyLibrary();
-  mInitialized = false;
 }
 
 int
 PDFiumEngineShim::GetPageCount(FPDF_DOCUMENT aDocument)
 {
   MOZ_ASSERT(mInitialized);
   return mFPDF_GetPageCount(aDocument);
 }
 
-int
-PDFiumEngineShim::GetPageSizeByIndex(FPDF_DOCUMENT aDocument,
-                                     int aPageIndex,
-                                     double* aWidth,
-                                     double* aHeight)
-{
-  MOZ_ASSERT(mInitialized);
-  return mFPDF_GetPageSizeByIndex(aDocument, aPageIndex, aWidth, aHeight);
-}
-
 FPDF_PAGE
 PDFiumEngineShim::LoadPage(FPDF_DOCUMENT aDocument, int aPageIndex)
 {
   MOZ_ASSERT(mInitialized);
   return mFPDF_LoadPage(aDocument, aPageIndex);
 }
 
 void
@@ -183,17 +163,10 @@ PDFiumEngineShim::RenderPage(HDC aDC, FP
                              int aSizeX, int aSizeY,
                              int aRotate, int aFlags)
 {
   MOZ_ASSERT(mInitialized);
   mFPDF_RenderPage(aDC, aPage, aStartX, aStartY,
                    aSizeX, aSizeY, aRotate, aFlags);
 }
 
-void
-PDFiumEngineShim::RenderPage_Close(FPDF_PAGE aPage)
-{
-  MOZ_ASSERT(mInitialized);
-  mFPDF_RenderPage_Close(aPage);
-}
-
 } // namespace widget
 } // namespace mozilla
\ No newline at end of file
--- a/widget/windows/PDFiumEngineShim.h
+++ b/widget/windows/PDFiumEngineShim.h
@@ -2,166 +2,92 @@
 /* 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/. */
 
 #ifndef PDFIUMENGINESHIM_H
 #define PDFIUMENGINESHIM_H
 
 #include "prlink.h"
+#include "fpdfview.h"
+
+//#define USE_EXTERNAL_PDFIUM
 
 /* include windows.h for the HDC definitions that we need. */
 #include <windows.h>
 
 namespace mozilla {
 namespace widget {
-/**
- * Create Bug 1349139 to replace following defines with an appropriate include file.
- */
-// Page rendering flags. They can be combined with bit-wise OR.
-//
-// Set if annotations are to be rendered.
-#define FPDF_ANNOT 0x01
-// Set if using text rendering optimized for LCD display.
-#define FPDF_LCD_TEXT 0x02
-// Don't use the native text output available on some platforms
-#define FPDF_NO_NATIVETEXT 0x04
-// Grayscale output.
-#define FPDF_GRAYSCALE 0x08
-// Set if you want to get some debug info.
-#define FPDF_DEBUG_INFO 0x80
-// Set if you don't want to catch exceptions.
-#define FPDF_NO_CATCH 0x100
-// Limit image cache size.
-#define FPDF_RENDER_LIMITEDIMAGECACHE 0x200
-// Always use halftone for image stretching.
-#define FPDF_RENDER_FORCEHALFTONE 0x400
-// Render for printing.
-#define FPDF_PRINTING 0x800
-// Set to disable anti-aliasing on text.
-#define FPDF_RENDER_NO_SMOOTHTEXT 0x1000
-// Set to disable anti-aliasing on images.
-#define FPDF_RENDER_NO_SMOOTHIMAGE 0x2000
-// Set to disable anti-aliasing on paths.
-#define FPDF_RENDER_NO_SMOOTHPATH 0x4000
-// Set whether to render in a reverse Byte order, this flag is only used when
-// rendering to a bitmap.
-#define FPDF_REVERSE_BYTE_ORDER 0x10
-
-// PDF types
-typedef void* FPDF_ACTION;
-typedef void* FPDF_BITMAP;
-typedef void* FPDF_BOOKMARK;
-typedef void* FPDF_CLIPPATH;
-typedef void* FPDF_DEST;
-typedef void* FPDF_DOCSCHHANDLE;
-typedef void* FPDF_DOCUMENT;
-typedef void* FPDF_FONT;
-typedef void* FPDF_HMODULE;
-typedef void* FPDF_LINK;
-typedef void* FPDF_MODULEMGR;
-typedef void* FPDF_PAGE;
-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);
 
 typedef FPDF_PAGE (*FPDF_LoadPage_Pfn)(FPDF_DOCUMENT aDocument, int aPageIndex);
 typedef void (*FPDF_ClosePage_Pfn)(FPDF_PAGE aPage);
 typedef void (*FPDF_RenderPage_Pfn)(HDC aDC,
                                     FPDF_PAGE aPage,
                                     int aStartX,
                                     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();
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PDFiumEngineShim)
 
-  FPDF_DOCUMENT LoadMemDocument(const void* aDataBuf,
-                                int aSize,
-                                FPDF_BYTESTRING aPassword);
+  static already_AddRefed<PDFiumEngineShim> GetInstanceOrNull();
+
+  bool Init();
+
   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,
                   int aStartX, int aStartY,
                   int aSizeX, int aSizeY,
                   int aRotate, int aFlags);
 
-  void RenderPage_Close(FPDF_PAGE aPage);
-
 private:
 
-  bool InitSymbolsAndLibrary();
-  void InitLibrary();
-  void DestroyLibrary();
+  PDFiumEngineShim();
+  ~PDFiumEngineShim();
 
-  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;
 
+#ifdef USE_EXTERNAL_PDFIUM
+  PRLibrary*  mPRLibrary;
+#endif
 };
 
 } // namespace widget
 } // namespace mozilla
 
 #endif /* PDFIUMENGINESHIM_H */
\ No newline at end of file
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -92,36 +92,39 @@ if CONFIG['MOZ_CRASHREPORTER']:
         'LSPAnnotator.cpp',
     ]
 
 if CONFIG['NS_PRINTING']:
     UNIFIED_SOURCES += [
         'nsDeviceContextSpecWin.cpp',
         'nsPrintOptionsWin.cpp',
         'nsPrintSettingsWin.cpp',
-        'PDFiumEngineShim.cpp',
-        'PDFViaEMFPrintHelper.cpp',
-        'WindowsEMF.cpp',
     ]
     if CONFIG['MOZ_ENABLE_SKIA_PDF']:
         DIRS += ['/modules/pdfium']
+        UNIFIED_SOURCES += [
+            'PDFiumEngineShim.cpp',
+            'PDFViaEMFPrintHelper.cpp',
+            'WindowsEMF.cpp',
+        ]
 
 if CONFIG['NS_ENABLE_TSF']:
     SOURCES += [
         'TSFTextStore.cpp',
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 if CONFIG['MOZ_ENABLE_SKIA_PDF']:
   LOCAL_INCLUDES += [
     '/gfx/skia/skia/include/config',
     '/gfx/skia/skia/include/core',
+    '/modules/pdfium/pdfium/public',
   ]
 
 LOCAL_INCLUDES += [
     '/layout/generic',
     '/layout/xul',
     '/toolkit/xre',
     '/widget',
     '/widget/headless',