diff options
author | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-10 23:17:32 +0000 |
---|---|---|
committer | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-10 23:17:32 +0000 |
commit | 732b813ab60ebaad3cd2a60e19154e2c29b5a144 (patch) | |
tree | 9ed80f722ccf2e478ec771614193e88f9126e419 | |
parent | 66122f44aec56f163aed88a673f062f035619bc2 (diff) | |
download | chromium_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
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(¶ms); + 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, ¶ms); + 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, + ¶m); + 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 |