Commit ddf90dc6 authored by kmadhusu@chromium.org's avatar kmadhusu@chromium.org

Reland 96406 - Print preview page selection should not require a rerendering of draft pages.

On page selection, regenerate the complete document with the selection, but preserve the existing draft pages and simply display a subset of them.

1. Added a new param |clear all preview data| to |PrintHostMsg_DidGetPreviewPageCount|.
2. Removed |requested_preview_page_index| from |PrintMsg_ContinuePreview|

Review URL: http://codereview.chromium.org/7544018

Original Commit: http://src.chromium.org/viewvc/chrome?view=rev&revision=96406

Revert Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=96414

BUG=84383
TEST=print preview works after code changes.

Review URL: http://codereview.chromium.org/7628019

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96567 0039d316-1c4b-4281-b951-d872f2087c98
parent f12b5127
......@@ -82,9 +82,11 @@ void PrintPreviewMessageHandler::OnRequestPrintPreview() {
PrintPreviewTabController::PrintPreview(tab_contents());
}
void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(int document_cookie,
void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(
int document_cookie,
int page_count,
bool is_modifiable) {
bool is_modifiable,
bool clear_preview_data) {
if (page_count <= 0)
return;
......@@ -94,6 +96,10 @@ void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(int document_cookie,
PrintPreviewUI* print_preview_ui =
static_cast<PrintPreviewUI*>(print_preview_tab->web_ui());
if (!is_modifiable || clear_preview_data)
print_preview_ui->ClearAllPreviewData();
print_preview_ui->OnDidGetPreviewPageCount(
document_cookie, page_count, is_modifiable);
}
......@@ -119,12 +125,7 @@ void PrintPreviewMessageHandler::OnDidPreviewPage(
return;
}
int requested_preview_page_index = INVALID_PAGE_INDEX;
int page_number = params.page_number;
if (page_number == FIRST_PAGE_INDEX)
print_preview_ui->ClearAllPreviewData();
if (page_number >= FIRST_PAGE_INDEX && params.data_size) {
RefCountedBytes* data_bytes =
GetDataFromHandle(params.metafile_data_handle, params.data_size);
......@@ -132,15 +133,12 @@ void PrintPreviewMessageHandler::OnDidPreviewPage(
print_preview_ui->SetPrintPreviewDataForIndex(page_number, data_bytes);
print_preview_ui->OnDidPreviewPage(page_number);
// TODO(kmadhusu): Query |PrintPreviewUI| and update
// |requested_preview_page_index| accordingly.
}
rvh->Send(new PrintMsg_ContinuePreview(rvh->routing_id(),
requested_preview_page_index));
rvh->Send(new PrintMsg_ContinuePreview(rvh->routing_id()));
}
void PrintPreviewMessageHandler::OnPagesReadyForPreview(
void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
const PrintHostMsg_DidPreviewDocument_Params& params) {
StopWorker(params.document_cookie);
......@@ -218,8 +216,8 @@ bool PrintPreviewMessageHandler::OnMessageReceived(
OnDidGetPreviewPageCount)
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage,
OnDidPreviewPage)
IPC_MESSAGE_HANDLER(PrintHostMsg_PagesReadyForPreview,
OnPagesReadyForPreview)
IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
OnMetafileReadyForPrinting)
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed,
OnPrintPreviewFailed)
IPC_MESSAGE_UNHANDLED(handled = false)
......
......@@ -33,10 +33,11 @@ class PrintPreviewMessageHandler : public TabContentsObserver {
void OnRequestPrintPreview();
void OnDidGetPreviewPageCount(int document_cookie,
int page_count,
bool is_modifiable);
bool is_modifiable,
bool clear_preview_data);
// |page_number| is 0-based.
void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params);
void OnPagesReadyForPreview(
void OnMetafileReadyForPrinting(
const PrintHostMsg_DidPreviewDocument_Params& params);
void OnPrintPreviewFailed(int document_cookie);
......
......@@ -177,9 +177,8 @@ cr.define('print_preview', function() {
/**
* Updates |this.previouslySelectedPages_| with the currently selected
* pages.
* @private
*/
updatePageSelection_: function() {
updatePageSelection: function() {
this.previouslySelectedPages_ = this.selectedPagesSet;
},
......@@ -193,6 +192,14 @@ cr.define('print_preview', function() {
this.selectedPagesSet);
},
/**
* Checks if the page selection has changed and is valid.
* @return {boolean} true if the page selection is changed and is valid.
*/
hasPageSelectionChangedAndIsValid: function() {
return this.isPageSelectionValid() && this.hasPageSelectionChanged_();
},
/**
* Validates the contents of |this.selectedPagesTextfield|.
*
......@@ -212,8 +219,8 @@ cr.define('print_preview', function() {
* @return {boolean} true if a new preview was requested.
*/
requestPrintPreviewIfNeeded: function() {
if (this.isPageSelectionValid() && this.hasPageSelectionChanged_()) {
this.updatePageSelection_();
if (this.hasPageSelectionChangedAndIsValid()) {
this.updatePageSelection();
requestPrintPreview();
return true;
}
......@@ -274,7 +281,6 @@ cr.define('print_preview', function() {
cr.dispatchSimpleEvent(document, 'updatePrintButton');
return;
}
this.previouslySelectedPages_ = this.selectedPagesSet;
requestPrintPreview();
},
......
......@@ -23,6 +23,7 @@ const MANAGE_LOCAL_PRINTERS = 'manageLocalPrinters';
const MORE_PRINTERS = 'morePrinters';
const SIGN_IN = 'signIn';
const PRINT_TO_PDF = 'Print to PDF';
const COMPLETE_PREVIEW_DATA_INDEX = -1;
// State of the print preview settings.
var printSettings = new PrintSettings();
......@@ -62,6 +63,11 @@ var showingSystemDialog = false;
var firstCloudPrintOptionPos = 0;
var lastCloudPrintOptionPos = firstCloudPrintOptionPos;
// Store the current previewUid.
var currentPreviewUid = '';
// True if we need to generate draft preview data.
var generateDraftData = true;
// TODO(abodenha@chromium.org) A lot of cloud print specific logic has
// made its way into this file. Refactor to create a cleaner boundary
......@@ -311,7 +317,8 @@ function getSettings() {
'landscape': layoutSettings.isLandscape(),
'color': colorSettings.isColor(),
'printToPDF': printToPDF,
'requestID': 0};
'requestID': 0,
'generateDraftData': generateDraftData};
var printerList = $('printer-list');
var selectedPrinter = printerList.selectedIndex;
......@@ -420,6 +427,22 @@ function sendPrintDocumentRequest() {
cloudprint.getPrintTicketJSON(printer)]);
}
/**
* Loads the selected preview pages.
*/
function loadSelectedPages() {
hasPendingPreviewRequest = false;
pageSettings.updatePageSelection();
var pageSet = pageSettings.previouslySelectedPages;
var pageCount = pageSet.length;
if (pageCount == 0 || currentPreviewUid == '')
return;
for (var i = 0; i < pageCount; i++)
onDidPreviewPage(pageSet[i] - 1, currentPreviewUid);
addEventListeners();
}
/**
* Asks the browser to generate a preview PDF based on current print settings.
*/
......@@ -427,9 +450,20 @@ function requestPrintPreview() {
hasPendingPreviewRequest = true;
removeEventListeners();
printSettings.save();
generateDraftData = true;
if (!isTabHidden)
showLoadingAnimation();
if (previewModifiable && hasOnlyPageSettingsChanged()) {
loadSelectedPages();
generateDraftData = false;
} else {
pageSettings.updatePageSelection();
}
if (!previewModifiable && pageSettings.totalPageCount > 0)
generateDraftData = false;
var settings = getSettings();
settings.requestID = generatePreviewRequestID();
chrome.send('getPreview', [JSON.stringify(settings)]);
......@@ -829,12 +863,16 @@ function onDidPreviewPage(pageNumber, previewUid) {
if (!previewModifiable)
return;
var pageIndex = pageSettings.previouslySelectedPages.indexOf(pageNumber + 1);
if (checkIfSettingsChangedAndRegeneratePreview())
return;
var pageIndex = pageSettings.previouslySelectedPages.indexOf(pageNumber + 1);
if (pageIndex == -1)
return;
currentPreviewUid = previewUid;
if (pageIndex == 0)
createPDFPlugin(previewUid);
createPDFPlugin(pageNumber);
$('pdf-viewer').loadPreviewPage(
getPageSrcURL(previewUid, pageNumber), pageIndex);
......@@ -864,7 +902,8 @@ function updatePrintPreview(jobTitle,
if (!previewModifiable) {
// If the preview is not modifiable the plugin has not been created yet.
createPDFPlugin(previewUid);
currentPreviewUid = previewUid;
createPDFPlugin(COMPLETE_PREVIEW_DATA_INDEX);
}
cr.dispatchSimpleEvent(document, 'updateSummary');
......@@ -897,29 +936,42 @@ function checkIfSettingsChangedAndRegeneratePreview() {
return false;
}
/**
* Check if only page selection has been changed since the last preview request
* and is valid.
* @return {boolean} true if the new page selection is valid.
*/
function hasOnlyPageSettingsChanged() {
var tempPrintSettings = new PrintSettings();
tempPrintSettings.save();
return !!(printSettings.deviceName == tempPrintSettings.deviceName &&
printSettings.isLandscape == tempPrintSettings.isLandscape &&
pageSettings.hasPageSelectionChangedAndIsValid());
}
/**
* Create the PDF plugin or reload the existing one.
* @param {string} previewUid Preview unique identifier.
* @param {number} srcDataIndex Preview data source index.
*/
function createPDFPlugin(previewUid) {
function createPDFPlugin(srcDataIndex) {
var pdfViewer = $('pdf-viewer');
var srcURL = getPageSrcURL(currentPreviewUid, srcDataIndex);
if (pdfViewer) {
// Need to call this before the reload(), where the plugin resets its
// internal page count.
pdfViewer.goToPage('0');
pdfViewer.resetPrintPreviewUrl(srcURL);
pdfViewer.reload();
pdfViewer.grayscale(!colorSettings.isColor());
return;
}
// Get the complete preview document.
var dataIndex = previewModifiable ? '0' : '-1';
pdfViewer = document.createElement('embed');
pdfViewer.setAttribute('id', 'pdf-viewer');
pdfViewer.setAttribute('type',
'application/x-google-chrome-print-preview-pdf');
pdfViewer.setAttribute('src', getPageSrcURL(previewUid, dataIndex));
pdfViewer.setAttribute('src', srcURL);
pdfViewer.setAttribute('aria-live', 'polite');
pdfViewer.setAttribute('aria-atomic', 'true');
$('mainview').appendChild(pdfViewer);
......@@ -937,7 +989,8 @@ function checkCompatiblePluginExists() {
dummyPlugin.goToPage &&
dummyPlugin.removePrintButton &&
dummyPlugin.loadPreviewPage &&
dummyPlugin.printPreviewPageCount);
dummyPlugin.printPreviewPageCount &&
dummyPlugin.resetPrintPreviewUrl);
}
window.addEventListener('DOMContentLoaded', onLoad);
......
......@@ -187,11 +187,7 @@ IPC_MESSAGE_ROUTED0(PrintMsg_PrintForSystemDialog)
IPC_MESSAGE_ROUTED0(PrintMsg_ResetScriptedPrintCount)
// Tells a renderer to continue generating the print preview.
// Use |requested_preview_page_index| to request a specific preview page data.
// |requested_preview_page_index| is 1-based or |printing::INVALID_PAGE_INDEX|
// to render the next page.
IPC_MESSAGE_ROUTED1(PrintMsg_ContinuePreview,
int /* requested_preview_page_index */)
IPC_MESSAGE_ROUTED0(PrintMsg_ContinuePreview)
// Tells a renderer to abort the print preview and reset all state.
IPC_MESSAGE_ROUTED0(PrintMsg_AbortPreview)
......@@ -259,10 +255,11 @@ IPC_MESSAGE_CONTROL1(PrintHostMsg_TempFileForPrintingWritten,
IPC_MESSAGE_ROUTED0(PrintHostMsg_RequestPrintPreview)
// Notify the browser the number of pages in the print preview document.
IPC_MESSAGE_ROUTED3(PrintHostMsg_DidGetPreviewPageCount,
IPC_MESSAGE_ROUTED4(PrintHostMsg_DidGetPreviewPageCount,
int /* document cookie */,
int /* page count */,
bool /* is modifiable */)
bool /* is modifiable */,
bool /* clear all preview data */)
// Notify the browser a print preview page has been rendered.
IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPreviewPage,
......@@ -271,7 +268,7 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPreviewPage,
// 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,
IPC_MESSAGE_ROUTED1(PrintHostMsg_MetafileReadyForPrinting,
PrintHostMsg_DidPreviewDocument_Params /* params */)
// Tell the browser printing failed.
......
......@@ -94,10 +94,12 @@ void MockPrinter::ScriptedPrint(int cookie,
}
void MockPrinter::UpdateSettings(int cookie,
PrintMsg_PrintPages_Params* params) {
PrintMsg_PrintPages_Params* params,
const std::vector<int>& pages) {
EXPECT_EQ(document_cookie_, cookie);
memset(params, 0, sizeof(PrintMsg_PrintPages_Params));
params->pages = pages;
SetPrintParams(&(params->params));
printer_status_ = PRINTER_PRINTING;
}
......
......@@ -75,7 +75,8 @@ class MockPrinter {
int expected_pages_count,
bool has_selection,
PrintMsg_PrintPages_Params* settings);
void UpdateSettings(int cookie, PrintMsg_PrintPages_Params* params);
void UpdateSettings(int cookie, PrintMsg_PrintPages_Params* params,
const std::vector<int>& page_range_array);
void SetPrintedPagesCount(int cookie, int number_pages);
void PrintPage(const PrintHostMsg_DidPrintPage_Params& params);
......
......@@ -16,6 +16,7 @@
#include "ipc/ipc_message_utils.h"
#include "ipc/ipc_sync_message.h"
#include "printing/print_job_constants.h"
#include "printing/page_range.h"
#include "testing/gtest/include/gtest/gtest.h"
MockRenderThread::MockRenderThread()
......@@ -213,7 +214,8 @@ void MockRenderThread::OnDidPrintPage(
void MockRenderThread::OnDidGetPreviewPageCount(int document_cookie,
int number_pages,
bool is_modifiable) {
bool is_modifiable,
bool clear_preview_data) {
print_preview_pages_remaining_ = number_pages;
}
......@@ -242,8 +244,29 @@ void MockRenderThread::OnUpdatePrintSettings(
}
// Just return the default settings.
if (printer_.get())
printer_->UpdateSettings(document_cookie, params);
if (printer_.get()) {
ListValue* page_range_array = new ListValue();
printing::PageRanges new_ranges;
if (job_settings.GetList(printing::kSettingPageRange, &page_range_array)) {
for (size_t index = 0; index < page_range_array->GetSize(); ++index) {
DictionaryValue* dict;
if (!page_range_array->GetDictionary(index, &dict))
continue;
printing::PageRange range;
if (!dict->GetInteger(printing::kSettingPageRangeFrom, &range.from) ||
!dict->GetInteger(printing::kSettingPageRangeTo, &range.to)) {
continue;
}
// Page numbers are 1-based in the dictionary.
// Page numbers are 0-based for the printing context.
range.from--;
range.to--;
new_ranges.push_back(range);
}
}
std::vector<int> pages(printing::PageRange::GetPages(new_ranges));
printer_->UpdateSettings(document_cookie, params, pages);
}
}
void MockRenderThread::set_print_dialog_user_response(bool response) {
......
......@@ -126,7 +126,7 @@ class MockRenderThread : public RenderThreadBase {
void OnDidGetPrintedPagesCount(int cookie, int number_pages);
void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params);
void OnDidGetPreviewPageCount(int document_cookie, int number_pages,
bool is_modifiable);
bool is_modifiable, bool clear_preview_data);
void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params);
// For print preview, PrintWebViewHelper will update settings.
......
This diff is collapsed.
......@@ -6,7 +6,6 @@
#define CHROME_RENDERER_PRINT_WEB_VIEW_HELPER_H_
#pragma once
#include <utility>
#include <vector>
#include "base/memory/scoped_ptr.h"
......@@ -110,6 +109,8 @@ class PrintWebViewHelper : public RenderViewObserver,
OnPrintForPrintPreview);
FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperPreviewTest,
OnPrintForPrintPreviewFail);
FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperPreviewTest,
OnPrintPreviewForSelectedPages);
#if defined(OS_WIN) || defined(OS_MACOSX)
FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintLayoutTest);
......@@ -136,14 +137,12 @@ class PrintWebViewHelper : public RenderViewObserver,
// Initialize the print preview document.
bool CreatePreviewDocument();
// Continue generating the print preview. |requested_preview_page_index|
// specifies the browser requested preview page index. It is 1-based or
// |printing::INVALID_PAGE_INDEX| to continue with next page.
void OnContinuePreview(int requested_preview_page_index);
// 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();
// Finalize the print ready preview document.
bool FinalizePrintReadyDocument();
// Abort the preview to put |print_preview_context_| into the 'UNINITIALIZED'
// state.
......@@ -298,6 +297,7 @@ class PrintWebViewHelper : public RenderViewObserver,
scoped_ptr<PrintMsg_PrintPages_Params> print_pages_params_;
bool is_preview_;
bool is_print_ready_metafile_sent_;
// Used for scripted initiated printing blocking.
base::Time last_cancelled_script_print_;
......@@ -331,8 +331,11 @@ class PrintWebViewHelper : public RenderViewObserver,
// rendering took.
void RenderedPreviewPage(const base::TimeDelta& page_time);
// Finalizes the print preview document.
void FinalizePreviewDocument();
// Updates the print preview context when the required pages are rendered.
void AllPagesRendered();
// Finalizes the print ready preview document.
void FinalizePrintReadyDocument();
// Cleanup after print preview finishes.
void Finished();
......@@ -348,11 +351,17 @@ class PrintWebViewHelper : public RenderViewObserver,
bool IsReadyToRender() const;
bool IsBusy() const;
bool IsModifiable() const;
bool IsLastPageOfPrintReadyMetafile() const;
bool IsFinalPageRendered() const;
// Setters
void set_generate_draft_pages(bool generate_draft_pages);
// Getters
WebKit::WebFrame* frame() const;
WebKit::WebNode* node() const;
int total_page_count() const;
bool generate_draft_pages();
printing::PreviewMetafile* metafile() const;
const PrintMsg_Print_Params& print_params() const;
const gfx::Size& GetPrintCanvasSize() const;
......@@ -379,16 +388,17 @@ class PrintWebViewHelper : public RenderViewObserver,
// Total page count in the renderer.
int total_page_count_;
// Number of pages to render.
int actual_page_count_;
// List of page indices that need to be rendered.
std::vector<int> render_page_list_;
// Specifies the current list index.
int render_page_list_index_;
// The current page to render.
int current_page_number_;
// True, when draft pages needs to be generated.
bool generate_draft_pages_;
// |rendered_pages_| tracks which pages need to be printed as well as
// the page slot it should be printed in. See GetPageSlotForPage.
typedef std::pair<bool, int> PreviewPageInfo;
std::vector<PreviewPageInfo> rendered_pages_;
// Specifies the total number of pages in the print ready metafile.
int print_ready_metafile_page_count_;
base::TimeDelta document_render_time_;
base::TimeTicks begin_time_;
......
......@@ -42,6 +42,7 @@ void CreatePrintSettingsDictionary(DictionaryValue* dict) {
dict->SetInteger(printing::kSettingCopies, 1);
dict->SetString(printing::kSettingDeviceName, "dummy");
dict->SetInteger(printing::kPreviewRequestID, 12345);
dict->SetBoolean(printing::kSettingGenerateDraftData, true);
}
} // namespace
......@@ -320,12 +321,12 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
void VerifyPrintPreviewGenerated(bool generated_preview) {
const IPC::Message* preview_msg =
render_thread_.sink().GetUniqueMessageMatching(
PrintHostMsg_PagesReadyForPreview::ID);
PrintHostMsg_MetafileReadyForPrinting::ID);
bool did_get_preview_msg = (NULL != preview_msg);
ASSERT_EQ(generated_preview, did_get_preview_msg);
if (did_get_preview_msg) {
PrintHostMsg_PagesReadyForPreview::Param preview_param;
PrintHostMsg_PagesReadyForPreview::Read(preview_msg, &preview_param);
PrintHostMsg_MetafileReadyForPrinting::Param preview_param;
PrintHostMsg_MetafileReadyForPrinting::Read(preview_msg, &preview_param);
EXPECT_NE(0, preview_param.a.document_cookie);
EXPECT_NE(0, preview_param.a.expected_pages_count);
EXPECT_NE(0U, preview_param.a.data_size);
......@@ -338,6 +339,28 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
EXPECT_EQ(did_fail, print_failed);
}
// |page_number| is 0-based.
void VerifyDidPreviewPage(bool generate_draft_pages, int page_number) {
bool msg_found = false;
size_t msg_count = render_thread_.sink().message_count();
for (size_t i = 0; i < msg_count; ++i) {
const IPC::Message* msg = render_thread_.sink().GetMessageAt(i);
if (msg->type() == PrintHostMsg_DidPreviewPage::ID) {
PrintHostMsg_DidPreviewPage::Param page_param;
PrintHostMsg_DidPreviewPage::Read(msg, &page_param);
if (page_param.a.page_number == page_number) {
msg_found = true;
if (generate_draft_pages)
EXPECT_NE(0U, page_param.a.data_size);
else
EXPECT_EQ(0U, page_param.a.data_size);
break;
}
}
}
ASSERT_EQ(true, msg_found);
}
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperPreviewTest);
};
......@@ -354,10 +377,50 @@ TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreview) {
// Need to finish simulating print preview.
// Generate the page and finalize it.
PrintWebViewHelper::Get(view_)->OnContinuePreview(
printing::INVALID_PAGE_INDEX);
PrintWebViewHelper::Get(view_)->OnContinuePreview(
printing::INVALID_PAGE_INDEX);
PrintWebViewHelper::Get(view_)->OnContinuePreview();
// Verify that we did create the draft metafile for the first page.
VerifyDidPreviewPage(true, 0);
PrintWebViewHelper::Get(view_)->OnContinuePreview();
EXPECT_EQ(0, render_thread_.print_preview_pages_remaining());
VerifyPrintPreviewFailed(false);
VerifyPrintPreviewGenerated(true);
VerifyPagesPrinted(false);
}
// Test to verify that complete metafile is generated for a subset of pages
// without creating draft pages.
TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewForSelectedPages) {
LoadHTML(kHelloWorldHTML);
PrintWebViewHelper::Get(view_)->OnInitiatePrintPreview();
// Fill in some dummy values.
DictionaryValue dict;
CreatePrintSettingsDictionary(&dict);
// Set a page range and update the dictionary to generate only the complete
// metafile with the selected pages. Page numbers used in the dictionary
// are 1-based.
DictionaryValue* page_range = new DictionaryValue();
page_range->SetInteger(printing::kSettingPageRangeFrom, 1);
page_range->SetInteger(printing::kSettingPageRangeTo, 1);
ListValue* page_range_array = new ListValue();
page_range_array->Append(page_range);
dict.Set(printing::kSettingPageRange, page_range_array);
dict.SetBoolean(printing::kSettingGenerateDraftData, false);
PrintWebViewHelper::Get(view_)->OnPrintPreview(dict);
// Need to finish simulating print preview.
// Generate the page and finalize it.
PrintWebViewHelper::Get(view_)->OnContinuePreview();
// Verify that we did not create the draft metafile for the first page.
VerifyDidPreviewPage(false, 0);
PrintWebViewHelper::Get(view_)->OnContinuePreview();
EXPECT_EQ(0, render_thread_.print_preview_pages_remaining());
VerifyPrintPreviewFailed(false);
......
......@@ -29,21 +29,29 @@ 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;
scoped_ptr<printing::Metafile> draft_metafile;
printing::Metafile* initial_render_metafile =
print_preview_context_.metafile();
if (print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_) {
draft_metafile.reset(new printing::PreviewMetafile);
initial_render_metafile = draft_metafile.get();
}
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_.frame(), initial_render_metafile);
print_preview_context_.RenderedPreviewPage(
base::TimeTicks::Now() - begin_time);
scoped_ptr<printing::Metafile> page_metafile;
if (print_preview_context_.IsModifiable()) {
page_metafile.reset(
if (draft_metafile.get()) {
draft_metafile->FinishDocument();
} else if (print_preview_context_.IsModifiable() &&
print_preview_context_.generate_draft_pages()){
DCHECK(!draft_metafile.get());
draft_metafile.reset(
print_preview_context_.metafile()->GetMetafileForCurrentPage());
}
PreviewPageRendered(page_number, page_metafile.get());
PreviewPageRendered(page_number, draft_metafile.get());
}
bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params,
......@@ -207,6 +215,8 @@ void PrintWebViewHelper::PrintPageInternal(
SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device);
canvas->unref(); // SkRefPtr and new both took a reference.
printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile);
printing::MetafileSkiaWrapper::SetDraftMode(canvas.get(),
is_print_ready_metafile_sent_);
frame->printPage(params.page_number, canvas.get());
// TODO(myhuang): We should render the header and the footer.
......
......@@ -66,19 +66,30 @@ void PrintWebViewHelper::RenderPreviewPage(int page_number) {
printParams.printable_size.width(),
printParams.printable_size.height());
scoped_ptr<printing::Metafile> draft_metafile;
printing::Metafile* initial_render_metafile =
print_preview_context_.metafile();
scoped_ptr<printing::PreviewMetafile> draft_metafile;
#if !defined(USE_SKIA)
if (print_preview_context_.IsModifiable()) {
draft_metafile.reset(new printing::PreviewMetafile);
#if defined(USE_SKIA)
bool need_draft_metafile = print_preview_context_.IsModifiable() &&
is_print_ready_metafile_sent_;
#else
bool need_draft_metafile = print_preview_context_.IsModifiable() &&
print_preview_context_.generate_draft_pages();
// NOTE: If the rendering page need to be in draft metafile and print ready
// metafile, we should always render to the draft metafile first and then
// copy that into the print ready metafile because CG does not allow us to do
// it in the other order.
#endif
if (need_draft_metafile) {
draft_metafile.reset(new printing::PreviewMetafile());
if (!draft_metafile->Init()) {
DidFinishPrinting(FAIL_PREVIEW);
return;
}
initial_render_metafile = draft_metafile.get();
}
#endif
base::TimeTicks begin_time = base::TimeTicks::Now();
RenderPage(printParams.page_size, content_area, scale_factor, page_number,
......@@ -86,38 +97,44 @@ void PrintWebViewHelper::RenderPreviewPage(int page_number) {
print_preview_context_.RenderedPreviewPage(
base::TimeTicks::Now() - begin_time);
if (print_preview_context_.IsModifiable()) {
#if defined(USE_SKIA)
DCHECK(!draft_metafile.get());
draft_metafile.reset(
print_preview_context_.metafile()->GetMetafileForCurrentPage());
#else
if (draft_metafile.get()) {
draft_metafile->FinishDocument();
#if !defined(USE_SKIA)
if (!is_print_ready_metafile_sent_) {
// With CG, we rendered into a new metafile so we could get it as a draft
// document. Now we need to add it to complete document. But the document
// has already been scaled and adjusted for margins, so do a 1:1 drawing.
printing::Metafile* complete_metafile = print_preview_context_.metafile();
bool success = complete_metafile->StartPage(
// document. Now we need to add it to print ready document. But the
// document has already been scaled and adjusted for margins, so do a 1:1
// drawing.
printing::Metafile* print_ready_metafile =
print_preview_context_.metafile();
bool success = print_ready_metafile->StartPage(
printParams.page_size, gfx::Rect(printParams.page_size), 1.0);
DCHECK(success);
// StartPage unconditionally flips the content over, flip it back since it
// was already flipped in |draft_metafile|.
CGContextTranslateCTM(complete_metafile->context(), 0,
CGContextTranslateCTM(print_ready_metafile->context(), 0,
printParams.page_size.height());
CGContextScaleCTM(complete_metafile->context(), 1.0, -1.0);
CGContextScaleCTM(print_ready_metafile->context(), 1.0, -1.0);
draft_metafile->RenderPage(1,
complete_metafile->context(),
print_ready_metafile->context(),
draft_metafile->GetPageBounds(1).ToCGRect(),
false /* shrink_to_fit */,
false /* stretch_to_fit */,
true /* center_horizontally */,
true /* center_vertically */);
complete_metafile->FinishPage();
print_ready_metafile->FinishPage();
}
#endif
} else {
#if defined(USE_SKIA)
if (print_preview_context_.IsModifiable() &&
print_preview_context_.generate_draft_pages()) {
DCHECK(!draft_metafile.get());
draft_metafile.reset(
print_preview_context_.metafile()->GetMetafileForCurrentPage());
}
#endif
}
PreviewPageRendered(page_number, draft_metafile.get());
}
......@@ -137,6 +154,8 @@ void PrintWebViewHelper::RenderPage(
canvas->unref(); // SkRefPtr and new both took a reference.
WebKit::WebCanvas* canvasPtr = canvas.get();
printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvasPtr, metafile);
printing::MetafileSkiaWrapper::SetDraftMode(canvasPtr,
is_print_ready_metafile_sent_);
#else
bool success = metafile->StartPage(page_size, content_area, scale_factor);
DCHECK(success);
......
......@@ -126,24 +126,34 @@ void PrintWebViewHelper::RenderPreviewPage(int page_number) {
// Calculate the dpi adjustment.
float scale_factor = static_cast<float>(print_params.desired_dpi /
print_params.dpi);
scoped_ptr<Metafile> draft_metafile;
printing::Metafile* initial_render_metafile =
print_preview_context_.metafile();
if (print_preview_context_.IsModifiable() && is_print_ready_metafile_sent_) {
draft_metafile.reset(new printing::PreviewMetafile);
initial_render_metafile = draft_metafile.get();
}
base::TimeTicks begin_time = base::TimeTicks::Now();
printing::Metafile* render_page_result =
RenderPage(print_params, &scale_factor, page_number, true,
print_preview_context_.frame(),
print_preview_context_.metafile());
// In the preview flow, RenderPage will never return a new metafile.
DCHECK_EQ(render_page_result, print_preview_context_.metafile());
print_preview_context_.frame(), initial_render_metafile);
// In the preview flow, RenderPage will never return a new metafile.
DCHECK_EQ(render_page_result, initial_render_metafile);
print_preview_context_.RenderedPreviewPage(
base::TimeTicks::Now() - begin_time);
scoped_ptr<printing::Metafile> page_metafile;
if (print_preview_context_.IsModifiable()) {
page_metafile.reset(
if (draft_metafile.get()) {
draft_metafile->FinishDocument();
} else if (print_preview_context_.IsModifiable() &&
print_preview_context_.generate_draft_pages()){
DCHECK(!draft_metafile.get());
draft_metafile.reset(
print_preview_context_.metafile()->GetMetafileForCurrentPage());
}
PreviewPageRendered(page_number, page_metafile.get());
PreviewPageRendered(page_number, draft_metafile.get());
}
Metafile* PrintWebViewHelper::RenderPage(
......@@ -183,8 +193,11 @@ Metafile* PrintWebViewHelper::RenderPage(
// can't be a stack object.
SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device);
canvas->unref(); // SkRefPtr and new both took a reference.
if (is_preview)
if (is_preview) {
printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile);
printing::MetafileSkiaWrapper::SetDraftMode(canvas.get(),
is_print_ready_metafile_sent_);
}
float webkit_scale_factor = frame->printPage(page_number, canvas.get());
if (*scale_factor <= 0 || webkit_scale_factor <= 0) {
......
......@@ -27,6 +27,9 @@ const char kSettingDeviceName[] = "deviceName";
// Print job duplex mode.
const char kSettingDuplexMode[] = "duplex";
// True, when a new set of draft preview data is required.
const char kSettingGenerateDraftData[] = "generateDraftData";
// Page orientation: true for landscape, false for portrait.
const char kSettingLandscape[] = "landscape";
......
......@@ -14,6 +14,7 @@ extern const char kSettingColor[];
extern const char kSettingCopies[];
extern const char kSettingDeviceName[];
extern const char kSettingDuplexMode[];
extern const char kSettingGenerateDraftData[];
extern const char kSettingLandscape[];
extern const char kSettingPageRange[];
extern const char kSettingPageRangeFrom[];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment