Implement the basic OS-level printing mechanics on Mac

Part two of printing implementation on the Mac. This adds a Mac implementation of PrintSettings to get page setup and printer information, basic PDF->context rendering in PrintedDocument, and most of PrintingContext to allow getting print settings (both default and interactive).

Reworks the message flow a bit when asking for print settings on the Mac, since it can only be done from the UI thread. Uses a modal dialog for now, but will later be modified further to allow for a sheet.

BUG=13158
TEST=None; no user-visible effect yet.

Review URL: http://codereview.chromium.org/268036

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28857 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/printing/printed_document_mac.cc b/printing/printed_document_mac.cc
new file mode 100644
index 0000000..ace57f3
--- /dev/null
+++ b/printing/printed_document_mac.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "printing/printed_document.h"
+
+#import <ApplicationServices/ApplicationServices.h>
+#import <CoreFoundation/CoreFoundation.h>
+
+#include "base/logging.h"
+#include "base/scoped_cftyperef.h"
+#include "printing/page_number.h"
+#include "printing/printed_page.h"
+
+namespace printing {
+
+void PrintedDocument::RenderPrintedPage(
+    const PrintedPage& page, gfx::NativeDrawingContext context) const {
+#ifndef NDEBUG
+  {
+    // Make sure the page is from our list.
+    AutoLock lock(lock_);
+    DCHECK(&page == mutable_.pages_.find(page.page_number() - 1)->second.get());
+  }
+#endif
+
+  const printing::NativeMetafile* metafile = page.native_metafile();
+  unsigned int data_length = metafile->GetDataSize();
+  scoped_cftyperef<CFMutableDataRef> pdf_data(
+      CFDataCreateMutable(kCFAllocatorDefault, data_length));
+  CFDataIncreaseLength(pdf_data, data_length);
+  metafile->GetData(CFDataGetMutableBytePtr(pdf_data), data_length);
+  scoped_cftyperef<CGDataProviderRef> pdf_data_provider(
+      CGDataProviderCreateWithCFData(pdf_data));
+  scoped_cftyperef<CGPDFDocumentRef> pdf_doc(
+      CGPDFDocumentCreateWithProvider(pdf_data_provider));
+  if (!pdf_doc.get()) {
+    NOTREACHED() << "Unable to create PDF document from print data";
+    return;
+  }
+
+  const printing::PageSetup& page_setup(
+      immutable_.settings_.page_setup_pixels());
+  CGRect target_rect = page_setup.content_area().ToCGRect();
+
+  // Each NativeMetafile is a one-page PDF.
+  const int page_number = 1;
+  CGContextDrawPDFDocument(context, target_rect, pdf_doc, page_number);
+
+  // TODO(stuartmorgan): Print the header and footer.
+}
+
+}  // namespace printing