Bug 1399787 - Part 6. Implement PDFiumParent.
MozReview-Commit-ID: 415xovMsiwN
--- 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();
}
@@ -26,24 +27,27 @@ PDFiumParent::Init(IPC::Channel* aChanne
}
return true;
}
void
PDFiumParent::ActorDestroy(ActorDestroyReason aWhy)
{
+ mDevSpecWin->FinishPrint();
}
mozilla::ipc::IPCResult
PDFiumParent::RecvFinishedEMFConversions()
{
+ mDevSpecWin->FinishPrint();
return IPC_OK();
}
mozilla::ipc::IPCResult
PDFiumParent::RecvDoneConvertingToEMF(const nsString& aEMFFilePath)
{
+ mDevSpecWin->PrintEMF(aEMFFilePath);
return IPC_OK();
}
} // namespace widget
} // namespace mozilla
--- a/widget/windows/PDFiumParent.h
+++ b/widget/windows/PDFiumParent.h
@@ -3,34 +3,37 @@
* 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 PDFIUMPARENT_H_
#define PDFIUMPARENT_H_
#include "mozilla/widget/PPDFiumParent.h"
+class nsDeviceContextSpecWin;
namespace mozilla {
namespace widget {
class PDFiumParent final : public PPDFiumParent {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PDFiumParent)
- explicit PDFiumParent();
+ explicit PDFiumParent(nsDeviceContextSpecWin* aDevSpec);
bool Init(IPC::Channel* aChannel, base::ProcessId aPid);
private:
~PDFiumParent();
// PPDFiumParent functions.
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvDoneConvertingToEMF(const nsString& aEMFFilePath) override;
mozilla::ipc::IPCResult RecvFinishedEMFConversions() override;
+
+ RefPtr<nsDeviceContextSpecWin> mDevSpecWin;
};
} // namespace widget
} // namespace mozilla
#endif // PDFIUMPARENT_H_
--- a/widget/windows/PDFiumProcessParent.cpp
+++ b/widget/windows/PDFiumProcessParent.cpp
@@ -24,27 +24,27 @@ PDFiumProcessParent::PDFiumProcessParent
}
PDFiumProcessParent::~PDFiumProcessParent()
{
MOZ_COUNT_DTOR(PDFiumProcessParent);
}
bool
-PDFiumProcessParent::Launch()
+PDFiumProcessParent::Launch(nsDeviceContextSpecWin* aDeviceContext)
{
mLaunchThread = NS_GetCurrentThread();
if (!AsyncLaunch()) {
return false;
}
// Open the top level protocol for PDFium process.
MOZ_ASSERT(!mPDFiumActor);
- mPDFiumActor = new PDFiumParent();
+ mPDFiumActor = new PDFiumParent(aDeviceContext);
return mPDFiumActor->Init(GetChannel(),
base::GetProcId(GetChildProcessHandle()));
}
void
PDFiumProcessParent::Delete()
{
// PDFiumProcessParent::Launch is not called, protocol is not created.
--- a/widget/windows/PDFiumProcessParent.h
+++ b/widget/windows/PDFiumProcessParent.h
@@ -25,22 +25,24 @@ namespace mozilla {
namespace widget {
class PDFiumProcessParent final : public mozilla::ipc::GeckoChildProcessHost
{
public:
PDFiumProcessParent();
~PDFiumProcessParent();
- bool Launch();
+ bool Launch(nsDeviceContextSpecWin* aDeviceContext);
void Delete();
bool CanShutdown() override { return true; }
+ PDFiumParent* GetActor() const { return mPDFiumActor; }
+
private:
DISALLOW_COPY_AND_ASSIGN(PDFiumProcessParent);
RefPtr<PDFiumParent> mPDFiumActor;
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;
@@ -97,18 +99,16 @@ struct AutoFreeGlobalPrinters
//----------------------------------------------------------------------------------
nsDeviceContextSpecWin::nsDeviceContextSpecWin()
{
mDevMode = nullptr;
#ifdef MOZ_ENABLE_SKIA_PDF
mPrintViaSkPDF = false;
mDC = NULL;
- mPDFPageCount = 0;
- mPDFCurrentPageNum = 0;
mPrintViaPDFInProgress = false;
mPDFiumProcess = nullptr;
#endif
}
//----------------------------------------------------------------------------------
@@ -352,24 +352,27 @@ nsDeviceContextSpecWin::GetPrintingScale
// The print settings will have the resolution stored from the real device.
int32_t resolution;
mPrintSettings->GetResolution(&resolution);
return float(resolution) / GetDPI();
}
#ifdef MOZ_ENABLE_SKIA_PDF
void
+nsDeviceContextSpecWin::FinishPrint()
+{
+ NS_DispatchToMainThread(NewRunnableMethod(
+ "nsDeviceContextSpecWin::CleanupPrintViaPDF",
+ this,
+ &nsDeviceContextSpecWin::CleanupPrintViaPDF));
+}
+
+void
nsDeviceContextSpecWin::CleanupPrintViaPDF()
{
- if (mPDFPrintHelper) {
- mPDFPrintHelper->CloseDocument();
- mPDFPrintHelper = nullptr;
- mPDFPageCount = 0;
- }
-
if (mPDFTempFile) {
mPDFTempFile->Remove(/* aRecursive */ false);
mPDFTempFile = nullptr;
}
if (mDC != NULL) {
if (mPrintViaPDFInProgress) {
::EndDoc(mDC);
@@ -381,46 +384,47 @@ nsDeviceContextSpecWin::CleanupPrintViaP
if (mPDFiumProcess) {
mPDFiumProcess->Delete();
mPDFiumProcess = nullptr;
}
}
void
-nsDeviceContextSpecWin::FinishPrintViaPDF()
+nsDeviceContextSpecWin::PrintEMFInternal(nsString aEMFFilePath)
{
- MOZ_ASSERT(mDC != NULL);
- MOZ_ASSERT(mPDFPrintHelper);
- MOZ_ASSERT(mPDFTempFile);
- MOZ_ASSERT(mPrintViaPDFInProgress);
+ if (::StartPage(mDC) > 0) {
+ WindowsEMF emf;
+ if (emf.InitFromFileContents(aEMFFilePath.get())) {
+ RECT printRect = {0, 0, ::GetDeviceCaps(mDC, HORZRES),
+ ::GetDeviceCaps(mDC, VERTRES)};
+ emf.Playback(mDC, printRect);
+ }
- 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;
- }
+ ::EndPage(mDC);
}
- if (mPDFCurrentPageNum < mPDFPageCount && isPrinted && endPageSuccess) {
- nsresult rv = NS_DispatchToCurrentThread(NewRunnableMethod(
- "nsDeviceContextSpecWin::PrintPDFOnThread",
+ // Delete the intermediate EMF file.
+ nsCOMPtr<nsIFile> emfFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
+ if (emfFile) {
+ emfFile->InitWithPath(aEMFFilePath);
+ emfFile->Remove(/* aRecursive */ false);
+ }
+}
+
+void
+nsDeviceContextSpecWin::PrintEMF(const nsString& aEMFFilePath)
+{
+ NS_DispatchToCurrentThread(NewRunnableMethod<nsString>(
+ "nsDeviceContextSpecWin::PrintEMFInternal",
this,
- &nsDeviceContextSpecWin::FinishPrintViaPDF));
- if (NS_SUCCEEDED(rv)) {
- return;
- }
- }
+ &nsDeviceContextSpecWin::PrintEMFInternal,
+ aEMFFilePath));
+}
- CleanupPrintViaPDF();
-}
#endif
nsresult
nsDeviceContextSpecWin::BeginDocument(const nsAString& aTitle,
const nsAString& aPrintToFileName,
int32_t aStartPage,
int32_t aEndPage)
{
@@ -457,52 +461,38 @@ nsDeviceContextSpecWin::BeginDocument(co
if (::StartDocW(mDC, &di) <= 0) {
// Defer calling CleanupPrintViaPDF() in destructor because PDF temp file
// is not ready yet.
return NS_ERROR_FAILURE;
}
mPrintViaPDFInProgress = true;
- MOZ_ASSERT(!mPDFiumProcess);
+ MOZ_ASSERT(!mPDFiumProcess && mDC);
mPDFiumProcess = new PDFiumProcessParent();
NS_ENSURE_TRUE(mPDFiumProcess->Launch(this), NS_ERROR_FAILURE);
}
#endif
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);
+ if (mPDFiumProcess) {
+ MOZ_ASSERT(mDC);
+ nsAutoString pdfFilePath;
+ rv = mPDFTempFile->GetPath(pdfFilePath);
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!");
- }
+ mPDFiumProcess->GetActor()->SendConvertToEMF(pdfFilePath,
+ ::GetDeviceCaps(mDC, HORZRES),
+ ::GetDeviceCaps(mDC, VERTRES));
}
#endif
return rv;
}
//----------------------------------------------------------------------------------
void nsDeviceContextSpecWin::SetDeviceName(const nsAString& aDeviceName)
{
--- a/widget/windows/nsDeviceContextSpecWin.h
+++ b/widget/windows/nsDeviceContextSpecWin.h
@@ -61,45 +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 PrintEMF(const nsString& aEMFFilePath);
+ void FinishPrint();
+#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 CleanupPrintViaPDF();
+ void PrintEMFInternal(nsString aEMFFilePath);
+ 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
};
//-------------------------------------------------------------------------
// Printer Enumerator