Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/renderer/print_web_view_helper.h" | 5 #include "chrome/renderer/print_web_view_helper.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/common/render_messages.h" | 8 #include "chrome/common/render_messages.h" |
| 9 #include "printing/native_metafile.h" | |
| 9 #include "skia/ext/vector_canvas.h" | 10 #include "skia/ext/vector_canvas.h" |
| 10 #include "webkit/api/public/WebFrame.h" | 11 #include "webkit/api/public/WebFrame.h" |
| 11 | 12 |
| 12 using WebKit::WebFrame; | 13 using WebKit::WebFrame; |
| 13 | 14 |
| 14 void PrintWebViewHelper::Print(WebFrame* frame, bool script_initiated) { | 15 void PrintWebViewHelper::Print(WebFrame* frame, bool script_initiated) { |
| 15 // If still not finished with earlier print request simply ignore. | 16 // If still not finished with earlier print request simply ignore. |
| 16 if (IsPrinting()) | 17 if (IsPrinting()) |
| 17 return; | 18 return; |
| 18 | 19 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 30 const int kHeight = (11-0.25-0.56) * kDPI; | 31 const int kHeight = (11-0.25-0.56) * kDPI; |
| 31 ViewMsg_Print_Params default_settings; | 32 ViewMsg_Print_Params default_settings; |
| 32 default_settings.printable_size = gfx::Size(kWidth, kHeight); | 33 default_settings.printable_size = gfx::Size(kWidth, kHeight); |
| 33 default_settings.dpi = kDPI; | 34 default_settings.dpi = kDPI; |
| 34 default_settings.min_shrink = 1.25; | 35 default_settings.min_shrink = 1.25; |
| 35 default_settings.max_shrink = 2.0; | 36 default_settings.max_shrink = 2.0; |
| 36 default_settings.desired_dpi = kDPI; | 37 default_settings.desired_dpi = kDPI; |
| 37 default_settings.document_cookie = NULL; | 38 default_settings.document_cookie = NULL; |
| 38 default_settings.selection_only = false; | 39 default_settings.selection_only = false; |
| 39 | 40 |
| 40 // Calculate the estimated page count. | 41 ViewMsg_PrintPages_Params print_settings; |
| 41 PrepareFrameAndViewForPrint prep_frame_view(default_settings, | 42 print_settings.params = default_settings; |
| 43 | |
| 44 PrintPages(print_settings, frame); | |
| 45 } | |
| 46 | |
| 47 void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, | |
| 48 WebFrame* frame) { | |
| 49 PrepareFrameAndViewForPrint prep_frame_view(params.params, | |
| 42 frame, | 50 frame, |
| 43 frame->view()); | 51 frame->view()); |
| 44 int expected_pages_count = prep_frame_view.GetExpectedPageCount(); | 52 int page_count = prep_frame_view.GetExpectedPageCount(); |
| 45 DCHECK(expected_pages_count); | |
| 46 | 53 |
| 47 ViewMsg_PrintPage_Params page_params; | 54 // TODO(myhuang): Send ViewHostMsg_DidGetPrintedPagesCount. |
| 48 page_params.params = default_settings; | |
| 49 | 55 |
| 50 // TODO(myhuang): Get final printing settings via IPC. | 56 if (page_count) { |
| 51 // For testing purpose, we hard-coded printing settings here. | 57 // We only can use PDF in the renderer because Cairo needs to create a |
| 58 // temporary file for a PostScript surface. | |
| 59 printing::NativeMetafile metafile(printing::NativeMetafile::PDF); | |
| 60 metafile.Init(); | |
| 52 | 61 |
| 53 // Print the first page only. | 62 ViewMsg_PrintPage_Params print_page_params; |
| 54 expected_pages_count = 1; | 63 print_page_params.params = params.params; |
| 55 for (int i = 0; i < expected_pages_count; ++i) { | 64 const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize(); |
| 56 page_params.page_number = i; | 65 if (params.pages.empty()) { |
| 57 PrintPage(page_params, prep_frame_view.GetPrintCanvasSize(), frame); | 66 for (int i = 0; i < page_count; ++i) { |
| 67 print_page_params.page_number = i; | |
| 68 PrintPage(print_page_params, canvas_size, frame, &metafile); | |
| 69 } | |
| 70 } else { | |
| 71 for (size_t i = 0; i < params.pages.size(); ++i) { | |
| 72 print_page_params.page_number = params.pages[i]; | |
| 73 PrintPage(print_page_params, canvas_size, frame, &metafile); | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 metafile.Close(); | |
| 78 | |
| 79 // Get the size of the resulting metafile. | |
| 80 unsigned int buf_size = metafile.GetDataSize(); | |
| 81 DCHECK_GT(buf_size, 0u); | |
|
M-A Ruel
2009/09/08 14:38:51
uh
| |
| 82 | |
| 83 ViewHostMsg_DidPrintPage_Params did_page_params; | |
| 84 | |
| 85 // Ask the browser create the shared memory for us. | |
| 86 if (Send(new ViewHostMsg_AllocateShareMemory( | |
| 87 routing_id(), | |
| 88 buf_size, | |
| 89 &did_page_params.metafile_data_handle))) { | |
| 90 if (did_page_params.metafile_data_handle.fd > -1) { | |
| 91 base::SharedMemory shared_buf(did_page_params.metafile_data_handle, | |
| 92 false); | |
| 93 if (shared_buf.Map(buf_size)) { | |
| 94 if (metafile.GetData(shared_buf.memory(), buf_size)) { | |
| 95 // FIXME(myhuang): This is for testing purpose at this moment. | |
| 96 // We use this message to pass the resulting PDF to the browser, | |
| 97 // and the browser will save this PDF on the disk. | |
| 98 did_page_params.data_size = buf_size; | |
| 99 Send(new ViewHostMsg_DidPrintPage(routing_id(), did_page_params)); | |
| 100 } else { | |
| 101 NOTREACHED() << "GetData() failed"; | |
| 102 } | |
| 103 shared_buf.Unmap(); | |
| 104 } else { | |
| 105 NOTREACHED() << "Buffer mapping failed"; | |
| 106 } | |
| 107 } else { | |
| 108 NOTREACHED() << "Buffer allocation failed"; | |
| 109 } | |
| 110 } else { | |
| 111 NOTREACHED() << "Buffer allocation failed"; | |
| 112 } | |
| 58 } | 113 } |
| 59 } | 114 } |
| 60 | 115 |
| 61 void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, | 116 void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, |
| 62 const gfx::Size& canvas_size, | 117 const gfx::Size& canvas_size, |
| 63 WebFrame* frame) { | 118 WebFrame* frame, |
| 119 printing::NativeMetafile* metafile) { | |
| 64 // Since WebKit extends the page width depending on the magical shrink | 120 // Since WebKit extends the page width depending on the magical shrink |
| 65 // factor we make sure the canvas covers the worst case scenario | 121 // factor we make sure the canvas covers the worst case scenario |
| 66 // (x2.0 currently). PrintContext will then set the correct clipping region. | 122 // (x2.0 currently). PrintContext will then set the correct clipping region. |
| 67 int size_x = static_cast<int>(canvas_size.width() * params.params.max_shrink); | 123 int size_x = static_cast<int>(canvas_size.width() * params.params.max_shrink); |
| 68 int size_y = static_cast<int>(canvas_size.height() * | 124 int size_y = static_cast<int>(canvas_size.height() * |
| 69 params.params.max_shrink); | 125 params.params.max_shrink); |
| 70 // Calculate the dpi adjustment. | 126 // Calculate the dpi adjustment. |
| 71 float shrink = static_cast<float>(canvas_size.width()) / | 127 float shrink = static_cast<float>(canvas_size.width()) / |
| 72 params.params.printable_size.width(); | 128 params.params.printable_size.width(); |
| 73 | 129 |
| 74 // TODO(myhuang): We now use VectorCanvas to generate a PS/PDF file for | 130 cairo_t* cairo_context = metafile->StartPage(size_x, size_y); |
| 75 // each page in printing. We might also need to create a metafile class | 131 if (!cairo_context) { |
| 76 // on Linux. | 132 // TODO(myhuang): We should handle such kind of error further! |
| 77 skia::VectorCanvas canvas(size_x, size_y); | 133 // We already have had DLOG(ERROR) in NativeMetafile::StartPage(), |
| 134 // log the error here, too? | |
| 135 return; | |
| 136 } | |
| 137 | |
| 138 skia::VectorCanvas canvas(cairo_context, size_x, size_y); | |
| 78 float webkit_shrink = frame->printPage(params.page_number, &canvas); | 139 float webkit_shrink = frame->printPage(params.page_number, &canvas); |
| 79 if (shrink <= 0) { | 140 if (webkit_shrink <= 0) { |
| 80 NOTREACHED() << "Printing page " << params.page_number << " failed."; | 141 NOTREACHED() << "Printing page " << params.page_number << " failed."; |
| 81 } else { | 142 } else { |
| 82 // Update the dpi adjustment with the "page shrink" calculated in webkit. | 143 // Update the dpi adjustment with the "page shrink" calculated in webkit. |
| 83 shrink /= webkit_shrink; | 144 shrink /= webkit_shrink; |
| 84 } | 145 } |
| 146 | |
| 147 // TODO(myhuang): We should handle transformation for paper margins. | |
| 148 // TODO(myhuang): We should render the header and the footer. | |
| 149 | |
| 150 // Done printing. Close the device context to retrieve the compiled metafile. | |
| 151 if (!metafile->FinishPage(shrink)) { | |
| 152 NOTREACHED() << "metafile failed"; | |
| 153 } | |
| 85 } | 154 } |
| 86 | 155 |
| OLD | NEW |