Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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"
8 #include "nsCRT.h"
9 #include <unistd.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()
22 : mPrintSession(NULL)
23 , mPageFormat(kPMNoPageFormat)
24 , mPrintSettings(kPMNoPrintSettings)
25 {
26 }
28 nsDeviceContextSpecX::~nsDeviceContextSpecX()
29 {
30 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
32 if (mPrintSession)
33 ::PMRelease(mPrintSession);
35 NS_OBJC_END_TRY_ABORT_BLOCK;
36 }
38 NS_IMPL_ISUPPORTS(nsDeviceContextSpecX, nsIDeviceContextSpec)
40 NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget *aWidget,
41 nsIPrintSettings* aPS,
42 bool aIsPrintPreview)
43 {
44 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
46 nsRefPtr<nsPrintSettingsX> settings(do_QueryObject(aPS));
47 if (!settings)
48 return NS_ERROR_NO_INTERFACE;
50 mPrintSession = settings->GetPMPrintSession();
51 ::PMRetain(mPrintSession);
52 mPageFormat = settings->GetPMPageFormat();
53 mPrintSettings = settings->GetPMPrintSettings();
55 return NS_OK;
57 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
58 }
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;
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 }
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");
83 status = ::PMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat);
84 if (status != noErr)
85 return NS_ERROR_ABORT;
87 return NS_OK;
89 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
90 }
92 NS_IMETHODIMP nsDeviceContextSpecX::EndDocument()
93 {
94 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
96 ::PMSessionEndDocumentNoDialog(mPrintSession);
97 return NS_OK;
99 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
100 }
102 NS_IMETHODIMP nsDeviceContextSpecX::BeginPage()
103 {
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;
109 return NS_OK;
111 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
112 }
114 NS_IMETHODIMP nsDeviceContextSpecX::EndPage()
115 {
116 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
118 OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession);
119 if (status != noErr) return NS_ERROR_ABORT;
120 return NS_OK;
122 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
123 }
125 void nsDeviceContextSpecX::GetPaperRect(double* aTop, double* aLeft, double* aBottom, double* aRight)
126 {
127 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
129 PMRect paperRect;
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;
136 }
138 NS_IMETHODIMP nsDeviceContextSpecX::GetSurfaceForPrinter(gfxASurface **surface)
139 {
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;
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 }
162 if (!newSurface)
163 return NS_ERROR_FAILURE;
165 *surface = newSurface;
166 NS_ADDREF(*surface);
168 return NS_OK;
170 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
171 }