widget/cocoa/nsDeviceContextSpecX.mm

changeset 2
7e26c7da4463
equal deleted inserted replaced
-1:000000000000 0:5a9fc5388a08
1 /* -*- Mode: C++; tab-width: 4; 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 "nsDeviceContextSpecX.h"
7
8 #include "nsCRT.h"
9 #include <unistd.h>
10
11 #include "nsAutoPtr.h"
12 #include "nsIServiceManager.h"
13 #include "nsIPrintOptions.h"
14 #include "nsPrintSettingsX.h"
15
16 #include "gfxQuartzSurface.h"
17
18 // This must be the last include:
19 #include "nsObjCExceptions.h"
20
21 nsDeviceContextSpecX::nsDeviceContextSpecX()
22 : mPrintSession(NULL)
23 , mPageFormat(kPMNoPageFormat)
24 , mPrintSettings(kPMNoPrintSettings)
25 {
26 }
27
28 nsDeviceContextSpecX::~nsDeviceContextSpecX()
29 {
30 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
31
32 if (mPrintSession)
33 ::PMRelease(mPrintSession);
34
35 NS_OBJC_END_TRY_ABORT_BLOCK;
36 }
37
38 NS_IMPL_ISUPPORTS(nsDeviceContextSpecX, nsIDeviceContextSpec)
39
40 NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget *aWidget,
41 nsIPrintSettings* aPS,
42 bool aIsPrintPreview)
43 {
44 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
45
46 nsRefPtr<nsPrintSettingsX> settings(do_QueryObject(aPS));
47 if (!settings)
48 return NS_ERROR_NO_INTERFACE;
49
50 mPrintSession = settings->GetPMPrintSession();
51 ::PMRetain(mPrintSession);
52 mPageFormat = settings->GetPMPageFormat();
53 mPrintSettings = settings->GetPMPrintSettings();
54
55 return NS_OK;
56
57 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
58 }
59
60 NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(const nsAString& aTitle,
61 char16_t* aPrintToFileName,
62 int32_t aStartPage,
63 int32_t aEndPage)
64 {
65 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
66
67 if (!aTitle.IsEmpty()) {
68 CFStringRef cfString =
69 ::CFStringCreateWithCharacters(NULL, reinterpret_cast<const UniChar*>(aTitle.BeginReading()),
70 aTitle.Length());
71 if (cfString) {
72 ::PMPrintSettingsSetJobName(mPrintSettings, cfString);
73 ::CFRelease(cfString);
74 }
75 }
76
77 OSStatus status;
78 status = ::PMSetFirstPage(mPrintSettings, aStartPage, false);
79 NS_ASSERTION(status == noErr, "PMSetFirstPage failed");
80 status = ::PMSetLastPage(mPrintSettings, aEndPage, false);
81 NS_ASSERTION(status == noErr, "PMSetLastPage failed");
82
83 status = ::PMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat);
84 if (status != noErr)
85 return NS_ERROR_ABORT;
86
87 return NS_OK;
88
89 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
90 }
91
92 NS_IMETHODIMP nsDeviceContextSpecX::EndDocument()
93 {
94 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
95
96 ::PMSessionEndDocumentNoDialog(mPrintSession);
97 return NS_OK;
98
99 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
100 }
101
102 NS_IMETHODIMP nsDeviceContextSpecX::BeginPage()
103 {
104 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
105
106 PMSessionError(mPrintSession);
107 OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, NULL);
108 if (status != noErr) return NS_ERROR_ABORT;
109 return NS_OK;
110
111 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
112 }
113
114 NS_IMETHODIMP nsDeviceContextSpecX::EndPage()
115 {
116 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
117
118 OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession);
119 if (status != noErr) return NS_ERROR_ABORT;
120 return NS_OK;
121
122 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
123 }
124
125 void nsDeviceContextSpecX::GetPaperRect(double* aTop, double* aLeft, double* aBottom, double* aRight)
126 {
127 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
128
129 PMRect paperRect;
130 ::PMGetAdjustedPaperRect(mPageFormat, &paperRect);
131
132 *aTop = paperRect.top, *aLeft = paperRect.left;
133 *aBottom = paperRect.bottom, *aRight = paperRect.right;
134
135 NS_OBJC_END_TRY_ABORT_BLOCK;
136 }
137
138 NS_IMETHODIMP nsDeviceContextSpecX::GetSurfaceForPrinter(gfxASurface **surface)
139 {
140 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
141
142 double top, left, bottom, right;
143 GetPaperRect(&top, &left, &bottom, &right);
144 const double width = right - left;
145 const double height = bottom - top;
146
147 CGContextRef context;
148 ::PMSessionGetCGGraphicsContext(mPrintSession, &context);
149
150 nsRefPtr<gfxASurface> newSurface;
151
152 if (context) {
153 // Initially, origin is at bottom-left corner of the paper.
154 // Here, we translate it to top-left corner of the paper.
155 CGContextTranslateCTM(context, 0, height);
156 CGContextScaleCTM(context, 1.0, -1.0);
157 newSurface = new gfxQuartzSurface(context, gfxSize(width, height), true);
158 } else {
159 newSurface = new gfxQuartzSurface(gfxSize((int32_t)width, (int32_t)height), gfxImageFormat::ARGB32, true);
160 }
161
162 if (!newSurface)
163 return NS_ERROR_FAILURE;
164
165 *surface = newSurface;
166 NS_ADDREF(*surface);
167
168 return NS_OK;
169
170 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
171 }

mercurial