Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8016)

Unified Diff: chrome/renderer/print_web_view_helper.cc

Issue 8585017: PrintPreview: Honor the print media page size and margin values. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix conflicts Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/print_web_view_helper.cc
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc
index 499b1fd09270125e78d39fe1e8117b9f0dd49485..e7e7cca4a0061abf204a1717c9e7e98e4f897e20 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,175 @@ bool PrintMsg_Print_Params_IsEqual(
newParams.pages.begin());
}
+// Helper method to populate page layout information.
+// Set |ignore_css_margins| to true to ignore print media margin css.
+// If the page does not have any print media css, printer default values
+// are used.
+void PopulatePageLayoutInfo(
+ WebFrame* frame,
+ int page_index,
+ const PrintMsg_Print_Params& default_params,
+ bool ignore_css_margins,
vandebo (ex-Chrome) 2011/12/14 19:05:38 I was hoping to separate the fit/ignore logic from
kmadhusu 2011/12/19 09:52:19 Done.
+ bool fit_to_page,
+ 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 && !(ignore_css_margins && fit_to_page)) {
+ int old_margin_top_in_pixels = margin_top_in_pixels;
+ int old_margin_bottom_in_pixels = margin_bottom_in_pixels;
+ int old_margin_left_in_pixels = margin_left_in_pixels;
+ int old_margin_right_in_pixels = margin_right_in_pixels;
+
+ frame->pageSizeAndMarginsInPixels(page_index,
+ page_size_in_pixels,
+ margin_top_in_pixels,
+ margin_right_in_pixels,
+ margin_bottom_in_pixels,
+ margin_left_in_pixels);
+ if (ignore_css_margins) {
+ margin_top_in_pixels = old_margin_top_in_pixels;
+ margin_bottom_in_pixels = old_margin_bottom_in_pixels;
+ margin_left_in_pixels = old_margin_left_in_pixels;
+ margin_right_in_pixels = old_margin_right_in_pixels;
+ }
+ }
+ double margin_top_in_points =
+ ConvertPixelsToPointDouble(margin_top_in_pixels);
+ double margin_right_in_points =
+ ConvertPixelsToPointDouble(margin_right_in_pixels);
+ double margin_left_in_points =
+ ConvertPixelsToPointDouble(margin_left_in_pixels);
+ double margin_bottom_in_points =
+ ConvertPixelsToPointDouble(margin_bottom_in_pixels);
+ double new_content_width =
+ ConvertPixelsToPoint(page_size_in_pixels.width);
+ double new_content_height =
+ ConvertPixelsToPoint(page_size_in_pixels.height);
+
+ bool page_has_custom_page_size_style =
+ frame && frame->hasCustomPageSizeStyle(page_index);
+
+ // Do not subtract the margins from |page_size_in_pixels| when the page has
+ // custom page size style and the user has requested a custom margins.
+ if ((!ignore_css_margins && page_has_custom_page_size_style) ||
+ (ignore_css_margins && page_has_custom_page_size_style && !fit_to_page)) {
+ new_content_width -= (margin_left_in_points + margin_right_in_points);
+ new_content_height -= (margin_top_in_points + margin_bottom_in_points);
+ } else {
+ double page_width_in_points =
+ ConvertUnit(default_params.page_size.width(),
+ dpi, printing::kPointsPerInch);
+ double page_height_in_points =
+ ConvertUnit(default_params.page_size.height(),
+ dpi, printing::kPointsPerInch);
+ new_content_width = page_width_in_points - margin_left_in_points -
+ margin_right_in_points;
+ new_content_height = page_height_in_points - margin_top_in_points -
+ margin_bottom_in_points;
+ }
+
+ // Invalid page size and/or margins. We just use the default setting.
+ if (new_content_width < 1.0 || new_content_height < 1.0) {
+ CHECK(frame != NULL);
+ PopulatePageLayoutInfo(NULL, page_index, default_params, false,
+ false, page_layout_in_points);
+ return;
+ }
+
+ page_layout_in_points->content_width = new_content_width;
+ page_layout_in_points->content_height = new_content_height;
+ page_layout_in_points->margin_top = margin_top_in_points;
+ page_layout_in_points->margin_right = margin_right_in_points;
+ page_layout_in_points->margin_bottom = margin_bottom_in_points;
+ page_layout_in_points->margin_left = margin_left_in_points;
+}
+
+// Helper method to fit |css_page_layout_in_points| to default paper size.
+void FitCssPageSizeAndMarginsToPaperSize(
+ const PrintMsg_Print_Params& default_params,
+ const PageSizeMargins& css_page_layout_in_points,
vandebo (ex-Chrome) 2011/12/14 19:05:38 As is, I think you can pass a single PageSizeMargi
kmadhusu 2011/12/19 09:52:19 Done.
+ double* scale_factor,
+ PageSizeMargins* page_layout_in_points) {
+ int dpi = GetDPI(&default_params);
+ double margin_top_in_points = css_page_layout_in_points.margin_top;
+ double margin_bottom_in_points = css_page_layout_in_points.margin_bottom;
+ double margin_left_in_points = css_page_layout_in_points.margin_left;
+ double margin_right_in_points = css_page_layout_in_points.margin_right;
+ double content_width = css_page_layout_in_points.content_width;
+ double content_height = css_page_layout_in_points.content_height;
+
+ double new_page_box_width = content_width + margin_left_in_points +
+ margin_right_in_points;
+ double new_page_box_height = content_height + margin_top_in_points +
+ margin_bottom_in_points;
+ double default_page_size_height =
+ ConvertUnit(default_params.page_size.height(), dpi,
+ printing::kPointsPerInch);
+ double default_page_size_width =
+ ConvertUnit(default_params.page_size.width(), dpi,
+ printing::kPointsPerInch);
+
+ if (default_page_size_height != new_page_box_height ||
+ default_page_size_width != new_page_box_width) {
+ double factor = 1.0f;
+ if (default_page_size_width < new_page_box_width ||
+ default_page_size_height < new_page_box_height) {
+ double minimum_printable_width =
+ ConvertUnit(default_params.printable_area.width(), dpi,
+ printing::kPointsPerInch);
+ double minimum_printable_height =
+ ConvertUnit(default_params.printable_area.height(), dpi,
+ printing::kPointsPerInch);
+ double ratio_width = minimum_printable_width / new_page_box_width;
+ double ratio_height = minimum_printable_height / new_page_box_height;
+ factor = ratio_width < ratio_height ? ratio_width : ratio_height;
+ if (scale_factor)
+ *scale_factor = factor;
+
+ content_width *= factor;
+ content_height *= factor;
+ }
+ margin_top_in_points =
+ (default_page_size_height - new_page_box_height * factor)/2 +
+ (margin_top_in_points * factor);
+ margin_bottom_in_points =
+ (default_page_size_height - new_page_box_height * factor)/2 +
+ (margin_bottom_in_points * factor);
+ margin_right_in_points =
+ (default_page_size_width - new_page_box_width * factor)/2 +
+ (margin_right_in_points * factor);
+ margin_left_in_points =
+ (default_page_size_width - new_page_box_width * factor)/2 +
+ (margin_left_in_points * factor);
+ page_layout_in_points->content_width = content_width;
+ page_layout_in_points->content_height = content_height;
+ page_layout_in_points->margin_top = margin_top_in_points;
+ page_layout_in_points->margin_right = margin_right_in_points;
+ page_layout_in_points->margin_bottom = margin_bottom_in_points;
+ page_layout_in_points->margin_left = margin_left_in_points;
+ }
+}
+
void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params,
gfx::Size* result) {
int dpi = GetDPI(&print_params);
@@ -152,6 +323,12 @@ bool PrintingNodeOrPdfFrame(const WebFrame* frame, const WebNode& node) {
return mime == "application/pdf";
}
+bool PrintingFrameHasPageSizeStyle(WebFrame* frame) {
+ if (!frame)
+ return false;
+ return frame->hasCustomPageSizeStyle(0);
+}
+
printing::MarginType GetMarginsForPdf(WebFrame* frame, const WebNode& node) {
if (frame->isPrintScalingDisabledForPlugin(node))
return printing::NO_MARGINS;
@@ -440,6 +617,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 +739,39 @@ void PrintWebViewHelper::OnPrintForSystemDialog() {
Print(frame, print_preview_context_.node());
}
+void PrintWebViewHelper::UpdatePageSizeAndContentAreaFromPageLayout(
+ 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 +832,25 @@ 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;
+ GetPageSizeAndMarginsInPoints(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());
+ // 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 +1070,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);
+ UpdatePageSizeAndMarginsInFrameAndView(frame, node, &prep_frame_view,
+ print_params, ignore_css_margins_,
+ fit_to_page_);
int page_count = prep_frame_view.GetExpectedPageCount();
if (!page_count)
@@ -882,86 +1112,45 @@ void PrintWebViewHelper::GetPageSizeAndMarginsInPoints(
WebFrame* frame,
int page_index,
const PrintMsg_Print_Params& default_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);
+ PageSizeMargins css_page_layout_in_points;
+ PopulatePageLayoutInfo(frame, page_index, default_params,
+ ignore_css_margins, fit_to_page, &css_page_layout_in_points);
+ *page_layout_in_points = css_page_layout_in_points;
+
+ if (fit_to_page) {
+ FitCssPageSizeAndMarginsToPaperSize(default_params,
+ css_page_layout_in_points, scale_factor, page_layout_in_points);
}
-
- 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);
}
// static - Not anonymous so that platform implementations can use it.
-void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
+void PrintWebViewHelper::UpdatePageSizeAndMarginsInFrameAndView(
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(
+ PrintMsg_Print_Params current_params = params;
+ PrintWebViewHelper::GetPageSizeAndMarginsInPoints(frame, 0,
+ current_params, ignore_css_margins,
+ ignore_css_margins && fit_to_page, NULL,
+ &page_layout_in_points);
+ int dpi = GetDPI(&current_params);
+ current_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 +
@@ -971,18 +1160,17 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
page_layout_in_points.margin_top +
page_layout_in_points.margin_bottom;
- params->page_size = gfx::Size(
+ current_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(
+ current_params.margin_top =
+ static_cast<int>(ConvertUnitDouble(
+ page_layout_in_points.margin_top, printing::kPointsPerInch, dpi));
+ current_params.margin_left = static_cast<int>(ConvertUnitDouble(
page_layout_in_points.margin_left, printing::kPointsPerInch, dpi));
-
- prepare->UpdatePrintParams(*params);
+ prepare->UpdatePrintParams(current_params);
}
bool PrintWebViewHelper::InitPrintSettings(WebKit::WebFrame* frame,
@@ -1025,8 +1213,10 @@ 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);
+ UpdatePageSizeAndMarginsInFrameAndView(frame, node, prepare->get(),
+ print_pages_params_->params,
+ ignore_css_margins_,
vandebo (ex-Chrome) 2011/12/14 19:05:38 These two will always be false here, just use fals
kmadhusu 2011/12/19 09:52:19 ignore_css_margins_ is false and fit_to_page_ is t
+ fit_to_page_);
Send(new PrintHostMsg_DidGetDocumentCookie(
routing_id(), print_pages_params_->params.document_cookie));
return true;
@@ -1127,15 +1317,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 +1557,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 +1573,10 @@ 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);
+ UpdatePageSizeAndMarginsInFrameAndView(frame_, node_,
+ prep_frame_view_.get(), *print_params,
+ ignore_css_margins,
+ fit_to_page);
print_params_.reset(new PrintMsg_Print_Params(*print_params));

Powered by Google App Engine
This is Rietveld 408576698