1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "PrintTargetWindows.h"
8 #include "cairo-win32.h"
9 #include "mozilla/gfx/HelpersCairo.h"
16 PrintTargetWindows::PrintTargetWindows(cairo_surface_t
* aCairoSurface
,
17 const IntSize
& aSize
, HDC aDC
)
18 : PrintTarget(aCairoSurface
, aSize
), mDC(aDC
) {
19 // TODO: At least add basic memory reporting.
20 // 4 * mSize.width * mSize.height + sizeof(PrintTargetWindows) ?
24 already_AddRefed
<PrintTargetWindows
> PrintTargetWindows::CreateOrNull(HDC aDC
) {
25 // Figure out the paper size, the actual surface size will be the printable
26 // area which is likely smaller, but the size here is later used to create the
27 // draw target where the full page size is needed.
28 // Note: we only scale the printing using the LOGPIXELSY,
29 // so we use that when calculating the surface width as well as the height.
30 int32_t heightDPI
= ::GetDeviceCaps(aDC
, LOGPIXELSY
);
32 (::GetDeviceCaps(aDC
, PHYSICALWIDTH
) * POINTS_PER_INCH_FLOAT
) / heightDPI
;
34 (::GetDeviceCaps(aDC
, PHYSICALHEIGHT
) * POINTS_PER_INCH_FLOAT
) /
36 IntSize size
= IntSize::Truncate(width
, height
);
38 if (!Factory::CheckSurfaceSize(size
)) {
42 cairo_surface_t
* surface
= cairo_win32_printing_surface_create(aDC
);
44 if (cairo_surface_status(surface
)) {
48 // The new object takes ownership of our surface reference.
49 RefPtr
<PrintTargetWindows
> target
=
50 new PrintTargetWindows(surface
, size
, aDC
);
52 return target
.forget();
55 nsresult
PrintTargetWindows::BeginPrinting(const nsAString
& aTitle
,
56 const nsAString
& aPrintToFileName
,
59 const uint32_t DOC_TITLE_LENGTH
= MAX_PATH
- 1;
63 nsString
titleStr(aTitle
);
64 if (titleStr
.Length() > DOC_TITLE_LENGTH
) {
65 titleStr
.SetLength(DOC_TITLE_LENGTH
- 3);
66 titleStr
.AppendLiteral("...");
69 nsString
docName(aPrintToFileName
);
70 docinfo
.cbSize
= sizeof(docinfo
);
72 titleStr
.Length() > 0 ? titleStr
.get() : L
"Mozilla Document";
73 docinfo
.lpszOutput
= docName
.Length() > 0 ? docName
.get() : nullptr;
74 docinfo
.lpszDatatype
= nullptr;
77 // If the user selected Microsoft Print to PDF or XPS Document Printer, then
78 // the following StartDoc call will put up a dialog window to prompt the
79 // user to provide the name and location of the file to be saved. A zero or
80 // negative return value indicates failure. In that case we want to check
81 // whether that is because the user hit Cancel, since we want to treat that
82 // specially to avoid notifying the user that the print "failed" in that
84 // XXX We should perhaps introduce a new NS_ERROR_USER_CANCELLED errer.
85 int result
= ::StartDocW(mDC
, &docinfo
);
87 if (::GetLastError() == ERROR_CANCELLED
) {
88 return NS_ERROR_ABORT
;
90 return NS_ERROR_FAILURE
;
95 nsresult
PrintTargetWindows::EndPrinting() {
96 int result
= ::EndDoc(mDC
);
97 return (result
<= 0) ? NS_ERROR_FAILURE
: NS_OK
;
100 nsresult
PrintTargetWindows::AbortPrinting() {
101 PrintTarget::AbortPrinting();
102 int result
= ::AbortDoc(mDC
);
103 return (result
<= 0) ? NS_ERROR_FAILURE
: NS_OK
;
106 nsresult
PrintTargetWindows::BeginPage(const IntSize
& aSizeInPoints
) {
107 PrintTarget::BeginPage(aSizeInPoints
);
108 int result
= ::StartPage(mDC
);
109 return (result
<= 0) ? NS_ERROR_FAILURE
: NS_OK
;
112 nsresult
PrintTargetWindows::EndPage() {
113 cairo_surface_show_page(mCairoSurface
);
114 PrintTarget::EndPage();
115 int result
= ::EndPage(mDC
);
116 return (result
<= 0) ? NS_ERROR_FAILURE
: NS_OK
;
120 } // namespace mozilla