diff options
author | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-21 22:30:10 +0000 |
---|---|---|
committer | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-21 22:30:10 +0000 |
commit | 15c2bb32e4b2a436e404695ee7b5ea564cc9c60b (patch) | |
tree | 3b5208034639c45ba114eb2d8b7c729ee38eeeef | |
parent | 6e74a3bcc45e25f4a249649953b5120324facf16 (diff) | |
download | chromium_src-15c2bb32e4b2a436e404695ee7b5ea564cc9c60b.zip chromium_src-15c2bb32e4b2a436e404695ee7b5ea564cc9c60b.tar.gz chromium_src-15c2bb32e4b2a436e404695ee7b5ea564cc9c60b.tar.bz2 |
Refactor mac printing workflow.
To support print preview, made code changes to create a single metafile for the entire printing document.
BUG=64121
TEST=printing works after code changes.
Review URL: http://codereview.chromium.org/5892002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69885 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 38 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 4 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 1 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 11 | ||||
-rw-r--r-- | chrome/common/render_messages_params.cc | 35 | ||||
-rw-r--r-- | chrome/common/render_messages_params.h | 23 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.cc | 83 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.h | 26 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_linux.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_mac.mm | 149 | ||||
-rw-r--r-- | printing/pdf_metafile_mac.cc | 11 | ||||
-rw-r--r-- | printing/pdf_metafile_mac.h | 10 | ||||
-rw-r--r-- | printing/pdf_metafile_mac_unittest.cc | 15 | ||||
-rw-r--r-- | printing/printed_document_mac.cc | 2 |
14 files changed, 292 insertions, 122 deletions
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 83b1f8c..5833296 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -53,6 +53,7 @@ #include "chrome/common/web_apps.h" #include "gfx/native_widget_types.h" #include "net/base/net_util.h" +#include "printing/native_metafile.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/WebKit/chromium/public/WebFindOptions.h" #include "webkit/glue/context_menu.h" @@ -2256,25 +2257,38 @@ TabContents* RenderViewHost::GetOrCreatePrintPreviewTab() { return NULL; } -void RenderViewHost::OnPagesReadyForPreview(int document_cookie, - int fd_in_browser) { +void RenderViewHost::OnPagesReadyForPreview( + const ViewHostMsg_DidPreviewDocument_Params& params) { +#if defined(OS_MACOSX) + base::SharedMemory shared_buf(params.metafile_data_handle, true); + if (!shared_buf.Map(params.data_size)) { + NOTREACHED(); + return; + } + scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile()); + if (!metafile->Init(shared_buf.memory(), params.data_size)) { + NOTREACHED(); + return; + } + + // TODO(kmadhusu): Add more functionality for the preview tab to access this + // |metafile| data. +#endif + // Get/Create print preview tab. TabContents* print_preview_tab = GetOrCreatePrintPreviewTab(); DCHECK(print_preview_tab); - // TODO(kmadhusu): Function definition needs to be changed. - // fd_in_browser should be the file descriptor of the metafile. - scoped_refptr<printing::PrinterQuery> printer_query; - g_browser_process->print_job_manager()->PopPrinterQuery(document_cookie, - &printer_query); + g_browser_process->print_job_manager()->PopPrinterQuery( + params.document_cookie, &printer_query); if (printer_query.get()) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(printer_query.get(), - &printing::PrinterQuery::StopWorker)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(printer_query.get(), + &printing::PrinterQuery::StopWorker)); } // Send the printingDone msg for now. - Send(new ViewMsg_PrintingDone(routing_id(), -1, true)); + Send(new ViewMsg_PrintingDone(routing_id(), params.document_cookie, true)); } diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 4a23704..163039b 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -39,6 +39,7 @@ struct ContextMenuParams; struct MediaPlayerAction; struct ThumbnailScore; struct ViewHostMsg_AccessibilityNotification_Params; +struct ViewHostMsg_DidPreviewDocument_Params; struct ViewHostMsg_DidPrintPage_Params; struct ViewHostMsg_DomMessage_Params; struct ViewHostMsg_PageHasOSDD_Type; @@ -733,7 +734,8 @@ class RenderViewHost : public RenderWidgetHost { const SkBitmap& thumbnail); void OnScriptEvalResponse(int id, const ListValue& result); void OnUpdateContentRestrictions(int restrictions); - void OnPagesReadyForPreview(int document_cookie, int fd_in_browser); + void OnPagesReadyForPreview( + const ViewHostMsg_DidPreviewDocument_Params& params); #if defined(OS_MACOSX) void OnMsgShowPopup(const ViewHostMsg_ShowPopup_Params& params); diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 06e597c..e06a667 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -100,6 +100,7 @@ struct ViewHostMsg_Resource_Request; struct ViewMsg_Print_Params; struct ViewMsg_PrintPage_Params; struct ViewMsg_PrintPages_Params; +struct ViewHostMsg_DidPreviewDocument_Params; struct ViewHostMsg_DidPrintPage_Params; struct ViewHostMsg_Audio_CreateStream_Params; struct ViewHostMsg_ShowPopup_Params; diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 01fc555..f94f1ed 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -170,12 +170,11 @@ IPC_MESSAGE_ROUTED2(ViewMsg_PrintingDone, // requested pages for print preview. IPC_MESSAGE_ROUTED0(ViewMsg_PrintPreview) -// Sends back to the browser the rendered "printed page" for preview that was -// requested by a ViewMsg_PrintPage message or from scripted printing. The -// memory handle in this message is already valid in the browser process. -IPC_MESSAGE_ROUTED2(ViewHostMsg_PagesReadyForPreview, - int /* document cookie */, - int /* fd in browser */) +// Sends back to the browser the rendered "printed document" for preview that +// was requested by a ViewMsg_PrintPreview message. The memory handle in this +// message is already valid in the browser process. +IPC_MESSAGE_ROUTED1(ViewHostMsg_PagesReadyForPreview, + ViewHostMsg_DidPreviewDocument_Params /* params */) // Tells the renderer to dump as much memory as it can, perhaps because we // have memory pressure or the renderer is (or will be) paged out. This diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc index 618ca8e..7fab193 100644 --- a/chrome/common/render_messages_params.cc +++ b/chrome/common/render_messages_params.cc @@ -118,6 +118,21 @@ ViewMsg_PrintPages_Params::ViewMsg_PrintPages_Params() { ViewMsg_PrintPages_Params::~ViewMsg_PrintPages_Params() { } +ViewHostMsg_DidPreviewDocument_Params::ViewHostMsg_DidPreviewDocument_Params() + : data_size(0) { +#if defined(OS_WIN) + // Initialize |metafile_data_handle| only on Windows because it maps + // base::SharedMemoryHandle to HANDLE. We do not need to initialize this + // variable on Posix because it maps base::SharedMemoryHandle to + // FileDescriptior, which has the default constructor. + metafile_data_handle = INVALID_HANDLE_VALUE; +#endif +} + +ViewHostMsg_DidPreviewDocument_Params:: + ~ViewHostMsg_DidPreviewDocument_Params() { +} + ViewHostMsg_DidPrintPage_Params::ViewHostMsg_DidPrintPage_Params() : data_size(0), document_cookie(0), @@ -995,6 +1010,26 @@ void ParamTraits<ViewMsg_PrintPages_Params>::Log(const param_type& p, l->append("<ViewMsg_PrintPages_Params>"); } +void ParamTraits<ViewHostMsg_DidPreviewDocument_Params>::Write(Message* m, + const param_type& p) { + WriteParam(m, p.metafile_data_handle); + WriteParam(m, p.data_size); + WriteParam(m, p.document_cookie); +} + +bool ParamTraits<ViewHostMsg_DidPreviewDocument_Params>::Read(const Message* m, + void** iter, + param_type* p) { + return ReadParam(m, iter, &p->metafile_data_handle) && + ReadParam(m, iter, &p->data_size) && + ReadParam(m, iter, &p->document_cookie); +} + +void ParamTraits<ViewHostMsg_DidPreviewDocument_Params>::Log( + const param_type& p, std::string* l) { + l->append("<ViewHostMsg_DidPreviewDocument_Params>"); +} + void ParamTraits<ViewHostMsg_DidPrintPage_Params>::Write(Message* m, const param_type& p) { WriteParam(m, p.metafile_data_handle); diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h index 911e3ae..97817d2 100644 --- a/chrome/common/render_messages_params.h +++ b/chrome/common/render_messages_params.h @@ -552,6 +552,21 @@ struct ViewMsg_PrintPages_Params { std::vector<int> pages; }; +//Parameters to describe a rendered document. +struct ViewHostMsg_DidPreviewDocument_Params { + ViewHostMsg_DidPreviewDocument_Params(); + ~ViewHostMsg_DidPreviewDocument_Params(); + + // A shared memory handle to metafile data. + base::SharedMemoryHandle metafile_data_handle; + + // Size of metafile data. + uint32 data_size; + + // Cookie for the document to ensure correctness. + int document_cookie; +}; + // Parameters to describe a rendered page. struct ViewHostMsg_DidPrintPage_Params { ViewHostMsg_DidPrintPage_Params(); @@ -986,6 +1001,14 @@ struct ParamTraits<ViewMsg_PrintPages_Params> { }; template <> +struct ParamTraits<ViewHostMsg_DidPreviewDocument_Params> { + typedef ViewHostMsg_DidPreviewDocument_Params param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> struct ParamTraits<ViewHostMsg_DidPrintPage_Params> { typedef ViewHostMsg_DidPrintPage_Params param_type; static void Write(Message* m, const param_type& p); diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index 751b9ec..d5b0a79 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -6,6 +6,7 @@ #include "app/l10n_util.h" #include "base/logging.h" +#include "base/process_util.h" #include "base/utf_string_conversions.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" @@ -149,7 +150,11 @@ void PrintWebViewHelper::Print(WebFrame* frame, // Render Pages for printing. if (!print_cancelled) { - RenderPagesForPrint(frame); + if (is_preview_) + RenderPagesForPreview(frame); + else + RenderPagesForPrint(frame); + // Reset cancel counter on first successful print. user_cancelled_scripted_print_count_ = 0; return; // All went well. @@ -227,11 +232,9 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, frame->view()); int page_count = prep_frame_view.GetExpectedPageCount(); - if (!is_preview_) { - Send(new ViewHostMsg_DidGetPrintedPagesCount(routing_id(), - printParams.document_cookie, - page_count)); - } + Send(new ViewHostMsg_DidGetPrintedPagesCount(routing_id(), + printParams.document_cookie, + page_count)); if (!page_count) return; @@ -251,13 +254,6 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, PrintPage(page_params, canvas_size, frame); } } - - if (is_preview_) { - // TODO(kmadhusu) Put this in the right place when fixing bug 64121. - Send(new ViewHostMsg_PagesReadyForPreview(routing_id(), - printParams.document_cookie, - -1)); - } } #endif // OS_MACOSX || OS_WIN @@ -359,14 +355,24 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters( WebFrame* frame, ViewMsg_Print_Params* params) { double content_width_in_points; double content_height_in_points; + double margin_top_in_points; + double margin_right_in_points; + double margin_bottom_in_points; + double margin_left_in_points; PrepareFrameAndViewForPrint prepare(*params, frame, frame->view()); PrintWebViewHelper::GetPageSizeAndMarginsInPoints(frame, 0, *params, - &content_width_in_points, - &content_height_in_points, - NULL, NULL, NULL, NULL); + &content_width_in_points, &content_height_in_points, + &margin_top_in_points, &margin_right_in_points, + &margin_bottom_in_points, &margin_left_in_points); + #if defined(OS_MACOSX) - params->printable_size = gfx::Size( - static_cast<int>(content_width_in_points), + params->page_size = gfx::Size( + static_cast<int>(content_width_in_points + + margin_left_in_points + margin_right_in_points), + static_cast<int>(content_height_in_points + + margin_top_in_points + margin_bottom_in_points)); + + params->printable_size = gfx::Size(static_cast<int>(content_width_in_points), static_cast<int>(content_height_in_points)); #else params->printable_size = gfx::Size( @@ -375,6 +381,8 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters( static_cast<int>(ConvertUnitDouble( content_height_in_points, printing::kPointsPerInch, params->dpi))); #endif + params->margin_top = static_cast<int>(margin_top_in_points); + params->margin_left = static_cast<int>(margin_left_in_points); } bool PrintWebViewHelper::InitPrintSettings(WebFrame* frame) { @@ -455,3 +463,42 @@ void PrintWebViewHelper::RenderPagesForPrint(WebFrame *frame) { PrintPages(print_settings, frame); } } + +void PrintWebViewHelper::RenderPagesForPreview(WebFrame *frame) { + ViewMsg_PrintPages_Params print_settings = *print_pages_params_; + ViewHostMsg_DidPreviewDocument_Params print_params; + CreatePreviewDocument(print_settings, frame, &print_params); + Send(new ViewHostMsg_PagesReadyForPreview(routing_id(), print_params)); +} + +#if !defined(OS_MACOSX) +void PrintWebViewHelper::CreatePreviewDocument( + const ViewMsg_PrintPages_Params& params, + WebFrame* frame, + ViewHostMsg_DidPreviewDocument_Params* print_params) { + // TODO(kmadhusu): Implement this function for windows & linux. + print_params->document_cookie = params.params.document_cookie; +} +#endif + +#if defined(OS_MACOSX) +bool PrintWebViewHelper::CopyMetafileDataToSharedMem( + printing::NativeMetafile* metafile, + base::SharedMemoryHandle* shared_mem_handle) { + uint32 buf_size = metafile->GetDataSize(); + base::SharedMemoryHandle mem_handle; + if (Send(new ViewHostMsg_AllocateSharedMemoryBuffer(buf_size, &mem_handle))) { + if (base::SharedMemory::IsHandleValid(mem_handle)) { + base::SharedMemory shared_buf(mem_handle, false); + if (shared_buf.Map(buf_size)) { + metafile->GetData(shared_buf.memory(), buf_size); + shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), + shared_mem_handle); + return true; + } + } + } + NOTREACHED(); + return false; +} +#endif diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h index 5fee3b9..c473e72 100644 --- a/chrome/renderer/print_web_view_helper.h +++ b/chrome/renderer/print_web_view_helper.h @@ -11,9 +11,14 @@ #include "base/scoped_ptr.h" #include "base/time.h" #include "gfx/size.h" +#include "printing/native_metafile.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h" #include "third_party/WebKit/WebKit/chromium/public/WebViewClient.h" +#if defined(OS_MACOSX) +#include "base/shared_memory.h" +#endif // defined(OS_MACOSX) + namespace gfx { class Size; } @@ -22,17 +27,11 @@ namespace IPC { class Message; } -#if defined(USE_X11) -namespace printing { -class PdfPsMetafile; -typedef PdfPsMetafile NativeMetafile; -} -#endif - class RenderView; struct ViewMsg_Print_Params; struct ViewMsg_PrintPage_Params; struct ViewMsg_PrintPages_Params; +struct ViewHostMsg_DidPreviewDocument_Params; // Class that calls the Begin and End print functions on the frame and changes // the size of the view temporarily to support full page printing.. @@ -147,6 +146,19 @@ class PrintWebViewHelper : public WebKit::WebViewClient, // Render the frame for printing. void RenderPagesForPrint(WebKit::WebFrame* frame); + // Render the frame for preview. + void RenderPagesForPreview(WebKit::WebFrame* frame); + void CreatePreviewDocument(const ViewMsg_PrintPages_Params& params, + WebKit::WebFrame* frame, + ViewHostMsg_DidPreviewDocument_Params* print_params); +#if defined(OS_MACOSX) + void RenderPage(const gfx::Size& page_size, const gfx::Point& content_origin, + const float& scale_factor, int page_number, + WebKit::WebFrame* frame, printing::NativeMetafile* metafile); + bool CopyMetafileDataToSharedMem(printing::NativeMetafile* metafile, + base::SharedMemoryHandle* shared_mem_handle); +#endif + RenderView* render_view_; WebKit::WebView* print_web_view_; scoped_ptr<ViewMsg_PrintPages_Params> print_pages_params_; diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc index 4624db1..06e98b2 100644 --- a/chrome/renderer/print_web_view_helper_linux.cc +++ b/chrome/renderer/print_web_view_helper_linux.cc @@ -52,12 +52,6 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, metafile.Close(); int fd_in_browser = -1; - if (is_preview_) { - Send(new ViewHostMsg_PagesReadyForPreview(routing_id(), - params.params.document_cookie, - fd_in_browser)); - return; - } // Get the size of the resulting metafile. uint32 buf_size = metafile.GetDataSize(); DCHECK_GT(buf_size, 0u); diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm index 77b8972..592ff38 100644 --- a/chrome/renderer/print_web_view_helper_mac.mm +++ b/chrome/renderer/print_web_view_helper_mac.mm @@ -8,7 +8,6 @@ #include "app/l10n_util.h" #include "base/logging.h" -#include "base/process_util.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" #include "chrome/renderer/render_view.h" @@ -28,80 +27,108 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, const gfx::Size& canvas_size, WebFrame* frame) { printing::NativeMetafile metafile; - CGContextRef context = metafile.Init(); + if (!metafile.Init()) + return; float scale_factor = frame->getPrintPageShrink(params.page_number); - double content_width_in_points; - double content_height_in_points; - double margin_top_in_points; - double margin_right_in_points; - double margin_bottom_in_points; - double margin_left_in_points; - GetPageSizeAndMarginsInPoints(frame, - params.page_number, - params.params, - &content_width_in_points, - &content_height_in_points, - &margin_top_in_points, - &margin_right_in_points, - &margin_bottom_in_points, - &margin_left_in_points); - metafile.StartPage(content_width_in_points, - content_height_in_points, - scale_factor); - - // printPage can create autoreleased references to |canvas|. PDF contexts - // don't write all their data until they are destroyed, so we need to make - // certain that there are no lingering references. - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - frame->printPage(params.page_number, context); - [pool release]; + double width = params.params.printable_size.width(); + double height = params.params.printable_size.height(); + int page_number = params.page_number; + + // Render page for printing. + gfx::Point origin(0.0f, 0.0f); + RenderPage(params.params.printable_size, origin, scale_factor, page_number, + frame, &metafile); - metafile.FinishPage(); metafile.Close(); + double margin_left = params.params.margin_left; + double margin_top = params.params.margin_top; + // Get the size of the compiled metafile. ViewHostMsg_DidPrintPage_Params page_params; page_params.data_size = 0; - page_params.page_number = params.page_number; + page_params.page_number = page_number; page_params.document_cookie = params.params.document_cookie; page_params.actual_shrink = scale_factor; - base::SharedMemory shared_buf; - - page_params.page_size = gfx::Size( - static_cast<int>(content_width_in_points + - margin_left_in_points + margin_right_in_points), - static_cast<int>(content_height_in_points + - margin_top_in_points + margin_bottom_in_points)); - page_params.content_area = gfx::Rect( - static_cast<int>(margin_left_in_points), - static_cast<int>(margin_top_in_points), - static_cast<int>(content_width_in_points), - static_cast<int>(content_height_in_points)); + + page_params.page_size = params.params.page_size; + page_params.content_area = gfx::Rect(margin_left, margin_top, width, height); // Ask the browser to create the shared memory for us. - uint32 buf_size = metafile.GetDataSize(); - base::SharedMemoryHandle shared_mem_handle; - if (Send(new ViewHostMsg_AllocateSharedMemoryBuffer(buf_size, - &shared_mem_handle))) { - if (base::SharedMemory::IsHandleValid(shared_mem_handle)) { - base::SharedMemory shared_buf(shared_mem_handle, false); - if (shared_buf.Map(buf_size)) { - metafile.GetData(shared_buf.memory(), buf_size); - page_params.data_size = buf_size; - shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), - &(page_params.metafile_data_handle)); - } else { - NOTREACHED() << "Map failed"; - } - } else { - NOTREACHED() << "Browser failed to allocate shared memory"; + if (!CopyMetafileDataToSharedMem(&metafile, + &(page_params.metafile_data_handle))) { + NOTREACHED(); + return; + } + + page_params.data_size = metafile.GetDataSize(); + Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params)); +} + +void PrintWebViewHelper::CreatePreviewDocument( + const ViewMsg_PrintPages_Params& params, + WebFrame* frame, + ViewHostMsg_DidPreviewDocument_Params* print_params) { + ViewMsg_Print_Params printParams = params.params; + UpdatePrintableSizeInPrintParameters(frame, &printParams); + + PrepareFrameAndViewForPrint prep_frame_view(printParams, + frame, frame->view()); + int page_count = prep_frame_view.GetExpectedPageCount(); + + if (!page_count) + return; + + float scale_factor = frame->getPrintPageShrink(0); + double originX = printParams.margin_left; + double originY = printParams.margin_top; + + printing::NativeMetafile metafile; + if (!metafile.Init()) + return; + + gfx::Point origin(originX, originY); + + if (params.pages.empty()) { + for (int i = 0; i < page_count; ++i) { + RenderPage(printParams.page_size, origin, scale_factor, i, frame, + &metafile); } } else { - NOTREACHED() << "Browser allocation request message failed"; + for (size_t i = 0; i < params.pages.size(); ++i) { + if (params.pages[i] >= page_count) + break; + RenderPage(printParams.page_size, origin, scale_factor, + static_cast<int>(params.pages[i]), frame, &metafile); + } } - - if (!is_preview_) - Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params)); + metafile.Close(); + // Ask the browser to create the shared memory for us. + if (!CopyMetafileDataToSharedMem(&metafile, + &(print_params->metafile_data_handle))) { + NOTREACHED(); + return; + } + print_params->document_cookie = params.params.document_cookie; + print_params->data_size = metafile.GetDataSize(); } +void PrintWebViewHelper::RenderPage( + const gfx::Size& page_size, const gfx::Point& content_origin, + const float& scale_factor, int page_number, WebFrame* frame, + printing::NativeMetafile* metafile) { + CGContextRef context = metafile->StartPage(page_size, content_origin, + scale_factor); + DCHECK(context); + + // printPage can create autoreleased references to |context|. PDF contexts + // don't write all their data until they are destroyed, so we need to make + // certain that there are no lingering references. + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + frame->printPage(page_number, context); + [pool release]; + + // Done printing. Close the device context to retrieve the compiled metafile. + metafile->FinishPage(); +} diff --git a/printing/pdf_metafile_mac.cc b/printing/pdf_metafile_mac.cc index d09721f..2533205 100644 --- a/printing/pdf_metafile_mac.cc +++ b/printing/pdf_metafile_mac.cc @@ -59,10 +59,14 @@ bool PdfMetafile::Init(const void* src_buffer, uint32 src_buffer_size) { return true; } -void PdfMetafile::StartPage(double width, double height, double scale_factor) { +CGContextRef PdfMetafile::StartPage(const gfx::Size& page_size, + const gfx::Point& content_origin, const float& scale_factor) { DCHECK(context_.get()); DCHECK(!page_is_open_); + double height = page_size.height(); + double width = page_size.width(); + CGRect bounds = CGRectMake(0, 0, width, height); CGContextBeginPage(context_, &bounds); page_is_open_ = true; @@ -71,6 +75,11 @@ void PdfMetafile::StartPage(double width, double height, double scale_factor) { // Flip the context. CGContextTranslateCTM(context_, 0, height); CGContextScaleCTM(context_, scale_factor, -scale_factor); + + // Move the context to origin. + CGContextTranslateCTM(context_, content_origin.x(), content_origin.y()); + + return context_.get(); } void PdfMetafile::FinishPage() { diff --git a/printing/pdf_metafile_mac.h b/printing/pdf_metafile_mac.h index 8872d99..38be634 100644 --- a/printing/pdf_metafile_mac.h +++ b/printing/pdf_metafile_mac.h @@ -13,6 +13,8 @@ namespace gfx { class Rect; +class Size; +class Point; } class FilePath; @@ -38,9 +40,11 @@ class PdfMetafile { // Initializes a copy of metafile from PDF data. Returns true on success. bool Init(const void* src_buffer, uint32 src_buffer_size); - // Prepares a new pdf page with the given width and height and a scale - // factor to use for the drawing. - void StartPage(double width, double height, double scale_factor); + // Prepares a new pdf page at specified |content_origin| with the given + // |page_size| and a |scale_factor| to use for the drawing. + CGContextRef StartPage(const gfx::Size& page_size, + const gfx::Point& content_origin, + const float& scale_factor); // Closes the current page. void FinishPage(); diff --git a/printing/pdf_metafile_mac_unittest.cc b/printing/pdf_metafile_mac_unittest.cc index fdf833c..c72b265 100644 --- a/printing/pdf_metafile_mac_unittest.cc +++ b/printing/pdf_metafile_mac_unittest.cc @@ -15,15 +15,18 @@ TEST(PdfMetafileTest, Pdf) { // Test in-renderer constructor. printing::PdfMetafile pdf; - CGContextRef context = pdf.Init(); - EXPECT_TRUE(context != NULL); + EXPECT_TRUE(pdf.Init() != NULL); - // Render page 1. - pdf.StartPage(540, 720, 1.25); + // Render page 1 at origin (10.0, 10.0). + gfx::Point origin_1(10.0f, 10.0f); + gfx::Size size_1(540, 720); + pdf.StartPage(size_1, origin_1, 1.25); pdf.FinishPage(); - // Render page 2. - pdf.StartPage(720, 540, 2.0); + // Render page 2 at origin (10.0, 10.0). + gfx::Point origin_2(10.0f, 10.0f); + gfx::Size size_2(720, 540); + pdf.StartPage(size_2, origin_2, 2.0); pdf.FinishPage(); pdf.Close(); diff --git a/printing/printed_document_mac.cc b/printing/printed_document_mac.cc index d429109..3c5a401 100644 --- a/printing/printed_document_mac.cc +++ b/printing/printed_document_mac.cc @@ -34,7 +34,7 @@ void PrintedDocument::RenderPrintedPage( // Each NativeMetafile is a one-page PDF, and pages use 1-based indexing. const int page_number = 1; metafile->RenderPage(page_number, context, content_area.ToCGRect(), - true, false, false, false); + false, false, false, false); // TODO(stuartmorgan): Print the header and footer. } |