Bug 1156742 Part 14: Complete RemotePrintJob using PrintTranslator. r=mconley

This commit is contained in:
Bob Owen 2015-12-21 20:33:14 +00:00
parent f7f010b245
commit 14c806bb15
6 changed files with 176 additions and 23 deletions

View File

@ -33,6 +33,10 @@ parent:
child:
// Inform the child that the print has been initialized in the parent or has
// failed with result aRv.
async PrintInitializationResult(nsresult aRv);
// Inform the child that the latest page has been processed remotely.
async PageProcessed();

View File

@ -18,6 +18,40 @@ RemotePrintJobChild::RemotePrintJobChild()
MOZ_COUNT_CTOR(RemotePrintJobChild);
}
nsresult
RemotePrintJobChild::InitializePrint(const nsString& aDocumentTitle,
const nsString& aPrintToFile,
const int32_t& aStartPage,
const int32_t& aEndPage)
{
// Print initialization can sometimes display a dialog in the parent, so we
// need to spin a nested event loop until initialization completes.
Unused << SendInitializePrint(aDocumentTitle, aPrintToFile, aStartPage,
aEndPage);
while (!mPrintInitialized) {
Unused << NS_ProcessNextEvent();
}
return mInitializationResult;
}
bool
RemotePrintJobChild::RecvPrintInitializationResult(const nsresult& aRv)
{
mPrintInitialized = true;
mInitializationResult = aRv;
return true;
}
void
RemotePrintJobChild::ProcessPage(Shmem& aStoredPage)
{
MOZ_ASSERT(mPagePrintTimer);
mPagePrintTimer->WaitForRemotePrint();
Unused << SendProcessPage(aStoredPage);
}
bool
RemotePrintJobChild::RecvPageProcessed()
{
@ -36,15 +70,6 @@ RemotePrintJobChild::RecvAbortPrint(const nsresult& aRv)
return true;
}
void
RemotePrintJobChild::ProcessPage(Shmem& aStoredPage)
{
MOZ_ASSERT(mPagePrintTimer);
mPagePrintTimer->WaitForRemotePrint();
Unused << SendProcessPage(aStoredPage);
}
void
RemotePrintJobChild::SetPagePrintTimer(nsPagePrintTimer* aPagePrintTimer)
{

View File

@ -26,12 +26,19 @@ public:
void ActorDestroy(ActorDestroyReason aWhy) final;
nsresult InitializePrint(const nsString& aDocumentTitle,
const nsString& aPrintToFile,
const int32_t& aStartPage,
const int32_t& aEndPage);
bool RecvPrintInitializationResult(const nsresult& aRv) final;
void ProcessPage(Shmem& aStoredPage);
bool RecvPageProcessed() final;
bool RecvAbortPrint(const nsresult& aRv) final;
void ProcessPage(Shmem& aStoredPage);
void SetPagePrintTimer(nsPagePrintTimer* aPagePrintTimer);
void SetPrintEngine(nsPrintEngine* aPrintEngine);
@ -39,6 +46,8 @@ public:
private:
~RemotePrintJobChild() final;
bool mPrintInitialized = false;
nsresult mInitializationResult = NS_OK;
RefPtr<nsPagePrintTimer> mPagePrintTimer;
RefPtr<nsPrintEngine> mPrintEngine;
};

View File

