diff options
author | vandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-26 07:25:56 +0000 |
---|---|---|
committer | vandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-26 07:25:56 +0000 |
commit | 099a0d328bff5382e08e8004e9e84deb490a4550 (patch) | |
tree | ed5d0c7d2289ea555601bf3b87759bdfd254ac55 /chrome/renderer | |
parent | 1891d75dd8c1b73102a49f414406c08dc9dda1cd (diff) | |
download | chromium_src-099a0d328bff5382e08e8004e9e84deb490a4550.zip chromium_src-099a0d328bff5382e08e8004e9e84deb490a4550.tar.gz chromium_src-099a0d328bff5382e08e8004e9e84deb490a4550.tar.bz2 |
Change printing code to minimize the number of page reflows (3 to 1-2).
BUG=83894
TEST=NONE
Review URL: http://codereview.chromium.org/7513004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94052 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/print_web_view_helper.cc | 175 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.h | 39 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_linux.cc | 28 |
3 files changed, 157 insertions, 85 deletions
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index 36a67c4..8430356 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -26,7 +26,6 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h" @@ -92,6 +91,16 @@ bool PrintMsg_Print_Params_IsEqual( newParams.pages.begin()); } +void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params, + gfx::Size* result) { + int dpi = GetDPI(&print_params); + result->set_width(ConvertUnit(print_params.printable_size.width(), dpi, + print_params.desired_dpi)); + + result->set_height(ConvertUnit(print_params.printable_size.height(), dpi, + print_params.desired_dpi)); +} + } // namespace PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( @@ -100,17 +109,43 @@ PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( WebNode* node) : frame_(frame), web_view_(frame->view()), + dpi_(static_cast<int>(print_params.dpi)), expected_pages_count_(0), use_browser_overlays_(true), finished_(false) { - int dpi = GetDPI(&print_params); - print_canvas_size_.set_width( - ConvertUnit(print_params.printable_size.width(), dpi, - print_params.desired_dpi)); + gfx::Size canvas_size; + CalculatePrintCanvasSize(print_params, &canvas_size); + + if (WebFrame* web_frame = web_view_->mainFrame()) + prev_scroll_offset_ = web_frame->scrollOffset(); + prev_view_size_ = web_view_->size(); - print_canvas_size_.set_height( - ConvertUnit(print_params.printable_size.height(), dpi, - print_params.desired_dpi)); + if (node) + node_to_print_ = *node; + + StartPrinting(canvas_size); +} + +PrepareFrameAndViewForPrint::~PrepareFrameAndViewForPrint() { + FinishPrinting(); +} + +void PrepareFrameAndViewForPrint::UpdatePrintParams( + const PrintMsg_Print_Params& print_params) { + DCHECK(!finished_); + gfx::Size canvas_size; + CalculatePrintCanvasSize(print_params, &canvas_size); + if (canvas_size == print_canvas_size_) + return; + + frame_->printEnd(); + dpi_ = static_cast<int>(print_params.dpi); + StartPrinting(canvas_size); +} + +void PrepareFrameAndViewForPrint::StartPrinting( + const gfx::Size& print_canvas_size) { + print_canvas_size_ = print_canvas_size; // Layout page according to printer page size. Since WebKit shrinks the // size of the page automatically (from 125% to 200%) we trick it to @@ -121,22 +156,10 @@ PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( print_layout_size.set_height(static_cast<int>( static_cast<double>(print_layout_size.height()) * 1.25)); - if (WebFrame* web_frame = web_view_->mainFrame()) - prev_scroll_offset_ = web_frame->scrollOffset(); - prev_view_size_ = web_view_->size(); - web_view_->resize(print_layout_size); - WebNode node_to_print; - if (node) - node_to_print = *node; - expected_pages_count_ = frame->printBegin( - print_canvas_size_, node_to_print, static_cast<int>(print_params.dpi), - &use_browser_overlays_); -} - -PrepareFrameAndViewForPrint::~PrepareFrameAndViewForPrint() { - FinishPrinting(); + expected_pages_count_ = frame_->printBegin(print_canvas_size_, node_to_print_, + dpi_, &use_browser_overlays_); } void PrepareFrameAndViewForPrint::FinishPrinting() { @@ -153,9 +176,9 @@ PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view) : RenderViewObserver(render_view), RenderViewObserverTracker<PrintWebViewHelper>(render_view), print_web_view_(NULL), + is_preview_(switches::IsPrintPreviewEnabled()), user_cancelled_scripted_print_count_(0), notify_browser_of_print_failure_(true) { - is_preview_ = switches::IsPrintPreviewEnabled(); } PrintWebViewHelper::~PrintWebViewHelper() {} @@ -227,7 +250,8 @@ void PrintWebViewHelper::OnPrintForPrintPreview( } WebFrame* pdf_frame = pdf_element.document().frame(); - if (!InitPrintSettings(pdf_frame, &pdf_element)) { + scoped_ptr<PrepareFrameAndViewForPrint> prepare; + if (!InitPrintSettingsAndPrepareFrame(pdf_frame, &pdf_element, &prepare)) { NOTREACHED() << "Failed to initialize print page settings"; return; } @@ -238,7 +262,7 @@ void PrintWebViewHelper::OnPrintForPrintPreview( } // Render Pages for printing. - if (!RenderPagesForPrint(pdf_frame, &pdf_element)) + if (!RenderPagesForPrint(pdf_frame, &pdf_element, prepare.get())) DidFinishPrinting(FAIL_PRINT); } @@ -321,13 +345,9 @@ void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) { } bool PrintWebViewHelper::CreatePreviewDocument() { - PrintMsg_Print_Params printParams = print_pages_params_->params; - UpdatePrintableSizeInPrintParameters(print_preview_context_.frame(), - print_preview_context_.node(), - &printParams); - + PrintMsg_Print_Params print_params = print_pages_params_->params; const std::vector<int>& pages = print_pages_params_->pages; - if (!print_preview_context_.CreatePreviewDocument(printParams, pages)) + if (!print_preview_context_.CreatePreviewDocument(&print_params, pages)) return false; int page_count = print_preview_context_.total_page_count(); int document_cookie = print_pages_params_->params.document_cookie; @@ -433,37 +453,36 @@ void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) { return; // Initialize print settings. - if (!InitPrintSettings(frame, node)) + scoped_ptr<PrepareFrameAndViewForPrint> prepare; + if (!InitPrintSettingsAndPrepareFrame(frame, node, &prepare)) return; // Failed to init print page settings. - int expected_pages_count = 0; + int expected_page_count = 0; bool use_browser_overlays = true; - // Prepare once to calculate the estimated page count. This must be in - // a scope for itself (see comments on PrepareFrameAndViewForPrint). - { - PrepareFrameAndViewForPrint prep_frame_view( - print_pages_params_->params, frame, node); - expected_pages_count = prep_frame_view.GetExpectedPageCount(); - if (expected_pages_count) - use_browser_overlays = prep_frame_view.ShouldUseBrowserOverlays(); - } + expected_page_count = prepare->GetExpectedPageCount(); + if (expected_page_count) + use_browser_overlays = prepare->ShouldUseBrowserOverlays(); + + // Release the prepare before going any further, since we are going to + // show UI and wait for the user. + prepare.reset(); // Some full screen plugins can say they don't want to print. - if (!expected_pages_count) { + if (!expected_page_count) { DidFinishPrinting(OK); // Release resources and fail silently. return; } // Ask the browser to show UI to retrieve the final print settings. - if (!GetPrintSettingsFromUser(frame, expected_pages_count, + if (!GetPrintSettingsFromUser(frame, expected_page_count, use_browser_overlays)) { DidFinishPrinting(OK); // Release resources and fail silently. return; } // Render Pages for printing. - if (!RenderPagesForPrint(frame, node)) + if (!RenderPagesForPrint(frame, node, NULL)) DidFinishPrinting(FAIL_PRINT); ResetScriptedPrintCount(); } @@ -533,21 +552,27 @@ bool PrintWebViewHelper::CopyAndPrint(WebKit::WebFrame* web_frame) { #if defined(OS_MACOSX) || defined(OS_WIN) bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params, WebFrame* frame, - WebNode* node) { - PrintMsg_Print_Params printParams = params.params; - UpdatePrintableSizeInPrintParameters(frame, node, &printParams); + WebNode* node, + PrepareFrameAndViewForPrint* prepare) { + PrintMsg_Print_Params print_params = params.params; + scoped_ptr<PrepareFrameAndViewForPrint> prep_frame_view; + if (!prepare) { + prep_frame_view.reset(new PrepareFrameAndViewForPrint(print_params, frame, + node)); + prepare = prep_frame_view.get(); + } + UpdatePrintableSizeInPrintParameters(frame, node, prepare, &print_params); - PrepareFrameAndViewForPrint prep_frame_view(printParams, frame, node); - int page_count = prep_frame_view.GetExpectedPageCount(); + int page_count = prepare->GetExpectedPageCount(); if (!page_count) return false; Send(new PrintHostMsg_DidGetPrintedPagesCount(routing_id(), - printParams.document_cookie, + print_params.document_cookie, page_count)); - const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize(); + const gfx::Size& canvas_size = prepare->GetPrintCanvasSize(); PrintMsg_PrintPage_Params page_params; - page_params.params = printParams; + page_params.params = print_params; if (params.pages.empty()) { for (int i = 0; i < page_count; ++i) { page_params.page_number = i; @@ -568,9 +593,10 @@ bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params, void PrintWebViewHelper::didStopLoading() { PrintMsg_PrintPages_Params* params = print_pages_params_.get(); DCHECK(params != NULL); - PrintPages(*params, print_web_view_->mainFrame(), NULL); + PrintPages(*params, print_web_view_->mainFrame(), NULL, NULL); } +// static - Not anonymous so that platform implementations can use it. void PrintWebViewHelper::GetPageSizeAndMarginsInPoints( WebFrame* frame, int page_index, @@ -634,12 +660,14 @@ void PrintWebViewHelper::GetPageSizeAndMarginsInPoints( ConvertPixelsToPointDouble(margin_left_in_pixels); } +// static - Not anonymous so that platform implementations can use it. void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters( WebFrame* frame, WebNode* node, + PrepareFrameAndViewForPrint* prepare, PrintMsg_Print_Params* params) { - PrepareFrameAndViewForPrint prepare(*params, frame, node); PageSizeMargins page_layout_in_points; + prepare->UpdatePrintParams(*params); PrintWebViewHelper::GetPageSizeAndMarginsInPoints(frame, 0, *params, &page_layout_in_points); int dpi = GetDPI(params); @@ -693,11 +721,25 @@ bool PrintWebViewHelper::InitPrintSettings(WebKit::WebFrame* frame, NOTREACHED(); return false; } - UpdatePrintableSizeInPrintParameters(frame, node, &settings.params); + settings.pages.clear(); print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); - Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(), - settings.params.document_cookie)); + return true; +} + +bool PrintWebViewHelper::InitPrintSettingsAndPrepareFrame( + WebKit::WebFrame* frame, WebKit::WebNode* node, + scoped_ptr<PrepareFrameAndViewForPrint>* prepare) { + if (!InitPrintSettings(frame, node)) + return false; + + DCHECK(!prepare->get()); + prepare->reset(new PrepareFrameAndViewForPrint(print_pages_params_->params, + frame, node)); + UpdatePrintableSizeInPrintParameters(frame, node, prepare->get(), + &print_pages_params_->params); + Send(new PrintHostMsg_DidGetDocumentCookie( + routing_id(), print_pages_params_->params.document_cookie)); return true; } @@ -761,14 +803,16 @@ bool PrintWebViewHelper::GetPrintSettingsFromUser(WebKit::WebFrame* frame, return (print_settings.params.dpi && print_settings.params.document_cookie); } -bool PrintWebViewHelper::RenderPagesForPrint(WebKit::WebFrame* frame, - WebKit::WebNode* node) { +bool PrintWebViewHelper::RenderPagesForPrint( + WebKit::WebFrame* frame, + WebKit::WebNode* node, + PrepareFrameAndViewForPrint* prepare) { PrintMsg_PrintPages_Params print_settings = *print_pages_params_; if (print_settings.params.selection_only) { return CopyAndPrint(frame); } else { // TODO: Always copy before printing. - return PrintPages(print_settings, frame, node); + return PrintPages(print_settings, frame, node, prepare); } } @@ -898,20 +942,23 @@ void PrintWebViewHelper::PrintPreviewContext::OnPrintPreview() { } bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument( - const PrintMsg_Print_Params& printParams, + PrintMsg_Print_Params* print_params, const std::vector<int>& pages) { DCHECK(IsReadyToRender()); state_ = RENDERING; - print_params_.reset(new PrintMsg_Print_Params(printParams)); + print_params_.reset(new PrintMsg_Print_Params(*print_params)); metafile_.reset(new printing::PreviewMetafile); if (!metafile_->Init()) return false; // Need to make sure old object gets destroyed first. - prep_frame_view_.reset(new PrepareFrameAndViewForPrint(printParams, frame(), + prep_frame_view_.reset(new PrepareFrameAndViewForPrint(*print_params, frame(), node())); + UpdatePrintableSizeInPrintParameters(frame_, node_.get(), + prep_frame_view_.get(), print_params); + total_page_count_ = prep_frame_view_->GetExpectedPageCount(); if (total_page_count_ == 0) return false; diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h index 4bae6dc..fa555fe 100644 --- a/chrome/renderer/print_web_view_helper.h +++ b/chrome/renderer/print_web_view_helper.h @@ -15,6 +15,7 @@ #include "content/renderer/render_view_observer_tracker.h" #include "printing/metafile.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebViewClient.h" #include "ui/gfx/size.h" @@ -39,6 +40,8 @@ class PrepareFrameAndViewForPrint { WebKit::WebNode* node); ~PrepareFrameAndViewForPrint(); + void UpdatePrintParams(const PrintMsg_Print_Params& print_params); + int GetExpectedPageCount() const { return expected_pages_count_; } @@ -54,11 +57,15 @@ class PrepareFrameAndViewForPrint { void FinishPrinting(); private: + void StartPrinting(const gfx::Size& print_params); + WebKit::WebFrame* frame_; + WebKit::WebNode node_to_print_; WebKit::WebView* web_view_; gfx::Size print_canvas_size_; gfx::Size prev_view_size_; gfx::Size prev_scroll_offset_; + int dpi_; int expected_pages_count_; bool use_browser_overlays_; bool finished_; @@ -164,8 +171,15 @@ class PrintWebViewHelper : public RenderViewObserver, // Print Settings ----------------------------------------------------------- // Initialize print page settings with default settings. - bool InitPrintSettings(WebKit::WebFrame* frame, - WebKit::WebNode* node); + bool InitPrintSettings(WebKit::WebFrame* frame, WebKit::WebNode* node); + + // Initialize print page settings with default settings and prepare the frame + // for print. A new PrepareFrameAndViewForPrint is created to fulfill the + // request and is filled into the |prepare| argument. + bool InitPrintSettingsAndPrepareFrame( + WebKit::WebFrame* frame, + WebKit::WebNode* node, + scoped_ptr<PrepareFrameAndViewForPrint>* prepare); // Parse the request id out of |job_settings| and store it in |params|. // Returns false on failure. @@ -189,7 +203,8 @@ class PrintWebViewHelper : public RenderViewObserver, // It will implicitly revert the document to display CSS media type. bool PrintPages(const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, - WebKit::WebNode* node); + WebKit::WebNode* node, + PrepareFrameAndViewForPrint* prepare); // Prints the page listed in |params|. #if defined(USE_X11) @@ -204,7 +219,8 @@ class PrintWebViewHelper : public RenderViewObserver, #endif // Render the frame for printing. - bool RenderPagesForPrint(WebKit::WebFrame* frame, WebKit::WebNode* node); + bool RenderPagesForPrint(WebKit::WebFrame* frame, WebKit::WebNode* node, + PrepareFrameAndViewForPrint* prepare); // Platform specific helper function for rendering page(s) to |metafile|. #if defined(OS_WIN) @@ -218,7 +234,8 @@ class PrintWebViewHelper : public RenderViewObserver, #elif defined(OS_POSIX) bool RenderPages(const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, WebKit::WebNode* node, - int* page_count, printing::Metafile* metafile); + int* page_count, PrepareFrameAndViewForPrint* prepare, + printing::Metafile* metafile); #endif // defined(OS_WIN) // Helper methods ----------------------------------------------------------- @@ -228,15 +245,17 @@ class PrintWebViewHelper : public RenderViewObserver, bool CopyMetafileDataToSharedMem(printing::Metafile* metafile, base::SharedMemoryHandle* shared_mem_handle); - void GetPageSizeAndMarginsInPoints( + static void GetPageSizeAndMarginsInPoints( WebKit::WebFrame* frame, int page_index, const PrintMsg_Print_Params& default_params, PageSizeMargins* page_layout_in_points); - void UpdatePrintableSizeInPrintParameters(WebKit::WebFrame* frame, - WebKit::WebNode* node, - PrintMsg_Print_Params* params); + static void UpdatePrintableSizeInPrintParameters( + WebKit::WebFrame* frame, + WebKit::WebNode* node, + PrepareFrameAndViewForPrint* prepare, + PrintMsg_Print_Params* params); bool GetPrintFrame(WebKit::WebFrame** frame); @@ -295,7 +314,7 @@ class PrintWebViewHelper : public RenderViewObserver, void OnPrintPreview(); // Create the print preview document. |pages| is empty to print all pages. - bool CreatePreviewDocument(const PrintMsg_Print_Params& params, + bool CreatePreviewDocument(PrintMsg_Print_Params* params, const std::vector<int>& pages); // Called after a page gets rendered. |page_time| is how long the diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc index 3df18be..6620693 100644 --- a/chrome/renderer/print_web_view_helper_linux.cc +++ b/chrome/renderer/print_web_view_helper_linux.cc @@ -42,13 +42,20 @@ void PrintWebViewHelper::RenderPreviewPage(int page_number) { bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params, WebFrame* frame, - WebNode* node) { + WebNode* node, + PrepareFrameAndViewForPrint* prepare) { printing::NativeMetafile metafile; if (!metafile.Init()) return false; + scoped_ptr<PrepareFrameAndViewForPrint> prep_frame_view; + if (!prepare) { + prep_frame_view.reset(new PrepareFrameAndViewForPrint(params.params, frame, + node)); + prepare = prep_frame_view.get(); + } int page_count = 0; - if (!RenderPages(params, frame, node, &page_count, &metafile)) + if (!RenderPages(params, frame, node, &page_count, prepare, &metafile)) return false; // Get the size of the resulting metafile. @@ -123,19 +130,18 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, WebKit::WebNode* node, int* page_count, + PrepareFrameAndViewForPrint* prepare, printing::Metafile* metafile) { - PrintMsg_Print_Params printParams = params.params; - - UpdatePrintableSizeInPrintParameters(frame, node, &printParams); + PrintMsg_Print_Params print_params = params.params; + UpdatePrintableSizeInPrintParameters(frame, node, prepare, &print_params); - PrepareFrameAndViewForPrint prep_frame_view(printParams, frame, node); - *page_count = prep_frame_view.GetExpectedPageCount(); + *page_count = prepare->GetExpectedPageCount(); if (!*page_count) return false; #if !defined(OS_CHROMEOS) Send(new PrintHostMsg_DidGetPrintedPagesCount(routing_id(), - printParams.document_cookie, + print_params.document_cookie, *page_count)); #endif @@ -143,8 +149,8 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params, base::TimeTicks page_begin_time = begin_time; PrintMsg_PrintPage_Params page_params; - page_params.params = printParams; - const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize(); + page_params.params = print_params; + const gfx::Size& canvas_size = prepare->GetPrintCanvasSize(); if (params.pages.empty()) { for (int i = 0; i < *page_count; ++i) { page_params.page_number = i; @@ -159,7 +165,7 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params, base::TimeDelta render_time = base::TimeTicks::Now() - begin_time; - prep_frame_view.FinishPrinting(); + prepare->FinishPrinting(); metafile->FinishDocument(); return true; } |