diff --git a/gfx/thebes/PrintTargetEMF.cpp b/gfx/thebes/PrintTargetEMF.cpp index 486548ba485d..8972c45da631 100644 --- a/gfx/thebes/PrintTargetEMF.cpp +++ b/gfx/thebes/PrintTargetEMF.cpp @@ -22,6 +22,7 @@ PrintTargetEMF::PrintTargetEMF(HDC aDC, const IntSize& aSize) : PrintTarget(/* not using cairo_surface_t */ nullptr, aSize) , mPrinterDC(aDC) , mWaitingForEMFConversion(false) + , mChannelBroken(false) { } @@ -68,12 +69,15 @@ PrintTargetEMF::BeginPrinting(const nsAString& aTitle, mPDFiumProcess = new PDFiumProcessParent(); NS_ENSURE_TRUE(mPDFiumProcess->Launch(this), NS_ERROR_FAILURE); + mChannelBroken = false; + return NS_OK; } nsresult PrintTargetEMF::EndPrinting() { + mPDFiumProcess->GetActor()->EndConversion(); return (::EndDoc(mPrinterDC) <= 0) ? NS_ERROR_FAILURE : NS_OK; } @@ -87,7 +91,7 @@ nsresult PrintTargetEMF::BeginPage() { MOZ_ASSERT(!mPDFFileForOnePage && !mTargetForCurrentPage); - + NS_ENSURE_TRUE(!mChannelBroken, NS_ERROR_FAILURE); NS_ENSURE_TRUE(::StartPage(mPrinterDC) >0, NS_ERROR_FAILURE); // We create a new file for each page so that we can make sure each new @@ -112,6 +116,8 @@ PrintTargetEMF::BeginPage() nsresult PrintTargetEMF::EndPage() { + NS_ENSURE_TRUE(!mChannelBroken, NS_ERROR_FAILURE); + mTargetForCurrentPage->EndPage(); mTargetForCurrentPage->EndPrinting(); mTargetForCurrentPage->Finish(); @@ -122,9 +128,13 @@ PrintTargetEMF::EndPage() &prfile); NS_ENSURE_SUCCESS(rv, rv); FileDescriptor descriptor(FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(prfile))); - mPDFiumProcess->GetActor()->SendConvertToEMF(descriptor, + if (!mPDFiumProcess->GetActor()->SendConvertToEMF(descriptor, ::GetDeviceCaps(mPrinterDC, HORZRES), - ::GetDeviceCaps(mPrinterDC, VERTRES)); + ::GetDeviceCaps(mPrinterDC, VERTRES))) + { + return NS_ERROR_FAILURE; + } + PR_Close(prfile); mWaitingForEMFConversion = true; @@ -135,6 +145,7 @@ already_AddRefed PrintTargetEMF::MakeDrawTarget(const IntSize& aSize, DrawEventRecorder* aRecorder) { + MOZ_ASSERT(!mChannelBroken); return mTargetForCurrentPage->MakeDrawTarget(aSize, aRecorder); } @@ -157,6 +168,8 @@ void PrintTargetEMF::ConvertToEMFDone(const nsresult& aResult, mozilla::ipc::Shmem&& aEMF) { + MOZ_ASSERT(!mChannelBroken, "It is not possible to get conversion callback " + "after the channel was broken."); mWaitingForEMFConversion = false; if (::StartPage(mPrinterDC) > 0) { diff --git a/gfx/thebes/PrintTargetEMF.h b/gfx/thebes/PrintTargetEMF.h index 3a6d713e4469..e238618b59fe 100644 --- a/gfx/thebes/PrintTargetEMF.h +++ b/gfx/thebes/PrintTargetEMF.h @@ -56,6 +56,7 @@ public: void ConvertToEMFDone(const nsresult& aResult, mozilla::ipc::Shmem&& aEMF); bool IsSyncPagePrinting() const final { return false; } + void ChannelIsBroken() { mChannelBroken = true; } private: PrintTargetEMF(HDC aDC, const IntSize& aSize); @@ -68,6 +69,7 @@ private: PDFiumProcessParent* mPDFiumProcess; HDC mPrinterDC; bool mWaitingForEMFConversion; + bool mChannelBroken; }; } // namespace gfx diff --git a/widget/windows/PDFiumParent.cpp b/widget/windows/PDFiumParent.cpp index f4355a3360dd..aadafb0e3d3e 100644 --- a/widget/windows/PDFiumParent.cpp +++ b/widget/windows/PDFiumParent.cpp @@ -29,6 +29,10 @@ PDFiumParent::Init(IPC::Channel* aChannel, base::ProcessId aPid) void PDFiumParent::ActorDestroy(ActorDestroyReason aWhy) { + if (mTarget) { + mTarget->ChannelIsBroken(); + } + if (mConversionDoneCallback) { // Since this printing job was aborted, we do not need to report EMF buffer // back to mTarget. @@ -59,6 +63,12 @@ PDFiumParent::AbortConversion(ConversionDoneCallback aCallback) mConversionDoneCallback = aCallback; } +void PDFiumParent::EndConversion() +{ + // The printing job is finished correctly, mTarget is no longer needed. + mTarget = nullptr; +} + void PDFiumParent::OnChannelConnected(int32_t pid) { diff --git a/widget/windows/PDFiumParent.h b/widget/windows/PDFiumParent.h index 4ee968e4f95d..535e97b29c2b 100644 --- a/widget/windows/PDFiumParent.h +++ b/widget/windows/PDFiumParent.h @@ -30,6 +30,7 @@ class PDFiumParent final : public PPDFiumParent, bool Init(IPC::Channel* aChannel, base::ProcessId aPid); void AbortConversion(ConversionDoneCallback aCallback); + void EndConversion(); FORWARD_SHMEM_ALLOCATOR_TO(PPDFiumParent) private: