Bug 1700051: part 45) Remove outdated part of comment in <mozInlineSpellChecker.cpp...
[gecko.git] / widget / nsDeviceContextSpecProxy.cpp
blob283b8e165a81a8a4c2601ef1279f2c7b54283c87
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsDeviceContextSpecProxy.h"
9 #include "gfxASurface.h"
10 #include "gfxPlatform.h"
11 #include "mozilla/gfx/DrawEventRecorder.h"
12 #include "mozilla/gfx/PrintTargetThebes.h"
13 #include "mozilla/layout/RemotePrintJobChild.h"
14 #include "mozilla/RefPtr.h"
15 #include "mozilla/Unused.h"
16 #include "nsComponentManagerUtils.h"
17 #include "nsAppDirectoryServiceDefs.h"
18 #include "nsDirectoryServiceUtils.h"
19 #include "nsIPrintSession.h"
20 #include "nsIPrintSettings.h"
21 #include "private/pprio.h"
23 using mozilla::Unused;
25 using namespace mozilla;
26 using namespace mozilla::gfx;
28 NS_IMPL_ISUPPORTS(nsDeviceContextSpecProxy, nsIDeviceContextSpec)
30 NS_IMETHODIMP
31 nsDeviceContextSpecProxy::Init(nsIWidget* aWidget,
32 nsIPrintSettings* aPrintSettings,
33 bool aIsPrintPreview) {
34 nsresult rv;
35 mRealDeviceContextSpec =
36 do_CreateInstance("@mozilla.org/gfx/devicecontextspec;1", &rv);
37 if (NS_WARN_IF(NS_FAILED(rv))) {
38 return rv;
41 mRealDeviceContextSpec->Init(nullptr, aPrintSettings, aIsPrintPreview);
42 if (NS_WARN_IF(NS_FAILED(rv))) {
43 mRealDeviceContextSpec = nullptr;
44 return rv;
47 mPrintSettings = aPrintSettings;
49 if (aIsPrintPreview) {
50 return NS_OK;
53 // nsIPrintSettings only has a weak reference to nsIPrintSession, so we hold
54 // it to make sure it's available for the lifetime of the print.
55 rv = mPrintSettings->GetPrintSession(getter_AddRefs(mPrintSession));
56 if (NS_FAILED(rv) || !mPrintSession) {
57 NS_WARNING("We can't print via the parent without an nsIPrintSession.");
58 return NS_ERROR_FAILURE;
61 mRemotePrintJob = mPrintSession->GetRemotePrintJob();
62 if (!mRemotePrintJob) {
63 NS_WARNING("We can't print via the parent without a RemotePrintJobChild.");
64 return NS_ERROR_FAILURE;
67 return NS_OK;
70 already_AddRefed<PrintTarget> nsDeviceContextSpecProxy::MakePrintTarget() {
71 MOZ_ASSERT(mRealDeviceContextSpec);
73 double width, height;
74 mPrintSettings->GetEffectiveSheetSize(&width, &height);
75 if (width <= 0 || height <= 0) {
76 return nullptr;
79 // convert twips to points
80 width /= TWIPS_PER_POINT_FLOAT;
81 height /= TWIPS_PER_POINT_FLOAT;
83 RefPtr<gfxASurface> surface =
84 gfxPlatform::GetPlatform()->CreateOffscreenSurface(
85 mozilla::gfx::IntSize::Ceil(width, height),
86 mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32);
87 if (!surface) {
88 return nullptr;
91 // The type of PrintTarget that we return here shouldn't really matter since
92 // our implementation of GetDrawEventRecorder returns an object, which means
93 // the DrawTarget returned by the PrintTarget will be a
94 // DrawTargetWrapAndRecord. The recording will be serialized and sent over to
95 // the parent process where PrintTranslator::TranslateRecording will call
96 // MakePrintTarget (indirectly via PrintTranslator::CreateDrawTarget) on
97 // whatever type of nsIDeviceContextSpecProxy is created for the platform that
98 // we are running on. It is that DrawTarget that the recording will be
99 // replayed on to print.
100 // XXX(jwatt): The above isn't quite true. We do want to use a
101 // PrintTargetRecording here, but we can't until bug 1280324 is figured out
102 // and fixed otherwise we will cause bug 1280181 to happen again.
103 RefPtr<PrintTarget> target = PrintTargetThebes::CreateOrNull(surface);
105 return target.forget();
108 NS_IMETHODIMP
109 nsDeviceContextSpecProxy::GetDrawEventRecorder(
110 mozilla::gfx::DrawEventRecorder** aDrawEventRecorder) {
111 MOZ_ASSERT(aDrawEventRecorder);
112 RefPtr<mozilla::gfx::DrawEventRecorder> result = mRecorder;
113 result.forget(aDrawEventRecorder);
114 return NS_OK;
117 float nsDeviceContextSpecProxy::GetDPI() {
118 MOZ_ASSERT(mRealDeviceContextSpec);
120 return mRealDeviceContextSpec->GetDPI();
123 float nsDeviceContextSpecProxy::GetPrintingScale() {
124 MOZ_ASSERT(mRealDeviceContextSpec);
126 return mRealDeviceContextSpec->GetPrintingScale();
129 gfxPoint nsDeviceContextSpecProxy::GetPrintingTranslate() {
130 MOZ_ASSERT(mRealDeviceContextSpec);
132 return mRealDeviceContextSpec->GetPrintingTranslate();
135 NS_IMETHODIMP
136 nsDeviceContextSpecProxy::BeginDocument(const nsAString& aTitle,
137 const nsAString& aPrintToFileName,
138 int32_t aStartPage, int32_t aEndPage) {
139 if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
140 mRemotePrintJob = nullptr;
141 return NS_ERROR_NOT_AVAILABLE;
144 mRecorder = new mozilla::layout::DrawEventRecorderPRFileDesc();
145 nsresult rv = mRemotePrintJob->InitializePrint(
146 nsString(aTitle), nsString(aPrintToFileName), aStartPage, aEndPage);
147 if (NS_FAILED(rv)) {
148 // The parent process will send a 'delete' message to tell this process to
149 // delete our RemotePrintJobChild. As soon as we return to the event loop
150 // and evaluate that message we will crash if we try to access
151 // mRemotePrintJob. We must not try to use it again.
152 mRemotePrintJob = nullptr;
154 return rv;
157 NS_IMETHODIMP
158 nsDeviceContextSpecProxy::EndDocument() {
159 if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
160 mRemotePrintJob = nullptr;
161 return NS_ERROR_NOT_AVAILABLE;
164 Unused << mRemotePrintJob->SendFinalizePrint();
166 return NS_OK;
169 NS_IMETHODIMP
170 nsDeviceContextSpecProxy::AbortDocument() {
171 if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
172 mRemotePrintJob = nullptr;
173 return NS_ERROR_NOT_AVAILABLE;
176 Unused << mRemotePrintJob->SendAbortPrint(NS_OK);
178 return NS_OK;
181 NS_IMETHODIMP
182 nsDeviceContextSpecProxy::BeginPage() {
183 if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
184 mRemotePrintJob = nullptr;
185 return NS_ERROR_NOT_AVAILABLE;
188 mRecorder->OpenFD(mRemotePrintJob->GetNextPageFD());
190 return NS_OK;
193 NS_IMETHODIMP
194 nsDeviceContextSpecProxy::EndPage() {
195 if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
196 mRemotePrintJob = nullptr;
197 return NS_ERROR_NOT_AVAILABLE;
200 // Send the page recording to the parent.
201 mRecorder->Close();
202 mRemotePrintJob->ProcessPage(std::move(mRecorder->TakeDependentSurfaces()));
204 return NS_OK;