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/. */
6 #include "nsDeviceContextSpecX.h"
11 #include "nsAutoPtr.h"
12 #include "nsIServiceManager.h"
13 #include "nsIPrintOptions.h"
14 #include "nsPrintSettingsX.h"
16 #include "gfxQuartzSurface.h"
18 // This must be the last include:
19 #include "nsObjCExceptions.h"
21 nsDeviceContextSpecX::nsDeviceContextSpecX()
23 , mPageFormat(kPMNoPageFormat)
24 , mPrintSettings(kPMNoPrintSettings)
28 nsDeviceContextSpecX::~nsDeviceContextSpecX()
30 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
33 ::PMRelease(mPrintSession);
35 NS_OBJC_END_TRY_ABORT_BLOCK;
38 NS_IMPL_ISUPPORTS(nsDeviceContextSpecX, nsIDeviceContextSpec)
40 NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget *aWidget,
41 nsIPrintSettings* aPS,
44 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
46 nsRefPtr<nsPrintSettingsX> settings(do_QueryObject(aPS));
48 return NS_ERROR_NO_INTERFACE;
50 mPrintSession = settings->GetPMPrintSession();
51 ::PMRetain(mPrintSession);
52 mPageFormat = settings->GetPMPageFormat();
53 mPrintSettings = settings->GetPMPrintSettings();
57 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
60 NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(const nsAString& aTitle,
61 char16_t* aPrintToFileName,
65 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
67 if (!aTitle.IsEmpty()) {
68 CFStringRef cfString =
69 ::CFStringCreateWithCharacters(NULL, reinterpret_cast<const UniChar*>(aTitle.BeginReading()),
72 ::PMPrintSettingsSetJobName(mPrintSettings, cfString);
73 ::CFRelease(cfString);
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");
83 status = ::PMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat);
85 return NS_ERROR_ABORT;
89 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
92 NS_IMETHODIMP nsDeviceContextSpecX::EndDocument()
94 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
96 ::PMSessionEndDocumentNoDialog(mPrintSession);
99 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
102 NS_IMETHODIMP nsDeviceContextSpecX::BeginPage()
104 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
106 PMSessionError(mPrintSession);
107 OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, NULL);
108 if (status != noErr) return NS_ERROR_ABORT;
111 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
114 NS_IMETHODIMP nsDeviceContextSpecX::EndPage()
116 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
118 OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession);
119 if (status != noErr) return NS_ERROR_ABORT;
122 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
125 void nsDeviceContextSpecX::GetPaperRect(double* aTop, double* aLeft, double* aBottom, double* aRight)
127 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
130 ::PMGetAdjustedPaperRect(mPageFormat, &paperRect);
132 *aTop = paperRect.top, *aLeft = paperRect.left;
133 *aBottom = paperRect.bottom, *aRight = paperRect.right;
135 NS_OBJC_END_TRY_ABORT_BLOCK;
138 NS_IMETHODIMP nsDeviceContextSpecX::GetSurfaceForPrinter(gfxASurface **surface)
140 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
142 double top, left, bottom, right;
143 GetPaperRect(&top, &left, &bottom, &right);
144 const double width = right - left;
145 const double height = bottom - top;
147 CGContextRef context;
148 ::PMSessionGetCGGraphicsContext(mPrintSession, &context);
150 nsRefPtr<gfxASurface> newSurface;
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);
159 newSurface = new gfxQuartzSurface(gfxSize((int32_t)width, (int32_t)height), gfxImageFormat::ARGB32, true);
163 return NS_ERROR_FAILURE;
165 *surface = newSurface;
170 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;