summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-10 23:17:32 +0000
committerkmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-10 23:17:32 +0000
commit732b813ab60ebaad3cd2a60e19154e2c29b5a144 (patch)
tree9ed80f722ccf2e478ec771614193e88f9126e419
parent66122f44aec56f163aed88a673f062f035619bc2 (diff)
downloadchromium_src-732b813ab60ebaad3cd2a60e19154e2c29b5a144.zip
chromium_src-732b813ab60ebaad3cd2a60e19154e2c29b5a144.tar.gz
chromium_src-732b813ab60ebaad3cd2a60e19154e2c29b5a144.tar.bz2
PrintPreview: Honor the print media page size and margin values.
BUG=104210, 100819 TEST=Added PrintWebViewHelperPreviewTests. Review URL: http://codereview.chromium.org/8585017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117102 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/printing/print_dialog_cloud.cc2
-rw-r--r--chrome/browser/printing/print_preview_message_handler.cc6
-rw-r--r--chrome/browser/printing/print_preview_message_handler.h3
-rw-r--r--chrome/browser/printing/printing_message_filter.cc5
-rw-r--r--chrome/browser/resources/print_preview/layout_settings.js2
-rw-r--r--chrome/browser/resources/print_preview/print_preview.js10
-rw-r--r--chrome/browser/ui/webui/print_preview_ui.cc6
-rw-r--r--chrome/browser/ui/webui/print_preview_ui.h3
-rw-r--r--chrome/common/print_messages.cc4
-rw-r--r--chrome/common/print_messages.h15
-rw-r--r--chrome/renderer/chrome_mock_render_thread.cc6
-rw-r--r--chrome/renderer/mock_printer.cc37
-rw-r--r--chrome/renderer/mock_printer.h6
-rw-r--r--chrome/renderer/print_web_view_helper.cc390
-rw-r--r--chrome/renderer/print_web_view_helper.h52
-rw-r--r--chrome/renderer/print_web_view_helper_browsertest.cc187
-rw-r--r--chrome/renderer/print_web_view_helper_linux.cc33
-rw-r--r--chrome/renderer/print_web_view_helper_mac.mm66
-rw-r--r--chrome/renderer/print_web_view_helper_win.cc104
-rw-r--r--printing/pdf_metafile_cg_mac.cc12
-rw-r--r--printing/printed_document.cc12
-rw-r--r--printing/printed_document.h3
-rw-r--r--printing/printed_document_win.cc2
-rw-r--r--printing/printed_page.cc6
-rw-r--r--printing/printed_page.h7
-rw-r--r--printing/printed_page_unittest.cc16
26 files changed, 734 insertions, 261 deletions
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index daf1213..b225f65 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -411,6 +411,7 @@ void CloudPrintFlowHandler::HandleSetPageParameters(const ListValue* args) {
PrintMsg_Print_Params default_settings;
default_settings.content_size = gfx::Size(kWidth, kHeight);
+ default_settings.printable_area = gfx::Rect(0, 0, kWidth, kHeight);
default_settings.dpi = kDPI;
default_settings.min_shrink = kMinPageShrink;
default_settings.max_shrink = kMaxPageShrink;
@@ -419,6 +420,7 @@ void CloudPrintFlowHandler::HandleSetPageParameters(const ListValue* args) {
default_settings.selection_only = false;
default_settings.preview_request_id = 0;
default_settings.is_first_request = true;
+ default_settings.print_to_pdf = false;
if (!GetPageSetupParameters(json, default_settings)) {
NOTREACHED();
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc
index 74b36e9..212750c 100644
--- a/chrome/browser/printing/print_preview_message_handler.cc
+++ b/chrome/browser/printing/print_preview_message_handler.cc
@@ -199,14 +199,16 @@ void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) {
}
void PrintPreviewMessageHandler::OnDidGetDefaultPageLayout(
- const PageSizeMargins& page_layout_in_points) {
+ const PageSizeMargins& page_layout_in_points,
+ bool has_custom_page_size_style) {
TabContentsWrapper* print_preview_tab = GetPrintPreviewTab();
if (!print_preview_tab || !print_preview_tab->web_contents()->GetWebUI())
return;
PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
print_preview_tab->web_contents()->GetWebUI());
- print_preview_ui->OnDidGetDefaultPageLayout(page_layout_in_points);
+ print_preview_ui->OnDidGetDefaultPageLayout(page_layout_in_points,
+ has_custom_page_size_style);
}
void PrintPreviewMessageHandler::OnPrintPreviewCancelled(int document_cookie) {
diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h
index f9eab85..5a90f05 100644
--- a/chrome/browser/printing/print_preview_message_handler.h
+++ b/chrome/browser/printing/print_preview_message_handler.h
@@ -46,7 +46,8 @@ class PrintPreviewMessageHandler : public content::WebContentsObserver {
// Message handlers.
void OnRequestPrintPreview(bool source_is_modifiable);
void OnDidGetDefaultPageLayout(
- const printing::PageSizeMargins& page_layout_in_points);
+ const printing::PageSizeMargins& page_layout_in_points,
+ bool has_custom_page_size_style);
void OnDidGetPreviewPageCount(
const PrintHostMsg_DidGetPreviewPageCount_Params& params);
void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params);
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
index ef50b6f..63238e8 100644
--- a/chrome/browser/printing/printing_message_filter.cc
+++ b/chrome/browser/printing/printing_message_filter.cc
@@ -47,6 +47,11 @@ void RenderParamsFromPrintSettings(const printing::PrintSettings& settings,
params->content_size.SetSize(
settings.page_setup_device_units().content_area().width(),
settings.page_setup_device_units().content_area().height());
+ params->printable_area.SetRect(
+ settings.page_setup_device_units().printable_area().x(),
+ settings.page_setup_device_units().printable_area().y(),
+ settings.page_setup_device_units().printable_area().width(),
+ settings.page_setup_device_units().printable_area().height());
params->margin_top = settings.page_setup_device_units().content_area().y();
params->margin_left = settings.page_setup_device_units().content_area().x();
params->dpi = settings.dpi();
diff --git a/chrome/browser/resources/print_preview/layout_settings.js b/chrome/browser/resources/print_preview/layout_settings.js
index a341ce8..7a9b187 100644
--- a/chrome/browser/resources/print_preview/layout_settings.js
+++ b/chrome/browser/resources/print_preview/layout_settings.js
@@ -100,7 +100,7 @@ cr.define('print_preview', function() {
* @private
*/
onPDFLoaded_: function() {
- this.fadeInOut_(!previewModifiable);
+ this.fadeInOut_(!previewModifiable || hasPageSizeStyle);
},
/**
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index beaced6..e45aa60 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -16,6 +16,9 @@ var lastSelectedPrinterIndex = 0;
// Used to disable some printing options when the preview is not modifiable.
var previewModifiable = false;
+// Used to identify whether the printing frame has specific page size style.
+var hasPageSizeStyle = false;
+
// Destination list special value constants.
const MANAGE_CLOUD_PRINTERS = 'manageCloudPrinters';
const MANAGE_LOCAL_PRINTERS = 'manageLocalPrinters';
@@ -835,7 +838,7 @@ function setPluginPreviewPageCount() {
* Called from PrintPreviewUI::OnDidGetPreviewPageCount().
* @param {number} pageCount The number of pages.
* @param {number} previewResponseId The preview request id that resulted in
- * this response.
+ * this response.
*/
function onDidGetPreviewPageCount(pageCount, previewResponseId) {
if (!isExpectedPreviewResponse(previewResponseId))
@@ -850,8 +853,11 @@ function onDidGetPreviewPageCount(pageCount, previewResponseId) {
/**
* @param {printing::PageSizeMargins} pageLayout The default layout of the page
* in points.
+ * @param {boolean} hasCustomPageSizeStyle Indicates whether the previewed
+ * document has a custom page size style.
*/
-function onDidGetDefaultPageLayout(pageLayout) {
+function onDidGetDefaultPageLayout(pageLayout, hasCustomPageSizeStyle) {
+ hasPageSizeStyle = hasCustomPageSizeStyle;
marginSettings.currentDefaultPageLayout = new print_preview.PageLayout(
pageLayout.contentWidth,
pageLayout.contentHeight,
diff --git a/chrome/browser/ui/webui/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview_ui.cc
index a18df71..e3331d9 100644
--- a/chrome/browser/ui/webui/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview_ui.cc
@@ -202,7 +202,7 @@ void PrintPreviewUI::OnDidGetPreviewPageCount(
}
void PrintPreviewUI::OnDidGetDefaultPageLayout(
- const PageSizeMargins& page_layout) {
+ const PageSizeMargins& page_layout, bool has_custom_page_size_style) {
if (page_layout.margin_top < 0 || page_layout.margin_left < 0 ||
page_layout.margin_bottom < 0 || page_layout.margin_right < 0 ||
page_layout.content_width < 0 || page_layout.content_height < 0) {
@@ -218,7 +218,9 @@ void PrintPreviewUI::OnDidGetDefaultPageLayout(
layout.SetDouble(printing::kSettingContentWidth, page_layout.content_width);
layout.SetDouble(printing::kSettingContentHeight, page_layout.content_height);
- CallJavascriptFunction("onDidGetDefaultPageLayout", layout);
+ base::FundamentalValue has_page_size_style(has_custom_page_size_style);
+ CallJavascriptFunction("onDidGetDefaultPageLayout", layout,
+ has_page_size_style);
}
void PrintPreviewUI::OnDidPreviewPage(int page_number,
diff --git a/chrome/browser/ui/webui/print_preview_ui.h b/chrome/browser/ui/webui/print_preview_ui.h
index 39ec422..53130d6 100644
--- a/chrome/browser/ui/webui/print_preview_ui.h
+++ b/chrome/browser/ui/webui/print_preview_ui.h
@@ -79,7 +79,8 @@ class PrintPreviewUI : public ConstrainedHtmlUI {
// Notifies the Web UI of the default page layout according to the currently
// selected printer and page size.
void OnDidGetDefaultPageLayout(
- const printing::PageSizeMargins& page_layout);
+ const printing::PageSizeMargins& page_layout,
+ bool has_custom_page_size_style);
// Notifies the Web UI that the 0-based page |page_number| has been rendered.
// |preview_request_id| indicates wich request resulted in this response.
diff --git a/chrome/common/print_messages.cc b/chrome/common/print_messages.cc
index 8ec7074..a0656e4 100644
--- a/chrome/common/print_messages.cc
+++ b/chrome/common/print_messages.cc
@@ -11,6 +11,7 @@
PrintMsg_Print_Params::PrintMsg_Print_Params()
: page_size(),
content_size(),
+ printable_area(),
margin_top(0),
margin_left(0),
dpi(0),
@@ -23,6 +24,7 @@ PrintMsg_Print_Params::PrintMsg_Print_Params()
preview_ui_addr(),
preview_request_id(0),
is_first_request(false),
+ print_to_pdf(false),
display_header_footer(false),
date(),
title(),
@@ -34,6 +36,7 @@ PrintMsg_Print_Params::~PrintMsg_Print_Params() {}
void PrintMsg_Print_Params::Reset() {
page_size = gfx::Size();
content_size = gfx::Size();
+ printable_area = gfx::Rect();
margin_top = 0;
margin_left = 0;
dpi = 0;
@@ -46,6 +49,7 @@ void PrintMsg_Print_Params::Reset() {
preview_ui_addr = std::string();
preview_request_id = 0;
is_first_request = false;
+ print_to_pdf = false;
display_header_footer = false;
date = string16();
title = string16();
diff --git a/chrome/common/print_messages.h b/chrome/common/print_messages.h
index fef3034..c97ead0 100644
--- a/chrome/common/print_messages.h
+++ b/chrome/common/print_messages.h
@@ -28,6 +28,7 @@ struct PrintMsg_Print_Params {
gfx::Size page_size;
gfx::Size content_size;
+ gfx::Rect printable_area;
int margin_top;
int margin_left;
double dpi;
@@ -40,6 +41,7 @@ struct PrintMsg_Print_Params {
std::string preview_ui_addr;
int preview_request_id;
bool is_first_request;
+ bool print_to_pdf;
bool display_header_footer;
string16 date;
string16 title;
@@ -72,6 +74,9 @@ IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params)
// In pixels according to dpi_x and dpi_y.
IPC_STRUCT_TRAITS_MEMBER(content_size)
+ // Physical printable area of the page in pixels according to dpi.
+ IPC_STRUCT_TRAITS_MEMBER(printable_area)
+
// The y-offset of the printable area, in pixels according to dpi.
IPC_STRUCT_TRAITS_MEMBER(margin_top)
@@ -110,6 +115,9 @@ IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params)
// True if this is the first preview request.
IPC_STRUCT_TRAITS_MEMBER(is_first_request)
+ // True if print to pdf is requested.
+ IPC_STRUCT_TRAITS_MEMBER(print_to_pdf)
+
// Specifies if the header and footer should be rendered.
IPC_STRUCT_TRAITS_MEMBER(display_header_footer)
@@ -351,8 +359,11 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetPreviewPageCount,
// Notify the browser of the default page layout according to the currently
// selected printer and page size.
-IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetDefaultPageLayout,
- printing::PageSizeMargins /* page layout in points */)
+// |has_custom_page_size_style| is true when the printing frame has a custom
+// page size css otherwise false.
+IPC_MESSAGE_ROUTED2(PrintHostMsg_DidGetDefaultPageLayout,
+ printing::PageSizeMargins /* page layout in points */,
+ bool /* has custom page size style */)
// Notify the browser a print preview page has been rendered.
IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPreviewPage,
diff --git a/chrome/renderer/chrome_mock_render_thread.cc b/chrome/renderer/chrome_mock_render_thread.cc
index 027998d..d3abcab 100644
--- a/chrome/renderer/chrome_mock_render_thread.cc
+++ b/chrome/renderer/chrome_mock_render_thread.cc
@@ -145,6 +145,7 @@ void ChromeMockRenderThread::OnUpdatePrintSettings(
// Check and make sure the required settings are all there.
// We don't actually care about the values.
std::string dummy_string;
+ int margins_type = 0;
if (!job_settings.GetBoolean(printing::kSettingLandscape, NULL) ||
!job_settings.GetBoolean(printing::kSettingCollate, NULL) ||
!job_settings.GetInteger(printing::kSettingColor, NULL) ||
@@ -154,7 +155,8 @@ void ChromeMockRenderThread::OnUpdatePrintSettings(
!job_settings.GetInteger(printing::kSettingDuplexMode, NULL) ||
!job_settings.GetInteger(printing::kSettingCopies, NULL) ||
!job_settings.GetString(printing::kPreviewUIAddr, &dummy_string) ||
- !job_settings.GetInteger(printing::kPreviewRequestID, NULL)) {
+ !job_settings.GetInteger(printing::kPreviewRequestID, NULL) ||
+ !job_settings.GetInteger(printing::kSettingMarginsType, &margins_type)) {
return;
}
@@ -180,7 +182,7 @@ void ChromeMockRenderThread::OnUpdatePrintSettings(
}
}
std::vector<int> pages(printing::PageRange::GetPages(new_ranges));
- printer_->UpdateSettings(document_cookie, params, pages);
+ printer_->UpdateSettings(document_cookie, params, pages, margins_type);
}
}
diff --git a/chrome/renderer/mock_printer.cc b/chrome/renderer/mock_printer.cc
index 28708df..8546d61 100644
--- a/chrome/renderer/mock_printer.cc
+++ b/chrome/renderer/mock_printer.cc
@@ -15,6 +15,29 @@
#include "printing/units.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace {
+
+void UpdateMargins(int margins_type, int dpi, PrintMsg_Print_Params* params) {
+ if (margins_type == printing::NO_MARGINS) {
+ params->content_size.SetSize(static_cast<int>((8.5 * dpi)),
+ static_cast<int>((11.0 * dpi)));
+ params->margin_left = 0;
+ params->margin_top = 0;
+ } else if (margins_type == printing::PRINTABLE_AREA_MARGINS) {
+ params->content_size.SetSize(static_cast<int>((8.0 * dpi)),
+ static_cast<int>((10.5 * dpi)));
+ params->margin_left = static_cast<int>(0.25 * dpi);
+ params->margin_top = static_cast<int>(0.25 * dpi);
+ } else if (margins_type == printing::CUSTOM_MARGINS) {
+ params->content_size.SetSize(static_cast<int>((7.9 * dpi)),
+ static_cast<int>((10.4 * dpi)));
+ params->margin_left = static_cast<int>(0.30 * dpi);
+ params->margin_top = static_cast<int>(0.30 * dpi);
+ }
+}
+
+} // end
+
MockPrinterPage::MockPrinterPage(const void* source_data,
uint32 source_size,
const printing::Image& image)
@@ -40,6 +63,7 @@ MockPrinter::MockPrinter()
number_pages_(0),
page_number_(0),
is_first_request_(true),
+ print_to_pdf_(false),
preview_request_id_(0),
display_header_footer_(false),
date_(ASCIIToUTF16("date")),
@@ -51,6 +75,10 @@ MockPrinter::MockPrinter()
content_size_.SetSize(static_cast<int>((7.5 * dpi_)),
static_cast<int>((10.0 * dpi_)));
margin_left_ = margin_top_ = static_cast<int>(0.5 * dpi_);
+ printable_area_.SetRect(static_cast<int>(0.25 * dpi_),
+ static_cast<int>(0.25 *dpi_),
+ static_cast<int>(8 * dpi_),
+ static_cast<int>(10.5 * dpi_));
}
MockPrinter::~MockPrinter() {
@@ -80,6 +108,7 @@ void MockPrinter::SetDefaultPrintSettings(const PrintMsg_Print_Params& params) {
selection_only_ = params.selection_only;
page_size_ = params.page_size;
content_size_ = params.content_size;
+ printable_area_ = params.printable_area;
margin_left_ = params.margin_left;
margin_top_ = params.margin_top;
display_header_footer_ = params.display_header_footer;
@@ -111,7 +140,9 @@ void MockPrinter::ScriptedPrint(int cookie,
settings->params.document_cookie = document_cookie_;
settings->params.page_size = page_size_;
settings->params.content_size = content_size_;
+ settings->params.printable_area = printable_area_;
settings->params.is_first_request = is_first_request_;
+ settings->params.print_to_pdf = print_to_pdf_;
settings->params.preview_request_id = preview_request_id_;
settings->params.display_header_footer = display_header_footer_;
settings->params.date = date_;
@@ -122,13 +153,15 @@ void MockPrinter::ScriptedPrint(int cookie,
void MockPrinter::UpdateSettings(int cookie,
PrintMsg_PrintPages_Params* params,
- const std::vector<int>& pages) {
+ const std::vector<int>& pages,
+ int margins_type) {
if (document_cookie_ == -1) {
document_cookie_ = CreateDocumentCookie();
}
params->Reset();
params->pages = pages;
SetPrintParams(&(params->params));
+ UpdateMargins(margins_type, dpi_, &(params->params));
printer_status_ = PRINTER_PRINTING;
}
@@ -258,9 +291,11 @@ void MockPrinter::SetPrintParams(PrintMsg_Print_Params* params) {
params->document_cookie = document_cookie_;
params->page_size = page_size_;
params->content_size = content_size_;
+ params->printable_area = printable_area_;
params->margin_left = margin_left_;
params->margin_top = margin_top_;
params->is_first_request = is_first_request_;
+ params->print_to_pdf = print_to_pdf_;
params->preview_request_id = preview_request_id_;
params->display_header_footer = display_header_footer_;
params->date = date_;
diff --git a/chrome/renderer/mock_printer.h b/chrome/renderer/mock_printer.h
index c73ac87..75e151f 100644
--- a/chrome/renderer/mock_printer.h
+++ b/chrome/renderer/mock_printer.h
@@ -14,6 +14,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "printing/image.h"
+#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
struct PrintMsg_Print_Params;
@@ -78,7 +79,8 @@ class MockPrinter {
bool has_selection,
PrintMsg_PrintPages_Params* settings);
void UpdateSettings(int cookie, PrintMsg_PrintPages_Params* params,
- const std::vector<int>& page_range_array);
+ const std::vector<int>& page_range_array,
+ int margins_type);
void SetPrintedPagesCount(int cookie, int number_pages);
void PrintPage(const PrintHostMsg_DidPrintPage_Params& params);
@@ -110,6 +112,7 @@ class MockPrinter {
gfx::Size content_size_;
int margin_left_;
int margin_top_;
+ gfx::Rect printable_area_;
// Specifies dots per inch.
double dpi_;
@@ -135,6 +138,7 @@ class MockPrinter {
// Used only in the preview sequence.
bool is_first_request_;
+ bool print_to_pdf_;
int preview_request_id_;
// Used for displaying headers and footers.
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc
index 499b1fd..be0e3b2 100644
--- a/chrome/renderer/print_web_view_helper.cc
+++ b/chrome/renderer/print_web_view_helper.cc
@@ -109,6 +109,7 @@ bool PrintMsg_Print_Params_IsEmpty(const PrintMsg_Print_Params& params) {
bool PageLayoutIsEqual(const PrintMsg_PrintPages_Params& oldParams,
const PrintMsg_PrintPages_Params& newParams) {
return oldParams.params.content_size == newParams.params.content_size &&
+ oldParams.params.printable_area == newParams.params.printable_area &&
oldParams.params.page_size == newParams.params.page_size &&
oldParams.params.margin_top == newParams.params.margin_top &&
oldParams.params.margin_left == newParams.params.margin_left &&
@@ -126,6 +127,7 @@ bool PrintMsg_Print_Params_IsEqual(
oldParams.params.supports_alpha_blend ==
newParams.params.supports_alpha_blend &&
oldParams.pages.size() == newParams.pages.size() &&
+ oldParams.params.print_to_pdf == newParams.params.print_to_pdf &&
oldParams.params.display_header_footer ==
newParams.params.display_header_footer &&
oldParams.params.date == newParams.params.date &&
@@ -135,6 +137,140 @@ bool PrintMsg_Print_Params_IsEqual(
newParams.pages.begin());
}
+PrintMsg_Print_Params GetCssPrintParams(
+ WebFrame* frame,
+ int page_index,
+ const PrintMsg_Print_Params& page_params) {
+ PrintMsg_Print_Params page_css_params = page_params;
+ int dpi = GetDPI(&page_params);
+ WebSize page_size_in_pixels(
+ ConvertUnit(page_params.page_size.width(),
+ dpi, printing::kPixelsPerInch),
+ ConvertUnit(page_params.page_size.height(),
+ dpi, printing::kPixelsPerInch));
+ int margin_top_in_pixels = ConvertUnit(
+ page_params.margin_top,
+ dpi, printing::kPixelsPerInch);
+ int margin_right_in_pixels = ConvertUnit(
+ page_params.page_size.width() -
+ page_params.content_size.width() - page_params.margin_left,
+ dpi, printing::kPixelsPerInch);
+ int margin_bottom_in_pixels = ConvertUnit(
+ page_params.page_size.height() -
+ page_params.content_size.height() - page_params.margin_top,
+ dpi, printing::kPixelsPerInch);
+ int margin_left_in_pixels = ConvertUnit(
+ page_params.margin_left,
+ dpi, printing::kPixelsPerInch);
+
+ if (frame) {
+ frame->pageSizeAndMarginsInPixels(page_index,
+ page_size_in_pixels,
+ margin_top_in_pixels,
+ margin_right_in_pixels,
+ margin_bottom_in_pixels,
+ margin_left_in_pixels);
+ }
+
+ int new_content_width = page_size_in_pixels.width -
+ margin_left_in_pixels - margin_right_in_pixels;
+ int new_content_height = page_size_in_pixels.height -
+ margin_top_in_pixels - margin_bottom_in_pixels;
+
+ // Invalid page size and/or margins. We just use the default setting.
+ if (new_content_width < 1 || new_content_height < 1) {
+ CHECK(frame != NULL);
+ page_css_params = GetCssPrintParams(NULL, page_index, page_params);
+ return page_css_params;
+ }
+
+ page_css_params.content_size = gfx::Size(
+ static_cast<int>(ConvertUnit(new_content_width,
+ printing::kPixelsPerInch, dpi)),
+ static_cast<int>(ConvertUnit(new_content_height,
+ printing::kPixelsPerInch, dpi)));
+
+ page_css_params.page_size = gfx::Size(
+ static_cast<int>(ConvertUnit(page_size_in_pixels.width,
+ printing::kPixelsPerInch, dpi)),
+ static_cast<int>(ConvertUnit(page_size_in_pixels.height,
+ printing::kPixelsPerInch, dpi)));
+
+ page_css_params.margin_top =
+ static_cast<int>(ConvertUnit(margin_top_in_pixels,
+ printing::kPixelsPerInch, dpi));
+
+ page_css_params.margin_left =
+ static_cast<int>(ConvertUnit(margin_left_in_pixels,
+ printing::kPixelsPerInch, dpi));
+ return page_css_params;
+}
+
+double FitPrintParamsToPage(const PrintMsg_Print_Params& page_params,
+ PrintMsg_Print_Params* params_to_fit) {
+ double content_width =
+ static_cast<double>(params_to_fit->content_size.width());
+ double content_height =
+ static_cast<double>(params_to_fit->content_size.height());
+ int default_page_size_height = page_params.page_size.height();
+ int default_page_size_width = page_params.page_size.width();
+ int css_page_size_height = params_to_fit->page_size.height();
+ int css_page_size_width = params_to_fit->page_size.width();
+
+ double scale_factor = 1.0f;
+ if (page_params.page_size == params_to_fit->page_size)
+ return scale_factor;
+
+ if (default_page_size_width < css_page_size_width ||
+ default_page_size_height < css_page_size_height) {
+ double ratio_width =
+ static_cast<double>(page_params.printable_area.width()) /
+ css_page_size_width;
+ double ratio_height =
+ static_cast<double>(page_params.printable_area.height()) /
+ css_page_size_height;
+ scale_factor = ratio_width < ratio_height ? ratio_width : ratio_height;
+ content_width *= scale_factor;
+ content_height *= scale_factor;
+ }
+ params_to_fit->margin_top = static_cast<int>(
+ (default_page_size_height - css_page_size_height * scale_factor) / 2 +
+ (params_to_fit->margin_top * scale_factor));
+ params_to_fit->margin_left = static_cast<int>(
+ (default_page_size_width - css_page_size_width * scale_factor) / 2 +
+ (params_to_fit->margin_left * scale_factor));
+ params_to_fit->content_size = gfx::Size(
+ static_cast<int>(content_width), static_cast<int>(content_height));
+ params_to_fit->page_size = page_params.page_size;
+ return scale_factor;
+}
+
+void CalculatePageLayoutFromPrintParams(
+ const PrintMsg_Print_Params& params,
+ PageSizeMargins* page_layout_in_points) {
+ int dpi = GetDPI(&params);
+ int content_width = params.content_size.width();
+ int content_height = params.content_size.height();
+
+ int margin_bottom = params.page_size.height() -
+ content_height - params.margin_top;
+ int margin_right = params.page_size.width() -
+ content_width - params.margin_left;
+
+ page_layout_in_points->content_width = ConvertUnit(
+ content_width, dpi, printing::kPointsPerInch);
+ page_layout_in_points->content_height = ConvertUnit(
+ content_height, dpi, printing::kPointsPerInch);
+ page_layout_in_points->margin_top = ConvertUnit(
+ params.margin_top, dpi, printing::kPointsPerInch);
+ page_layout_in_points->margin_right = ConvertUnit(
+ margin_right, dpi, printing::kPointsPerInch);
+ page_layout_in_points->margin_bottom = ConvertUnit(
+ margin_bottom, dpi, printing::kPointsPerInch);
+ page_layout_in_points->margin_left = ConvertUnit(
+ params.margin_left, dpi, printing::kPointsPerInch);
+}
+
void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params,
gfx::Size* result) {
int dpi = GetDPI(&print_params);
@@ -152,6 +288,19 @@ bool PrintingNodeOrPdfFrame(const WebFrame* frame, const WebNode& node) {
return mime == "application/pdf";
}
+bool PrintingFrameHasPageSizeStyle(WebFrame* frame, int total_page_count) {
+ if (!frame)
+ return false;
+ bool frame_has_custom_page_size_style = false;
+ for (int i = 0; i < total_page_count; ++i) {
+ if (frame->hasCustomPageSizeStyle(i)) {
+ frame_has_custom_page_size_style = true;
+ break;
+ }
+ }
+ return frame_has_custom_page_size_style;
+}
+
printing::MarginType GetMarginsForPdf(WebFrame* frame, const WebNode& node) {
if (frame->isPrintScalingDisabledForPlugin(node))
return printing::NO_MARGINS;
@@ -253,6 +402,43 @@ void PrintHeaderFooterText(
#endif
}
+PrintMsg_Print_Params CalculatePrintParamsForCss(
+ WebFrame* frame,
+ int page_index,
+ const PrintMsg_Print_Params& page_params,
+ bool ignore_css_margins,
+ bool fit_to_page,
+ double* scale_factor) {
+ if (ignore_css_margins && fit_to_page)
+ return page_params;
+
+ PrintMsg_Print_Params params = GetCssPrintParams(frame, page_index,
+ page_params);
+
+ if (ignore_css_margins) {
+ params.margin_top = page_params.margin_top;
+ params.margin_left = page_params.margin_left;
+
+ DCHECK(!fit_to_page);
+ // Since we are ignoring the margins, the css page size is no longer
+ // valid.
+ int default_margin_right = page_params.page_size.width() -
+ page_params.content_size.width() - page_params.margin_left;
+ int default_margin_bottom = page_params.page_size.height() -
+ page_params.content_size.height() - page_params.margin_top;
+ params.content_size = gfx::Size(
+ params.page_size.width() - params.margin_left - default_margin_right,
+ params.page_size.height() - params.margin_top - default_margin_bottom);
+ }
+
+ if (fit_to_page) {
+ double factor = FitPrintParamsToPage(page_params, &params);
+ if (scale_factor)
+ *scale_factor = factor;
+ }
+ return params;
+}
+
} // namespace
// static - Not anonymous so that platform implementations can use it.
@@ -440,6 +626,8 @@ PrintWebViewHelper::PrintWebViewHelper(content::RenderView* render_view)
print_web_view_(NULL),
is_preview_enabled_(switches::IsPrintPreviewEnabled()),
is_print_ready_metafile_sent_(false),
+ ignore_css_margins_(false),
+ fit_to_page_(true),
user_cancelled_scripted_print_count_(0),
notify_browser_of_print_failure_(true) {
}
@@ -560,6 +748,39 @@ void PrintWebViewHelper::OnPrintForSystemDialog() {
Print(frame, print_preview_context_.node());
}
+void PrintWebViewHelper::GetPageSizeAndContentAreaFromPageLayout(
+ const printing::PageSizeMargins& page_layout_in_points,
+ gfx::Size* page_size,
+ gfx::Rect* content_area) {
+ *page_size = gfx::Size(
+ page_layout_in_points.content_width +
+ page_layout_in_points.margin_right +
+ page_layout_in_points.margin_left,
+ page_layout_in_points.content_height +
+ page_layout_in_points.margin_top +
+ page_layout_in_points.margin_bottom);
+ *content_area = gfx::Rect(page_layout_in_points.margin_left,
+ page_layout_in_points.margin_top,
+ page_layout_in_points.content_width,
+ page_layout_in_points.content_height);
+}
+
+void PrintWebViewHelper::UpdateFrameMarginsCssInfo(
+ const DictionaryValue& settings) {
+ int margins_type = 0;
+ if (!settings.GetInteger(printing::kSettingMarginsType, &margins_type))
+ margins_type = printing::DEFAULT_MARGINS;
+ ignore_css_margins_ = margins_type != printing::DEFAULT_MARGINS;
+}
+
+bool PrintWebViewHelper::IsPrintToPdfRequested(
+ const DictionaryValue& job_settings) {
+ bool print_to_pdf = false;
+ if (!job_settings.GetBoolean(printing::kSettingPrintToPDF, &print_to_pdf))
+ NOTREACHED();
+ return print_to_pdf;
+}
+
void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) {
DCHECK(is_preview_enabled_);
print_preview_context_.OnPrintPreview();
@@ -620,8 +841,27 @@ void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) {
bool PrintWebViewHelper::CreatePreviewDocument() {
PrintMsg_Print_Params print_params = print_pages_params_->params;
const std::vector<int>& pages = print_pages_params_->pages;
- if (!print_preview_context_.CreatePreviewDocument(&print_params, pages))
+ if (!print_preview_context_.CreatePreviewDocument(&print_params, pages,
+ ignore_css_margins_,
+ fit_to_page_)) {
return false;
+ }
+
+ PageSizeMargins default_page_layout;
+ ComputePageLayoutInPointsForCss(print_preview_context_.frame(), 0,
+ print_params, ignore_css_margins_,
+ fit_to_page_, NULL, &default_page_layout);
+ if (!old_print_pages_params_.get() ||
+ !PageLayoutIsEqual(*old_print_pages_params_, *print_pages_params_)) {
+ bool has_page_size_style = PrintingFrameHasPageSizeStyle(
+ print_preview_context_.frame(),
+ print_preview_context_.total_page_count());
+ // Margins: Send default page layout to browser process.
+ Send(new PrintHostMsg_DidGetDefaultPageLayout(routing_id(),
+ default_page_layout,
+ has_page_size_style));
+ }
+
PrintHostMsg_DidGetPreviewPageCount_Params params;
params.page_count = print_preview_context_.total_page_count();
params.is_modifiable = print_preview_context_.IsModifiable();
@@ -841,8 +1081,9 @@ bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params,
const WebNode& node) {
PrintMsg_Print_Params print_params = params.params;
PrepareFrameAndViewForPrint prep_frame_view(print_params, frame, node);
- UpdatePrintableSizeInPrintParameters(frame, node, &prep_frame_view,
- &print_params);
+ UpdateFrameAndViewFromCssPageLayout(frame, node, &prep_frame_view,
+ print_params, ignore_css_margins_,
+ fit_to_page_);
int page_count = prep_frame_view.GetExpectedPageCount();
if (!page_count)
@@ -878,111 +1119,36 @@ void PrintWebViewHelper::didStopLoading() {
}
// static - Not anonymous so that platform implementations can use it.
-void PrintWebViewHelper::GetPageSizeAndMarginsInPoints(
+void PrintWebViewHelper::ComputePageLayoutInPointsForCss(
WebFrame* frame,
int page_index,
- const PrintMsg_Print_Params& default_params,
+ const PrintMsg_Print_Params& page_params,
+ bool ignore_css_margins,
+ bool fit_to_page,
+ double* scale_factor,
PageSizeMargins* page_layout_in_points) {
- int dpi = GetDPI(&default_params);
-
- WebSize page_size_in_pixels(
- ConvertUnit(default_params.page_size.width(),
- dpi, printing::kPixelsPerInch),
- ConvertUnit(default_params.page_size.height(),
- dpi, printing::kPixelsPerInch));
- int margin_top_in_pixels = ConvertUnit(
- default_params.margin_top,
- dpi, printing::kPixelsPerInch);
- int margin_right_in_pixels = ConvertUnit(
- default_params.page_size.width() -
- default_params.content_size.width() - default_params.margin_left,
- dpi, printing::kPixelsPerInch);
- int margin_bottom_in_pixels = ConvertUnit(
- default_params.page_size.height() -
- default_params.content_size.height() - default_params.margin_top,
- dpi, printing::kPixelsPerInch);
- int margin_left_in_pixels = ConvertUnit(
- default_params.margin_left,
- dpi, printing::kPixelsPerInch);
-
- if (frame) {
- frame->pageSizeAndMarginsInPixels(page_index,
- page_size_in_pixels,
- margin_top_in_pixels,
- margin_right_in_pixels,
- margin_bottom_in_pixels,
- margin_left_in_pixels);
- }
-
- page_layout_in_points->content_width =
- ConvertPixelsToPoint(page_size_in_pixels.width -
- margin_left_in_pixels -
- margin_right_in_pixels);
- page_layout_in_points->content_height =
- ConvertPixelsToPoint(page_size_in_pixels.height -
- margin_top_in_pixels -
- margin_bottom_in_pixels);
-
- // Invalid page size and/or margins. We just use the default setting.
- if (page_layout_in_points->content_width < 1.0 ||
- page_layout_in_points->content_height < 1.0) {
- CHECK(frame != NULL);
- GetPageSizeAndMarginsInPoints(NULL, page_index, default_params,
- page_layout_in_points);
- return;
- }
-
- page_layout_in_points->margin_top =
- ConvertPixelsToPointDouble(margin_top_in_pixels);
- page_layout_in_points->margin_right =
- ConvertPixelsToPointDouble(margin_right_in_pixels);
- page_layout_in_points->margin_bottom =
- ConvertPixelsToPointDouble(margin_bottom_in_pixels);
- page_layout_in_points->margin_left =
- ConvertPixelsToPointDouble(margin_left_in_pixels);
+ PrintMsg_Print_Params params = CalculatePrintParamsForCss(frame, page_index,
+ page_params,
+ ignore_css_margins,
+ fit_to_page,
+ scale_factor);
+ CalculatePageLayoutFromPrintParams(params, page_layout_in_points);
}
// static - Not anonymous so that platform implementations can use it.
-void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
+void PrintWebViewHelper::UpdateFrameAndViewFromCssPageLayout(
WebFrame* frame,
const WebNode& node,
PrepareFrameAndViewForPrint* prepare,
- PrintMsg_Print_Params* params) {
+ const PrintMsg_Print_Params& params,
+ bool ignore_css_margins,
+ bool fit_to_page) {
if (PrintingNodeOrPdfFrame(frame, node))
return;
- PageSizeMargins page_layout_in_points;
- PrintWebViewHelper::GetPageSizeAndMarginsInPoints(frame, 0, *params,
- &page_layout_in_points);
- int dpi = GetDPI(params);
- params->content_size = gfx::Size(
- static_cast<int>(ConvertUnitDouble(
- page_layout_in_points.content_width,
- printing::kPointsPerInch, dpi)),
- static_cast<int>(ConvertUnitDouble(
- page_layout_in_points.content_height,
- printing::kPointsPerInch, dpi)));
-
- double page_width_in_points =
- page_layout_in_points.content_width +
- page_layout_in_points.margin_left +
- page_layout_in_points.margin_right;
- double page_height_in_points =
- page_layout_in_points.content_height +
- page_layout_in_points.margin_top +
- page_layout_in_points.margin_bottom;
-
- params->page_size = gfx::Size(
- static_cast<int>(ConvertUnitDouble(
- page_width_in_points, printing::kPointsPerInch, dpi)),
- static_cast<int>(ConvertUnitDouble(
- page_height_in_points, printing::kPointsPerInch, dpi)));
-
- params->margin_top = static_cast<int>(ConvertUnitDouble(
- page_layout_in_points.margin_top, printing::kPointsPerInch, dpi));
- params->margin_left = static_cast<int>(ConvertUnitDouble(
- page_layout_in_points.margin_left, printing::kPointsPerInch, dpi));
-
- prepare->UpdatePrintParams(*params);
+ PrintMsg_Print_Params print_params = CalculatePrintParamsForCss(
+ frame, 0, params, ignore_css_margins, ignore_css_margins && fit_to_page,
+ NULL);
+ prepare->UpdatePrintParams(print_params);
}
bool PrintWebViewHelper::InitPrintSettings(WebKit::WebFrame* frame,
@@ -990,6 +1156,10 @@ bool PrintWebViewHelper::InitPrintSettings(WebKit::WebFrame* frame,
DCHECK(frame);
PrintMsg_PrintPages_Params settings;
+ // Reset to default values.
+ ignore_css_margins_ = false;
+ fit_to_page_ = true;
+
Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(),
&settings.params));
// Check if the printer returned any settings, if the settings is empty, we
@@ -1025,8 +1195,9 @@ bool PrintWebViewHelper::InitPrintSettingsAndPrepareFrame(
DCHECK(!prepare->get());
prepare->reset(new PrepareFrameAndViewForPrint(print_pages_params_->params,
frame, node));
- UpdatePrintableSizeInPrintParameters(frame, node, prepare->get(),
- &print_pages_params_->params);
+ UpdateFrameAndViewFromCssPageLayout(frame, node, prepare->get(),
+ print_pages_params_->params,
+ ignore_css_margins_, fit_to_page_);
Send(new PrintHostMsg_DidGetDocumentCookie(
routing_id(), print_pages_params_->params.document_cookie));
return true;
@@ -1127,15 +1298,9 @@ bool PrintWebViewHelper::UpdatePrintSettings(
return false;
}
- // Margins: Send default page layout to browser process.
- PageSizeMargins default_page_layout;
- GetPageSizeAndMarginsInPoints(NULL, -1, settings.params,
- &default_page_layout);
- if (!old_print_pages_params_.get() ||
- !PageLayoutIsEqual(*old_print_pages_params_, settings)) {
- Send(new PrintHostMsg_DidGetDefaultPageLayout(routing_id(),
- default_page_layout));
- }
+ settings.params.print_to_pdf = IsPrintToPdfRequested(*job_settings);
+ UpdateFrameMarginsCssInfo(*job_settings);
+ fit_to_page_ = source_is_html && !IsPrintToPdfRequested(*job_settings);
// Header/Footer: Set |header_footer_info_|.
if (settings.params.display_header_footer) {
@@ -1373,7 +1538,9 @@ void PrintWebViewHelper::PrintPreviewContext::OnPrintPreview() {
bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument(
PrintMsg_Print_Params* print_params,
- const std::vector<int>& pages) {
+ const std::vector<int>& pages,
+ bool ignore_css_margins,
+ bool fit_to_page) {
DCHECK_EQ(INITIALIZED, state_);
state_ = RENDERING;
@@ -1387,8 +1554,9 @@ bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument(
// Need to make sure old object gets destroyed first.
prep_frame_view_.reset(new PrepareFrameAndViewForPrint(*print_params, frame(),
node()));
- UpdatePrintableSizeInPrintParameters(frame_, node_,
- prep_frame_view_.get(), print_params);
+ UpdateFrameAndViewFromCssPageLayout(frame_, node_, prep_frame_view_.get(),
+ *print_params, ignore_css_margins,
+ fit_to_page);
print_params_.reset(new PrintMsg_Print_Params(*print_params));
diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h
index 24de40e..984a52c 100644
--- a/chrome/renderer/print_web_view_helper.h
+++ b/chrome/renderer/print_web_view_helper.h
@@ -117,6 +117,19 @@ class PrintWebViewHelper
// Print the document with the print preview frame/node.
void OnPrintForSystemDialog();
+ // Get |page_size| and |content_area| information from
+ // |page_layout_in_points|.
+ void GetPageSizeAndContentAreaFromPageLayout(
+ const printing::PageSizeMargins& page_layout_in_points,
+ gfx::Size* page_size,
+ gfx::Rect* content_area);
+
+ // Update |ignore_css_margins_| based on settings.
+ void UpdateFrameMarginsCssInfo(const base::DictionaryValue& settings);
+
+ // Returns true if the current destination printer is PRINT_TO_PDF.
+ bool IsPrintToPdfRequested(const base::DictionaryValue& settings);
+
// Initiate print preview.
void OnInitiatePrintPreview();
@@ -216,14 +229,18 @@ class PrintWebViewHelper
// |metafile| or a new one. In either case, the caller owns both |metafile|
// and the result.
printing::Metafile* RenderPage(const PrintMsg_Print_Params& params,
- float* scale_factor, int page_number,
- bool is_preview, WebKit::WebFrame* frame,
- printing::Metafile* metafile);
+ int page_number,
+ WebKit::WebFrame* frame,
+ bool is_preview,
+ printing::Metafile* metafile,
+ double* scale_factor,
+ gfx::Size* page_size_in_dpi,
+ gfx::Rect* content_area_in_dpi);
#elif defined(OS_MACOSX)
- void RenderPage(const gfx::Size& page_size, const gfx::Rect& content_area,
- const float& scale_factor, int page_number,
+ void RenderPage(const PrintMsg_Print_Params& params, int page_number,
WebKit::WebFrame* frame, bool is_preview,
- printing::Metafile* metafile);
+ printing::Metafile* metafile, gfx::Size* page_size,
+ gfx::Rect* content_rect);
#elif defined(OS_POSIX)
bool RenderPages(const PrintMsg_PrintPages_Params& params,
WebKit::WebFrame* frame, const WebKit::WebNode& node,
@@ -238,17 +255,25 @@ class PrintWebViewHelper
bool CopyMetafileDataToSharedMem(printing::Metafile* metafile,
base::SharedMemoryHandle* shared_mem_handle);
- static void GetPageSizeAndMarginsInPoints(
+ // Helper method to get page layout in points and fit to page if needed.
+ static void ComputePageLayoutInPointsForCss(
WebKit::WebFrame* frame,
int page_index,
const PrintMsg_Print_Params& default_params,
+ bool ignore_css_margins,
+ bool fit_to_page,
+ double* scale_factor,
printing::PageSizeMargins* page_layout_in_points);
- static void UpdatePrintableSizeInPrintParameters(
+ // Prepare the frame and view for print and then call this function to honor
+ // the CSS page layout information.
+ static void UpdateFrameAndViewFromCssPageLayout(
WebKit::WebFrame* frame,
const WebKit::WebNode& node,
PrepareFrameAndViewForPrint* prepare,
- PrintMsg_Print_Params* params);
+ const PrintMsg_Print_Params& params,
+ bool ignore_css_margins,
+ bool fit_to_page);
// Given the |device| and |canvas| to draw on, prints the appropriate headers
// and footers using strings from |header_footer_info| on to the canvas.
@@ -299,6 +324,11 @@ class PrintWebViewHelper
scoped_ptr<PrintMsg_PrintPages_Params> print_pages_params_;
bool is_preview_enabled_;
bool is_print_ready_metafile_sent_;
+ bool ignore_css_margins_;
+
+ // True if we need to auto fit to page else false.
+ // NOTE: When we print to pdf, we don't fit to page.
+ bool fit_to_page_;
// Used for scripted initiated printing blocking.
base::Time last_cancelled_script_print_;
@@ -343,7 +373,9 @@ class PrintWebViewHelper
// Create the print preview document. |pages| is empty to print all pages.
bool CreatePreviewDocument(PrintMsg_Print_Params* params,
- const std::vector<int>& pages);
+ const std::vector<int>& pages,
+ bool ignore_css_margins,
+ bool fit_to_page);
// Called after a page gets rendered. |page_time| is how long the
// rendering took.
diff --git a/chrome/renderer/print_web_view_helper_browsertest.cc b/chrome/renderer/print_web_view_helper_browsertest.cc
index 2b72538..5d4610c 100644
--- a/chrome/renderer/print_web_view_helper_browsertest.cc
+++ b/chrome/renderer/print_web_view_helper_browsertest.cc
@@ -26,6 +26,18 @@ namespace {
// A simple web page.
const char kHelloWorldHTML[] = "<body><p>Hello World!</p></body>";
+// A simple web page with print page size css.
+const char kHTMLWithPageSizeCss[] =
+ "<html><head><style>"
+ "@media print {"
+ " @page {"
+ " size: 4in 4in;"
+ " }"
+ "}"
+ "</style></head>"
+ "<body>Lorem Ipsum:"
+ "</body></html>";
+
// A simple webpage that prints itself.
const char kPrintWithJSHTML[] =
"<body>Hello<script>window.print()</script>World</body>";
@@ -242,7 +254,7 @@ const TestPageData kTestPages[] = {
#if defined(OS_MACOSX)
// Mac printing code compensates for the WebKit scale factor while generating
// the metafile, so we expect smaller pages.
- 1, 540, 720,
+ 1, 600, 780,
#else
1, 675, 900,
#endif
@@ -389,6 +401,28 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
ASSERT_EQ(generate_draft_pages, msg_found);
}
+ void VerifyDefaultPageLayout(int content_width, int content_height,
+ int margin_top, int margin_bottom,
+ int margin_left, int margin_right,
+ bool page_has_print_css) {
+ const IPC::Message* default_page_layout_msg =
+ render_thread_->sink().GetUniqueMessageMatching(
+ PrintHostMsg_DidGetDefaultPageLayout::ID);
+ bool did_get_default_page_layout_msg = (NULL != default_page_layout_msg);
+ if (did_get_default_page_layout_msg) {
+ PrintHostMsg_DidGetDefaultPageLayout::Param param;
+ PrintHostMsg_DidGetDefaultPageLayout::Read(default_page_layout_msg,
+ &param);
+ EXPECT_EQ(content_width, param.a.content_width);
+ EXPECT_EQ(content_height, param.a.content_height);
+ EXPECT_EQ(margin_top, param.a.margin_top);
+ EXPECT_EQ(margin_right, param.a.margin_right);
+ EXPECT_EQ(margin_left, param.a.margin_left);
+ EXPECT_EQ(margin_bottom, param.a.margin_bottom);
+ EXPECT_EQ(page_has_print_css, param.b);
+ }
+ }
+
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperPreviewTest);
};
@@ -403,12 +437,163 @@ TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreview) {
OnPrintPreview(dict);
EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
+ VerifyDefaultPageLayout(540, 720, 36, 36, 36, 36, false);
+ VerifyPrintPreviewCancelled(false);
+ VerifyPrintPreviewFailed(false);
+ VerifyPrintPreviewGenerated(true);
+ VerifyPagesPrinted(false);
+}
+
+TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewHTMLWithPageMarginsCss) {
+ // A simple web page with print margins css.
+ const char kHTMLWithPageMarginsCss[] =
+ "<html><head><style>"
+ "@media print {"
+ " @page {"
+ " margin: 3in 1in 2in 0.3in;"
+ " }"
+ "}"
+ "</style></head>"
+ "<body>Lorem Ipsum:"
+ "</body></html>";
+ LoadHTML(kHTMLWithPageMarginsCss);
+
+ // Fill in some dummy values.
+ DictionaryValue dict;
+ CreatePrintSettingsDictionary(&dict);
+ dict.SetBoolean(printing::kSettingPrintToPDF, false);
+ dict.SetInteger(printing::kSettingMarginsType, printing::DEFAULT_MARGINS);
+ OnPrintPreview(dict);
+
+ EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
+ VerifyDefaultPageLayout(519, 432, 216, 144, 21, 72, false);
+ VerifyPrintPreviewCancelled(false);
+ VerifyPrintPreviewFailed(false);
+ VerifyPrintPreviewGenerated(true);
+ VerifyPagesPrinted(false);
+}
+
+// Test to verify that print preview ignores print media css when non-default
+// margin is selected.
+TEST_F(PrintWebViewHelperPreviewTest, NonDefaultMarginsSelectedIgnorePrintCss) {
+ LoadHTML(kHTMLWithPageSizeCss);
+
+ // Fill in some dummy values.
+ DictionaryValue dict;
+ CreatePrintSettingsDictionary(&dict);
+ dict.SetBoolean(printing::kSettingPrintToPDF, false);
+ dict.SetInteger(printing::kSettingMarginsType, printing::NO_MARGINS);
+ OnPrintPreview(dict);
+
+ EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
+ VerifyDefaultPageLayout(612, 792, 0, 0, 0, 0, true);
VerifyPrintPreviewCancelled(false);
VerifyPrintPreviewFailed(false);
VerifyPrintPreviewGenerated(true);
VerifyPagesPrinted(false);
}
+// Test to verify that print preview honor print media size css when
+// PRINT_TO_PDF is selected and doesn't fit to printer default paper size.
+TEST_F(PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorPrintCss) {
+ LoadHTML(kHTMLWithPageSizeCss);
+
+ // Fill in some dummy values.
+ DictionaryValue dict;
+ CreatePrintSettingsDictionary(&dict);
+ dict.SetBoolean(printing::kSettingPrintToPDF, true);
+ dict.SetInteger(printing::kSettingMarginsType,
+ printing::PRINTABLE_AREA_MARGINS);
+ OnPrintPreview(dict);
+
+ EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
+ // Since PRINT_TO_PDF is selected, pdf page size is equal to print media page
+ // size.
+ VerifyDefaultPageLayout(252, 252, 18, 18, 18, 18, true);
+ VerifyPrintPreviewCancelled(false);
+ VerifyPrintPreviewFailed(false);
+}
+
+// Test to verify that print preview honor print margin css when PRINT_TO_PDF
+// is selected and doesn't fit to printer default paper size.
+TEST_F(PrintWebViewHelperPreviewTest, PrintToPDFSelectedHonorPageMarginsCss) {
+ // A simple web page with print margins css.
+ const char kHTMLWithPageCss[] =
+ "<html><head><style>"
+ "@media print {"
+ " @page {"
+ " margin: 3in 1in 2in 0.3in;"
+ " size: 14in 14in;"
+ " }"
+ "}"
+ "</style></head>"
+ "<body>Lorem Ipsum:"
+ "</body></html>";
+ LoadHTML(kHTMLWithPageCss);
+
+ // Fill in some dummy values.
+ DictionaryValue dict;
+ CreatePrintSettingsDictionary(&dict);
+ dict.SetBoolean(printing::kSettingPrintToPDF, true);
+ dict.SetInteger(printing::kSettingMarginsType, printing::DEFAULT_MARGINS);
+ OnPrintPreview(dict);
+
+ EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
+ // Since PRINT_TO_PDF is selected, pdf page size is equal to print media page
+ // size.
+ VerifyDefaultPageLayout(915, 648, 216, 144, 21, 72, true);
+ VerifyPrintPreviewCancelled(false);
+ VerifyPrintPreviewFailed(false);
+}
+
+// Test to verify that print preview workflow center the html page contents to
+// fit the page size.
+TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewCenterToFitPage) {
+ LoadHTML(kHTMLWithPageSizeCss);
+
+ // Fill in some dummy values.
+ DictionaryValue dict;
+ CreatePrintSettingsDictionary(&dict);
+ dict.SetBoolean(printing::kSettingPrintToPDF, false);
+ dict.SetInteger(printing::kSettingMarginsType, printing::DEFAULT_MARGINS);
+ OnPrintPreview(dict);
+
+ EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
+ VerifyDefaultPageLayout(288, 288, 252, 252, 162, 162, true);
+ VerifyPrintPreviewCancelled(false);
+ VerifyPrintPreviewFailed(false);
+ VerifyPrintPreviewGenerated(true);
+}
+
+// Test to verify that print preview workflow scale the html page contents to
+// fit the page size.
+TEST_F(PrintWebViewHelperPreviewTest, PrintPreviewShrinkToFitPage) {
+ // A simple web page with print margins css.
+ const char kHTMLWithPageCss[] =
+ "<html><head><style>"
+ "@media print {"
+ " @page {"
+ " size: 15in 17in;"
+ " }"
+ "}"
+ "</style></head>"
+ "<body>Lorem Ipsum:"
+ "</body></html>";
+ LoadHTML(kHTMLWithPageCss);
+
+ // Fill in some dummy values.
+ DictionaryValue dict;
+ CreatePrintSettingsDictionary(&dict);
+ dict.SetBoolean(printing::kSettingPrintToPDF, false);
+ dict.SetInteger(printing::kSettingMarginsType, printing::DEFAULT_MARGINS);
+ OnPrintPreview(dict);
+
+ EXPECT_EQ(0, chrome_render_thread_->print_preview_pages_remaining());
+ VerifyDefaultPageLayout(576, 652, 69, 71, 18, 18, true);
+ VerifyPrintPreviewCancelled(false);
+ VerifyPrintPreviewFailed(false);
+}
+
// Test to verify that complete metafile is generated for a subset of pages
// without creating draft pages.
TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewForSelectedPages) {
diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc
index 6b6d9e6..57b77c9 100644
--- a/chrome/renderer/print_web_view_helper_linux.cc
+++ b/chrome/renderer/print_web_view_helper_linux.cc
@@ -143,7 +143,8 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params,
PrepareFrameAndViewForPrint* prepare,
printing::Metafile* metafile) {
PrintMsg_Print_Params print_params = params.params;
- UpdatePrintableSizeInPrintParameters(frame, node, prepare, &print_params);
+ UpdateFrameAndViewFromCssPageLayout(frame, node, prepare, print_params,
+ ignore_css_margins_, fit_to_page_);
*page_count = prepare->GetExpectedPageCount();
if (!*page_count)
@@ -181,23 +182,16 @@ void PrintWebViewHelper::PrintPageInternal(
WebFrame* frame,
printing::Metafile* metafile) {
printing::PageSizeMargins page_layout_in_points;
- GetPageSizeAndMarginsInPoints(frame, params.page_number, params.params,
- &page_layout_in_points);
-
- gfx::Size page_size(
- page_layout_in_points.content_width +
- page_layout_in_points.margin_right +
- page_layout_in_points.margin_left,
- page_layout_in_points.content_height +
- page_layout_in_points.margin_top +
- page_layout_in_points.margin_bottom);
- gfx::Rect content_area(page_layout_in_points.margin_left,
- page_layout_in_points.margin_top,
- page_layout_in_points.content_width,
- page_layout_in_points.content_height);
-
+ double scale_factor = 1.0f;
+ ComputePageLayoutInPointsForCss(frame, params.page_number, params.params,
+ ignore_css_margins_, fit_to_page_,
+ &scale_factor, &page_layout_in_points);
+ gfx::Size page_size;
+ gfx::Rect content_area;
+ GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, &page_size,
+ &content_area);
SkDevice* device = metafile->StartPageForVectorCanvas(
- page_size, content_area, 1.0f);
+ page_size, content_area, scale_factor);
if (!device)
return;
@@ -213,8 +207,9 @@ void PrintWebViewHelper::PrintPageInternal(
// |page_number| is 0-based, so 1 is added.
// The scale factor on Linux is 1.
PrintHeaderAndFooter(canvas.get(), params.page_number + 1,
- print_preview_context_.total_page_count(), 1,
- page_layout_in_points, *header_footer_info_);
+ print_preview_context_.total_page_count(),
+ scale_factor, page_layout_in_points,
+ *header_footer_info_);
}
// Done printing. Close the device context to retrieve the compiled metafile.
diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm
index 5962a1a..508fde2 100644
--- a/chrome/renderer/print_web_view_helper_mac.mm
+++ b/chrome/renderer/print_web_view_helper_mac.mm
@@ -32,25 +32,19 @@ void PrintWebViewHelper::PrintPageInternal(
if (!metafile.Init())
return;
- float scale_factor = frame->getPrintPageShrink(params.page_number);
int page_number = params.page_number;
-
- // Render page for printing.
- gfx::Rect content_area(params.params.content_size);
- RenderPage(params.params.content_size, content_area, scale_factor,
- page_number, frame, false, &metafile);
+ gfx::Size page_size_in_dpi;
+ gfx::Rect content_area_in_dpi;
+ RenderPage(print_pages_params_->params, page_number, frame, false, &metafile,
+ &page_size_in_dpi, &content_area_in_dpi);
metafile.FinishDocument();
PrintHostMsg_DidPrintPage_Params page_params;
page_params.data_size = metafile.GetDataSize();
page_params.page_number = page_number;
page_params.document_cookie = params.params.document_cookie;
- page_params.actual_shrink = scale_factor;
- page_params.page_size = params.params.page_size;
- page_params.content_area = gfx::Rect(params.params.margin_left,
- params.params.margin_top,
- params.params.content_size.width(),
- params.params.content_size.height());
+ page_params.page_size = page_size_in_dpi;
+ page_params.content_area = content_area_in_dpi;
// Ask the browser to create the shared memory for us.
if (!CopyMetafileDataToSharedMem(&metafile,
@@ -62,12 +56,7 @@ void PrintWebViewHelper::PrintPageInternal(
}
bool 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.content_size.width(),
- printParams.content_size.height());
-
scoped_ptr<printing::Metafile> draft_metafile;
printing::Metafile* initial_render_metafile =
print_preview_context_.metafile();
@@ -96,8 +85,9 @@ bool PrintWebViewHelper::RenderPreviewPage(int page_number) {
}
base::TimeTicks begin_time = base::TimeTicks::Now();
- RenderPage(printParams.page_size, content_area, scale_factor, page_number,
- print_preview_context_.frame(), true, initial_render_metafile);
+ gfx::Size page_size;
+ RenderPage(printParams, page_number, print_preview_context_.frame(), true,
+ initial_render_metafile, &page_size, NULL);
print_preview_context_.RenderedPreviewPage(
base::TimeTicks::Now() - begin_time);
@@ -111,13 +101,13 @@ bool PrintWebViewHelper::RenderPreviewPage(int page_number) {
// 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);
+ bool success = print_ready_metafile->StartPage(page_size,
+ gfx::Rect(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());
+ page_size.height());
CGContextScaleCTM(print_ready_metafile->context(), 1.0, -1.0);
draft_metafile->RenderPage(1,
print_ready_metafile->context(),
@@ -143,14 +133,27 @@ bool PrintWebViewHelper::RenderPreviewPage(int page_number) {
}
void PrintWebViewHelper::RenderPage(
- const gfx::Size& page_size, const gfx::Rect& content_area,
- const float& scale_factor, int page_number, WebFrame* frame,
- bool is_preview, printing::Metafile* metafile) {
-
+ const PrintMsg_Print_Params& params, int page_number, WebFrame* frame,
+ bool is_preview, printing::Metafile* metafile, gfx::Size* page_size,
+ gfx::Rect* content_rect) {
+ double scale_factor = 1.0f;
+ double webkit_shrink_factor = frame->getPrintPageShrink(page_number);
+ printing::PageSizeMargins page_layout_in_points;
+ gfx::Rect content_area;
+
+ ComputePageLayoutInPointsForCss(frame, page_number, params,
+ ignore_css_margins_, fit_to_page_,
+ &scale_factor, &page_layout_in_points);
+ GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, page_size,
+ &content_area);
+ if (content_rect)
+ *content_rect = content_area;
+
+ scale_factor *= webkit_shrink_factor;
{
#if defined(USE_SKIA)
SkDevice* device = metafile->StartPageForVectorCanvas(
- page_size, content_area, scale_factor);
+ *page_size, content_area, scale_factor);
if (!device)
return;
@@ -161,7 +164,7 @@ void PrintWebViewHelper::RenderPage(
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
skia::SetIsPreviewMetafile(*canvas, is_preview);
#else
- bool success = metafile->StartPage(page_size, content_area, scale_factor);
+ bool success = metafile->StartPage(*page_size, content_area, scale_factor);
DCHECK(success);
// printPage can create autoreleased references to |context|. PDF contexts
// don't write all their data until they are destroyed, so we need to make
@@ -169,14 +172,7 @@ void PrintWebViewHelper::RenderPage(
base::mac::ScopedNSAutoreleasePool pool;
CGContextRef cgContext = metafile->context();
CGContextRef canvas_ptr = cgContext;
-#endif
-
- printing::PageSizeMargins page_layout_in_points;
- GetPageSizeAndMarginsInPoints(frame, page_number,
- print_pages_params_->params,
- &page_layout_in_points);
-#if !defined(USE_SKIA)
// For CoreGraphics, print in the margins before printing in the content
// area so that we don't spill over. Webkit draws a white background in the
// content area and this acts as a clip.
diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc
index 4ee351b..648f219 100644
--- a/chrome/renderer/print_web_view_helper_win.cc
+++ b/chrome/renderer/print_web_view_helper_win.cc
@@ -109,12 +109,15 @@ void PrintWebViewHelper::PrintPageInternal(
int page_number = params.page_number;
// Calculate the dpi adjustment.
- float scale_factor = static_cast<float>(params.params.desired_dpi /
- params.params.dpi);
+ double actual_shrink = static_cast<float>(params.params.desired_dpi /
+ params.params.dpi);
+ gfx::Size page_size_in_dpi;
+ gfx::Rect content_area_in_dpi;
// Render page for printing.
- metafile.reset(RenderPage(params.params, &scale_factor, page_number, false,
- frame, metafile.get()));
+ metafile.reset(RenderPage(params.params, page_number, frame, false,
+ metafile.get(), &actual_shrink, &page_size_in_dpi,
+ &content_area_in_dpi));
// Close the device context to retrieve the compiled metafile.
if (!metafile->FinishDocument())
@@ -129,11 +132,9 @@ void PrintWebViewHelper::PrintPageInternal(
page_params.metafile_data_handle = NULL;
page_params.page_number = page_number;
page_params.document_cookie = params.params.document_cookie;
- page_params.actual_shrink = scale_factor;
- page_params.page_size = params.params.page_size;
- page_params.content_area = gfx::Rect(params.params.margin_left,
- params.params.margin_top, params.params.content_size.width(),
- params.params.content_size.height());
+ page_params.actual_shrink = actual_shrink;
+ page_params.page_size = page_size_in_dpi;
+ page_params.content_area = content_area_in_dpi;
if (!CopyMetafileDataToSharedMem(metafile.get(),
&(page_params.metafile_data_handle))) {
@@ -146,8 +147,8 @@ void PrintWebViewHelper::PrintPageInternal(
bool PrintWebViewHelper::RenderPreviewPage(int page_number) {
PrintMsg_Print_Params print_params = print_preview_context_.print_params();
// Calculate the dpi adjustment.
- float scale_factor = static_cast<float>(print_params.desired_dpi /
- print_params.dpi);
+ double actual_shrink = static_cast<float>(print_params.desired_dpi /
+ print_params.dpi);
scoped_ptr<Metafile> draft_metafile;
printing::Metafile* initial_render_metafile =
print_preview_context_.metafile();
@@ -159,8 +160,8 @@ bool PrintWebViewHelper::RenderPreviewPage(int page_number) {
base::TimeTicks begin_time = base::TimeTicks::Now();
printing::Metafile* render_page_result =
- RenderPage(print_params, &scale_factor, page_number, true,
- print_preview_context_.frame(), initial_render_metafile);
+ RenderPage(print_params, page_number, print_preview_context_.frame(),
+ true, initial_render_metafile, &actual_shrink, NULL, NULL);
// In the preview flow, RenderPage will never return a new metafile.
DCHECK_EQ(render_page_result, initial_render_metafile);
print_preview_context_.RenderedPreviewPage(
@@ -178,37 +179,54 @@ bool PrintWebViewHelper::RenderPreviewPage(int page_number) {
}
Metafile* PrintWebViewHelper::RenderPage(
- const PrintMsg_Print_Params& params, float* scale_factor, int page_number,
- bool is_preview, WebFrame* frame, Metafile* metafile) {
+ const PrintMsg_Print_Params& params, int page_number, WebFrame* frame,
+ bool is_preview, Metafile* metafile, double* actual_shrink,
+ gfx::Size* page_size_in_dpi, gfx::Rect* content_area_in_dpi) {
printing::PageSizeMargins page_layout_in_points;
- GetPageSizeAndMarginsInPoints(frame, page_number, params,
- &page_layout_in_points);
+ double css_scale_factor = 1.0f;
+ ComputePageLayoutInPointsForCss(frame, page_number, params,
+ ignore_css_margins_, fit_to_page_,
+ &css_scale_factor, &page_layout_in_points);
+ gfx::Size page_size;
+ gfx::Rect content_area;
+ GetPageSizeAndContentAreaFromPageLayout(page_layout_in_points, &page_size,
+ &content_area);
+ int dpi = static_cast<int>(params.dpi);
+ // Calculate the actual page size and content area in dpi.
+ if (page_size_in_dpi) {
+ *page_size_in_dpi = gfx::Size(
+ static_cast<int>(ConvertUnitDouble(
+ page_size.width(), printing::kPointsPerInch, dpi)),
+ static_cast<int>(ConvertUnitDouble(
+ page_size.height(), printing::kPointsPerInch, dpi)));
+ }
- int width;
- int height;
- if (is_preview) {
- int dpi = static_cast<int>(params.dpi);
- int desired_dpi = printing::kPointsPerInch;
- width = ConvertUnit(params.page_size.width(), dpi, desired_dpi);
- height = ConvertUnit(params.page_size.height(), dpi, desired_dpi);
- } else {
+ if (content_area_in_dpi) {
+ *content_area_in_dpi = gfx::Rect(
+ static_cast<int>(ConvertUnitDouble(content_area.x(),
+ printing::kPointsPerInch, dpi)),
+ static_cast<int>(ConvertUnitDouble(content_area.y(),
+ printing::kPointsPerInch, dpi)),
+ static_cast<int>(ConvertUnitDouble(content_area.width(),
+ printing::kPointsPerInch, dpi)),
+ static_cast<int>(ConvertUnitDouble(content_area.height(),
+ printing::kPointsPerInch, dpi)));
+ }
+
+ if (!is_preview) {
// Since WebKit extends the page width depending on the magical scale factor
// we make sure the canvas covers the worst case scenario (x2.0 currently).
// PrintContext will then set the correct clipping region.
- width = static_cast<int>(page_layout_in_points.content_width *
- params.max_shrink);
- height = static_cast<int>(page_layout_in_points.content_height *
- params.max_shrink);
+ page_size = gfx::Size(
+ static_cast<int>(page_layout_in_points.content_width *
+ params.max_shrink),
+ static_cast<int>(page_layout_in_points.content_height *
+ params.max_shrink));
}
- gfx::Size page_size(width, height);
- gfx::Rect content_area(
- static_cast<int>(page_layout_in_points.margin_left),
- static_cast<int>(page_layout_in_points.margin_top),
- static_cast<int>(page_layout_in_points.content_width),
- static_cast<int>(page_layout_in_points.content_height));
+ float webkit_page_shrink_factor = frame->getPrintPageShrink(page_number);
SkDevice* device = metafile->StartPageForVectorCanvas(
- page_size, content_area, frame->getPrintPageShrink(page_number));
+ page_size, content_area, css_scale_factor * webkit_page_shrink_factor);
DCHECK(device);
// The printPage method may take a reference to the canvas we pass down, so it
// can't be a stack object.
@@ -226,16 +244,17 @@ Metafile* PrintWebViewHelper::RenderPage(
// |page_number| is 0-based, so 1 is added.
PrintHeaderAndFooter(canvas.get(), page_number + 1,
print_preview_context_.total_page_count(),
- webkit_scale_factor, page_layout_in_points,
+ css_scale_factor * webkit_page_shrink_factor,
+ page_layout_in_points,
*header_footer_info_);
}
- if (*scale_factor <= 0 || webkit_scale_factor <= 0) {
+ if (*actual_shrink <= 0 || webkit_scale_factor <= 0) {
NOTREACHED() << "Printing page " << page_number << " failed.";
} else {
- // Update the dpi adjustment with the "page |scale_factor|" calculated in
+ // Update the dpi adjustment with the "page |actual_shrink|" calculated in
// webkit.
- *scale_factor /= webkit_scale_factor;
+ *actual_shrink /= (webkit_scale_factor * css_scale_factor);
}
bool result = metafile->FinishPage();
@@ -264,14 +283,15 @@ Metafile* PrintWebViewHelper::RenderPage(
SetGraphicsMode(bitmap_dc, GM_ADVANCED);
void* bits = NULL;
BITMAPINFO hdr;
- gfx::CreateBitmapHeader(width, height, &hdr.bmiHeader);
+ gfx::CreateBitmapHeader(page_size.width(), page_size.height(),
+ &hdr.bmiHeader);
base::win::ScopedBitmap hbitmap(CreateDIBSection(
bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0));
if (!hbitmap)
NOTREACHED() << "Raster bitmap creation for printing failed";
base::win::ScopedSelectObject selectBitmap(bitmap_dc, hbitmap);
- RECT rect = {0, 0, width, height };
+ RECT rect = { 0, 0, page_size.width(), page_size.height() };
HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
FillRect(bitmap_dc, &rect, whiteBrush);
diff --git a/printing/pdf_metafile_cg_mac.cc b/printing/pdf_metafile_cg_mac.cc
index 78c1110..bf2f68d 100644
--- a/printing/pdf_metafile_cg_mac.cc
+++ b/printing/pdf_metafile_cg_mac.cc
@@ -202,20 +202,16 @@ bool PdfMetafileCg::RenderPage(unsigned int page_number,
}
}
// Some PDFs have a non-zero origin. Need to take that into account.
- float x_offset = rect.origin.x - (source_rect.origin.x * scaling_factor);
- float y_offset = rect.origin.y - (source_rect.origin.y * scaling_factor);
+ float x_offset = -1 * source_rect.origin.x * scaling_factor;
+ float y_offset = -1 * source_rect.origin.y * scaling_factor;
- if (center_vertically) {
+ if (center_horizontally) {
x_offset += (rect.size.width -
(source_rect.size.width * scaling_factor))/2;
}
- if (center_horizontally) {
+ if (center_vertically) {
y_offset += (rect.size.height -
(source_rect.size.height * scaling_factor))/2;
- } else {
- // Since 0 y begins at the bottom, we need to adjust so the output appears
- // nearer the top if we are not centering horizontally.
- y_offset += rect.size.height - (source_rect.size.height * scaling_factor);
}
CGContextSaveGState(context);
CGContextTranslateCTM(context, x_offset, y_offset);
diff --git a/printing/printed_document.cc b/printing/printed_document.cc
index 77771c4..c4f2254 100644
--- a/printing/printed_document.cc
+++ b/printing/printed_document.cc
@@ -74,7 +74,8 @@ void PrintedDocument::SetPage(int page_number,
new PrintedPage(page_number + 1,
metafile,
paper_size,
- page_rect));
+ page_rect,
+ shrink));
{
base::AutoLock lock(lock_);
mutable_.pages_[page_number] = page;
@@ -83,12 +84,6 @@ void PrintedDocument::SetPage(int page_number,
if (page_number < mutable_.first_page)
mutable_.first_page = page_number;
#endif
-
- if (mutable_.shrink_factor == 0) {
- mutable_.shrink_factor = shrink;
- } else {
- DCHECK_EQ(mutable_.shrink_factor, shrink);
- }
}
DebugDump(*page);
}
@@ -208,8 +203,7 @@ const FilePath& PrintedDocument::debug_dump_path() {
PrintedDocument::Mutable::Mutable(PrintedPagesSource* source)
: source_(source),
expected_page_count_(0),
- page_count_(0),
- shrink_factor(0) {
+ page_count_(0) {
#if defined(OS_POSIX) && !defined(OS_MACOSX)
first_page = INT_MAX;
#endif
diff --git a/printing/printed_document.h b/printing/printed_document.h
index 3e3217a..3a61541 100644
--- a/printing/printed_document.h
+++ b/printing/printed_document.h
@@ -127,9 +127,6 @@ class PRINTING_EXPORT PrintedDocument
// The total number of pages in the document.
int page_count_;
- // Shrink done in comparison to desired_dpi.
- double shrink_factor;
-
#if defined(OS_POSIX) && !defined(OS_MACOSX)
// Page number of the first page.
int first_page;
diff --git a/printing/printed_document_win.cc b/printing/printed_document_win.cc
index 2d1a117..3926793 100644
--- a/printing/printed_document_win.cc
+++ b/printing/printed_document_win.cc
@@ -67,7 +67,7 @@ void PrintedDocument::RenderPrintedPage(
context,
content_area.x() - page_setup.printable_area().x(),
content_area.y() - page_setup.printable_area().y(),
- mutable_.shrink_factor);
+ page.shrink_factor());
if (!page.metafile()->SafePlayback(context)) {
NOTREACHED();
diff --git a/printing/printed_page.cc b/printing/printed_page.cc
index 7701dbd2..af7b738 100644
--- a/printing/printed_page.cc
+++ b/printing/printed_page.cc
@@ -9,11 +9,13 @@ namespace printing {
PrintedPage::PrintedPage(int page_number,
Metafile* metafile,
const gfx::Size& page_size,
- const gfx::Rect& page_content_rect)
+ const gfx::Rect& page_content_rect,
+ double shrink_factor)
: page_number_(page_number),
metafile_(metafile),
page_size_(page_size),
- page_content_rect_(page_content_rect) {
+ page_content_rect_(page_content_rect),
+ shrink_factor_(shrink_factor) {
}
PrintedPage::~PrintedPage() {
diff --git a/printing/printed_page.h b/printing/printed_page.h
index 28bf191..40e96e0 100644
--- a/printing/printed_page.h
+++ b/printing/printed_page.h
@@ -25,13 +25,15 @@ class PRINTING_EXPORT PrintedPage
PrintedPage(int page_number,
Metafile* metafile,
const gfx::Size& page_size,
- const gfx::Rect& page_content_rect);
+ const gfx::Rect& page_content_rect,
+ double shrink_factor);
// Getters
int page_number() const { return page_number_; }
const Metafile* metafile() const;
const gfx::Size& page_size() const { return page_size_; }
const gfx::Rect& page_content_rect() const { return page_content_rect_; }
+ double shrink_factor() const { return shrink_factor_; }
// Get page content rect adjusted based on
// http://dev.w3.org/csswg/css3-page/#positioning-page-box
@@ -56,6 +58,9 @@ class PRINTING_EXPORT PrintedPage
// The printable area of the page.
const gfx::Rect page_content_rect_;
+ // Shrink done in comparison to desired_dpi.
+ double shrink_factor_;
+
DISALLOW_COPY_AND_ASSIGN(PrintedPage);
};
diff --git a/printing/printed_page_unittest.cc b/printing/printed_page_unittest.cc
index 1a33d10..9cce52a 100644
--- a/printing/printed_page_unittest.cc
+++ b/printing/printed_page_unittest.cc
@@ -15,45 +15,53 @@ TEST(PrintedPageTest, GetCenteredPageContentRect) {
page = new PrintedPage(1,
NULL,
gfx::Size(1200, 1200),
- gfx::Rect(0, 0, 400, 1100));
+ gfx::Rect(0, 0, 400, 1100),
+ 0.2f);
page->GetCenteredPageContentRect(gfx::Size(1000, 1000), &page_content);
EXPECT_EQ(0, page_content.x());
EXPECT_EQ(0, page_content.y());
EXPECT_EQ(400, page_content.width());
EXPECT_EQ(1100, page_content.height());
+ EXPECT_EQ(0.2f, page->shrink_factor());
// X centered.
page = new PrintedPage(1,
NULL,
gfx::Size(500, 1200),
- gfx::Rect(0, 0, 400, 1100));
+ gfx::Rect(0, 0, 400, 1100),
+ 0.8f);
page->GetCenteredPageContentRect(gfx::Size(1000, 1000), &page_content);
EXPECT_EQ(250, page_content.x());
EXPECT_EQ(0, page_content.y());
EXPECT_EQ(400, page_content.width());
EXPECT_EQ(1100, page_content.height());
+ EXPECT_EQ(0.8f, page->shrink_factor());
// Y centered.
page = new PrintedPage(1,
NULL,
gfx::Size(1200, 500),
- gfx::Rect(0, 0, 400, 1100));
+ gfx::Rect(0, 0, 400, 1100),
+ 1.0f);
page->GetCenteredPageContentRect(gfx::Size(1000, 1000), &page_content);
EXPECT_EQ(0, page_content.x());
EXPECT_EQ(250, page_content.y());
EXPECT_EQ(400, page_content.width());
EXPECT_EQ(1100, page_content.height());
+ EXPECT_EQ(1.0f, page->shrink_factor());
// Both X and Y centered.
page = new PrintedPage(1,
NULL,
gfx::Size(500, 500),
- gfx::Rect(0, 0, 400, 1100));
+ gfx::Rect(0, 0, 400, 1100),
+ 0.3f);
page->GetCenteredPageContentRect(gfx::Size(1000, 1000), &page_content);
EXPECT_EQ(250, page_content.x());
EXPECT_EQ(250, page_content.y());
EXPECT_EQ(400, page_content.width());
EXPECT_EQ(1100, page_content.height());
+ EXPECT_EQ(0.3f, page->shrink_factor());
}
} // namespace printing