Bug 1399787 - Part 6. Conntect actor with nsDeviceContextSpecWin. draft
authorcku <cku@mozilla.com>
Tue, 17 Oct 2017 15:53:14 +0800
changeset 682389 a3432c4815fbab4ce4582c124b92923cba404392
parent 682388 d139b9f8f797dae85baf8baecbb57f1bff9420e2
child 682390 f4a719d2d471663490edef1655a594ada89b59ef
push id85086
push usercku@mozilla.com
push dateWed, 18 Oct 2017 14:51:34 +0000
bugs1399787
milestone58.0a1
Bug 1399787 - Part 6. Conntect actor with nsDeviceContextSpecWin. MozReview-Commit-ID: 415xovMsiwN
widget/windows/PDFiumParent.cpp
widget/windows/PDFiumParent.h
widget/windows/PDFiumProcessParent.cpp
widget/windows/PDFiumProcessParent.h
widget/windows/nsDeviceContextSpecWin.cpp
widget/windows/nsDeviceContextSpecWin.h
--- a/widget/windows/PDFiumParent.cpp
+++ b/widget/windows/PDFiumParent.cpp
@@ -4,17 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PDFiumParent.h"
 #include "nsDeviceContextSpecWin.h"
 
 namespace mozilla {
 namespace widget {
 
-PDFiumParent::PDFiumParent()
+PDFiumParent::PDFiumParent(nsDeviceContextSpecWin* aDevSpec)
+  : mDevSpecWin(aDevSpec)
 {
 }
 
 PDFiumParent::~PDFiumParent()
 {
   Close();
 }
 
@@ -27,22 +28,24 @@ PDFiumParent::Init(IPC::Channel* aChanne
 void
 PDFiumParent::ActorDestroy(ActorDestroyReason aWhy)
 {
 }
 
 mozilla::ipc::IPCResult
 PDFiumParent::RecvNotifyPageCount(const int& aPageCount)
 {
+  mDevSpecWin->SetPDFPageCount(aPageCount);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 PDFiumParent::RecvPrintEMF(const nsString& aFilePath)
 {
+  mDevSpecWin->PrintEMF(aFilePath);
   return IPC_OK();
 }
 
 void
 PDFiumParent::FinishPrint()
 {
 }
 
--- a/widget/windows/PDFiumParent.h
+++ b/widget/windows/PDFiumParent.h
@@ -16,27 +16,29 @@ namespace widget {
 
 class PDFiumProcessParent;
 
 class PDFiumParent final : public PPDFiumParent {
   typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PDFiumParent)
 
-  explicit PDFiumParent();
+  explicit PDFiumParent(nsDeviceContextSpecWin* aDevSpec);
 
   bool Init(IPC::Channel* aChannel, base::ProcessId aPid);
 
   void FinishPrint();
 
 private:
   ~PDFiumParent();
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
   // PPDFiumParent.
   mozilla::ipc::IPCResult RecvNotifyPageCount(const int& aPageCount) override;
   mozilla::ipc::IPCResult RecvPrintEMF(const nsString& aFilePath) override;
+
+  RefPtr<nsDeviceContextSpecWin> mDevSpecWin;
 };
 
 } // namespace widget
 } // namespace mozilla
 
 #endif // PDFIUMPARENT_H_
--- a/widget/windows/PDFiumProcessParent.cpp
+++ b/widget/windows/PDFiumProcessParent.cpp
@@ -35,17 +35,17 @@ PDFiumProcessParent::Launch(nsDeviceCont
   mLaunchThread = NS_GetCurrentThread();
 
   if (!AsyncLaunch()) {
     return false;
   }
 
   // Open the top level protocol for PDFium process.
   MOZ_ASSERT(!mParent);
-  mParent = new PDFiumParent();
+  mParent = new PDFiumParent(aDeviceContext);
   return mParent->Init(GetChannel(), base::GetProcId(GetChildProcessHandle()));
 }
 
 void
 PDFiumProcessParent::Delete()
 {
   // PDFiumProcessParent::Launch is not called, protocol is not created.
   // It is safe to destroy this object on any thread.
--- a/widget/windows/PDFiumProcessParent.h
+++ b/widget/windows/PDFiumProcessParent.h
@@ -31,16 +31,17 @@ public:
   ~PDFiumProcessParent();
 
   bool Launch(nsDeviceContextSpecWin* aDeviceContext);
 
   void Delete();
 
   bool CanShutdown() override { return true; }
 
+  PDFiumParent* GetActor() const { return mParent; }
 private:
 
   DISALLOW_COPY_AND_ASSIGN(PDFiumProcessParent);
 
   RefPtr<PDFiumParent> mParent;
   nsCOMPtr<nsIThread> mLaunchThread;
 };
 
--- a/widget/windows/nsDeviceContextSpecWin.cpp
+++ b/widget/windows/nsDeviceContextSpecWin.cpp
@@ -37,16 +37,18 @@
 #ifdef MOZ_ENABLE_SKIA_PDF
 #include "mozilla/gfx/PrintTargetSkPDF.h"
 #include "nsIUUIDGenerator.h"
 #include "mozilla/widget/PDFViaEMFPrintHelper.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsPrintfCString.h"
 #include "nsThreadUtils.h"
 #include "PDFiumProcessParent.h"
+#include "PDFiumParent.h"
+#include "WindowsEMF.h"
 #endif
 
 static mozilla::LazyLogModule kWidgetPrintingLogMod("printing-widget");
 #define PR_PL(_p1)  MOZ_LOG(kWidgetPrintingLogMod, mozilla::LogLevel::Debug, _p1)
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
@@ -354,68 +356,86 @@ nsDeviceContextSpecWin::GetPrintingScale
   mPrintSettings->GetResolution(&resolution);
   return float(resolution) / GetDPI();
 }
 
 #ifdef MOZ_ENABLE_SKIA_PDF
 void
 nsDeviceContextSpecWin::CleanupPrintViaPDF()
 {
-  if (mPDFPrintHelper) {
-    mPDFPrintHelper->CloseDocument();
-    mPDFPrintHelper = nullptr;
-    mPDFPageCount = 0;
-  }
+  MOZ_ASSERT(mPDFCurrentPageNum == mPDFPageCount);
+  mPDFPageCount = mPDFCurrentPageNum = 0;
 
   if (mPDFTempFile) {
     mPDFTempFile->Remove(/* aRecursive */ false);
     mPDFTempFile = nullptr;
   }
 
+  if (mPDFiumProcess) {
+    mPDFiumProcess->GetActor()->FinishPrint();
+    mPDFiumProcess->Delete();
+    mPDFiumProcess = nullptr;
+  }
+
   if (mDC != NULL) {
     if (mPrintViaPDFInProgress) {
       ::EndDoc(mDC);
       mPrintViaPDFInProgress = false;
     }
     ::DeleteDC(mDC);
     mDC = NULL;
   }
 }
 
 void
-nsDeviceContextSpecWin::FinishPrintViaPDF()
+nsDeviceContextSpecWin::FinishPrintViaPDF(nsString aFilePath)
 {
-  MOZ_ASSERT(mDC != NULL);
-  MOZ_ASSERT(mPDFPrintHelper);
-  MOZ_ASSERT(mPDFTempFile);
-  MOZ_ASSERT(mPrintViaPDFInProgress);
+  const int pageWidth = ::GetDeviceCaps(mDC, HORZRES);
+  const int pageHeight = ::GetDeviceCaps(mDC, VERTRES);
 
-  bool isPrinted = false;
-  bool endPageSuccess = false;
   if (::StartPage(mDC) > 0) {
-    isPrinted = mPDFPrintHelper->DrawPage(mDC, mPDFCurrentPageNum++,
-                                          ::GetDeviceCaps(mDC, HORZRES),
-                                          ::GetDeviceCaps(mDC, VERTRES));
-    if (::EndPage(mDC) > 0) {
-      endPageSuccess = true;
+    WindowsEMF emf;
+    if (emf.InitFromFileContents(aFilePath.get())) {
+      RECT printRect = {0, 0, pageWidth, pageHeight};
+      emf.Playback(mDC, printRect);
     }
+
+    ::EndPage(mDC);
   }
 
-  if (mPDFCurrentPageNum < mPDFPageCount && isPrinted && endPageSuccess) {
-    nsresult rv = NS_DispatchToCurrentThread(NewRunnableMethod(
-      "nsDeviceContextSpecWin::PrintPDFOnThread",
-      this,
-      &nsDeviceContextSpecWin::FinishPrintViaPDF));
-    if (NS_SUCCEEDED(rv)) {
-      return;
-    }
+  if (mPDFCurrentPageNum < mPDFPageCount) {
+    mPDFiumProcess->GetActor()->SendConvertPDFToEMF(mPDFCurrentPageNum++,
+                                                    pageWidth, pageHeight);
+    return;
   }
 
   CleanupPrintViaPDF();
 }
+
+void
+nsDeviceContextSpecWin::SetPDFPageCount(int aPageCount)
+{
+  mPDFPageCount = aPageCount;
+  mPDFCurrentPageNum = 0;
+
+  mPDFiumProcess->GetActor()->SendConvertPDFToEMF(mPDFCurrentPageNum++,
+                                                ::GetDeviceCaps(mDC, HORZRES),
+                                                ::GetDeviceCaps(mDC, VERTRES));
+}
+
+void
+nsDeviceContextSpecWin::PrintEMF(const nsString& aFilePath)
+{
+  NS_DispatchToCurrentThread(NewRunnableMethod<nsString>(
+      "nsDeviceContextSpecWin::FinishPrintViaPDF",
+      this,
+      &nsDeviceContextSpecWin::FinishPrintViaPDF,
+      aFilePath));
+}
+
 #endif
 
 nsresult
 nsDeviceContextSpecWin::BeginDocument(const nsAString& aTitle,
                                       const nsAString& aPrintToFileName,
                                       int32_t          aStartPage,
                                       int32_t          aEndPage)
 {
@@ -470,38 +490,20 @@ nsDeviceContextSpecWin::BeginDocument(co
   return NS_OK;
 }
 
 nsresult
 nsDeviceContextSpecWin::EndDocument()
 {
   nsresult rv = NS_OK;
 #ifdef MOZ_ENABLE_SKIA_PDF
-  if (mPrintViaSkPDF &&
-      mOutputFormat != nsIPrintSettings::kOutputFormatPDF &&
-      mPrintViaPDFInProgress) {
-
-    mPDFPrintHelper = MakeUnique<PDFViaEMFPrintHelper>();
-    rv = mPDFPrintHelper->OpenDocument(mPDFTempFile);
-    NS_ENSURE_SUCCESS(rv, rv);
-    mPDFPageCount = mPDFPrintHelper->GetPageCount();
-    if (mPDFPageCount <= 0) {
-      CleanupPrintViaPDF();
-      return NS_ERROR_FAILURE;
-    }
-    mPDFCurrentPageNum = 0;
-
-    rv = NS_DispatchToCurrentThread(NewRunnableMethod(
-      "nsDeviceContextSpecWin::PrintPDFOnThread",
-      this,
-      &nsDeviceContextSpecWin::FinishPrintViaPDF));
-    if (NS_FAILED(rv)) {
-      CleanupPrintViaPDF();
-      NS_WARNING("Failed to dispatch to the current thread!");
-    }
+  if (mPDFiumProcess) {
+    nsAutoString path;
+    mPDFTempFile->GetPath(path);
+    mPDFiumProcess->GetActor()->SendStartPrint(path);
   }
 #endif
   return rv;
 }
 
 //----------------------------------------------------------------------------------
 void nsDeviceContextSpecWin::SetDeviceName(const nsAString& aDeviceName)
 {
--- a/widget/windows/nsDeviceContextSpecWin.h
+++ b/widget/windows/nsDeviceContextSpecWin.h
@@ -61,43 +61,47 @@ public:
   // To get the DevMode from the Global memory Handle it must lock it 
   // So this call must be paired with a call to UnlockGlobalHandle
   void GetDevMode(LPDEVMODEW &aDevMode);
 
   // helper functions
   nsresult GetDataFromPrinter(const nsAString& aName,
                               nsIPrintSettings* aPS = nullptr);
 
+#ifdef MOZ_ENABLE_SKIA_PDF
+  void SetPDFPageCount(int aPageCount);
+  void PrintEMF(const nsString& aFilePath);
+#endif
+
 protected:
 
   void SetDeviceName(const nsAString& aDeviceName);
   void SetDriverName(const nsAString& aDriverName);
   void SetDevMode(LPDEVMODEW aDevMode);
 
   virtual ~nsDeviceContextSpecWin();
 
   nsString mDriverName;
   nsString mDeviceName;
   LPDEVMODEW mDevMode;
 
   nsCOMPtr<nsIPrintSettings> mPrintSettings;
   int16_t mOutputFormat = nsIPrintSettings::kOutputFormatNative;
 
 #ifdef MOZ_ENABLE_SKIA_PDF
-  void  FinishPrintViaPDF();
+  void  FinishPrintViaPDF(nsString aFilePath);
   void  CleanupPrintViaPDF();
 
   // This variable is independant of nsIPrintSettings::kOutputFormatPDF.
   // It controls both whether normal printing is done via PDF using Skia and
   // whether print-to-PDF uses Skia.
   bool mPrintViaSkPDF;
   nsCOMPtr<nsIFile> mPDFTempFile;
   HDC mDC;
   bool mPrintViaPDFInProgress;
-  mozilla::UniquePtr<PDFViaEMFPrintHelper> mPDFPrintHelper;
   int mPDFPageCount;
   int mPDFCurrentPageNum;
 
   PDFiumProcessParent* mPDFiumProcess;
 #endif
 };