@ -6,7 +6,16 @@
#include "RemotePrintJobParent.h"
#include <istream>
#include "gfxContext.h"
#include "mozilla/Attributes.h"
#include "mozilla/unused.h"
#include "nsComponentManagerUtils.h"
#include "nsDeviceContext.h"
#include "nsIDeviceContextSpec.h"
#include "nsIPrintSettings.h"
#include "PrintTranslator.h"
namespace mozilla {
namespace layout {
@ -23,29 +32,123 @@ RemotePrintJobParent::RecvInitializePrint(const nsString& aDocumentTitle,
const int32_t& aStartPage,
const int32_t& aEndPage)
{
NS_NOTREACHED("RemotePrintJobParent::RecvInitializePrint not implemented!");
return false;
nsresult rv = InitializePrintDevice(aDocumentTitle, aPrintToFile, aStartPage,
aEndPage);
if (NS_FAILED(rv)) {
Unused << SendPrintInitializationResult(rv);
Unused << Send__delete__(this);
return true;
}
mPrintTranslator.reset(new PrintTranslator(mPrintDeviceContext));
Unused << SendPrintInitializationResult(NS_OK);
return true;
}
nsresult
RemotePrintJobParent::InitializePrintDevice(const nsString& aDocumentTitle,
const nsString& aPrintToFile,
const int32_t& aStartPage,
const int32_t& aEndPage)
{
nsresult rv;
nsCOMPtr<nsIDeviceContextSpec> deviceContextSpec =
do_CreateInstance("@mozilla.org/gfx/devicecontextspec;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = deviceContextSpec->Init(nullptr, mPrintSettings, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mPrintDeviceContext = new nsDeviceContext();
rv = mPrintDeviceContext->InitForPrinting(deviceContextSpec);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = mPrintDeviceContext->BeginDocument(aDocumentTitle, aPrintToFile,
aStartPage, aEndPage);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
bool
RemotePrintJobParent::RecvProcessPage(Shmem&& aStoredPage)
{
NS_NOTREACHED("PrintingParent::RecvProcessPage not implemented!");
return false;
nsresult rv = PrintPage(aStoredPage);
// Always deallocate the shared memory no matter what the result.
if (!DeallocShmem(aStoredPage)) {
NS_WARNING("Failed to deallocated shared memory, remote print will abort.");
rv = NS_ERROR_FAILURE;
}
if (NS_FAILED(rv)) {
Unused << SendAbortPrint(rv);
} else {
Unused << SendPageProcessed();
}
return true;
}
nsresult
RemotePrintJobParent::PrintPage(const Shmem& aStoredPage)
{
MOZ_ASSERT(mPrintDeviceContext);
nsresult rv = mPrintDeviceContext->BeginPage();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
std::istringstream recording(std::string(aStoredPage.get<char>(),
aStoredPage.Size<char>()));
mPrintTranslator->TranslateRecording(recording);
rv = mPrintDeviceContext->EndPage();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mPrintTranslator->ClearSavedFonts();
return NS_OK;
}
bool
RemotePrintJobParent::RecvFinalizePrint()
{
NS_NOTREACHED("PrintingParent::RecvFinalizePrint not implemented!");
return false;
// EndDocument is sometimes called in the child even when BeginDocument has
// not been called. See bug 1223332.
if (mPrintDeviceContext) {
nsresult rv = mPrintDeviceContext->EndDocument();
// Too late to abort the child just log.
NS_WARN_IF(NS_FAILED(rv));
}
Unused << Send__delete__(this);
return true;
}
bool
RemotePrintJobParent::RecvAbortPrint(const nsresult& aRv)
{
NS_NOTREACHED("PrintingParent::RecvAbortPrint not implemented!");
return false;
if (mPrintDeviceContext) {
Unused << mPrintDeviceContext->AbortDocument();
}
Unused << Send__delete__(this);
return true;
}
RemotePrintJobParent::~RemotePrintJobParent()

View File

@ -10,8 +10,12 @@
#include "mozilla/layout/PRemotePrintJobParent.h"
#include "nsCOMPtr.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
class nsDeviceContext;
class nsIPrintSettings;
class PrintTranslator;
namespace mozilla {
namespace layout {
@ -37,7 +41,16 @@ public:
private:
~RemotePrintJobParent() final;
nsresult InitializePrintDevice(const nsString& aDocumentTitle,
const nsString& aPrintToFile,
const int32_t& aStartPage,
const int32_t& aEndPage);
nsresult PrintPage(const Shmem& aStoredPage);
nsCOMPtr<nsIPrintSettings> mPrintSettings;
RefPtr<nsDeviceContext> mPrintDeviceContext;
UniquePtr<PrintTranslator> mPrintTranslator;
};
} // namespace layout

View File

@ -123,10 +123,9 @@ nsDeviceContextSpecProxy::BeginDocument(const nsAString& aTitle,
int32_t aStartPage, int32_t aEndPage)
{
mRecorder = new DrawEventRecorderMemory();
Unused << mRemotePrintJob->SendInitializePrint(nsString(aTitle),
nsString(aPrintToFileName),
aStartPage, aEndPage);
return NS_OK;
return mRemotePrintJob->InitializePrint(nsString(aTitle),
nsString(aPrintToFileName),
aStartPage, aEndPage);
}
NS_IMETHODIMP