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; |