Chromium Code Reviews| Index: headless/lib/browser/headless_print_manager.cc |
| diff --git a/headless/lib/browser/headless_print_manager.cc b/headless/lib/browser/headless_print_manager.cc |
| index a17c5a4486f3cc2ec64a4af5d84ae67cfd8e76d9..0e0ee69e0c67142da99864c9d90a3359f07e9ad3 100644 |
| --- a/headless/lib/browser/headless_print_manager.cc |
| +++ b/headless/lib/browser/headless_print_manager.cc |
| @@ -8,53 +8,69 @@ |
| #include <vector> |
| #include "base/base64.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/strings/utf_string_conversions.h" |
| #include "components/printing/browser/print_manager_utils.h" |
| #include "components/printing/common/print_messages.h" |
| #include "printing/pdf_metafile_skia.h" |
| -#include "printing/print_settings.h" |
| +#include "printing/print_job_constants.h" |
| #include "printing/units.h" |
| +#include "ui/gfx/geometry/size_f.h" |
| DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::HeadlessPrintManager); |
| namespace printing { |
| -namespace { |
| +HeadlessPrintSettings::HeadlessPrintSettings() |
| + : dpi(kDefaultPdfDpi), |
| + paper_type(LETTER), |
| + margin_type(DEFAULT_MARGINS), |
| + landscape(false), |
| + display_header_footer(false), |
| + should_print_backgrounds(false), |
| + scale(1) {} |
| -// TODO(jzfeng): let the print settings to be configurable. |
| -const double kTopMarginInInch = 0.25; |
| -const double kBottomMarginInInch = 0.56; |
| -const double kLeftMarginInInch = 0.25; |
| -const double kRightMarginInInch = 0.25; |
| +HeadlessPrintSettings::HeadlessPrintSettings(const HeadlessPrintSettings& obj) = |
| + default; |
| +HeadlessPrintSettings::~HeadlessPrintSettings() = default; |
| -PrintSettings GetDefaultPDFPrinterSettings() { |
| +int HeadlessPrintSettings::GetDPI() { |
|
Eric Seckler
2017/04/20 09:15:28
nit: this doesn't always return the DPI, so should
jzfeng
2017/04/27 06:56:06
Removed this method since setting different dpi do
|
| #if defined(OS_MACOSX) |
| // On the Mac, the printable area is in points, use kPointsPerInch to compute |
| // its bounds. |
| - int dpi = kPointsPerInch; |
| + return kPointsPerInch; |
| #else |
| - int dpi = kDefaultPdfDpi; |
| + return dpi; |
| #endif |
| - gfx::Size physical_size_device_units; |
| - gfx::Rect printable_area_device_units; |
| - double page_width_in_pixel = kLetterWidthInch * dpi; |
| - double page_height_in_pixel = kLetterHeightInch * dpi; |
| - physical_size_device_units.SetSize(static_cast<int>(page_width_in_pixel), |
| - static_cast<int>(page_height_in_pixel)); |
| - printable_area_device_units.SetRect( |
| - static_cast<int>(kLeftMarginInInch * dpi), |
| - static_cast<int>(kTopMarginInInch * dpi), |
| - page_width_in_pixel - (kLeftMarginInInch + kRightMarginInInch) * dpi, |
| - page_height_in_pixel - (kTopMarginInInch + kBottomMarginInInch) * dpi); |
| - |
| - PrintSettings settings; |
| - settings.set_dpi(dpi); |
| - settings.SetPrinterPrintableArea(physical_size_device_units, |
| - printable_area_device_units, true); |
| - settings.set_should_print_backgrounds(true); |
| - return settings; |
| -} |
| - |
| -} // namespace |
| +} |
| + |
| +gfx::Size HeadlessPrintSettings::PaperSizeInPixel() { |
|
Eric Seckler
2017/04/20 09:15:28
nit: PaperSizeInPixelsOrPoints
jzfeng
2017/04/27 06:56:06
Change to PaperSizeInPoints.
|
| + gfx::SizeF paper_size(kLetterWidthInch, kLetterHeightInch); |
| + switch (paper_type) { |
| + case LEGAL: |
| + paper_size.SetSize(kLegalWidthInch, kLegalHeightInch); |
| + break; |
| + case A4: |
| + paper_size.SetSize(kA4WidthInch, kA4HeightInch); |
| + break; |
| + case A3: |
| + paper_size.SetSize(kA3WidthInch, kA3HeightInch); |
| + break; |
| + default: // LETTER is used for default fallback. |
| + break; |
| + } |
| + return gfx::Size(paper_size.width() * GetDPI(), |
| + paper_size.height() * GetDPI()); |
| +} |
| + |
| +PageMargins HeadlessPrintSettings::MarginInPoints() { |
| + PageMargins margins_in_points; |
| + margins_in_points.top = margin_top_in_inch * kPointsPerInch; |
| + margins_in_points.bottom = margin_bottom_in_inch * kPointsPerInch; |
| + margins_in_points.left = margin_left_in_inch * kPointsPerInch; |
| + margins_in_points.right = margin_right_in_inch * kPointsPerInch; |
| + return margins_in_points; |
| +} |
| HeadlessPrintManager::HeadlessPrintManager(content::WebContents* web_contents) |
| : PrintManager(web_contents) { |
| @@ -84,6 +100,8 @@ std::string HeadlessPrintManager::PrintResultToString(PrintResult result) { |
| return "Get data from metafile error"; |
| case SIMULTANEOUS_PRINT_ACTIVE: |
| return "The previous printing job hasn't finished"; |
| + case EXCEED_PAGE_LIMIT: |
| + return "Page range exceed page count"; |
|
Eric Seckler
2017/04/20 09:15:28
nit: exceeds
jzfeng
2017/04/27 06:56:06
Done.
|
| default: |
| NOTREACHED(); |
| return "Unknown PrintResult"; |
| @@ -101,6 +119,7 @@ HeadlessPrintManager::PDFContentsToDictionaryValue(const std::string& data) { |
| } |
| void HeadlessPrintManager::GetPDFContents(content::RenderFrameHost* rfh, |
| + HeadlessPrintSettings settings, |
| const GetPDFCallback& callback) { |
| DCHECK(callback); |
| @@ -110,9 +129,42 @@ void HeadlessPrintManager::GetPDFContents(content::RenderFrameHost* rfh, |
| } |
| printing_rfh_ = rfh; |
| callback_ = callback; |
| + print_params_ = PrintParams(settings); |
| rfh->Send(new PrintMsg_PrintPages(rfh->GetRoutingID())); |
| } |
| +std::unique_ptr<PrintMsg_PrintPages_Params> HeadlessPrintManager::PrintParams( |
| + HeadlessPrintSettings settings) { |
| + PrintSettings print_settings; |
| + print_settings.set_dpi(settings.GetDPI()); |
| + print_settings.set_should_print_backgrounds( |
| + settings.should_print_backgrounds); |
| + print_settings.set_scale_factor(settings.scale); |
| + print_settings.SetOrientation(settings.landscape); |
| + print_settings.set_ranges(settings.page_ranges); |
| + |
| + print_settings.set_display_header_footer(settings.display_header_footer); |
| + if (print_settings.display_header_footer()) { |
| + print_settings.set_url( |
|
Lei Zhang
2017/04/20 08:35:58
Do you need to set the page title as well? Sanitiz
jzfeng
2017/04/27 06:56:06
Setting page title doesn't work in most case, sinc
|
| + base::UTF8ToUTF16(printing_rfh_->GetLastCommittedURL().spec())); |
| + } |
| + |
| + print_settings.set_margin_type(settings.margin_type); |
| + if (settings.margin_type == CUSTOM_MARGINS) |
| + print_settings.SetCustomMargins(settings.MarginInPoints()); |
| + |
| + gfx::Size physical_size_device_units = settings.PaperSizeInPixel(); |
| + gfx::Rect printable_area_device_units(physical_size_device_units); |
| + print_settings.SetPrinterPrintableArea(physical_size_device_units, |
| + printable_area_device_units, true); |
| + |
| + auto print_params = base::MakeUnique<PrintMsg_PrintPages_Params>(); |
| + RenderParamsFromPrintSettings(print_settings, &print_params->params); |
| + print_params->params.document_cookie = PrintSettings::NewCookie(); |
| + print_params->pages = PageRange::GetPages(settings.page_ranges); |
| + return print_params; |
| +} |
| + |
| bool HeadlessPrintManager::OnMessageReceived( |
| const IPC::Message& message, |
| content::RenderFrameHost* render_frame_host) { |
| @@ -123,17 +175,29 @@ bool HeadlessPrintManager::OnMessageReceived( |
| IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) |
| IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings, |
| OnGetDefaultPrintSettings) |
| + IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled || PrintManager::OnMessageReceived(message, render_frame_host); |
| } |
| void HeadlessPrintManager::OnGetDefaultPrintSettings(IPC::Message* reply_msg) { |
| - PrintMsg_Print_Params print_params; |
| - RenderParamsFromPrintSettings(GetDefaultPDFPrinterSettings(), &print_params); |
| - print_params.document_cookie = PrintSettings::NewCookie(); |
| PrintHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, |
| - print_params); |
| + print_params_->params); |
| + printing_rfh_->Send(reply_msg); |
| +} |
| + |
| +void HeadlessPrintManager::OnScriptedPrint( |
| + const PrintHostMsg_ScriptedPrint_Params& params, |
| + IPC::Message* reply_msg) { |
| + if (!print_params_->pages.empty() && |
| + print_params_->pages.back() > params.expected_pages_count) { |
|
Lei Zhang
2017/04/20 08:35:58
Is the vector of pages sorted? If the range input
jzfeng
2017/04/27 06:56:06
Yes, it is sorted. PageRange::GetPages use a set t
|
| + printing_rfh_->Send(reply_msg); |
| + ReleaseJob(EXCEED_PAGE_LIMIT); |
| + return; |
| + } |
| + |
| + PrintHostMsg_ScriptedPrint::WriteReplyParams(reply_msg, *print_params_); |
| printing_rfh_->Send(reply_msg); |
| } |
| @@ -145,6 +209,13 @@ void HeadlessPrintManager::OnPrintingFailed(int cookie) { |
| ReleaseJob(PRINTING_FAILED); |
| } |
| +void HeadlessPrintManager::OnDidGetPrintedPagesCount(int cookie, |
| + int number_pages) { |
| + PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); |
| + if (!print_params_->pages.empty()) |
| + number_pages_ = print_params_->pages.size(); |
|
Lei Zhang
2017/04/20 08:35:58
Why do we need to do this?
jzfeng
2017/04/27 06:56:06
number_pages returned from the renderer is always
Lei Zhang
2017/04/27 22:17:46
Is this the issue described in https://crbug.com/1
jzfeng
2017/05/02 07:50:55
The bug you found is right. The reason why chrome
|
| +} |
| + |
| void HeadlessPrintManager::OnDidPrintPage( |
| const PrintHostMsg_DidPrintPage_Params& params) { |
| if (!callback_) { |
| @@ -193,6 +264,7 @@ void HeadlessPrintManager::OnDidPrintPage( |
| void HeadlessPrintManager::Reset() { |
| printing_rfh_ = nullptr; |
| callback_.Reset(); |
| + print_params_.reset(nullptr); |
|
Lei Zhang
2017/04/20 08:35:58
There's no need to pass nullptr to std::unique_ptr
jzfeng
2017/04/27 06:56:06
Done.
|
| data_.clear(); |
| expecting_first_page_ = true; |
| number_pages_ = 0; |