| 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/file_descriptor_posix.h" |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 8 #include "chrome/common/render_messages.h" | 9 #include "chrome/common/render_messages.h" |
| 9 #include "printing/native_metafile.h" | 10 #include "printing/native_metafile.h" |
| 10 #include "skia/ext/vector_canvas.h" | 11 #include "skia/ext/vector_canvas.h" |
| 11 #include "webkit/api/public/WebFrame.h" | 12 #include "webkit/api/public/WebFrame.h" |
| 12 | 13 |
| 13 using WebKit::WebFrame; | 14 using WebKit::WebFrame; |
| 14 | 15 |
| 15 void PrintWebViewHelper::Print(WebFrame* frame, bool script_initiated) { | 16 void PrintWebViewHelper::Print(WebFrame* frame, bool script_initiated) { |
| 16 // If still not finished with earlier print request simply ignore. | 17 // If still not finished with earlier print request simply ignore. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 46 | 47 |
| 47 void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, | 48 void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, |
| 48 WebFrame* frame) { | 49 WebFrame* frame) { |
| 49 PrepareFrameAndViewForPrint prep_frame_view(params.params, | 50 PrepareFrameAndViewForPrint prep_frame_view(params.params, |
| 50 frame, | 51 frame, |
| 51 frame->view()); | 52 frame->view()); |
| 52 int page_count = prep_frame_view.GetExpectedPageCount(); | 53 int page_count = prep_frame_view.GetExpectedPageCount(); |
| 53 | 54 |
| 54 // TODO(myhuang): Send ViewHostMsg_DidGetPrintedPagesCount. | 55 // TODO(myhuang): Send ViewHostMsg_DidGetPrintedPagesCount. |
| 55 | 56 |
| 56 if (page_count) { | 57 if (page_count == 0) |
| 57 // We only can use PDF in the renderer because Cairo needs to create a | 58 return; |
| 58 // temporary file for a PostScript surface. | |
| 59 printing::NativeMetafile metafile(printing::NativeMetafile::PDF); | |
| 60 metafile.Init(); | |
| 61 | 59 |
| 62 ViewMsg_PrintPage_Params print_page_params; | 60 // We only can use PDF in the renderer because Cairo needs to create a |
| 63 print_page_params.params = params.params; | 61 // temporary file for a PostScript surface. |
| 64 const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize(); | 62 printing::NativeMetafile metafile(printing::NativeMetafile::PDF); |
| 65 if (params.pages.empty()) { | 63 metafile.Init(); |
| 66 for (int i = 0; i < page_count; ++i) { | 64 |
| 67 print_page_params.page_number = i; | 65 ViewMsg_PrintPage_Params print_page_params; |
| 68 PrintPage(print_page_params, canvas_size, frame, &metafile); | 66 print_page_params.params = params.params; |
| 69 } | 67 const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize(); |
| 70 } else { | 68 if (params.pages.empty()) { |
| 71 for (size_t i = 0; i < params.pages.size(); ++i) { | 69 for (int i = 0; i < page_count; ++i) { |
| 72 print_page_params.page_number = params.pages[i]; | 70 print_page_params.page_number = i; |
| 73 PrintPage(print_page_params, canvas_size, frame, &metafile); | 71 PrintPage(print_page_params, canvas_size, frame, &metafile); |
| 74 } | |
| 75 } | 72 } |
| 76 | 73 } else { |
| 77 metafile.Close(); | 74 for (size_t i = 0; i < params.pages.size(); ++i) { |
| 78 | 75 print_page_params.page_number = params.pages[i]; |
| 79 // Get the size of the resulting metafile. | 76 PrintPage(print_page_params, canvas_size, frame, &metafile); |
| 80 unsigned int buf_size = metafile.GetDataSize(); | |
| 81 DCHECK_GT(buf_size, 0u); | |
| 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 } | 77 } |
| 113 } | 78 } |
| 79 |
| 80 metafile.Close(); |
| 81 |
| 82 // Get the size of the resulting metafile. |
| 83 unsigned int buf_size = metafile.GetDataSize(); |
| 84 DCHECK_GT(buf_size, 0u); |
| 85 |
| 86 base::FileDescriptor fd; |
| 87 int fd_in_browser = -1; |
| 88 |
| 89 // Ask the browser to open a file for us. |
| 90 if (!Send(new ViewHostMsg_AllocateTempFileForPrinting(&fd, |
| 91 &fd_in_browser))) { |
| 92 return; |
| 93 } |
| 94 |
| 95 if (!metafile.SaveTo(fd)) |
| 96 return; |
| 97 |
| 98 // Tell the browser we've finished writing the file. |
| 99 Send(new ViewHostMsg_TempFileForPrintingWritten(fd_in_browser)); |
| 114 } | 100 } |
| 115 | 101 |
| 116 void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, | 102 void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, |
| 117 const gfx::Size& canvas_size, | 103 const gfx::Size& canvas_size, |
| 118 WebFrame* frame, | 104 WebFrame* frame, |
| 119 printing::NativeMetafile* metafile) { | 105 printing::NativeMetafile* metafile) { |
| 120 // Since WebKit extends the page width depending on the magical shrink | 106 // Since WebKit extends the page width depending on the magical shrink |
| 121 // factor we make sure the canvas covers the worst case scenario | 107 // factor we make sure the canvas covers the worst case scenario |
| 122 // (x2.0 currently). PrintContext will then set the correct clipping region. | 108 // (x2.0 currently). PrintContext will then set the correct clipping region. |
| 123 int size_x = static_cast<int>(canvas_size.width() * params.params.max_shrink); | 109 int size_x = static_cast<int>(canvas_size.width() * params.params.max_shrink); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 146 | 132 |
| 147 // TODO(myhuang): We should handle transformation for paper margins. | 133 // TODO(myhuang): We should handle transformation for paper margins. |
| 148 // TODO(myhuang): We should render the header and the footer. | 134 // TODO(myhuang): We should render the header and the footer. |
| 149 | 135 |
| 150 // Done printing. Close the device context to retrieve the compiled metafile. | 136 // Done printing. Close the device context to retrieve the compiled metafile. |
| 151 if (!metafile->FinishPage(shrink)) { | 137 if (!metafile->FinishPage(shrink)) { |
| 152 NOTREACHED() << "metafile failed"; | 138 NOTREACHED() << "metafile failed"; |
| 153 } | 139 } |
| 154 } | 140 } |
| 155 | 141 |
| OLD | NEW |