summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/printing/print_preview_data_service.cc17
-rw-r--r--chrome/browser/printing/print_preview_data_service.h3
-rw-r--r--chrome/browser/printing/print_preview_message_handler.cc14
-rw-r--r--chrome/browser/printing/print_preview_message_handler.h2
-rw-r--r--chrome/browser/resources/print_preview/page_settings.js16
-rw-r--r--chrome/browser/resources/print_preview/print_preview.js126
-rw-r--r--chrome/browser/ui/webui/print_preview_handler.cc27
-rw-r--r--chrome/browser/ui/webui/print_preview_ui.cc5
-rw-r--r--chrome/browser/ui/webui/print_preview_ui.h5
-rw-r--r--chrome/common/print_messages.h5
-rw-r--r--chrome/renderer/mock_printer.cc4
-rw-r--r--chrome/renderer/mock_printer.h3
-rw-r--r--chrome/renderer/mock_render_thread.cc26
-rw-r--r--chrome/renderer/print_web_view_helper.cc102
-rw-r--r--chrome/renderer/print_web_view_helper.h30
-rw-r--r--chrome/renderer/print_web_view_helper_browsertest.cc63
-rw-r--r--chrome/renderer/print_web_view_helper_linux.cc24
-rw-r--r--chrome/renderer/print_web_view_helper_mac.mm90
-rw-r--r--chrome/renderer/print_web_view_helper_win.cc30
-rw-r--r--chrome/test/data/webui/print_preview.js19
-rw-r--r--printing/print_job_constants.cc3
-rw-r--r--printing/print_job_constants.h1
22 files changed, 477 insertions, 138 deletions
diff --git a/chrome/browser/printing/print_preview_data_service.cc b/chrome/browser/printing/print_preview_data_service.cc
index 53ba36f..1728158 100644
--- a/chrome/browser/printing/print_preview_data_service.cc
+++ b/chrome/browser/printing/print_preview_data_service.cc
@@ -49,6 +49,16 @@ class PrintPreviewDataStore : public base::RefCounted<PrintPreviewDataStore> {
page_data_map_[index] = const_cast<RefCountedBytes*>(data);
}
+ // Returns the available draft page count.
+ int GetAvailableDraftPageCount() {
+ int page_data_map_size = page_data_map_.size();
+ if (page_data_map_.find(printing::COMPLETE_PREVIEW_DOCUMENT_INDEX) !=
+ page_data_map_.end()) {
+ page_data_map_size--;
+ }
+ return page_data_map_size;
+ }
+
private:
friend class base::RefCounted<PrintPreviewDataStore>;
@@ -105,3 +115,10 @@ void PrintPreviewDataService::RemoveEntry(
if (it != data_store_map_.end())
data_store_map_.erase(it);
}
+
+int PrintPreviewDataService::GetAvailableDraftPageCount(
+ const std::string& preview_ui_addr_str) {
+ if (data_store_map_.find(preview_ui_addr_str) != data_store_map_.end())
+ return data_store_map_[preview_ui_addr_str]->GetAvailableDraftPageCount();
+ return 0;
+}
diff --git a/chrome/browser/printing/print_preview_data_service.h b/chrome/browser/printing/print_preview_data_service.h
index 2e94393..3642876 100644
--- a/chrome/browser/printing/print_preview_data_service.h
+++ b/chrome/browser/printing/print_preview_data_service.h
@@ -40,6 +40,9 @@ class PrintPreviewDataService {
// Remove the corresponding PrintPreviewUI entry from the map.
void RemoveEntry(const std::string& preview_ui_addr_str);
+ // Returns the available draft page count.
+ int GetAvailableDraftPageCount(const std::string& preview_ui_addr_str);
+
private:
friend struct DefaultSingletonTraits<PrintPreviewDataService>;
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc
index 2099b66..e0da894 100644
--- a/chrome/browser/printing/print_preview_message_handler.cc
+++ b/chrome/browser/printing/print_preview_message_handler.cc
@@ -99,6 +99,10 @@ void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(
PrintPreviewUI* print_preview_ui =
static_cast<PrintPreviewUI*>(print_preview_tab->web_ui());
+
+ if (!params.is_modifiable || params.clear_preview_data)
+ print_preview_ui->ClearAllPreviewData();
+
print_preview_ui->OnDidGetPreviewPageCount(params);
}
@@ -111,10 +115,6 @@ void PrintPreviewMessageHandler::OnDidPreviewPage(
PrintPreviewUI* print_preview_ui =
static_cast<PrintPreviewUI*>(print_preview_tab->web_ui());
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);
@@ -125,7 +125,7 @@ void PrintPreviewMessageHandler::OnDidPreviewPage(
}
}
-void PrintPreviewMessageHandler::OnPagesReadyForPreview(
+void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
const PrintHostMsg_DidPreviewDocument_Params& params) {
// Always try to stop the worker.
StopWorker(params.document_cookie);
@@ -219,8 +219,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_HANDLER(PrintHostMsg_DidGetDefaultPageLayout,
diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h
index f069afd..3a43610 100644
--- a/chrome/browser/printing/print_preview_message_handler.h
+++ b/chrome/browser/printing/print_preview_message_handler.h
@@ -42,7 +42,7 @@ class PrintPreviewMessageHandler : public TabContentsObserver {
void OnDidGetPreviewPageCount(
const PrintHostMsg_DidGetPreviewPageCount_Params& params);
void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params);
- void OnPagesReadyForPreview(
+ void OnMetafileReadyForPrinting(
const PrintHostMsg_DidPreviewDocument_Params& params);
void OnPrintPreviewFailed(int document_cookie);
void OnPrintPreviewCancelled(int document_cookie);
diff --git a/chrome/browser/resources/print_preview/page_settings.js b/chrome/browser/resources/print_preview/page_settings.js
index a0c36d0..dd36aaa 100644
--- a/chrome/browser/resources/print_preview/page_settings.js
+++ b/chrome/browser/resources/print_preview/page_settings.js
@@ -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;
},
@@ -194,6 +193,14 @@ cr.define('print_preview', function() {
},
/**
+ * 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|.
*
* @return {boolean} true if the text is valid.
@@ -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();
},
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index e49541c..86459f3 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -24,6 +24,12 @@ const MORE_PRINTERS = 'morePrinters';
const SIGN_IN = 'signIn';
const PRINT_TO_PDF = 'Print to PDF';
+// State of the print preview settings.
+var printSettings = new PrintSettings();
+
+// Print ready data index.
+const PRINT_READY_DATA_INDEX = -1;
+
// The name of the default or last used printer.
var defaultOrLastUsedPrinterName = '';
@@ -39,6 +45,9 @@ var initialPreviewRequestID = -1;
// True when a pending print file request exists.
var hasPendingPrintDocumentRequest = false;
+// True when a pending print ready document request exists.
+var hasPendingPrintReadyDocumentRequest = false;
+
// True when preview tab is hidden.
var isTabHidden = false;
@@ -68,6 +77,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
@@ -336,7 +350,8 @@ function getSettings() {
'headerFooterEnabled': headerFooterSettings.hasHeaderFooter(),
'defaultMarginsSelected': marginSettings.isDefaultMarginsSelected(),
'margins': marginSettings.customMargins,
- 'requestID': -1};
+ 'requestID': -1,
+ 'generateDraftData': generateDraftData};
var printerList = $('printer-list');
var selectedPrinter = printerList.selectedIndex;
@@ -413,7 +428,7 @@ function getSelectedPrinterName() {
* called once the preview loads.
*/
function requestToPrintDocument() {
- hasPendingPrintDocumentRequest = hasPendingPreviewRequest;
+ hasPendingPrintDocumentRequest = hasPendingPrintReadyDocumentRequest;
var printToPDF = getSelectedPrinterName() == PRINT_TO_PDF;
if (hasPendingPrintDocumentRequest) {
@@ -467,15 +482,50 @@ function sendPrintDocumentRequest() {
}
/**
+ * Loads the selected preview pages.
+ */
+function loadSelectedPages() {
+ hasPendingPreviewRequest = false;
+ pageSettings.updatePageSelection();
+ var pageSet = pageSettings.previouslySelectedPages;
+ var pageCount = pageSet.length;
+ if (pageCount == 0 || currentPreviewUid == '')
+ return;
+
+ cr.dispatchSimpleEvent(document, 'updateSummary');
+ for (var i = 0; i < pageCount; i++)
+ onDidPreviewPage(pageSet[i] - 1, currentPreviewUid, lastPreviewRequestID);
+}
+
+/**
* Asks the browser to generate a preview PDF based on current print settings.
*/
function requestPrintPreview() {
- hasPendingPreviewRequest = true;
- layoutSettings.updateState();
if (!isTabHidden)
showLoadingAnimation();
- chrome.send('getPreview', [JSON.stringify(getSettingsWithRequestID())]);
+ if (!hasPendingPreviewRequest && previewModifiable &&
+ hasOnlyPageSettingsChanged()) {
+ loadSelectedPages();
+ generateDraftData = false;
+ } else {
+ hasPendingPreviewRequest = true;
+ generateDraftData = true;
+ pageSettings.updatePageSelection();
+ }
+
+ printSettings.save();
+ layoutSettings.updateState();
+ hasPendingPrintReadyDocumentRequest = true;
+
+ var totalPageCount = pageSettings.totalPageCount;
+ if (!previewModifiable && totalPageCount > 0)
+ generateDraftData = false;
+
+ var pageCount = totalPageCount != undefined ? totalPageCount : -1;
+ chrome.send('getPreview', [JSON.stringify(getSettingsWithRequestID()),
+ String(pageCount),
+ previewModifiable]);
}
/**
@@ -889,12 +939,18 @@ function onDidPreviewPage(pageNumber, previewUid, previewResponseId) {
if (!previewModifiable)
return;
- var pageIndex = pageSettings.previouslySelectedPages.indexOf(pageNumber + 1);
-
if (pageSettings.requestPrintPreviewIfNeeded())
return;
- if (pageIndex == 0)
- createPDFPlugin(previewUid);
+
+ var pageIndex = pageSettings.previouslySelectedPages.indexOf(pageNumber + 1);
+ if (pageIndex == -1)
+ return;
+
+ currentPreviewUid = previewUid;
+ if (pageIndex == 0) {
+ createPDFPlugin(pageNumber);
+ hasPendingPreviewRequest = false;
+ }
$('pdf-viewer').loadPreviewPage(
getPageSrcURL(previewUid, pageNumber), pageIndex);
@@ -913,10 +969,12 @@ function updatePrintPreview(previewUid, previewResponseId) {
if (!isExpectedPreviewResponse(previewResponseId))
return;
hasPendingPreviewRequest = false;
+ hasPendingPrintReadyDocumentRequest = false;
if (!previewModifiable) {
// If the preview is not modifiable the plugin has not been created yet.
- createPDFPlugin(previewUid);
+ currentPreviewUid = previewUid;
+ createPDFPlugin(PRINT_READY_DATA_INDEX);
}
cr.dispatchSimpleEvent(document, 'updatePrintButton');
@@ -926,28 +984,43 @@ function updatePrintPreview(previewUid, previewResponseId) {
}
/**
+ * 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 &&
+ printSettings.hasHeaderFooter ==
+ tempPrintSettings.hasHeaderFooter &&
+ 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);
@@ -965,7 +1038,8 @@ function checkCompatiblePluginExists() {
dummyPlugin.goToPage &&
dummyPlugin.removePrintButton &&
dummyPlugin.loadPreviewPage &&
- dummyPlugin.printPreviewPageCount);
+ dummyPlugin.printPreviewPageCount &&
+ dummyPlugin.resetPrintPreviewUrl);
}
window.addEventListener('DOMContentLoaded', onLoad);
@@ -981,6 +1055,24 @@ function setDefaultValuesAndRegeneratePreview(resetMargins) {
requestPrintPreview();
}
+/**
+ * Class that represents the state of the print settings.
+ */
+function PrintSettings() {
+ this.deviceName = '';
+ this.isLandscape = '';
+ this.hasHeaderFooter = '';
+}
+
+/**
+ * Takes a snapshot of the print settings.
+ */
+PrintSettings.prototype.save = function() {
+ this.deviceName = getSelectedPrinterName();
+ this.isLandscape = layoutSettings.isLandscape();
+ this.hasHeaderFooter = headerFooterSettings.hasHeaderFooter();
+}
+
/// Pull in all other scripts in a single shot.
<include src="print_preview_animations.js"/>
<include src="print_preview_cloud.js"/>
diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc
index f237e0b..a0cc3ae 100644
--- a/chrome/browser/ui/webui/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview_handler.cc
@@ -15,6 +15,7 @@
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
+#include "base/string_number_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
@@ -479,6 +480,7 @@ void PrintPreviewHandler::HandleGetPrinters(const ListValue*) {
}
void PrintPreviewHandler::HandleGetPreview(const ListValue* args) {
+ DCHECK(args->GetSize() == 3);
scoped_ptr<DictionaryValue> settings(GetSettingsDictionary(args));
if (!settings.get())
return;
@@ -521,6 +523,31 @@ void PrintPreviewHandler::HandleGetPreview(const ListValue* args) {
settings->SetString(printing::kSettingHeaderFooterURL, url);
}
+ bool generate_draft_data = false;
+ if (!settings->GetBoolean(printing::kSettingGenerateDraftData,
+ &generate_draft_data)) {
+ NOTREACHED();
+ }
+
+ if (!generate_draft_data) {
+ int draft_page_count = -1;
+ bool preview_modifiable = false;
+ std::string draft_page_count_str;
+ if (!args->GetString(1, &draft_page_count_str) ||
+ !base::StringToInt(draft_page_count_str, &draft_page_count)) {
+ NOTREACHED();
+ draft_page_count = -1;
+ }
+
+ if (!args->GetBoolean(2, &preview_modifiable))
+ NOTREACHED();
+
+ if (draft_page_count != -1 && preview_modifiable &&
+ print_preview_ui->GetAvailableDraftPageCount() != draft_page_count) {
+ settings->SetBoolean(printing::kSettingGenerateDraftData, true);
+ }
+ }
+
VLOG(1) << "Print preview request start";
RenderViewHost* rvh = initiator_tab->render_view_host();
rvh->Send(new PrintMsg_PrintPreview(rvh->routing_id(), *settings));
diff --git a/chrome/browser/ui/webui/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview_ui.cc
index 208d207..d4f53e5 100644
--- a/chrome/browser/ui/webui/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview_ui.cc
@@ -104,6 +104,11 @@ void PrintPreviewUI::ClearAllPreviewData() {
print_preview_data_service()->RemoveEntry(preview_ui_addr_str_);
}
+int PrintPreviewUI::GetAvailableDraftPageCount() {
+ return print_preview_data_service()->GetAvailableDraftPageCount(
+ preview_ui_addr_str_);
+}
+
void PrintPreviewUI::SetInitiatorTabURLAndTitle(
const std::string& initiator_url,
const string16& job_title) {
diff --git a/chrome/browser/ui/webui/print_preview_ui.h b/chrome/browser/ui/webui/print_preview_ui.h
index 589f441..a219539 100644
--- a/chrome/browser/ui/webui/print_preview_ui.h
+++ b/chrome/browser/ui/webui/print_preview_ui.h
@@ -41,6 +41,9 @@ class PrintPreviewUI : public ChromeWebUI {
// Clear the existing print preview data.
void ClearAllPreviewData();
+ // Returns the available draft page count.
+ int GetAvailableDraftPageCount();
+
// Setters
void SetInitiatorTabURLAndTitle(const std::string& initiator_url,
const string16& initiator_tab_title);
@@ -80,6 +83,8 @@ class PrintPreviewUI : public ChromeWebUI {
void OnPreviewDataIsAvailable(int expected_pages_count,
int preview_request_id);
+ // Notifies the Web UI renderer to reuse the preview data.
+ // |preview_request_id| indicates which request resulted in this response.
void OnReusePreviewData(int preview_request_id);
// Notifies the Web UI that preview tab is destroyed. This is the last chance
diff --git a/chrome/common/print_messages.h b/chrome/common/print_messages.h
index cfb9719..89d377e 100644
--- a/chrome/common/print_messages.h
+++ b/chrome/common/print_messages.h
@@ -202,6 +202,9 @@ IPC_STRUCT_BEGIN(PrintHostMsg_DidGetPreviewPageCount_Params)
// The id of the preview request.
IPC_STRUCT_MEMBER(int, preview_request_id)
+
+ // Indicates whether the existing preview data needs to be cleared or not.
+ IPC_STRUCT_MEMBER(bool, clear_preview_data)
IPC_STRUCT_END()
// Parameters to describe a rendered page.
@@ -365,7 +368,7 @@ IPC_SYNC_MESSAGE_ROUTED2_1(PrintHostMsg_CheckForCancel,
// 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.
diff --git a/chrome/renderer/mock_printer.cc b/chrome/renderer/mock_printer.cc
index 3d14559..f8266c8 100644
--- a/chrome/renderer/mock_printer.cc
+++ b/chrome/renderer/mock_printer.cc
@@ -114,10 +114,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);
params->Reset();
+ params->pages = pages;
SetPrintParams(&(params->params));
printer_status_ = PRINTER_PRINTING;
}
diff --git a/chrome/renderer/mock_printer.h b/chrome/renderer/mock_printer.h
index 0a85780..bbde217 100644
--- a/chrome/renderer/mock_printer.h
+++ b/chrome/renderer/mock_printer.h
@@ -76,7 +76,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);
diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc
index 6844c44..c6fc519 100644
--- a/chrome/renderer/mock_render_thread.cc
+++ b/chrome/renderer/mock_render_thread.cc
@@ -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()
@@ -252,8 +253,29 @@ void MockRenderThread::OnUpdatePrintSettings(
}
// Just return the default settings.
- if (printer_.get())
- printer_->UpdateSettings(document_cookie, params);
+ if (printer_.get()) {
+ ListValue* page_range_array;
+ 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) {
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc
index 089e691..0d0ec73 100644
--- a/chrome/renderer/print_web_view_helper.cc
+++ b/chrome/renderer/print_web_view_helper.cc
@@ -497,6 +497,7 @@ PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view)
RenderViewObserverTracker<PrintWebViewHelper>(render_view),
print_web_view_(NULL),
is_preview_(switches::IsPrintPreviewEnabled()),
+ is_print_ready_metafile_sent_(false),
user_cancelled_scripted_print_count_(0),
notify_browser_of_print_failure_(true) {
}
@@ -656,14 +657,24 @@ void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) {
preview_params.preview_request_id =
print_pages_params_->params.preview_request_id;
- Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
+ Send(new PrintHostMsg_MetafileReadyForPrinting(routing_id(),
+ preview_params));
return;
}
// Always clear |old_print_pages_params_| before rendering the pages.
old_print_pages_params_.reset();
+ is_print_ready_metafile_sent_ = false;
// PDF printer device supports alpha blending.
print_pages_params_->params.supports_alpha_blend = true;
+
+ bool generate_draft_pages = false;
+ if (!settings.GetBoolean(printing::kSettingGenerateDraftData,
+ &generate_draft_pages)) {
+ NOTREACHED();
+ }
+ print_preview_context_.set_generate_draft_pages(generate_draft_pages);
+
if (CreatePreviewDocument()) {
DidFinishPrinting(OK);
} else {
@@ -683,6 +694,7 @@ bool PrintWebViewHelper::CreatePreviewDocument() {
params.is_modifiable = print_preview_context_.IsModifiable();
params.document_cookie = print_pages_params_->params.document_cookie;
params.preview_request_id = print_pages_params_->params.preview_request_id;
+ params.clear_preview_data = print_preview_context_.generate_draft_pages();
Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), params));
if (CheckForCancel())
return false;
@@ -693,17 +705,20 @@ bool PrintWebViewHelper::CreatePreviewDocument() {
return false;
if (CheckForCancel())
return false;
- };
-
- // Finished generating preview. Finalize the document.
- if (!FinalizePreviewDocument())
- return false;
+ if (print_preview_context_.IsLastPageOfPrintReadyMetafile()) {
+ // Finished generating preview. Finalize the document.
+ if (!FinalizePrintReadyDocument())
+ return false;
+ }
+ }
+ print_preview_context_.AllPagesRendered();
print_preview_context_.Finished();
return true;
}
-bool PrintWebViewHelper::FinalizePreviewDocument() {
- print_preview_context_.FinalizePreviewDocument();
+bool PrintWebViewHelper::FinalizePrintReadyDocument() {
+ DCHECK(!is_print_ready_metafile_sent_);
+ print_preview_context_.FinalizePrintReadyDocument();
// Get the size of the resulting metafile.
printing::PreviewMetafile* metafile = print_preview_context_.metafile();
@@ -726,7 +741,9 @@ bool PrintWebViewHelper::FinalizePreviewDocument() {
LOG(ERROR) << "CopyMetafileDataToSharedMem failed";
return false;
}
- Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
+ is_print_ready_metafile_sent_ = true;
+
+ Send(new PrintHostMsg_MetafileReadyForPrinting(routing_id(), preview_params));
return true;
}
@@ -1254,8 +1271,10 @@ bool PrintWebViewHelper::PreviewPageRendered(int page_number,
DCHECK_GE(page_number, printing::FIRST_PAGE_INDEX);
// For non-modifiable files, |metafile| should be NULL, so do not bother
- // sending a message.
- if (!print_preview_context_.IsModifiable()) {
+ // sending a message. If we don't generate draft metafiles, |metafile| is
+ // NULL.
+ if (!print_preview_context_.IsModifiable() ||
+ !print_preview_context_.generate_draft_pages()) {
DCHECK(!metafile);
return true;
}
@@ -1286,8 +1305,9 @@ bool PrintWebViewHelper::PreviewPageRendered(int page_number,
PrintWebViewHelper::PrintPreviewContext::PrintPreviewContext()
: frame_(NULL),
total_page_count_(0),
- actual_page_count_(0),
current_page_index_(0),
+ generate_draft_pages_(true),
+ print_ready_metafile_page_count_(0),
state_(UNINITIALIZED) {
}
@@ -1341,22 +1361,24 @@ bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument(
return false;
}
+ int selected_page_count = pages.size();
current_page_index_ = 0;
- if (pages.empty()) {
- actual_page_count_ = total_page_count_;
- for (int i = 0; i < actual_page_count_; ++i)
+ print_ready_metafile_page_count_ = selected_page_count;
+ pages_to_render_ = pages;
+
+ if (selected_page_count == 0) {
+ print_ready_metafile_page_count_ = total_page_count_;
+ // Render all pages.
+ for (int i = 0; i < total_page_count_; i++)
pages_to_render_.push_back(i);
- } else {
- actual_page_count_ = pages.size();
- for (int i = 0; i < actual_page_count_; ++i) {
- int page_number = pages[i];
- if (page_number < printing::FIRST_PAGE_INDEX ||
- page_number >= total_page_count_) {
- LOG(ERROR) << "CreatePreviewDocument got invalid page count "
- << page_number << " at index " << i;
- return false;
+ } else if (generate_draft_pages_) {
+ int pages_index = 0;
+ for (int i = 0; i < total_page_count_; i++) {
+ if (pages_index < selected_page_count && i == pages[pages_index]) {
+ pages_index++;
+ continue;
}
- pages_to_render_.push_back(page_number);
+ pages_to_render_.push_back(i);
}
}
@@ -1373,16 +1395,20 @@ void PrintWebViewHelper::PrintPreviewContext::RenderedPreviewPage(
UMA_HISTOGRAM_TIMES("PrintPreview.RenderPDFPageTime", page_time);
}
-void PrintWebViewHelper::PrintPreviewContext::FinalizePreviewDocument() {
+void PrintWebViewHelper::PrintPreviewContext::AllPagesRendered() {
DCHECK_EQ(RENDERING, state_);
state_ = DONE;
+ prep_frame_view_->FinishPrinting();
+}
- base::TimeTicks begin_time = base::TimeTicks::Now();
+void PrintWebViewHelper::PrintPreviewContext::FinalizePrintReadyDocument() {
+ if (state_ != DONE && state_ != RENDERING)
+ NOTREACHED();
- prep_frame_view_->FinishPrinting();
+ base::TimeTicks begin_time = base::TimeTicks::Now();
metafile_->FinishDocument();
- if (actual_page_count_ <= 0) {
+ if (print_ready_metafile_page_count_ <= 0) {
NOTREACHED();
return;
}
@@ -1394,7 +1420,7 @@ void PrintWebViewHelper::PrintPreviewContext::FinalizePreviewDocument() {
UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime",
total_time);
UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage",
- total_time / actual_page_count_);
+ total_time / pages_to_render_.size());
}
void PrintWebViewHelper::PrintPreviewContext::Finished() {
@@ -1410,7 +1436,7 @@ void PrintWebViewHelper::PrintPreviewContext::Failed() {
int PrintWebViewHelper::PrintPreviewContext::GetNextPageNumber() {
DCHECK_EQ(RENDERING, state_);
- if (current_page_index_ >= actual_page_count_)
+ if ((size_t)(current_page_index_) == pages_to_render_.size())
return -1;
return pages_to_render_[current_page_index_++];
}
@@ -1429,6 +1455,16 @@ bool PrintWebViewHelper::PrintPreviewContext::IsModifiable() const {
return mime != "application/pdf";
}
+bool PrintWebViewHelper::PrintPreviewContext::IsLastPageOfPrintReadyMetafile()
+ const {
+ return current_page_index_ == print_ready_metafile_page_count_;
+}
+
+void PrintWebViewHelper::PrintPreviewContext::set_generate_draft_pages(
+ bool generate_draft_pages) {
+ generate_draft_pages_ = generate_draft_pages;
+}
+
WebKit::WebFrame* PrintWebViewHelper::PrintPreviewContext::frame() const {
return frame_;
}
@@ -1442,6 +1478,10 @@ int PrintWebViewHelper::PrintPreviewContext::total_page_count() const {
return total_page_count_;
}
+bool PrintWebViewHelper::PrintPreviewContext::generate_draft_pages() {
+ return generate_draft_pages_;
+}
+
printing::PreviewMetafile*
PrintWebViewHelper::PrintPreviewContext::metafile() const {
return metafile_.get();
diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h
index 5d980a6..dc38462 100644
--- a/chrome/renderer/print_web_view_helper.h
+++ b/chrome/renderer/print_web_view_helper.h
@@ -6,7 +6,6 @@
#define CHROME_RENDERER_PRINT_WEB_VIEW_HELPER_H_
#pragma once
-#include <utility>
#include <vector>
#include "base/memory/scoped_ptr.h"
@@ -109,6 +108,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);
@@ -139,8 +140,8 @@ class PrintWebViewHelper : public RenderViewObserver,
// Returns true if print preview should continue, false on failure.
bool RenderPreviewPage(int page_number);
- // Finalize the print preview document.
- bool FinalizePreviewDocument();
+ // Finalize the print ready preview document.
+ bool FinalizePrintReadyDocument();
// Print / preview the node under the context menu.
void OnPrintNodeUnderContextMenu();
@@ -302,6 +303,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_;
@@ -339,8 +341,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();
@@ -352,11 +357,16 @@ class PrintWebViewHelper : public RenderViewObserver,
int GetNextPageNumber();
bool IsReadyToRender() const;
bool IsModifiable() const;
+ bool IsLastPageOfPrintReadyMetafile() 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;
@@ -383,14 +393,18 @@ class PrintWebViewHelper : public RenderViewObserver,
// 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_index_;
+ // List of page indices that need to be rendered.
std::vector<int> pages_to_render_;
+ // True, when draft pages needs to be generated.
+ bool generate_draft_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_;
diff --git a/chrome/renderer/print_web_view_helper_browsertest.cc b/chrome/renderer/print_web_view_helper_browsertest.cc
index 372123f..abc34d5 100644
--- a/chrome/renderer/print_web_view_helper_browsertest.cc
+++ b/chrome/renderer/print_web_view_helper_browsertest.cc
@@ -50,6 +50,7 @@ void CreatePrintSettingsDictionary(DictionaryValue* dict) {
dict->SetBoolean(printing::kIsFirstRequest, true);
dict->SetBoolean(printing::kSettingDefaultMarginsSelected, true);
dict->SetBoolean(printing::kSettingHeaderFooterEnabled, false);
+ dict->SetBoolean(printing::kSettingGenerateDraftData, true);
}
} // namespace
@@ -327,12 +328,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);
@@ -345,6 +346,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(generate_draft_pages, msg_found);
+ }
+
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperPreviewTest);
};
@@ -366,6 +389,40 @@ TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreview) {
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);
+
+ // Verify that we did not create the draft metafile for the first page.
+ VerifyDidPreviewPage(false, 0);
+
+ VerifyPrintPreviewCancelled(false);
+ VerifyPrintPreviewFailed(false);
+ VerifyPrintPreviewGenerated(true);
+ VerifyPagesPrinted(false);
+}
+
// Tests that print preview fails and receiving error messages through
// that channel all works.
TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewFail) {
diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc
index 6ece1a0..a65e5bf 100644
--- a/chrome/renderer/print_web_view_helper_linux.cc
+++ b/chrome/renderer/print_web_view_helper_linux.cc
@@ -29,21 +29,29 @@ bool 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());
}
- return PreviewPageRendered(page_number, page_metafile.get());
+ return 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());
if (params.params.display_header_footer) {
diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm
index f64a0bf..2048920 100644
--- a/chrome/renderer/print_web_view_helper_mac.mm
+++ b/chrome/renderer/print_web_view_helper_mac.mm
@@ -67,19 +67,30 @@ bool 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 render_to_draft = print_preview_context_.IsModifiable() &&
+ is_print_ready_metafile_sent_;
+#else
+ // If the page needs to be in both 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.
+ bool render_to_draft = print_preview_context_.IsModifiable() &&
+ print_preview_context_.generate_draft_pages();
+#endif
+
+ if (render_to_draft) {
+ draft_metafile.reset(new printing::PreviewMetafile());
if (!draft_metafile->Init()) {
LOG(ERROR) << "Draft PreviewMetafile Init failed";
return false;
}
initial_render_metafile = draft_metafile.get();
}
-#endif
base::TimeTicks begin_time = base::TimeTicks::Now();
RenderPage(printParams.page_size, content_area, scale_factor, page_number,
@@ -87,38 +98,44 @@ bool 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();
-
- // 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(
- 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,
- printParams.page_size.height());
- CGContextScaleCTM(complete_metafile->context(), 1.0, -1.0);
-
- draft_metafile->RenderPage(1,
- complete_metafile->context(),
- draft_metafile->GetPageBounds(1).ToCGRect(),
- false /* shrink_to_fit */,
- false /* stretch_to_fit */,
- true /* center_horizontally */,
- true /* center_vertically */);
- complete_metafile->FinishPage();
+#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 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(print_ready_metafile->context(), 0,
+ printParams.page_size.height());
+ CGContextScaleCTM(print_ready_metafile->context(), 1.0, -1.0);
+ draft_metafile->RenderPage(1,
+ print_ready_metafile->context(),
+ draft_metafile->GetPageBounds(1).ToCGRect(),
+ false /* shrink_to_fit */,
+ false /* stretch_to_fit */,
+ true /* center_horizontally */,
+ true /* center_vertically */);
+ 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
}
-
return PreviewPageRendered(page_number, draft_metafile.get());
}
@@ -136,8 +153,9 @@ void PrintWebViewHelper::RenderPage(
SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device);
canvas->unref(); // SkRefPtr and new both took a reference.
- WebKit::WebCanvas* canvas_ptr = canvas.get();
- printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas_ptr, metafile);
+ printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile);
+ printing::MetafileSkiaWrapper::SetDraftMode(canvas.get(),
+ is_print_ready_metafile_sent_);
#else
bool success = metafile->StartPage(page_size, content_area, scale_factor);
DCHECK(success);
diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc
index 7d18e3d..a17da2e 100644
--- a/chrome/renderer/print_web_view_helper_win.cc
+++ b/chrome/renderer/print_web_view_helper_win.cc
@@ -127,24 +127,33 @@ bool 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());
+ print_preview_context_.frame(), initial_render_metafile);
// In the preview flow, RenderPage will never return a new metafile.
- DCHECK_EQ(render_page_result, print_preview_context_.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());
}
- return PreviewPageRendered(page_number, page_metafile.get());
+ return PreviewPageRendered(page_number, draft_metafile.get());
}
Metafile* PrintWebViewHelper::RenderPage(
@@ -184,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());
diff --git a/chrome/test/data/webui/print_preview.js b/chrome/test/data/webui/print_preview.js
index 7d4a2adc..dacefd0 100644
--- a/chrome/test/data/webui/print_preview.js
+++ b/chrome/test/data/webui/print_preview.js
@@ -39,7 +39,7 @@ PrintPreviewWebUITest.prototype = {
MockPrintPreviewHandler.prototype = {
getDefaultPrinter: function() {},
getPrinters: function() {},
- getPreview: function(settings) {},
+ getPreview: function(settings, draft_page_count, modifiable) {},
print: function(settings) {},
getPrinterCapabilities: function(printerName) {},
showSystemDialog: function() {},
@@ -72,8 +72,8 @@ PrintPreviewWebUITest.prototype = {
}));
var savedArgs = new SaveMockArguments();
mockHandler.stubs().getPreview(savedArgs.match(NOT_NULL)).
- will(callFunctionWithSavedArgs(savedArgs, function(options) {
- updatePrintPreview('title', true, 1, JSON.parse(options).requestID);
+ will(callFunctionWithSavedArgs(savedArgs, function(args) {
+ updatePrintPreview(1, JSON.parse(args[0]).requestID);
}));
mockHandler.stubs().getPrinters().
@@ -143,19 +143,21 @@ PrintPreviewWebUITest.prototype = {
* attaches an HTMLDivElement to the |mainview| element with attributes and
* empty methods, which are used by testing and that would be provided by the
* HTMLEmbedElement when the PDF plugin exists.
- * @param {string} previewUid Preview unique identifier.
+ * @param {number} srcDataIndex Preview data source index.
*/
- createPDFPlugin: function(previewUid) {
+ createPDFPlugin: function(srcDataIndex) {
var pdfViewer = $('pdf-viewer');
if (pdfViewer)
return;
+ var previewUid = 1;
pdfViewer = document.createElement('div');
pdfViewer.setAttribute('id', 'pdf-viewer');
pdfViewer.setAttribute('type',
'application/x-google-chrome-print-preview-pdf');
pdfViewer.setAttribute(
- 'src', 'chrome://print/' + previewUid + '/print.pdf');
+ 'src',
+ 'chrome://print/' + previewUid + '/' + srcDataIndex + '/print.pdf');
pdfViewer.setAttribute('aria-live', 'polite');
pdfViewer.setAttribute('aria-atomic', 'true');
function fakeFunction() {}
@@ -341,9 +343,8 @@ TEST_F('PrintPreviewWebUITest', 'TestColorSettings', function() {
TEST_F('PrintPreviewWebUITest', 'TestPrinterChangeUpdatesPreview', function() {
var savedArgs = new SaveMockArguments();
this.mockHandler.expects(once()).getPreview(savedArgs.match(ANYTHING)).
- will(callFunctionWithSavedArgs(savedArgs, function(options) {
- updatePrintPreview('title', true, 2,
- JSON.parse(options).requestID);
+ will(callFunctionWithSavedArgs(savedArgs, function(args) {
+ updatePrintPreview(2, JSON.parse(args[0]).requestID);
}));
this.mockGlobals.expects(once()).updateWithPrinterCapabilities(
diff --git a/printing/print_job_constants.cc b/printing/print_job_constants.cc
index 5e7863e..0edea06 100644
--- a/printing/print_job_constants.cc
+++ b/printing/print_job_constants.cc
@@ -43,6 +43,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";
+
// Option to print headers and Footers: true if selected, false if not.
const char kSettingHeaderFooterEnabled[] = "headerFooterEnabled";
diff --git a/printing/print_job_constants.h b/printing/print_job_constants.h
index 5739ab9..7698599 100644
--- a/printing/print_job_constants.h
+++ b/printing/print_job_constants.h
@@ -19,6 +19,7 @@ extern const char kSettingCopies[];
extern const char kSettingDefaultMarginsSelected[];
extern const char kSettingDeviceName[];
extern const char kSettingDuplexMode[];
+extern const char kSettingGenerateDraftData[];
extern const char kSettingHeaderFooterEnabled[];
extern const int kSettingHeaderFooterCharacterSpacing;
extern const char kSettingHeaderFooterFontFamilyName[];