michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsDeviceContextSpecX.h" michael@0: michael@0: #include "nsCRT.h" michael@0: #include michael@0: michael@0: #include "nsAutoPtr.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIPrintOptions.h" michael@0: #include "nsPrintSettingsX.h" michael@0: michael@0: #include "gfxQuartzSurface.h" michael@0: michael@0: // This must be the last include: michael@0: #include "nsObjCExceptions.h" michael@0: michael@0: nsDeviceContextSpecX::nsDeviceContextSpecX() michael@0: : mPrintSession(NULL) michael@0: , mPageFormat(kPMNoPageFormat) michael@0: , mPrintSettings(kPMNoPrintSettings) michael@0: { michael@0: } michael@0: michael@0: nsDeviceContextSpecX::~nsDeviceContextSpecX() michael@0: { michael@0: NS_OBJC_BEGIN_TRY_ABORT_BLOCK; michael@0: michael@0: if (mPrintSession) michael@0: ::PMRelease(mPrintSession); michael@0: michael@0: NS_OBJC_END_TRY_ABORT_BLOCK; michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(nsDeviceContextSpecX, nsIDeviceContextSpec) michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget *aWidget, michael@0: nsIPrintSettings* aPS, michael@0: bool aIsPrintPreview) michael@0: { michael@0: NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; michael@0: michael@0: nsRefPtr settings(do_QueryObject(aPS)); michael@0: if (!settings) michael@0: return NS_ERROR_NO_INTERFACE; michael@0: michael@0: mPrintSession = settings->GetPMPrintSession(); michael@0: ::PMRetain(mPrintSession); michael@0: mPageFormat = settings->GetPMPageFormat(); michael@0: mPrintSettings = settings->GetPMPrintSettings(); michael@0: michael@0: return NS_OK; michael@0: michael@0: NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(const nsAString& aTitle, michael@0: char16_t* aPrintToFileName, michael@0: int32_t aStartPage, michael@0: int32_t aEndPage) michael@0: { michael@0: NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; michael@0: michael@0: if (!aTitle.IsEmpty()) { michael@0: CFStringRef cfString = michael@0: ::CFStringCreateWithCharacters(NULL, reinterpret_cast(aTitle.BeginReading()), michael@0: aTitle.Length()); michael@0: if (cfString) { michael@0: ::PMPrintSettingsSetJobName(mPrintSettings, cfString); michael@0: ::CFRelease(cfString); michael@0: } michael@0: } michael@0: michael@0: OSStatus status; michael@0: status = ::PMSetFirstPage(mPrintSettings, aStartPage, false); michael@0: NS_ASSERTION(status == noErr, "PMSetFirstPage failed"); michael@0: status = ::PMSetLastPage(mPrintSettings, aEndPage, false); michael@0: NS_ASSERTION(status == noErr, "PMSetLastPage failed"); michael@0: michael@0: status = ::PMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat); michael@0: if (status != noErr) michael@0: return NS_ERROR_ABORT; michael@0: michael@0: return NS_OK; michael@0: michael@0: NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecX::EndDocument() michael@0: { michael@0: NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; michael@0: michael@0: ::PMSessionEndDocumentNoDialog(mPrintSession); michael@0: return NS_OK; michael@0: michael@0: NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecX::BeginPage() michael@0: { michael@0: NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; michael@0: michael@0: PMSessionError(mPrintSession); michael@0: OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, NULL); michael@0: if (status != noErr) return NS_ERROR_ABORT; michael@0: return NS_OK; michael@0: michael@0: NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecX::EndPage() michael@0: { michael@0: NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; michael@0: michael@0: OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession); michael@0: if (status != noErr) return NS_ERROR_ABORT; michael@0: return NS_OK; michael@0: michael@0: NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; michael@0: } michael@0: michael@0: void nsDeviceContextSpecX::GetPaperRect(double* aTop, double* aLeft, double* aBottom, double* aRight) michael@0: { michael@0: NS_OBJC_BEGIN_TRY_ABORT_BLOCK; michael@0: michael@0: PMRect paperRect; michael@0: ::PMGetAdjustedPaperRect(mPageFormat, &paperRect); michael@0: michael@0: *aTop = paperRect.top, *aLeft = paperRect.left; michael@0: *aBottom = paperRect.bottom, *aRight = paperRect.right; michael@0: michael@0: NS_OBJC_END_TRY_ABORT_BLOCK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecX::GetSurfaceForPrinter(gfxASurface **surface) michael@0: { michael@0: NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; michael@0: michael@0: double top, left, bottom, right; michael@0: GetPaperRect(&top, &left, &bottom, &right); michael@0: const double width = right - left; michael@0: const double height = bottom - top; michael@0: michael@0: CGContextRef context; michael@0: ::PMSessionGetCGGraphicsContext(mPrintSession, &context); michael@0: michael@0: nsRefPtr newSurface; michael@0: michael@0: if (context) { michael@0: // Initially, origin is at bottom-left corner of the paper. michael@0: // Here, we translate it to top-left corner of the paper. michael@0: CGContextTranslateCTM(context, 0, height); michael@0: CGContextScaleCTM(context, 1.0, -1.0); michael@0: newSurface = new gfxQuartzSurface(context, gfxSize(width, height), true); michael@0: } else { michael@0: newSurface = new gfxQuartzSurface(gfxSize((int32_t)width, (int32_t)height), gfxImageFormat::ARGB32, true); michael@0: } michael@0: michael@0: if (!newSurface) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: *surface = newSurface; michael@0: NS_ADDREF(*surface); michael@0: michael@0: return NS_OK; michael@0: michael@0: NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; michael@0: }