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 |