1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/cocoa/nsDeviceContextSpecX.mm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,171 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsDeviceContextSpecX.h" 1.10 + 1.11 +#include "nsCRT.h" 1.12 +#include <unistd.h> 1.13 + 1.14 +#include "nsAutoPtr.h" 1.15 +#include "nsIServiceManager.h" 1.16 +#include "nsIPrintOptions.h" 1.17 +#include "nsPrintSettingsX.h" 1.18 + 1.19 +#include "gfxQuartzSurface.h" 1.20 + 1.21 +// This must be the last include: 1.22 +#include "nsObjCExceptions.h" 1.23 + 1.24 +nsDeviceContextSpecX::nsDeviceContextSpecX() 1.25 +: mPrintSession(NULL) 1.26 +, mPageFormat(kPMNoPageFormat) 1.27 +, mPrintSettings(kPMNoPrintSettings) 1.28 +{ 1.29 +} 1.30 + 1.31 +nsDeviceContextSpecX::~nsDeviceContextSpecX() 1.32 +{ 1.33 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK; 1.34 + 1.35 + if (mPrintSession) 1.36 + ::PMRelease(mPrintSession); 1.37 + 1.38 + NS_OBJC_END_TRY_ABORT_BLOCK; 1.39 +} 1.40 + 1.41 +NS_IMPL_ISUPPORTS(nsDeviceContextSpecX, nsIDeviceContextSpec) 1.42 + 1.43 +NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget *aWidget, 1.44 + nsIPrintSettings* aPS, 1.45 + bool aIsPrintPreview) 1.46 +{ 1.47 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; 1.48 + 1.49 + nsRefPtr<nsPrintSettingsX> settings(do_QueryObject(aPS)); 1.50 + if (!settings) 1.51 + return NS_ERROR_NO_INTERFACE; 1.52 + 1.53 + mPrintSession = settings->GetPMPrintSession(); 1.54 + ::PMRetain(mPrintSession); 1.55 + mPageFormat = settings->GetPMPageFormat(); 1.56 + mPrintSettings = settings->GetPMPrintSettings(); 1.57 + 1.58 + return NS_OK; 1.59 + 1.60 + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; 1.61 +} 1.62 + 1.63 +NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(const nsAString& aTitle, 1.64 + char16_t* aPrintToFileName, 1.65 + int32_t aStartPage, 1.66 + int32_t aEndPage) 1.67 +{ 1.68 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; 1.69 + 1.70 + if (!aTitle.IsEmpty()) { 1.71 + CFStringRef cfString = 1.72 + ::CFStringCreateWithCharacters(NULL, reinterpret_cast<const UniChar*>(aTitle.BeginReading()), 1.73 + aTitle.Length()); 1.74 + if (cfString) { 1.75 + ::PMPrintSettingsSetJobName(mPrintSettings, cfString); 1.76 + ::CFRelease(cfString); 1.77 + } 1.78 + } 1.79 + 1.80 + OSStatus status; 1.81 + status = ::PMSetFirstPage(mPrintSettings, aStartPage, false); 1.82 + NS_ASSERTION(status == noErr, "PMSetFirstPage failed"); 1.83 + status = ::PMSetLastPage(mPrintSettings, aEndPage, false); 1.84 + NS_ASSERTION(status == noErr, "PMSetLastPage failed"); 1.85 + 1.86 + status = ::PMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat); 1.87 + if (status != noErr) 1.88 + return NS_ERROR_ABORT; 1.89 + 1.90 + return NS_OK; 1.91 + 1.92 + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; 1.93 +} 1.94 + 1.95 +NS_IMETHODIMP nsDeviceContextSpecX::EndDocument() 1.96 +{ 1.97 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; 1.98 + 1.99 + ::PMSessionEndDocumentNoDialog(mPrintSession); 1.100 + return NS_OK; 1.101 + 1.102 + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; 1.103 +} 1.104 + 1.105 +NS_IMETHODIMP nsDeviceContextSpecX::BeginPage() 1.106 +{ 1.107 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; 1.108 + 1.109 + PMSessionError(mPrintSession); 1.110 + OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, NULL); 1.111 + if (status != noErr) return NS_ERROR_ABORT; 1.112 + return NS_OK; 1.113 + 1.114 + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; 1.115 +} 1.116 + 1.117 +NS_IMETHODIMP nsDeviceContextSpecX::EndPage() 1.118 +{ 1.119 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; 1.120 + 1.121 + OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession); 1.122 + if (status != noErr) return NS_ERROR_ABORT; 1.123 + return NS_OK; 1.124 + 1.125 + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; 1.126 +} 1.127 + 1.128 +void nsDeviceContextSpecX::GetPaperRect(double* aTop, double* aLeft, double* aBottom, double* aRight) 1.129 +{ 1.130 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK; 1.131 + 1.132 + PMRect paperRect; 1.133 + ::PMGetAdjustedPaperRect(mPageFormat, &paperRect); 1.134 + 1.135 + *aTop = paperRect.top, *aLeft = paperRect.left; 1.136 + *aBottom = paperRect.bottom, *aRight = paperRect.right; 1.137 + 1.138 + NS_OBJC_END_TRY_ABORT_BLOCK; 1.139 +} 1.140 + 1.141 +NS_IMETHODIMP nsDeviceContextSpecX::GetSurfaceForPrinter(gfxASurface **surface) 1.142 +{ 1.143 + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; 1.144 + 1.145 + double top, left, bottom, right; 1.146 + GetPaperRect(&top, &left, &bottom, &right); 1.147 + const double width = right - left; 1.148 + const double height = bottom - top; 1.149 + 1.150 + CGContextRef context; 1.151 + ::PMSessionGetCGGraphicsContext(mPrintSession, &context); 1.152 + 1.153 + nsRefPtr<gfxASurface> newSurface; 1.154 + 1.155 + if (context) { 1.156 + // Initially, origin is at bottom-left corner of the paper. 1.157 + // Here, we translate it to top-left corner of the paper. 1.158 + CGContextTranslateCTM(context, 0, height); 1.159 + CGContextScaleCTM(context, 1.0, -1.0); 1.160 + newSurface = new gfxQuartzSurface(context, gfxSize(width, height), true); 1.161 + } else { 1.162 + newSurface = new gfxQuartzSurface(gfxSize((int32_t)width, (int32_t)height), gfxImageFormat::ARGB32, true); 1.163 + } 1.164 + 1.165 + if (!newSurface) 1.166 + return NS_ERROR_FAILURE; 1.167 + 1.168 + *surface = newSurface; 1.169 + NS_ADDREF(*surface); 1.170 + 1.171 + return NS_OK; 1.172 + 1.173 + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; 1.174 +}