1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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/. */
5
6 #include "PrintTargetWindows.h"
7
8 #include "cairo-win32.h"
9 #include "mozilla/gfx/HelpersCairo.h"
10 #include "nsCoord.h"
11 #include "nsString.h"
12
13 namespace mozilla {
14 namespace gfx {
15
PrintTargetWindows(cairo_surface_t * aCairoSurface,const IntSize & aSize,HDC aDC)16 PrintTargetWindows::PrintTargetWindows(cairo_surface_t* aCairoSurface,
17 const IntSize& aSize,
18 HDC aDC)
19 : PrintTarget(aCairoSurface, aSize)
20 , mDC(aDC)
21 {
22 // TODO: At least add basic memory reporting.
23 // 4 * mSize.width * mSize.height + sizeof(PrintTargetWindows) ?
24 }
25
26 /* static */ already_AddRefed<PrintTargetWindows>
CreateOrNull(HDC aDC)27 PrintTargetWindows::CreateOrNull(HDC aDC)
28 {
29 // Figure out the cairo surface size - Windows we need to use the printable
30 // area of the page. Note: we only scale the printing using the LOGPIXELSY,
31 // so we use that when calculating the surface width as well as the height.
32 int32_t heightDPI = ::GetDeviceCaps(aDC, LOGPIXELSY);
33 float width =
34 (::GetDeviceCaps(aDC, HORZRES) * POINTS_PER_INCH_FLOAT) / heightDPI;
35 float height =
36 (::GetDeviceCaps(aDC, VERTRES) * POINTS_PER_INCH_FLOAT) / heightDPI;
37 IntSize size = IntSize::Truncate(width, height);
38
39 if (!Factory::CheckSurfaceSize(size)) {
40 return nullptr;
41 }
42
43 cairo_surface_t* surface = cairo_win32_printing_surface_create(aDC);
44
45 if (cairo_surface_status(surface)) {
46 return nullptr;
47 }
48
49 // The new object takes ownership of our surface reference.
50 RefPtr<PrintTargetWindows> target =
51 new PrintTargetWindows(surface, size, aDC);
52
53 return target.forget();
54 }
55
56 nsresult
BeginPrinting(const nsAString & aTitle,const nsAString & aPrintToFileName)57 PrintTargetWindows::BeginPrinting(const nsAString& aTitle,
58 const nsAString& aPrintToFileName)
59 {
60 const uint32_t DOC_TITLE_LENGTH = MAX_PATH - 1;
61
62 DOCINFOW docinfo;
63
64 nsString titleStr(aTitle);
65 if (titleStr.Length() > DOC_TITLE_LENGTH) {
66 titleStr.SetLength(DOC_TITLE_LENGTH - 3);
67 titleStr.AppendLiteral("...");
68 }
69
70 nsString docName(aPrintToFileName);
71 docinfo.cbSize = sizeof(docinfo);
72 docinfo.lpszDocName = titleStr.Length() > 0 ? titleStr.get() : L"Mozilla Document";
73 docinfo.lpszOutput = docName.Length() > 0 ? docName.get() : nullptr;
74 docinfo.lpszDatatype = nullptr;
75 docinfo.fwType = 0;
76
77 ::StartDocW(mDC, &docinfo);
78
79 return NS_OK;
80 }
81
82 nsresult
EndPrinting()83 PrintTargetWindows::EndPrinting()
84 {
85 int result = ::EndDoc(mDC);
86 return (result <= 0) ? NS_ERROR_FAILURE : NS_OK;
87 }
88
89 nsresult
AbortPrinting()90 PrintTargetWindows::AbortPrinting()
91 {
92 int result = ::AbortDoc(mDC);
93 return (result <= 0) ? NS_ERROR_FAILURE : NS_OK;
94 }
95
96 nsresult
BeginPage()97 PrintTargetWindows::BeginPage()
98 {
99 int result = ::StartPage(mDC);
100 return (result <= 0) ? NS_ERROR_FAILURE : NS_OK;
101 }
102
103 nsresult
EndPage()104 PrintTargetWindows::EndPage()
105 {
106 cairo_surface_show_page(mCairoSurface);
107 int result = ::EndPage(mDC);
108 return (result <= 0) ? NS_ERROR_FAILURE : NS_OK;
109 }
110
111 } // namespace gfx
112 } // namespace mozilla
113