summaryrefslogtreecommitdiff
path: root/widget/cocoa/nsDeviceContextSpecX.mm
diff options
context:
space:
mode:
Diffstat (limited to 'widget/cocoa/nsDeviceContextSpecX.mm')
-rw-r--r--widget/cocoa/nsDeviceContextSpecX.mm165
1 files changed, 165 insertions, 0 deletions
diff --git a/widget/cocoa/nsDeviceContextSpecX.mm b/widget/cocoa/nsDeviceContextSpecX.mm
new file mode 100644
index 0000000000..d252adef69
--- /dev/null
+++ b/widget/cocoa/nsDeviceContextSpecX.mm
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsDeviceContextSpecX.h"
+
+#include "mozilla/gfx/PrintTargetCG.h"
+#include "mozilla/RefPtr.h"
+#include "nsCRT.h"
+#include <unistd.h>
+
+#include "nsQueryObject.h"
+#include "nsIServiceManager.h"
+#include "nsPrintSettingsX.h"
+
+// This must be the last include:
+#include "nsObjCExceptions.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+
+nsDeviceContextSpecX::nsDeviceContextSpecX()
+: mPrintSession(NULL)
+, mPageFormat(kPMNoPageFormat)
+, mPrintSettings(kPMNoPrintSettings)
+{
+}
+
+nsDeviceContextSpecX::~nsDeviceContextSpecX()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+ if (mPrintSession)
+ ::PMRelease(mPrintSession);
+
+ NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
+NS_IMPL_ISUPPORTS(nsDeviceContextSpecX, nsIDeviceContextSpec)
+
+NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget *aWidget,
+ nsIPrintSettings* aPS,
+ bool aIsPrintPreview)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ RefPtr<nsPrintSettingsX> settings(do_QueryObject(aPS));
+ if (!settings)
+ return NS_ERROR_NO_INTERFACE;
+
+ mPrintSession = settings->GetPMPrintSession();
+ ::PMRetain(mPrintSession);
+ mPageFormat = settings->GetPMPageFormat();
+ mPrintSettings = settings->GetPMPrintSettings();
+
+ return NS_OK;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(const nsAString& aTitle,
+ const nsAString& aPrintToFileName,
+ int32_t aStartPage,
+ int32_t aEndPage)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ if (!aTitle.IsEmpty()) {
+ CFStringRef cfString =
+ ::CFStringCreateWithCharacters(NULL, reinterpret_cast<const UniChar*>(aTitle.BeginReading()),
+ aTitle.Length());
+ if (cfString) {
+ ::PMPrintSettingsSetJobName(mPrintSettings, cfString);
+ ::CFRelease(cfString);
+ }
+ }
+
+ OSStatus status;
+ status = ::PMSetFirstPage(mPrintSettings, aStartPage, false);
+ NS_ASSERTION(status == noErr, "PMSetFirstPage failed");
+ status = ::PMSetLastPage(mPrintSettings, aEndPage, false);
+ NS_ASSERTION(status == noErr, "PMSetLastPage failed");
+
+ status = ::PMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat);
+ if (status != noErr)
+ return NS_ERROR_ABORT;
+
+ return NS_OK;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP nsDeviceContextSpecX::EndDocument()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ ::PMSessionEndDocumentNoDialog(mPrintSession);
+ return NS_OK;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP nsDeviceContextSpecX::BeginPage()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ PMSessionError(mPrintSession);
+ OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, NULL);
+ if (status != noErr) return NS_ERROR_ABORT;
+ return NS_OK;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP nsDeviceContextSpecX::EndPage()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ OSStatus status = ::PMSessionEndPageNoDialog(mPrintSession);
+ if (status != noErr) return NS_ERROR_ABORT;
+ return NS_OK;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+void nsDeviceContextSpecX::GetPaperRect(double* aTop, double* aLeft, double* aBottom, double* aRight)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+ PMRect paperRect;
+ ::PMGetAdjustedPaperRect(mPageFormat, &paperRect);
+
+ *aTop = paperRect.top, *aLeft = paperRect.left;
+ *aBottom = paperRect.bottom, *aRight = paperRect.right;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
+already_AddRefed<PrintTarget> nsDeviceContextSpecX::MakePrintTarget()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ double top, left, bottom, right;
+ GetPaperRect(&top, &left, &bottom, &right);
+ const double width = right - left;
+ const double height = bottom - top;
+ IntSize size = IntSize::Floor(width, height);
+
+ CGContextRef context;
+ ::PMSessionGetCGGraphicsContext(mPrintSession, &context);
+
+ if (context) {
+ // Initially, origin is at bottom-left corner of the paper.
+ // Here, we translate it to top-left corner of the paper.
+ CGContextTranslateCTM(context, 0, height);
+ CGContextScaleCTM(context, 1.0, -1.0);
+ return PrintTargetCG::CreateOrNull(context, size);
+ }
+
+ // Apparently we do need this branch - bug 368933.
+ return PrintTargetCG::CreateOrNull(size, SurfaceFormat::A8R8G8B8_UINT32);
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL;
+}