Index: chrome/renderer/print_web_view_helper_linux.cc |
=================================================================== |
--- chrome/renderer/print_web_view_helper_linux.cc (revision 25608) |
+++ chrome/renderer/print_web_view_helper_linux.cc (working copy) |
@@ -6,6 +6,7 @@ |
#include "base/logging.h" |
#include "chrome/common/render_messages.h" |
+#include "printing/native_metafile.h" |
#include "skia/ext/vector_canvas.h" |
#include "webkit/api/public/WebFrame.h" |
@@ -37,30 +38,85 @@ |
default_settings.document_cookie = NULL; |
default_settings.selection_only = false; |
- // Calculate the estimated page count. |
- PrepareFrameAndViewForPrint prep_frame_view(default_settings, |
+ ViewMsg_PrintPages_Params print_settings; |
+ print_settings.params = default_settings; |
+ |
+ PrintPages(print_settings, frame); |
+} |
+ |
+void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, |
+ WebFrame* frame) { |
+ PrepareFrameAndViewForPrint prep_frame_view(params.params, |
frame, |
frame->view()); |
- int expected_pages_count = prep_frame_view.GetExpectedPageCount(); |
- DCHECK(expected_pages_count); |
+ int page_count = prep_frame_view.GetExpectedPageCount(); |
- ViewMsg_PrintPage_Params page_params; |
- page_params.params = default_settings; |
+ // TODO(myhuang): Send ViewHostMsg_DidGetPrintedPagesCount. |
- // TODO(myhuang): Get final printing settings via IPC. |
- // For testing purpose, we hard-coded printing settings here. |
+ if (page_count) { |
+ // We only can use PDF in the renderer because Cairo needs to create a |
+ // temporary file for a PostScript surface. |
+ printing::NativeMetafile metafile(printing::NativeMetafile::PDF); |
+ metafile.Init(); |
- // Print the first page only. |
- expected_pages_count = 1; |
- for (int i = 0; i < expected_pages_count; ++i) { |
- page_params.page_number = i; |
- PrintPage(page_params, prep_frame_view.GetPrintCanvasSize(), frame); |
+ ViewMsg_PrintPage_Params print_page_params; |
+ print_page_params.params = params.params; |
+ const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize(); |
+ if (params.pages.empty()) { |
+ for (int i = 0; i < page_count; ++i) { |
+ print_page_params.page_number = i; |
+ PrintPage(print_page_params, canvas_size, frame, &metafile); |
+ } |
+ } else { |
+ for (size_t i = 0; i < params.pages.size(); ++i) { |
+ print_page_params.page_number = params.pages[i]; |
+ PrintPage(print_page_params, canvas_size, frame, &metafile); |
+ } |
+ } |
+ |
+ metafile.Close(); |
+ |
+ // Get the size of the resulting metafile. |
+ unsigned int buf_size = metafile.GetDataSize(); |
+ DCHECK_GT(buf_size, 0u); |
M-A Ruel
2009/09/08 14:38:51
uh
|
+ |
+ ViewHostMsg_DidPrintPage_Params did_page_params; |
+ |
+ // Ask the browser create the shared memory for us. |
+ if (Send(new ViewHostMsg_AllocateShareMemory( |
+ routing_id(), |
+ buf_size, |
+ &did_page_params.metafile_data_handle))) { |
+ if (did_page_params.metafile_data_handle.fd > -1) { |
+ base::SharedMemory shared_buf(did_page_params.metafile_data_handle, |
+ false); |
+ if (shared_buf.Map(buf_size)) { |
+ if (metafile.GetData(shared_buf.memory(), buf_size)) { |
+ // FIXME(myhuang): This is for testing purpose at this moment. |
+ // We use this message to pass the resulting PDF to the browser, |
+ // and the browser will save this PDF on the disk. |
+ did_page_params.data_size = buf_size; |
+ Send(new ViewHostMsg_DidPrintPage(routing_id(), did_page_params)); |
+ } else { |
+ NOTREACHED() << "GetData() failed"; |
+ } |
+ shared_buf.Unmap(); |
+ } else { |
+ NOTREACHED() << "Buffer mapping failed"; |
+ } |
+ } else { |
+ NOTREACHED() << "Buffer allocation failed"; |
+ } |
+ } else { |
+ NOTREACHED() << "Buffer allocation failed"; |
+ } |
} |
} |
void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, |
const gfx::Size& canvas_size, |
- WebFrame* frame) { |
+ WebFrame* frame, |
+ printing::NativeMetafile* metafile) { |
// Since WebKit extends the page width depending on the magical shrink |
// factor we make sure the canvas covers the worst case scenario |
// (x2.0 currently). PrintContext will then set the correct clipping region. |
@@ -71,16 +127,29 @@ |
float shrink = static_cast<float>(canvas_size.width()) / |
params.params.printable_size.width(); |
- // TODO(myhuang): We now use VectorCanvas to generate a PS/PDF file for |
- // each page in printing. We might also need to create a metafile class |
- // on Linux. |
- skia::VectorCanvas canvas(size_x, size_y); |
+ cairo_t* cairo_context = metafile->StartPage(size_x, size_y); |
+ if (!cairo_context) { |
+ // TODO(myhuang): We should handle such kind of error further! |
+ // We already have had DLOG(ERROR) in NativeMetafile::StartPage(), |
+ // log the error here, too? |
+ return; |
+ } |
+ |
+ skia::VectorCanvas canvas(cairo_context, size_x, size_y); |
float webkit_shrink = frame->printPage(params.page_number, &canvas); |
- if (shrink <= 0) { |
+ if (webkit_shrink <= 0) { |
NOTREACHED() << "Printing page " << params.page_number << " failed."; |
} else { |
// Update the dpi adjustment with the "page shrink" calculated in webkit. |
shrink /= webkit_shrink; |
} |
+ |
+ // TODO(myhuang): We should handle transformation for paper margins. |
+ // TODO(myhuang): We should render the header and the footer. |
+ |
+ // Done printing. Close the device context to retrieve the compiled metafile. |
+ if (!metafile->FinishPage(shrink)) { |
+ NOTREACHED() << "metafile failed"; |
+ } |
} |