summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/printing/print_preview_message_handler.cc50
-rw-r--r--chrome/browser/printing/print_preview_message_handler.h5
-rw-r--r--chrome/browser/ui/webui/print_preview_handler.cc5
-rw-r--r--chrome/browser/ui/webui/print_preview_ui.cc12
-rw-r--r--chrome/browser/ui/webui/print_preview_ui.h7
-rw-r--r--chrome/common/print_messages.h23
-rw-r--r--chrome/renderer/mock_render_thread.cc30
-rw-r--r--chrome/renderer/mock_render_thread.h11
-rw-r--r--chrome/renderer/print_web_view_helper.cc475
-rw-r--r--chrome/renderer/print_web_view_helper.h152
-rw-r--r--chrome/renderer/print_web_view_helper_browsertest.cc36
-rw-r--r--chrome/renderer/print_web_view_helper_linux.cc75
-rw-r--r--chrome/renderer/print_web_view_helper_mac.mm80
-rw-r--r--chrome/renderer/print_web_view_helper_win.cc98
14 files changed, 567 insertions, 492 deletions
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc
index db57d77..99be3f5 100644
--- a/chrome/browser/printing/print_preview_message_handler.cc
+++ b/chrome/browser/printing/print_preview_message_handler.cc
@@ -63,7 +63,8 @@ void PrintPreviewMessageHandler::OnRequestPrintPreview() {
PrintPreviewTabController::PrintPreview(tab_contents());
}
-void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(int page_count) {
+void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(int document_cookie,
+ int page_count) {
if (page_count <= 0)
return;
TabContents* print_preview_tab = GetPrintPreviewTab();
@@ -72,34 +73,39 @@ void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(int page_count) {
PrintPreviewUI* print_preview_ui =
static_cast<PrintPreviewUI*>(print_preview_tab->web_ui());
- print_preview_ui->OnDidGetPreviewPageCount(page_count);
+ print_preview_ui->OnDidGetPreviewPageCount(document_cookie, page_count);
}
-void PrintPreviewMessageHandler::OnDidPreviewPage(int page_number,
- bool* cancel) {
+void PrintPreviewMessageHandler::OnDidPreviewPage(int page_number) {
+ RenderViewHost* rvh = tab_contents()->render_view_host();
TabContents* print_preview_tab = GetPrintPreviewTab();
- if (!print_preview_tab) {
- // Can't find print preview tab means we should cancel.
- *cancel = true;
+ if (!(print_preview_tab && print_preview_tab->web_ui())) {
+ // Can't find print preview tab means we should abort.
+ rvh->Send(new PrintMsg_AbortPreview(rvh->routing_id()));
return;
}
PrintPreviewUI* print_preview_ui =
static_cast<PrintPreviewUI*>(print_preview_tab->web_ui());
bool has_pending = print_preview_ui->HasPendingRequests();
- if (!has_pending && page_number >= 0)
+ if (has_pending) {
+ // Cancel. Next print preview request will cancel the current one.
+ // Just do the required maintainance work here.
+ StopWorker(print_preview_ui->document_cookie());
+ print_preview_ui->OnPrintPreviewCancelled();
+ return;
+ }
+
+ // Continue
+ if (page_number >= 0)
print_preview_ui->OnDidPreviewPage(page_number);
- *cancel = has_pending;
+ rvh->Send(new PrintMsg_ContinuePreview(rvh->routing_id()));
}
void PrintPreviewMessageHandler::OnPagesReadyForPreview(
const PrintHostMsg_DidPreviewDocument_Params& params) {
- // Always need to stop the worker and send PrintMsg_PrintingDone.
StopWorker(params.document_cookie);
- RenderViewHost* rvh = tab_contents()->render_view_host();
- rvh->Send(new PrintMsg_PrintingDone(rvh->routing_id(), true));
-
// Get the print preview tab.
TabContents* print_preview_tab = GetPrintPreviewTab();
// User might have closed it already.
@@ -114,7 +120,8 @@ void PrintPreviewMessageHandler::OnPagesReadyForPreview(
if (params.reuse_existing_data) {
// Need to match normal rendering where we are expected to send this.
- print_preview_ui->OnDidGetPreviewPageCount(params.expected_pages_count);
+ print_preview_ui->OnDidGetPreviewPageCount(params.document_cookie,
+ params.expected_pages_count);
print_preview_ui->OnPreviewDataIsAvailable(
params.expected_pages_count,
@@ -175,19 +182,6 @@ void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) {
}
}
-void PrintPreviewMessageHandler::OnPrintPreviewCancelled(int document_cookie) {
- // Always need to stop the worker.
- StopWorker(document_cookie);
-
- TabContents* print_preview_tab = GetPrintPreviewTab();
- if (!print_preview_tab)
- return;
-
- PrintPreviewUI* print_preview_ui =
- static_cast<PrintPreviewUI*>(print_preview_tab->web_ui());
- print_preview_ui->OnPrintPreviewCancelled();
-}
-
bool PrintPreviewMessageHandler::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
@@ -202,8 +196,6 @@ bool PrintPreviewMessageHandler::OnMessageReceived(
OnPagesReadyForPreview)
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed,
OnPrintPreviewFailed)
- IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled,
- OnPrintPreviewCancelled)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h
index 1421de9..9d049d0 100644
--- a/chrome/browser/printing/print_preview_message_handler.h
+++ b/chrome/browser/printing/print_preview_message_handler.h
@@ -30,13 +30,12 @@ class PrintPreviewMessageHandler : public TabContentsObserver {
// Message handlers.
void OnRequestPrintPreview();
- void OnDidGetPreviewPageCount(int page_count);
+ void OnDidGetPreviewPageCount(int document_cookie, int page_count);
// |page_number| is 0-based.
- void OnDidPreviewPage(int page_number, bool* cancel);
+ void OnDidPreviewPage(int page_number);
void OnPagesReadyForPreview(
const PrintHostMsg_DidPreviewDocument_Params& params);
void OnPrintPreviewFailed(int document_cookie);
- void OnPrintPreviewCancelled(int document_cookie);
DISALLOW_COPY_AND_ASSIGN(PrintPreviewMessageHandler);
};
diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc
index 4206b4b..e1455bd 100644
--- a/chrome/browser/ui/webui/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview_handler.cc
@@ -827,6 +827,11 @@ void PrintPreviewHandler::OnNavigation() {
TabContentsWrapper* wrapper =
TabContentsWrapper::GetCurrentWrapperForContents(initiator_tab);
wrapper->print_view_manager()->set_observer(NULL);
+
+ // Tell the initiator tab to stop rendering the print preview, if any,
+ // since the preview tab is gone.
+ RenderViewHost* rvh = initiator_tab->render_view_host();
+ rvh->Send(new PrintMsg_AbortPreview(rvh->routing_id()));
}
void PrintPreviewHandler::FileSelected(const FilePath& path,
diff --git a/chrome/browser/ui/webui/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview_ui.cc
index f6de73c..6fe75d5 100644
--- a/chrome/browser/ui/webui/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview_ui.cc
@@ -16,7 +16,8 @@
PrintPreviewUI::PrintPreviewUI(TabContents* contents)
: ChromeWebUI(contents),
initial_preview_start_time_(base::TimeTicks::Now()),
- request_count_(0U) {
+ request_count_(0U),
+ document_cookie_(0) {
// WebUI owns |handler_|.
handler_ = new PrintPreviewHandler();
AddMessageHandler(handler_->Attach(this));
@@ -54,8 +55,10 @@ void PrintPreviewUI::OnPrintPreviewRequest() {
request_count_++;
}
-void PrintPreviewUI::OnDidGetPreviewPageCount(int page_count) {
+void PrintPreviewUI::OnDidGetPreviewPageCount(int document_cookie,
+ int page_count) {
DCHECK_GT(page_count, 0);
+ document_cookie_ = document_cookie;
FundamentalValue count(page_count);
CallJavascriptFunction("onDidGetPreviewPageCount", count);
}
@@ -116,7 +119,10 @@ PrintPreviewDataService* PrintPreviewUI::print_preview_data_service() {
}
void PrintPreviewUI::DecrementRequestCount() {
- DCHECK_GT(request_count_, 0U);
if (request_count_ > 0)
request_count_--;
}
+
+int PrintPreviewUI::document_cookie() {
+ return document_cookie_;
+}
diff --git a/chrome/browser/ui/webui/print_preview_ui.h b/chrome/browser/ui/webui/print_preview_ui.h
index 28a91ad..13b4aff 100644
--- a/chrome/browser/ui/webui/print_preview_ui.h
+++ b/chrome/browser/ui/webui/print_preview_ui.h
@@ -36,7 +36,7 @@ class PrintPreviewUI : public ChromeWebUI {
void OnPrintPreviewRequest();
// Notify the Web UI that the print preview will have |page_count| pages.
- void OnDidGetPreviewPageCount(int page_count);
+ void OnDidGetPreviewPageCount(int document_cookie_, int page_count);
// Notify the Web UI that the 0-based page |page_number| has been rendered.
void OnDidPreviewPage(int page_number);
@@ -75,6 +75,8 @@ class PrintPreviewUI : public ChromeWebUI {
// Return true if there are pending requests.
bool HasPendingRequests();
+ int document_cookie();
+
private:
// Helper function
PrintPreviewDataService* print_preview_data_service();
@@ -92,6 +94,9 @@ class PrintPreviewUI : public ChromeWebUI {
// The number of print preview requests in flight.
uint32 request_count_;
+ // Document cookie from the initiator renderer.
+ int document_cookie_;
+
DISALLOW_COPY_AND_ASSIGN(PrintPreviewUI);
};
diff --git a/chrome/common/print_messages.h b/chrome/common/print_messages.h
index 11547bc..139b99b4 100644
--- a/chrome/common/print_messages.h
+++ b/chrome/common/print_messages.h
@@ -170,6 +170,11 @@ IPC_MESSAGE_ROUTED1(PrintMsg_PrintPreview,
// Tells a renderer to stop blocking script initiated printing.
IPC_MESSAGE_ROUTED0(PrintMsg_ResetScriptedPrintCount)
+// Tells a renderer to continue generating the print preview.
+IPC_MESSAGE_ROUTED0(PrintMsg_ContinuePreview)
+
+// Tells a renderer to abort the print preview and reset all state.
+IPC_MESSAGE_ROUTED0(PrintMsg_AbortPreview)
// Messages sent from the renderer to the browser.
@@ -234,19 +239,19 @@ IPC_MESSAGE_CONTROL1(PrintHostMsg_TempFileForPrintingWritten,
IPC_MESSAGE_ROUTED0(PrintHostMsg_RequestPrintPreview)
// Notify the browser the number of pages in the print preview document.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetPreviewPageCount,
+IPC_MESSAGE_ROUTED2(PrintHostMsg_DidGetPreviewPageCount,
+ int /* document cookie */,
int /* page count */)
// Notify the browser a print preview page has been rendered. Give the browser
// a chance to cancel the print preview as needed. Page number is zero-based,
// and can be -1 if it is just a check.
-IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_DidPreviewPage,
- int /* page number */,
- bool /* print preview cancelled */)
+IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPreviewPage,
+ int /* page number */)
-// Sends back to the browser the rendered "printed document" for preview that
-// was requested by a PrintMsg_PrintPreview message. The memory handle in this
-// message is already valid in the browser process.
+// Sends back to the browser the complete rendered document for print preview
+// that was requested by a PrintMsg_PrintPreview message. The memory handle in
+// this message is already valid in the browser process.
IPC_MESSAGE_ROUTED1(PrintHostMsg_PagesReadyForPreview,
PrintHostMsg_DidPreviewDocument_Params /* params */)
@@ -257,7 +262,3 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed,
// Tell the browser print preview failed.
IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewFailed,
int /* document cookie */)
-
-// Tell the browser print preview was cancelled.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewCancelled,
- int /* document cookie */)
diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc
index 2535ff3..ab0654d 100644
--- a/chrome/renderer/mock_render_thread.cc
+++ b/chrome/renderer/mock_render_thread.cc
@@ -25,7 +25,7 @@ MockRenderThread::MockRenderThread()
reply_deserializer_(NULL),
printer_(new MockPrinter),
print_dialog_user_response_(true),
- cancel_print_preview_(false) {
+ print_preview_pages_remaining_(0) {
}
MockRenderThread::~MockRenderThread() {
@@ -61,7 +61,7 @@ bool MockRenderThread::IsIncognitoProcess() const {
}
// Called by the Widget. Used to send messages to the browser.
-// We short-circuit the mechanim and handle the messages right here on this
+// We short-circuit the mechanism and handle the messages right here on this
// class.
bool MockRenderThread::Send(IPC::Message* msg) {
// We need to simulate a synchronous channel, thus we are going to receive
@@ -103,15 +103,14 @@ bool MockRenderThread::OnMessageReceived(const IPC::Message& msg) {
OnMsgOpenChannelToExtension)
IPC_MESSAGE_HANDLER(PrintHostMsg_GetDefaultPrintSettings,
OnGetDefaultPrintSettings)
- IPC_MESSAGE_HANDLER(PrintHostMsg_ScriptedPrint,
- OnScriptedPrint)
- IPC_MESSAGE_HANDLER(PrintHostMsg_UpdatePrintSettings,
- OnUpdatePrintSettings)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_UpdatePrintSettings, OnUpdatePrintSettings)
IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount,
OnDidGetPrintedPagesCount)
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
- IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage,
- OnDidPreviewPage)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
+ OnDidGetPreviewPageCount)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage)
#if defined(OS_WIN)
IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection)
#endif
@@ -212,8 +211,15 @@ void MockRenderThread::OnDidPrintPage(
printer_->PrintPage(params);
}
-void MockRenderThread::OnDidPreviewPage(int page_number, bool* cancel) {
- *cancel = cancel_print_preview_;
+void MockRenderThread::OnDidGetPreviewPageCount(int document_cookie,
+ int number_pages) {
+ print_preview_pages_remaining_ = number_pages;
+}
+
+void MockRenderThread::OnDidPreviewPage(int page_number) {
+ if (page_number < 0)
+ return;
+ print_preview_pages_remaining_--;
}
void MockRenderThread::OnUpdatePrintSettings(
@@ -242,6 +248,6 @@ void MockRenderThread::set_print_dialog_user_response(bool response) {
print_dialog_user_response_ = response;
}
-void MockRenderThread::set_cancel_print_preview(bool cancel) {
- cancel_print_preview_ = cancel;
+int MockRenderThread::print_preview_pages_remaining() {
+ return print_preview_pages_remaining_;
}
diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h
index 3b359cf..1d2036b 100644
--- a/chrome/renderer/mock_render_thread.h
+++ b/chrome/renderer/mock_render_thread.h
@@ -83,8 +83,8 @@ class MockRenderThread : public RenderThreadBase {
// False if the user decides to cancel.
void set_print_dialog_user_response(bool response);
- // Set to true to simulate canceling of a print preview.
- void set_cancel_print_preview(bool cancel);
+ // Get the number of pages to generate for print preview.
+ int print_preview_pages_remaining();
private:
// This function operates as a regular IPC listener.
@@ -124,7 +124,8 @@ class MockRenderThread : public RenderThreadBase {
void OnDidGetPrintedPagesCount(int cookie, int number_pages);
void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params);
- void OnDidPreviewPage(int page_number, bool* cancel);
+ void OnDidGetPreviewPageCount(int document_cookie, int number_pages);
+ void OnDidPreviewPage(int page_number);
// For print preview, PrintWebViewHelper will update settings.
void OnUpdatePrintSettings(int document_cookie,
@@ -152,8 +153,8 @@ class MockRenderThread : public RenderThreadBase {
// True to simulate user clicking print. False to cancel.
bool print_dialog_user_response_;
- // True to simulate cancelling a print preview.
- bool cancel_print_preview_;
+ // Number of pages to generate for print preview.
+ int print_preview_pages_remaining_;
};
#endif // CHROME_RENDERER_MOCK_RENDER_THREAD_H_
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc
index 9f870be..f55fc3b 100644
--- a/chrome/renderer/print_web_view_helper.cc
+++ b/chrome/renderer/print_web_view_helper.cc
@@ -18,7 +18,7 @@
#include "chrome/renderer/prerender/prerender_helper.h"
#include "content/renderer/render_view.h"
#include "grit/generated_resources.h"
-#include "printing/metafile.h"
+#include "printing/metafile_impl.h"
#include "printing/print_job_constants.h"
#include "printing/units.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
@@ -97,10 +97,9 @@ bool PrintMsg_Print_Params_IsEqual(
PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
const PrintMsg_Print_Params& print_params,
WebFrame* frame,
- WebNode* node,
- WebView* web_view)
+ WebNode* node)
: frame_(frame),
- web_view_(web_view),
+ web_view_(frame->view()),
expected_pages_count_(0),
use_browser_overlays_(true),
finished_(false) {
@@ -124,9 +123,9 @@ PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
if (WebFrame* web_frame = web_view_->mainFrame())
prev_scroll_offset_ = web_frame->scrollOffset();
- prev_view_size_ = web_view->size();
+ prev_view_size_ = web_view_->size();
- web_view->resize(print_layout_size);
+ web_view_->resize(print_layout_size);
WebNode node_to_print;
if (node)
@@ -154,11 +153,8 @@ PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view)
: RenderViewObserver(render_view),
RenderViewObserverTracker<PrintWebViewHelper>(render_view),
print_web_view_(NULL),
- script_initiated_preview_frame_(NULL),
- context_menu_preview_node_(NULL),
user_cancelled_scripted_print_count_(0),
- notify_browser_of_print_failure_(true),
- preview_page_count_(0) {
+ notify_browser_of_print_failure_(true) {
is_preview_ = switches::IsPrintPreviewEnabled();
}
@@ -179,8 +175,7 @@ void PrintWebViewHelper::PrintPage(WebKit::WebFrame* frame) {
IncrementScriptedPrintCount();
if (is_preview_) {
- script_initiated_preview_frame_ = frame;
- context_menu_preview_node_.reset();
+ print_preview_context_.InitWithFrame(frame);
RequestPrintPreview();
} else {
Print(frame, NULL);
@@ -191,16 +186,16 @@ bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PrintWebViewHelper, message)
IPC_MESSAGE_HANDLER(PrintMsg_PrintPages, OnPrintPages)
- IPC_MESSAGE_HANDLER(PrintMsg_InitiatePrintPreview,
- OnInitiatePrintPreview)
+ IPC_MESSAGE_HANDLER(PrintMsg_InitiatePrintPreview, OnInitiatePrintPreview)
IPC_MESSAGE_HANDLER(PrintMsg_PrintNodeUnderContextMenu,
OnPrintNodeUnderContextMenu)
IPC_MESSAGE_HANDLER(PrintMsg_PrintPreview, OnPrintPreview)
- IPC_MESSAGE_HANDLER(PrintMsg_PrintForPrintPreview,
- OnPrintForPrintPreview)
+ IPC_MESSAGE_HANDLER(PrintMsg_PrintForPrintPreview, OnPrintForPrintPreview)
IPC_MESSAGE_HANDLER(PrintMsg_PrintingDone, OnPrintingDone)
IPC_MESSAGE_HANDLER(PrintMsg_ResetScriptedPrintCount,
ResetScriptedPrintCount)
+ IPC_MESSAGE_HANDLER(PrintMsg_ContinuePreview, OnContinuePreview)
+ IPC_MESSAGE_HANDLER(PrintMsg_AbortPreview, OnAbortPreview)
IPC_MESSAGE_HANDLER(PrintMsg_PreviewPrintingRequestCancelled,
DisplayPrintJobError)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -268,21 +263,115 @@ void PrintWebViewHelper::OnPrintPages() {
void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) {
DCHECK(is_preview_);
- DCHECK(!context_menu_preview_node_.get() || !script_initiated_preview_frame_);
-
- if (script_initiated_preview_frame_) {
- // Script initiated print preview.
- PrintPreview(script_initiated_preview_frame_, NULL, settings);
- } else if (context_menu_preview_node_.get()) {
- // User initiated - print node under context menu.
- PrintPreview(context_menu_preview_node_->document().frame(),
- context_menu_preview_node_.get(), settings);
- } else {
- // User initiated - normal print preview.
- WebFrame* frame;
- if (GetPrintFrame(&frame))
- PrintPreview(frame, NULL, settings);
+ print_preview_context_.OnPrintPreview();
+
+ if (!InitPrintSettings(print_preview_context_.frame(),
+ print_preview_context_.node())) {
+ NOTREACHED();
+ return;
+ }
+
+ if (!UpdatePrintSettings(settings)) {
+ DidFinishPrinting(FAIL_PREVIEW);
+ return;
+ }
+
+ if (print_pages_params_->params.preview_request_id != 0 &&
+ old_print_pages_params_.get() &&
+ PrintMsg_Print_Params_IsEqual(*old_print_pages_params_,
+ *print_pages_params_)) {
+ PrintHostMsg_DidPreviewDocument_Params preview_params;
+ preview_params.reuse_existing_data = true;
+ preview_params.data_size = 0;
+ preview_params.document_cookie =
+ print_pages_params_->params.document_cookie;
+ preview_params.expected_pages_count =
+ print_preview_context_.total_page_count();
+ preview_params.modifiable = print_preview_context_.IsModifiable();
+ preview_params.preview_request_id =
+ print_pages_params_->params.preview_request_id;
+
+ Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
+ return;
+ }
+
+ // PDF printer device supports alpha blending.
+ print_pages_params_->params.supports_alpha_blend = true;
+ if (!CreatePreviewDocument())
+ DidFinishPrinting(FAIL_PREVIEW);
+}
+
+bool PrintWebViewHelper::CreatePreviewDocument() {
+ PrintMsg_Print_Params printParams = print_pages_params_->params;
+ UpdatePrintableSizeInPrintParameters(print_preview_context_.frame(),
+ print_preview_context_.node(),
+ &printParams);
+
+ const std::vector<int>& pages = print_pages_params_->pages;
+ if (!print_preview_context_.CreatePreviewDocument(printParams, pages))
+ return false;
+ int page_count = print_preview_context_.total_page_count();
+ int document_cookie = print_pages_params_->params.document_cookie;
+ Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), document_cookie,
+ page_count));
+ PreviewPageRendered(-1);
+ return true;
+}
+
+void PrintWebViewHelper::OnContinuePreview() {
+ // Spurious message. We already finished/cancelled/aborted the print preview.
+ if (!print_preview_context_.IsBusy())
+ return;
+
+ int page_number = print_preview_context_.GetNextPageNumber();
+ if (page_number >= 0) {
+ // Continue generating the print preview.
+ RenderPreviewPage(page_number);
+ return;
+ }
+
+ // Finished generating preview. Finalize the document.
+ if (FinalizePreviewDocument())
+ DidFinishPrinting(OK);
+ else
+ DidFinishPrinting(FAIL_PREVIEW);
+}
+
+void PrintWebViewHelper::OnAbortPreview() {
+ DidFinishPrinting(ABORT_PREVIEW);
+ return;
+}
+
+bool PrintWebViewHelper::FinalizePreviewDocument() {
+ print_preview_context_.FinalizePreviewDocument();
+
+ // Get the size of the resulting metafile.
+ printing::Metafile* metafile = print_preview_context_.metafile();
+ uint32 buf_size = metafile->GetDataSize();
+ DCHECK_GT(buf_size, 0u);
+
+ PrintHostMsg_DidPreviewDocument_Params preview_params;
+ preview_params.reuse_existing_data = false;
+ preview_params.data_size = buf_size;
+ preview_params.document_cookie = print_pages_params_->params.document_cookie;
+ preview_params.expected_pages_count =
+ print_preview_context_.total_page_count();
+ preview_params.modifiable = print_preview_context_.IsModifiable();
+ preview_params.preview_request_id =
+ print_pages_params_->params.preview_request_id;
+
+ // Ask the browser to create the shared memory for us.
+ if (!CopyMetafileDataToSharedMem(metafile,
+ &(preview_params.metafile_data_handle))) {
+ return false;
}
+#if defined(OS_WIN)
+ Send(new PrintHostMsg_DuplicateSection(routing_id(),
+ preview_params.metafile_data_handle,
+ &preview_params.metafile_data_handle));
+#endif
+ Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
+ return true;
}
void PrintWebViewHelper::OnPrintingDone(bool success) {
@@ -300,8 +389,7 @@ void PrintWebViewHelper::OnPrintNodeUnderContextMenu() {
// Make a copy of the node, in case RenderView::OnContextMenuClosed resets
// its |context_menu_node_|.
if (is_preview_) {
- context_menu_preview_node_.reset(new WebNode(context_menu_node));
- script_initiated_preview_frame_ = NULL;
+ print_preview_context_.InitWithNode(context_menu_node);
RequestPrintPreview();
} else {
WebNode duplicate_node(context_menu_node);
@@ -311,9 +399,11 @@ void PrintWebViewHelper::OnPrintNodeUnderContextMenu() {
void PrintWebViewHelper::OnInitiatePrintPreview() {
DCHECK(is_preview_);
- script_initiated_preview_frame_ = NULL;
- context_menu_preview_node_.reset();
- RequestPrintPreview();
+ WebFrame* frame;
+ if (GetPrintFrame(&frame)) {
+ print_preview_context_.InitWithFrame(frame);
+ RequestPrintPreview();
+ }
}
void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) {
@@ -332,7 +422,7 @@ void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) {
// a scope for itself (see comments on PrepareFrameAndViewForPrint).
{
PrepareFrameAndViewForPrint prep_frame_view(
- print_pages_params_->params, frame, node, 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();
@@ -357,44 +447,6 @@ void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) {
ResetScriptedPrintCount();
}
-void PrintWebViewHelper::PrintPreview(WebKit::WebFrame* frame,
- WebKit::WebNode* node,
- const DictionaryValue& settings) {
- DCHECK(is_preview_);
-
- if (!InitPrintSettings(frame, node)) {
- NOTREACHED() << "Failed to initialize print page settings";
- return;
- }
-
- if (!UpdatePrintSettings(settings)) {
- DidFinishPrinting(FAIL_PREVIEW);
- return;
- }
-
- if (print_pages_params_->params.preview_request_id != 0 &&
- old_print_pages_params_.get() &&
- PrintMsg_Print_Params_IsEqual(*old_print_pages_params_,
- *print_pages_params_)) {
- PrintHostMsg_DidPreviewDocument_Params preview_params;
- preview_params.reuse_existing_data = true;
- preview_params.data_size = 0;
- preview_params.document_cookie =
- print_pages_params_->params.document_cookie;
- preview_params.expected_pages_count = preview_page_count_;
- preview_params.modifiable = IsModifiable(frame, node);
- preview_params.preview_request_id =
- print_pages_params_->params.preview_request_id;
-
- Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
- return;
- }
-
- // Render Pages for preview.
- if (!RenderPagesForPreview(frame, node))
- DidFinishPrinting(FAIL_PREVIEW);
-}
-
void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) {
bool store_print_pages_params = true;
if (result == FAIL_PRINT) {
@@ -405,13 +457,17 @@ void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) {
Send(new PrintHostMsg_PrintingFailed(routing_id(), cookie));
}
} else if (result == FAIL_PREVIEW) {
+ DCHECK(is_preview_);
+ store_print_pages_params = false;
int cookie = print_pages_params_->params.document_cookie;
+ Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie));
+ print_preview_context_.Abort();
+ } else if (result == ABORT_PREVIEW) {
+ DCHECK(is_preview_);
store_print_pages_params = false;
- if (notify_browser_of_print_failure_) {
- Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie));
- } else {
- Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie));
- }
+ print_preview_context_.Abort();
+ } else if (result == OK && is_preview_) {
+ print_preview_context_.Finished();
}
if (print_web_view_) {
@@ -462,10 +518,7 @@ bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params,
PrintMsg_Print_Params printParams = params.params;
UpdatePrintableSizeInPrintParameters(frame, node, &printParams);
- PrepareFrameAndViewForPrint prep_frame_view(printParams,
- frame,
- node,
- frame->view());
+ PrepareFrameAndViewForPrint prep_frame_view(printParams, frame, node);
int page_count = prep_frame_view.GetExpectedPageCount();
if (!page_count)
return false;
@@ -575,16 +628,6 @@ void PrintWebViewHelper::GetPageSizeAndMarginsInPoints(
ConvertPixelsToPointDouble(margin_left_in_pixels);
}
-bool PrintWebViewHelper::IsModifiable(WebKit::WebFrame* frame,
- WebKit::WebNode* node) {
- if (node)
- return false;
- std::string mime(frame->dataSource()->response().mimeType().utf8());
- if (mime == "application/pdf")
- return false;
- return true;
-}
-
void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
WebFrame* frame,
WebNode* node,
@@ -595,7 +638,7 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
double margin_right_in_points;
double margin_bottom_in_points;
double margin_left_in_points;
- PrepareFrameAndViewForPrint prepare(*params, frame, node, frame->view());
+ PrepareFrameAndViewForPrint prepare(*params, frame, node);
PrintWebViewHelper::GetPageSizeAndMarginsInPoints(frame, 0, *params,
&content_width_in_points, &content_height_in_points,
&margin_top_in_points, &margin_right_in_points,
@@ -626,6 +669,7 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
bool PrintWebViewHelper::InitPrintSettings(WebKit::WebFrame* frame,
WebKit::WebNode* node) {
+ DCHECK(frame);
PrintMsg_PrintPages_Params settings;
// TODO(abodenha@chromium.org) It doesn't make sense to do this if our
@@ -751,42 +795,6 @@ bool PrintWebViewHelper::RenderPagesForPrint(WebKit::WebFrame* frame,
}
}
-bool PrintWebViewHelper::RenderPagesForPreview(WebKit::WebFrame* frame,
- WebKit::WebNode* node) {
- PrintMsg_PrintPages_Params print_settings = *print_pages_params_;
- // PDF printer device supports alpha blending.
- print_settings.params.supports_alpha_blend = true;
- // TODO(kmadhusu): Handle print selection.
- return CreatePreviewDocument(print_settings, frame, node);
-}
-
-base::TimeTicks PrintWebViewHelper::ReportPreviewPageRenderTime(
- base::TimeTicks start_time) {
- base::TimeTicks now = base::TimeTicks::Now();
- UMA_HISTOGRAM_TIMES("PrintPreview.RenderPDFPageTime", now - start_time);
- return now;
-}
-
-void PrintWebViewHelper::ReportTotalPreviewGenerationTime(
- int selected_pages_length, int total_pages,
- base::TimeDelta render_time, base::TimeDelta total_time) {
- if (selected_pages_length == 0)
- selected_pages_length = total_pages;
-
- if (selected_pages_length <= 0) {
- // This shouldn't happen, but this makes sure it doesn't affect the
- // statistics if it does.
- return;
- }
-
- UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderToPDFTime",
- render_time);
- UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime",
- total_time);
- UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage",
- total_time / selected_pages_length);
-}
-
#if defined(OS_POSIX)
bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
printing::Metafile* metafile,
@@ -812,6 +820,7 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent(
WebKit::WebFrame* frame) {
const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2;
const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 32;
+ bool too_frequent = false;
// Check if there is script repeatedly trying to print and ignore it if too
// frequent. The first 3 times, we use a constant wait time, but if this
@@ -829,15 +838,21 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent(
kMaxSecondsToIgnoreJavascriptInitiatedPrint);
}
if (diff.InSeconds() < min_wait_seconds) {
- WebString message(WebString::fromUTF8(
- "Ignoring too frequent calls to print()."));
- frame->addMessageToConsole(WebConsoleMessage(
- WebConsoleMessage::LevelWarning,
- message));
- return true;
+ too_frequent = true;
}
}
- return false;
+
+ if (!too_frequent && print_preview_context_.IsBusy())
+ too_frequent = true;
+
+ if (!too_frequent)
+ return false;
+
+ WebString message(WebString::fromUTF8(
+ "Ignoring too frequent calls to print()."));
+ frame->addMessageToConsole(WebConsoleMessage(WebConsoleMessage::LevelWarning,
+ message));
+ return true;
}
void PrintWebViewHelper::ResetScriptedPrintCount() {
@@ -865,10 +880,184 @@ void PrintWebViewHelper::RequestPrintPreview() {
Send(new PrintHostMsg_RequestPrintPreview(routing_id()));
}
-bool PrintWebViewHelper::PreviewPageRendered(int page_number) {
- bool cancel = false;
- Send(new PrintHostMsg_DidPreviewPage(routing_id(), page_number, &cancel));
- if (cancel)
- notify_browser_of_print_failure_ = false;
- return !cancel;
+void PrintWebViewHelper::PreviewPageRendered(int page_number) {
+ Send(new PrintHostMsg_DidPreviewPage(routing_id(), page_number));
+}
+
+PrintWebViewHelper::PrintPreviewContext::PrintPreviewContext()
+ : frame_(NULL),
+ total_page_count_(0),
+ actual_page_count_(0),
+ current_page_number_(0),
+ state_(UNINITIALIZED) {
+}
+
+PrintWebViewHelper::PrintPreviewContext::~PrintPreviewContext() {
+}
+
+void PrintWebViewHelper::PrintPreviewContext::InitWithFrame(
+ WebKit::WebFrame* web_frame) {
+ DCHECK(web_frame);
+ if (IsReadyToRender())
+ return;
+ state_ = INITIALIZED;
+ frame_ = web_frame;
+ node_.reset();
+}
+
+void PrintWebViewHelper::PrintPreviewContext::InitWithNode(
+ const WebKit::WebNode& web_node) {
+ DCHECK(!web_node.isNull());
+ if (IsReadyToRender())
+ return;
+ state_ = INITIALIZED;
+ frame_ = web_node.document().frame();
+ node_.reset(new WebNode(web_node));
+}
+
+void PrintWebViewHelper::PrintPreviewContext::OnPrintPreview() {
+ DCHECK(IsReadyToRender());
+ ClearContext();
+}
+
+bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument(
+ const PrintMsg_Print_Params& printParams,
+ const std::vector<int>& pages) {
+ DCHECK(IsReadyToRender());
+ state_ = RENDERING;
+
+ print_params_.reset(new PrintMsg_Print_Params(printParams));
+
+ 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(),
+ node()));
+ total_page_count_ = prep_frame_view_->GetExpectedPageCount();
+ if (total_page_count_ == 0)
+ return false;
+
+ current_page_number_ = 0;
+ if (pages.empty()) {
+ actual_page_count_ = total_page_count_;
+ rendered_pages_ = std::vector<bool>(total_page_count_, false);
+ } else {
+ actual_page_count_ = pages.size();
+ rendered_pages_ = std::vector<bool>(total_page_count_, true);
+ for (int i = 0; i < actual_page_count_; ++i) {
+ int page_number = pages[i];
+ if (page_number < 0 || page_number >= total_page_count_)
+ return false;
+ rendered_pages_[page_number] = false;
+ }
+ }
+
+ document_render_time_ = base::TimeDelta();
+ begin_time_ = base::TimeTicks::Now();
+
+ return true;
+}
+
+void PrintWebViewHelper::PrintPreviewContext::RenderedPreviewPage(
+ const base::TimeDelta& page_time) {
+ DCHECK_EQ(RENDERING, state_);
+ document_render_time_ += page_time;
+ UMA_HISTOGRAM_TIMES("PrintPreview.RenderPDFPageTime", page_time);
+}
+
+void PrintWebViewHelper::PrintPreviewContext::FinalizePreviewDocument() {
+ DCHECK_EQ(RENDERING, state_);
+ state_ = DONE;
+
+ base::TimeTicks begin_time = base::TimeTicks::Now();
+
+ prep_frame_view_->FinishPrinting();
+ metafile_->FinishDocument();
+
+ if (actual_page_count_ <= 0) {
+ NOTREACHED();
+ return;
+ }
+
+ UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderToPDFTime",
+ document_render_time_);
+ base::TimeDelta total_time = (base::TimeTicks::Now() - begin_time) +
+ document_render_time_;
+ UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime",
+ total_time);
+ UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage",
+ total_time / actual_page_count_);
+}
+
+void PrintWebViewHelper::PrintPreviewContext::Finished() {
+ DCHECK_EQ(DONE, state_);
+ ClearContext();
+}
+
+void PrintWebViewHelper::PrintPreviewContext::Abort() {
+ state_ = UNINITIALIZED;
+ ClearContext();
+ frame_ = NULL;
+ node_.reset();
+}
+
+int PrintWebViewHelper::PrintPreviewContext::GetNextPageNumber() {
+ DCHECK_EQ(RENDERING, state_);
+ while (current_page_number_ < total_page_count_ &&
+ rendered_pages_[current_page_number_]) {
+ ++current_page_number_;
+ }
+ if (current_page_number_ == total_page_count_)
+ return -1;
+ rendered_pages_[current_page_number_] = true;
+ return current_page_number_++;
+}
+
+bool PrintWebViewHelper::PrintPreviewContext::IsReadyToRender() const {
+ return state_ != UNINITIALIZED;
+}
+
+bool PrintWebViewHelper::PrintPreviewContext::IsBusy() const {
+ return state_ == INITIALIZED || state_ == RENDERING;
+}
+
+bool PrintWebViewHelper::PrintPreviewContext::IsModifiable() const {
+ if (node())
+ return false;
+ std::string mime(frame()->dataSource()->response().mimeType().utf8());
+ return mime != "application/pdf";
+}
+
+WebKit::WebFrame* PrintWebViewHelper::PrintPreviewContext::frame() const {
+ return frame_;
+}
+
+WebKit::WebNode* PrintWebViewHelper::PrintPreviewContext::node() const {
+ return node_.get();
+}
+
+int PrintWebViewHelper::PrintPreviewContext::total_page_count() const {
+ return total_page_count_;
+}
+
+printing::Metafile* PrintWebViewHelper::PrintPreviewContext::metafile() const {
+ return metafile_.get();
+}
+
+const PrintMsg_Print_Params&
+PrintWebViewHelper::PrintPreviewContext::print_params() const {
+ return *print_params_;
+}
+
+const gfx::Size&
+PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const {
+ return prep_frame_view_->GetPrintCanvasSize();
+}
+
+void PrintWebViewHelper::PrintPreviewContext::ClearContext() {
+ prep_frame_view_.reset();
+ metafile_.reset();
+ rendered_pages_.clear();
}
diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h
index 48b7037..81d40e3 100644
--- a/chrome/renderer/print_web_view_helper.h
+++ b/chrome/renderer/print_web_view_helper.h
@@ -6,6 +6,8 @@
#define CHROME_RENDERER_PRINT_WEB_VIEW_HELPER_H_
#pragma once
+#include <vector>
+
#include "base/memory/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/time.h"
@@ -34,8 +36,7 @@ class PrepareFrameAndViewForPrint {
// printed.
PrepareFrameAndViewForPrint(const PrintMsg_Print_Params& print_params,
WebKit::WebFrame* frame,
- WebKit::WebNode* node,
- WebKit::WebView* web_view);
+ WebKit::WebNode* node);
~PrepareFrameAndViewForPrint();
int GetExpectedPageCount() const {
@@ -108,8 +109,21 @@ class PrintWebViewHelper : public RenderViewObserver,
// Initiate print preview.
void OnInitiatePrintPreview();
- // Generate a print preview using |settings|.
+ // Start the process of generating a print preview using |settings|.
void OnPrintPreview(const base::DictionaryValue& settings);
+ // Initialize the print preview document.
+ bool CreatePreviewDocument();
+
+ // Continue generating the print preview.
+ void OnContinuePreview();
+ // Renders a print preview page. |page_number| is 0-based.
+ void RenderPreviewPage(int page_number);
+ // Finalize the print preview document.
+ bool FinalizePreviewDocument();
+
+ // Abort the preview to put |print_preview_context_| into the 'UNINITIALIZED'
+ // state.
+ void OnAbortPreview();
// Print / preview the node under the context menu.
void OnPrintNodeUnderContextMenu();
@@ -124,14 +138,11 @@ class PrintWebViewHelper : public RenderViewObserver,
void Print(WebKit::WebFrame* frame, WebKit::WebNode* node);
- void PrintPreview(WebKit::WebFrame* frame,
- WebKit::WebNode* node,
- const base::DictionaryValue& settings);
-
enum PrintingResult {
OK,
FAIL_PRINT,
FAIL_PREVIEW,
+ ABORT_PREVIEW,
};
// Notification when printing is done - signal tear-down/free resources.
@@ -187,16 +198,6 @@ class PrintWebViewHelper : public RenderViewObserver,
// Render the frame for printing.
bool RenderPagesForPrint(WebKit::WebFrame* frame, WebKit::WebNode* node);
- // Render the frame for preview.
- bool RenderPagesForPreview(WebKit::WebFrame* frame, WebKit::WebNode* node);
-
- // Renders all the pages listed in |params| for preview.
- // On success, Send PrintHostMsg_PagesReadyForPreview message with a
- // valid metafile data handle.
- bool CreatePreviewDocument(const PrintMsg_PrintPages_Params& params,
- WebKit::WebFrame* frame,
- WebKit::WebNode* node);
-
// Platform specific helper function for rendering page(s) to |metafile|.
#if defined(OS_WIN)
void RenderPage(const PrintMsg_Print_Params& params, float* scale_factor,
@@ -208,11 +209,8 @@ class PrintWebViewHelper : public RenderViewObserver,
WebKit::WebFrame* frame, printing::Metafile* metafile);
#elif defined(OS_POSIX)
bool RenderPages(const PrintMsg_PrintPages_Params& params,
- WebKit::WebFrame* frame,
- WebKit::WebNode* node,
- int* page_count,
- printing::Metafile* metafile,
- bool is_preview);
+ WebKit::WebFrame* frame, WebKit::WebNode* node,
+ int* page_count, printing::Metafile* metafile);
#endif // defined(OS_WIN)
// Helper methods -----------------------------------------------------------
@@ -233,21 +231,14 @@ class PrintWebViewHelper : public RenderViewObserver,
double* margin_bottom_in_points,
double* margin_left_in_points);
- bool IsModifiable(WebKit::WebFrame* frame, WebKit::WebNode* node);
-
void UpdatePrintableSizeInPrintParameters(WebKit::WebFrame* frame,
WebKit::WebNode* node,
PrintMsg_Print_Params* params);
bool GetPrintFrame(WebKit::WebFrame** frame);
- // This reports the current time - |start_time| as the time to render
- // a page and returns the current time.
- base::TimeTicks ReportPreviewPageRenderTime(base::TimeTicks start_time);
- void ReportTotalPreviewGenerationTime(int selected_pages_length,
- int total_pages,
- base::TimeDelta render_time,
- base::TimeDelta total_time);
+ // This reports the current time - |start_time| as the time to render a page.
+ void ReportPreviewPageRenderTime(base::TimeTicks start_time);
// Script Initiated Printing ------------------------------------------------
@@ -267,20 +258,12 @@ class PrintWebViewHelper : public RenderViewObserver,
void RequestPrintPreview();
- // Called every time print preview renders a page. Notify the browser of the
- // event and check if print preview should be cancelled. Returns false if
- // print preview has been cancelled. |page_number| is 0-based, or negative to
- // indicate its a cancel check only.
- bool PreviewPageRendered(int page_number);
+ // Notify the browser a print preview page has been rendered.
+ // |page_number| is 0-based.
+ void PreviewPageRendered(int page_number);
WebKit::WebView* print_web_view_;
- // The frame to print for script initiated print preview.
- WebKit::WebFrame* script_initiated_preview_frame_;
-
- // The node under the context menu to print preview.
- scoped_ptr<WebKit::WebNode> context_menu_preview_node_;
-
scoped_ptr<PrintMsg_PrintPages_Params> print_pages_params_;
bool is_preview_;
@@ -292,9 +275,92 @@ class PrintWebViewHelper : public RenderViewObserver,
// the failure came from the browser in the first place.
bool notify_browser_of_print_failure_;
- int preview_page_count_;
scoped_ptr<PrintMsg_PrintPages_Params> old_print_pages_params_;
+ // Keeps track of the state of print preview between messages.
+ class PrintPreviewContext {
+ public:
+ PrintPreviewContext();
+ ~PrintPreviewContext();
+
+ // Initializes the print preview context. Need to be called to set
+ // the |web_frame| / |web_node| to generate the print preview for.
+ void InitWithFrame(WebKit::WebFrame* web_frame);
+ void InitWithNode(const WebKit::WebNode& web_node);
+
+ // Does bookkeeping at the beginning of print preview.
+ void OnPrintPreview();
+
+ // Create the print preview document. |pages| is empty to print all pages.
+ bool CreatePreviewDocument(const PrintMsg_Print_Params& params,
+ const std::vector<int>& pages);
+
+ // Called after a page gets rendered. |page_time| is how long the
+ // rendering took.
+ void RenderedPreviewPage(const base::TimeDelta& page_time);
+
+ // Finalizes the print preview document.
+ void FinalizePreviewDocument();
+
+ // Cleanup after print preview finishes.
+ void Finished();
+
+ // Abort the print preview.
+ void Abort();
+
+ // Helper functions
+ int GetNextPageNumber();
+ bool IsReadyToRender() const;
+ bool IsBusy() const;
+ bool IsModifiable() const;
+
+ // Getters
+ WebKit::WebFrame* frame() const;
+ WebKit::WebNode* node() const;
+ int total_page_count() const;
+ printing::Metafile* metafile() const;
+ const PrintMsg_Print_Params& print_params() const;
+ const gfx::Size& GetPrintCanvasSize() const;
+
+ private:
+ enum State {
+ UNINITIALIZED, // Not ready to render.
+ INITIALIZED, // Ready to render.
+ RENDERING, // Rendering.
+ DONE // Finished rendering.
+ };
+
+ // Reset some of the internal rendering context.
+ void ClearContext();
+
+ // Specifies what to render for print preview.
+ WebKit::WebFrame* frame_;
+ scoped_ptr<WebKit::WebNode> node_;
+
+ scoped_ptr<PrepareFrameAndViewForPrint> prep_frame_view_;
+ scoped_ptr<printing::Metafile> metafile_;
+ scoped_ptr<PrintMsg_Print_Params> print_params_;
+
+ // Total page count in the renderer.
+ int total_page_count_;
+
+ // Number of pages to render.
+ int actual_page_count_;
+
+ // The current page to render.
+ int current_page_number_;
+
+ // Array to keep track of which pages have been printed.
+ std::vector<bool> rendered_pages_;
+
+ base::TimeDelta document_render_time_;
+ base::TimeTicks begin_time_;
+
+ State state_;
+ };
+
+ PrintPreviewContext print_preview_context_;
+
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper);
};
diff --git a/chrome/renderer/print_web_view_helper_browsertest.cc b/chrome/renderer/print_web_view_helper_browsertest.cc
index 97873d6..2bfa797 100644
--- a/chrome/renderer/print_web_view_helper_browsertest.cc
+++ b/chrome/renderer/print_web_view_helper_browsertest.cc
@@ -311,13 +311,6 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
}
protected:
- void VerifyPrintPreviewCancelled(bool did_cancel) {
- bool print_preview_cancelled =
- (render_thread_.sink().GetUniqueMessageMatching(
- PrintHostMsg_PrintPreviewCancelled::ID) != NULL);
- EXPECT_EQ(did_cancel, print_preview_cancelled);
- }
-
void VerifyPrintPreviewFailed(bool did_fail) {
bool print_preview_failed = (render_thread_.sink().GetUniqueMessageMatching(
PrintHostMsg_PrintPreviewFailed::ID) != NULL);
@@ -353,32 +346,20 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreview) {
LoadHTML(kHelloWorldHTML);
+ PrintWebViewHelper::Get(view_)->OnInitiatePrintPreview();
// Fill in some dummy values.
DictionaryValue dict;
CreatePrintSettingsDictionary(&dict);
PrintWebViewHelper::Get(view_)->OnPrintPreview(dict);
- VerifyPrintPreviewCancelled(false);
- VerifyPrintPreviewFailed(false);
- VerifyPrintPreviewGenerated(true);
- VerifyPagesPrinted(false);
-}
-
-// Tests that cancelling a print preview works correctly.
-TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewCancel) {
- LoadHTML(kPrintPreviewHTML);
-
- // Cancel the print preview.
- render_thread_.set_cancel_print_preview(true);
-
- // Fill in some dummy values.
- DictionaryValue dict;
- CreatePrintSettingsDictionary(&dict);
- PrintWebViewHelper::Get(view_)->OnPrintPreview(dict);
+ // Need to finish simulating print preview.
+ // Generate the page and finalize it.
+ PrintWebViewHelper::Get(view_)->OnContinuePreview();
+ PrintWebViewHelper::Get(view_)->OnContinuePreview();
- VerifyPrintPreviewCancelled(true);
+ EXPECT_EQ(0, render_thread_.print_preview_pages_remaining());
VerifyPrintPreviewFailed(false);
- VerifyPrintPreviewGenerated(false);
+ VerifyPrintPreviewGenerated(true);
VerifyPagesPrinted(false);
}
@@ -387,11 +368,12 @@ TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewCancel) {
TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewFail) {
LoadHTML(kHelloWorldHTML);
+ PrintWebViewHelper::Get(view_)->OnInitiatePrintPreview();
// An empty dictionary should fail.
DictionaryValue empty_dict;
PrintWebViewHelper::Get(view_)->OnPrintPreview(empty_dict);
- VerifyPrintPreviewCancelled(false);
+ EXPECT_EQ(0, render_thread_.print_preview_pages_remaining());
VerifyPrintPreviewFailed(true);
VerifyPrintPreviewGenerated(false);
VerifyPagesPrinted(false);
diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc
index 4947f14..8c6dad9 100644
--- a/chrome/renderer/print_web_view_helper_linux.cc
+++ b/chrome/renderer/print_web_view_helper_linux.cc
@@ -25,38 +25,19 @@
using WebKit::WebFrame;
using WebKit::WebNode;
-bool PrintWebViewHelper::CreatePreviewDocument(
- const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame,
- WebKit::WebNode* node) {
- if (!PreviewPageRendered(-1))
- return false;
-
- printing::PreviewMetafile metafile;
- if (!metafile.Init())
- return false;
-
- preview_page_count_ = 0;
- if (!RenderPages(params, frame, node, &preview_page_count_, &metafile, true))
- return false;
-
- // Get the size of the resulting metafile.
- uint32 buf_size = metafile.GetDataSize();
- DCHECK_GT(buf_size, 0u);
-
- PrintHostMsg_DidPreviewDocument_Params preview_params;
- preview_params.reuse_existing_data = false;
- preview_params.data_size = buf_size;
- preview_params.document_cookie = params.params.document_cookie;
- preview_params.expected_pages_count = preview_page_count_;
- preview_params.modifiable = IsModifiable(frame, node);
- preview_params.preview_request_id = params.params.preview_request_id;
+void PrintWebViewHelper::RenderPreviewPage(int page_number) {
+ PrintMsg_PrintPage_Params page_params;
+ page_params.params = print_preview_context_.print_params();
+ page_params.page_number = page_number;
- if (!CopyMetafileDataToSharedMem(&metafile,
- &(preview_params.metafile_data_handle))) {
- return false;
- }
- Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
- return true;
+ base::TimeTicks begin_time = base::TimeTicks::Now();
+ PrintPageInternal(page_params,
+ print_preview_context_.GetPrintCanvasSize(),
+ print_preview_context_.frame(),
+ print_preview_context_.metafile());
+ print_preview_context_.RenderedPreviewPage(
+ base::TimeTicks::Now() - begin_time);
+ PreviewPageRendered(page_number);
}
bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params,
@@ -67,7 +48,7 @@ bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params,
return false;
int page_count = 0;
- if (!RenderPages(params, frame, node, &page_count, &metafile, false))
+ if (!RenderPages(params, frame, node, &page_count, &metafile))
return false;
// Get the size of the resulting metafile.
@@ -142,29 +123,21 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params,
WebKit::WebFrame* frame,
WebKit::WebNode* node,
int* page_count,
- printing::Metafile* metafile,
- bool is_preview) {
+ printing::Metafile* metafile) {
PrintMsg_Print_Params printParams = params.params;
UpdatePrintableSizeInPrintParameters(frame, node, &printParams);
- PrepareFrameAndViewForPrint prep_frame_view(printParams, frame, node,
- frame->view());
- if (is_preview && !PreviewPageRendered(-1))
- return false;
-
+ PrepareFrameAndViewForPrint prep_frame_view(printParams, frame, node);
*page_count = prep_frame_view.GetExpectedPageCount();
if (!*page_count)
return false;
- if (is_preview) {
- Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), *page_count));
- } else {
+
#if !defined(OS_CHROMEOS)
Send(new PrintHostMsg_DidGetPrintedPagesCount(routing_id(),
printParams.document_cookie,
*page_count));
#endif
- }
base::TimeTicks begin_time = base::TimeTicks::Now();
base::TimeTicks page_begin_time = begin_time;
@@ -176,21 +149,11 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params,
for (int i = 0; i < *page_count; ++i) {
page_params.page_number = i;
PrintPageInternal(page_params, canvas_size, frame, metafile);
- if (is_preview) {
- page_begin_time = ReportPreviewPageRenderTime(page_begin_time);
- if (!PreviewPageRendered(i))
- return false;
- }
}
} else {
for (size_t i = 0; i < params.pages.size(); ++i) {
page_params.page_number = params.pages[i];
PrintPageInternal(page_params, canvas_size, frame, metafile);
- if (is_preview) {
- page_begin_time = ReportPreviewPageRenderTime(page_begin_time);
- if (!PreviewPageRendered(params.pages[i]))
- return false;
- }
}
}
@@ -198,12 +161,6 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params,
prep_frame_view.FinishPrinting();
metafile->FinishDocument();
-
- if (is_preview) {
- ReportTotalPreviewGenerationTime(params.pages.size(), *page_count,
- render_time,
- base::TimeTicks::Now() - begin_time);
- }
return true;
}
diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm
index 5878c20..3836161f 100644
--- a/chrome/renderer/print_web_view_helper_mac.mm
+++ b/chrome/renderer/print_web_view_helper_mac.mm
@@ -59,83 +59,19 @@ void PrintWebViewHelper::PrintPageInternal(
Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params));
}
-bool PrintWebViewHelper::CreatePreviewDocument(
- const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame,
- WebKit::WebNode* node) {
- if (!PreviewPageRendered(-1))
- return false;
-
- PrintMsg_Print_Params printParams = params.params;
- UpdatePrintableSizeInPrintParameters(frame, node, &printParams);
-
- PrepareFrameAndViewForPrint prep_frame_view(printParams,
- frame, node, frame->view());
- if (!PreviewPageRendered(-1))
- return false;
-
- preview_page_count_ = prep_frame_view.GetExpectedPageCount();
- if (!preview_page_count_)
- return false;
- Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(),
- preview_page_count_));
-
- printing::PreviewMetafile metafile;
- if (!metafile.Init())
- return false;
-
- float scale_factor = frame->getPrintPageShrink(0);
+void PrintWebViewHelper::RenderPreviewPage(int page_number) {
+ float scale_factor = print_preview_context_.frame()->getPrintPageShrink(0);
+ PrintMsg_Print_Params printParams = print_preview_context_.print_params();
gfx::Rect content_area(printParams.margin_left, printParams.margin_top,
printParams.printable_size.width(),
printParams.printable_size.height());
base::TimeTicks begin_time = base::TimeTicks::Now();
- base::TimeTicks page_begin_time = begin_time;
-
- if (params.pages.empty()) {
- for (int i = 0; i < preview_page_count_; ++i) {
- RenderPage(printParams.page_size, content_area, scale_factor, i, frame,
- &metafile);
- page_begin_time = ReportPreviewPageRenderTime(page_begin_time);
- if (!PreviewPageRendered(i))
- return false;
- }
- } else {
- for (size_t i = 0; i < params.pages.size(); ++i) {
- if (params.pages[i] >= preview_page_count_)
- break;
- RenderPage(printParams.page_size, content_area, scale_factor,
- params.pages[i], frame, &metafile);
- page_begin_time = ReportPreviewPageRenderTime(page_begin_time);
- if (!PreviewPageRendered(params.pages[i]))
- return false;
- }
- }
-
- base::TimeDelta render_time = base::TimeTicks::Now() - begin_time;
-
- prep_frame_view.FinishPrinting();
- metafile.FinishDocument();
-
- ReportTotalPreviewGenerationTime(params.pages.size(),
- preview_page_count_,
- render_time,
- base::TimeTicks::Now() - begin_time);
-
- PrintHostMsg_DidPreviewDocument_Params preview_params;
- preview_params.reuse_existing_data = false;
- preview_params.data_size = metafile.GetDataSize();
- preview_params.document_cookie = params.params.document_cookie;
- preview_params.expected_pages_count = preview_page_count_;
- preview_params.modifiable = IsModifiable(frame, node);
- preview_params.preview_request_id = params.params.preview_request_id;
-
- // Ask the browser to create the shared memory for us.
- if (!CopyMetafileDataToSharedMem(&metafile,
- &(preview_params.metafile_data_handle))) {
- return false;
- }
- Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
- return true;
+ RenderPage(printParams.page_size, content_area, scale_factor, page_number,
+ print_preview_context_.frame(), print_preview_context_.metafile());
+ print_preview_context_.RenderedPreviewPage(
+ base::TimeTicks::Now() - begin_time);
+ PreviewPageRendered(page_number);
}
void PrintWebViewHelper::RenderPage(
diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc
index 36139be..4627e0d 100644
--- a/chrome/renderer/print_web_view_helper_win.cc
+++ b/chrome/renderer/print_web_view_helper_win.cc
@@ -123,93 +123,23 @@ void PrintWebViewHelper::PrintPageInternal(
Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params));
}
-bool PrintWebViewHelper::CreatePreviewDocument(
- const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame,
- WebKit::WebNode* node) {
- if (!PreviewPageRendered(-1))
- return false;
-
- PrintMsg_Print_Params print_params = params.params;
- UpdatePrintableSizeInPrintParameters(frame, node, &print_params);
- PrepareFrameAndViewForPrint prep_frame_view(print_params, frame, node,
- frame->view());
- if (!PreviewPageRendered(-1))
- return false;
-
- preview_page_count_ = prep_frame_view.GetExpectedPageCount();
- if (!preview_page_count_)
- return false;
- Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(),
- preview_page_count_));
-
- scoped_ptr<Metafile> metafile(new printing::PreviewMetafile);
- metafile->Init();
-
+void PrintWebViewHelper::RenderPreviewPage(int page_number) {
+ PrintMsg_Print_Params print_params = print_preview_context_.print_params();
// Calculate the dpi adjustment.
- float shrink = static_cast<float>(print_params.desired_dpi /
- print_params.dpi);
+ float scale_factor = static_cast<float>(print_params.desired_dpi /
+ print_params.dpi);
+ // Needed for RenderPage() below.
+ // Not taking ownership with intent to reset().
+ scoped_ptr<Metafile> metafile(print_preview_context_.metafile());
base::TimeTicks begin_time = base::TimeTicks::Now();
- base::TimeTicks page_begin_time = begin_time;
-
- if (params.pages.empty()) {
- for (int i = 0; i < preview_page_count_; ++i) {
- float scale_factor = shrink;
- RenderPage(print_params, &scale_factor, i, true, frame, &metafile);
- page_begin_time = ReportPreviewPageRenderTime(page_begin_time);
- if (!PreviewPageRendered(i))
- return false;
- }
- } else {
- for (size_t i = 0; i < params.pages.size(); ++i) {
- if (params.pages[i] >= preview_page_count_)
- break;
- float scale_factor = shrink;
- RenderPage(print_params, &scale_factor, params.pages[i], true, frame,
- &metafile);
- page_begin_time = ReportPreviewPageRenderTime(page_begin_time);
- if (!PreviewPageRendered(params.pages[i]))
- return false;
- }
- }
-
- base::TimeDelta render_time = base::TimeTicks::Now() - begin_time;
-
- // Ensure that printing has finished before we start cleaning up and
- // allocating buffers; this causes prep_frame_view to flush anything pending
- // into the metafile. Then we can get the final size and copy it into a
- // shared segment.
- prep_frame_view.FinishPrinting();
-
- if (!metafile->FinishDocument())
- NOTREACHED();
-
- ReportTotalPreviewGenerationTime(params.pages.size(),
- preview_page_count_,
- render_time,
- base::TimeTicks::Now() - begin_time);
-
- // Get the size of the compiled metafile.
- uint32 buf_size = metafile->GetDataSize();
- DCHECK_GT(buf_size, 128u);
-
- PrintHostMsg_DidPreviewDocument_Params preview_params;
- preview_params.reuse_existing_data = false;
- preview_params.data_size = buf_size;
- preview_params.document_cookie = params.params.document_cookie;
- preview_params.expected_pages_count = preview_page_count_;
- preview_params.modifiable = IsModifiable(frame, node);
- preview_params.preview_request_id = params.params.preview_request_id;
-
- if (!CopyMetafileDataToSharedMem(metafile.get(),
- &(preview_params.metafile_data_handle))) {
- return false;
- }
- Send(new PrintHostMsg_DuplicateSection(routing_id(),
- preview_params.metafile_data_handle,
- &preview_params.metafile_data_handle));
- Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
- return true;
+ RenderPage(print_params, &scale_factor, page_number, true,
+ print_preview_context_.frame(), &metafile);
+ // Release since |print_preview_context_| is the real owner.
+ metafile.release();
+ print_preview_context_.RenderedPreviewPage(
+ base::TimeTicks::Now() - begin_time);
+ PreviewPageRendered(page_number);
}
void PrintWebViewHelper::RenderPage(