зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1399787 - Part 11.a. Use PrintTargetEMF to print content documents. r=jwatt
Before we introduce PrintTargetEMF, all PrintTargets finish page printing task before the end of PrintTarget::EndPage(). Unlike others, a page printing in PrintTargetEMF is done after receiving an async callback from the pdfium process. So we have both async and sync page printing behavior now. This patch is trying to make both of them work correctly while priting a content document. MozReview-Commit-ID: 2PHJToFlvtu --HG-- extra : rebase_source : 9d2d7cf7330a157a0e5c6a414c75de94ca3fb5a1 extra : source : f61eb00f83acf45511d8448922212dccb12b05aa
This commit is contained in:
Родитель
6f25ba1878
Коммит
3654a24e84
|
@ -735,3 +735,24 @@ nsDeviceContext::GetDesktopToDeviceScale()
|
|||
|
||||
return DesktopToLayoutDeviceScale(1.0);
|
||||
}
|
||||
|
||||
bool
|
||||
nsDeviceContext::IsSyncPagePrinting() const
|
||||
{
|
||||
MOZ_ASSERT(mPrintTarget);
|
||||
return mPrintTarget->IsSyncPagePrinting();
|
||||
}
|
||||
|
||||
void
|
||||
nsDeviceContext::RegisterPageDoneCallback(PrintTarget::PageDoneCallback&& aCallback)
|
||||
{
|
||||
MOZ_ASSERT(mPrintTarget && aCallback && !IsSyncPagePrinting());
|
||||
mPrintTarget->RegisterPageDoneCallback(Move(aCallback));
|
||||
}
|
||||
void
|
||||
nsDeviceContext::UnregisterPageDoneCallback()
|
||||
{
|
||||
if (mPrintTarget) {
|
||||
mPrintTarget->UnregisterPageDoneCallback();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "nscore.h" // for char16_t, nsAString
|
||||
#include "mozilla/AppUnits.h" // for AppUnits
|
||||
#include "nsFontMetrics.h" // for nsFontMetrics::Params
|
||||
#include "mozilla/gfx/PrintTarget.h" // for PrintTarget::PageDoneCallback
|
||||
|
||||
class gfxContext;
|
||||
class gfxTextPerfMetrics;
|
||||
|
@ -33,12 +34,6 @@ class nsIScreenManager;
|
|||
class nsIWidget;
|
||||
struct nsRect;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class PrintTarget;
|
||||
}
|
||||
}
|
||||
|
||||
class nsDeviceContext final
|
||||
{
|
||||
public:
|
||||
|
@ -280,6 +275,9 @@ public:
|
|||
|
||||
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale();
|
||||
|
||||
bool IsSyncPagePrinting() const;
|
||||
void RegisterPageDoneCallback(PrintTarget::PageDoneCallback&& aCallback);
|
||||
void UnregisterPageDoneCallback();
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
~nsDeviceContext();
|
||||
|
|
|
@ -229,5 +229,18 @@ PrintTarget::Finish()
|
|||
cairo_surface_finish(mCairoSurface);
|
||||
}
|
||||
|
||||
void
|
||||
PrintTarget::RegisterPageDoneCallback(PageDoneCallback&& aCallback)
|
||||
{
|
||||
MOZ_ASSERT(aCallback && !IsSyncPagePrinting());
|
||||
mPageDoneCallback = Move(aCallback);
|
||||
}
|
||||
|
||||
void
|
||||
PrintTarget::UnregisterPageDoneCallback()
|
||||
{
|
||||
mPageDoneCallback = nullptr;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#ifndef MOZILLA_GFX_PRINTTARGET_H
|
||||
#define MOZILLA_GFX_PRINTTARGET_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
@ -26,6 +28,7 @@ class DrawEventRecorder;
|
|||
*/
|
||||
class PrintTarget {
|
||||
public:
|
||||
typedef std::function<void(nsresult)> PageDoneCallback;
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(PrintTarget);
|
||||
|
||||
|
@ -136,6 +139,17 @@ public:
|
|||
*/
|
||||
virtual already_AddRefed<DrawTarget> GetReferenceDrawTarget(DrawEventRecorder* aRecorder);
|
||||
|
||||
/**
|
||||
* If IsSyncPagePrinting returns true, then a user can assume the content of
|
||||
* a page was already printed after EndPage().
|
||||
* If IsSyncPagePrinting returns false, then a user should register a
|
||||
* callback function using RegisterPageDoneCallback to receive page print
|
||||
* done notifications.
|
||||
*/
|
||||
virtual bool IsSyncPagePrinting() const { return true; }
|
||||
void RegisterPageDoneCallback(PageDoneCallback&& aCallback);
|
||||
void UnregisterPageDoneCallback();
|
||||
|
||||
static void AdjustPrintJobNameForIPP(const nsAString& aJobName,
|
||||
nsCString& aAdjustedJobName);
|
||||
static void AdjustPrintJobNameForIPP(const nsAString& aJobName,
|
||||
|
@ -169,6 +183,8 @@ protected:
|
|||
// owned by mRecordingRefDT, so kept alive for our entire lifetime if set:
|
||||
DrawEventRecorder* mRecorder;
|
||||
#endif
|
||||
|
||||
PageDoneCallback mPageDoneCallback;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -176,7 +176,9 @@ PrintTargetEMF::ConvertToEMFDone(const nsresult& aResult,
|
|||
mPDFFileForOnePage->Remove(/* aRecursive */ false);
|
||||
mPDFFileForOnePage = nullptr;
|
||||
|
||||
// TBD: We should call RemotePrintJobChild::SendPageProcessed here.
|
||||
if (mPageDoneCallback) {
|
||||
mPageDoneCallback(aResult);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
GetReferenceDrawTarget(DrawEventRecorder* aRecorder) final;
|
||||
|
||||
void ConvertToEMFDone(const nsresult& aResult, mozilla::ipc::Shmem&& aEMF);
|
||||
bool IsSyncPagePrinting() const final { return false; }
|
||||
|
||||
private:
|
||||
PrintTargetEMF(HDC aDC, const IntSize& aSize);
|
||||
|
|
|
@ -88,6 +88,10 @@ RemotePrintJobParent::InitializePrintDevice(const nsString& aDocumentTitle,
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (!mPrintDeviceContext->IsSyncPagePrinting()) {
|
||||
mPrintDeviceContext->RegisterPageDoneCallback([this](nsresult aResult) { PageDone(aResult); });
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -116,19 +120,10 @@ RemotePrintJobParent::RecvProcessPage()
|
|||
nsresult rv = PrintPage(mCurrentPageStream);
|
||||
mCurrentPageStream.Close();
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
Unused << SendAbortPrint(rv);
|
||||
return IPC_OK();
|
||||
if (mPrintDeviceContext->IsSyncPagePrinting()) {
|
||||
PageDone(rv);
|
||||
}
|
||||
|
||||
FileDescriptor fd;
|
||||
rv = PrepareNextPageFD(&fd);
|
||||
if (NS_FAILED(rv)) {
|
||||
Unused << SendAbortPrint(rv);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
Unused << SendPageProcessed(fd);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -153,6 +148,22 @@ RemotePrintJobParent::PrintPage(PRFileDescStream& aRecording)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
RemotePrintJobParent::PageDone(nsresult aResult)
|
||||
{
|
||||
if (NS_FAILED(aResult)) {
|
||||
Unused << SendAbortPrint(aResult);
|
||||
} else {
|
||||
FileDescriptor fd;
|
||||
aResult = PrepareNextPageFD(&fd);
|
||||
if (NS_FAILED(aResult)) {
|
||||
Unused << SendAbortPrint(aResult);
|
||||
}
|
||||
|
||||
Unused << SendPageProcessed(fd);
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RemotePrintJobParent::RecvFinalizePrint()
|
||||
{
|
||||
|
@ -163,8 +174,12 @@ RemotePrintJobParent::RecvFinalizePrint()
|
|||
|
||||
// Too late to abort the child just log.
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EndDocument failed");
|
||||
}
|
||||
|
||||
// Since RecvFinalizePrint is called after all page printed, there should
|
||||
// be no more page-done callbacks after that, in theory. Unregistering
|
||||
// page-done callback is not must have, but we still do this for safety.
|
||||
mPrintDeviceContext->UnregisterPageDoneCallback();
|
||||
}
|
||||
|
||||
Unused << Send__delete__(this);
|
||||
return IPC_OK();
|
||||
|
@ -175,6 +190,7 @@ RemotePrintJobParent::RecvAbortPrint(const nsresult& aRv)
|
|||
{
|
||||
if (mPrintDeviceContext) {
|
||||
Unused << mPrintDeviceContext->AbortDocument();
|
||||
mPrintDeviceContext->UnregisterPageDoneCallback();
|
||||
}
|
||||
|
||||
Unused << Send__delete__(this);
|
||||
|
@ -246,6 +262,9 @@ RemotePrintJobParent::~RemotePrintJobParent()
|
|||
void
|
||||
RemotePrintJobParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
if (mPrintDeviceContext) {
|
||||
mPrintDeviceContext->UnregisterPageDoneCallback();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layout
|
||||
|
|
|
@ -76,6 +76,12 @@ private:
|
|||
|
||||
nsresult PrintPage(PRFileDescStream& aRecording);
|
||||
|
||||
/**
|
||||
* Called to notify our corresponding RemotePrintJobChild once we've
|
||||
* finished printing a page.
|
||||
*/
|
||||
void PageDone(nsresult aResult);
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> mPrintSettings;
|
||||
RefPtr<nsDeviceContext> mPrintDeviceContext;
|
||||
UniquePtr<PrintTranslator> mPrintTranslator;
|
||||
|
|
Загрузка…
Ссылка в новой задаче