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..5312e0ba371e7643f291a951d649640ef829ba4b 100644 |
--- a/headless/lib/browser/headless_print_manager.cc |
+++ b/headless/lib/browser/headless_print_manager.cc |
@@ -8,54 +8,21 @@ |
#include <vector> |
#include "base/base64.h" |
+#include "base/memory/ptr_util.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_piece.h" |
+#include "base/strings/string_split.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" |
DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::HeadlessPrintManager); |
namespace printing { |
-namespace { |
- |
-// 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; |
- |
-PrintSettings GetDefaultPDFPrinterSettings() { |
-#if defined(OS_MACOSX) |
- // On the Mac, the printable area is in points, use kPointsPerInch to compute |
- // its bounds. |
- int dpi = kPointsPerInch; |
-#else |
- int dpi = kDefaultPdfDpi; |
-#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 |
- |
HeadlessPrintManager::HeadlessPrintManager(content::WebContents* web_contents) |
: PrintManager(web_contents) { |
Reset(); |
@@ -84,6 +51,10 @@ 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 PAGE_RANGE_SYNTAX_ERROR: |
+ return "Page range syntax error"; |
+ case PAGE_COUNT_EXCEEDED: |
+ return "Page range exceeds page count"; |
default: |
NOTREACHED(); |
return "Unknown PrintResult"; |
@@ -100,7 +71,57 @@ HeadlessPrintManager::PDFContentsToDictionaryValue(const std::string& data) { |
return result; |
} |
+// static |
+HeadlessPrintManager::PageRangeStatus |
+HeadlessPrintManager::PageRangeTextToPages(base::StringPiece page_range_text, |
+ int pages_count, |
+ std::vector<int>* pages) { |
+ PageRanges page_ranges; |
+ for (const auto& range_string : |
+ base::SplitStringPiece(page_range_text, ",", base::TRIM_WHITESPACE, |
+ base::SPLIT_WANT_NONEMPTY)) { |
+ printing::PageRange range; |
+ if (range_string.find("-") == base::StringPiece::npos) { |
+ if (!base::StringToInt(range_string, &range.from)) |
+ return SYNTAX_ERROR; |
+ range.to = range.from; |
+ } else if (range_string == "-") { |
+ range.from = 1; |
+ range.to = pages_count; |
+ } else if (range_string.starts_with("-")) { |
+ range.from = 1; |
+ if (!base::StringToInt(range_string.substr(1), &range.to)) |
+ return SYNTAX_ERROR; |
+ } else if (range_string.ends_with("-")) { |
+ range.to = pages_count; |
+ if (!base::StringToInt(range_string.substr(0, range_string.length() - 1), |
+ &range.from)) |
+ return SYNTAX_ERROR; |
+ } else { |
+ auto tokens = base::SplitStringPiece( |
+ range_string, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
+ if (tokens.size() != 2 || !base::StringToInt(tokens[0], &range.from) || |
+ !base::StringToInt(tokens[1], &range.to)) |
+ return SYNTAX_ERROR; |
+ } |
+ |
+ if (range.from < 1 || range.from > range.to) |
+ return SYNTAX_ERROR; |
+ if (range.to > pages_count) |
+ return LIMIT_ERROR; |
+ |
+ // Page numbers are 1-based in the dictionary. |
+ // Page numbers are 0-based for the print settings. |
+ range.from--; |
+ range.to--; |
+ page_ranges.push_back(range); |
+ } |
+ *pages = PageRange::GetPages(page_ranges); |
+ return NO_ERROR; |
+} |
+ |
void HeadlessPrintManager::GetPDFContents(content::RenderFrameHost* rfh, |
+ const HeadlessPrintSettings& settings, |
const GetPDFCallback& callback) { |
DCHECK(callback); |
@@ -110,9 +131,45 @@ void HeadlessPrintManager::GetPDFContents(content::RenderFrameHost* rfh, |
} |
printing_rfh_ = rfh; |
callback_ = callback; |
+ print_params_ = GetPrintParamsFromSettings(settings); |
+ page_ranges_text_ = settings.page_ranges; |
rfh->Send(new PrintMsg_PrintPages(rfh->GetRoutingID())); |
} |
+std::unique_ptr<PrintMsg_PrintPages_Params> |
+HeadlessPrintManager::GetPrintParamsFromSettings( |
+ const HeadlessPrintSettings& settings) { |
+ PrintSettings print_settings; |
+ print_settings.set_dpi(kPointsPerInch); |
+ 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_display_header_footer(settings.display_header_footer); |
+ if (print_settings.display_header_footer()) { |
+ url::Replacements<char> url_sanitizer; |
+ url_sanitizer.ClearUsername(); |
+ url_sanitizer.ClearPassword(); |
+ std::string url = printing_rfh_->GetLastCommittedURL() |
+ .ReplaceComponents(url_sanitizer) |
+ .spec(); |
+ print_settings.set_url(base::UTF8ToUTF16(url)); |
+ } |
+ |
+ print_settings.set_margin_type(CUSTOM_MARGINS); |
+ print_settings.SetCustomMargins(settings.margins_in_points); |
+ |
+ gfx::Rect printable_area_device_units(settings.paper_size_in_points); |
+ print_settings.SetPrinterPrintableArea(settings.paper_size_in_points, |
+ 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(); |
+ return print_params; |
+} |
+ |
bool HeadlessPrintManager::OnMessageReceived( |
const IPC::Message& message, |
content::RenderFrameHost* render_frame_host) { |
@@ -123,20 +180,42 @@ 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) { |
+ PageRangeStatus status = PageRangeTextToPages( |
+ page_ranges_text_, params.expected_pages_count, &print_params_->pages); |
+ switch (status) { |
+ case SYNTAX_ERROR: |
+ printing_rfh_->Send(reply_msg); |
+ ReleaseJob(PAGE_RANGE_SYNTAX_ERROR); |
+ return; |
+ case LIMIT_ERROR: |
+ printing_rfh_->Send(reply_msg); |
+ ReleaseJob(PAGE_COUNT_EXCEEDED); |
+ return; |
+ case NO_ERROR: |
+ PrintHostMsg_ScriptedPrint::WriteReplyParams(reply_msg, *print_params_); |
+ printing_rfh_->Send(reply_msg); |
+ return; |
+ default: |
+ NOTREACHED(); |
+ return; |
+ } |
+} |
+ |
void HeadlessPrintManager::OnShowInvalidPrinterSettingsError() { |
ReleaseJob(INVALID_PRINTER_SETTINGS); |
} |
@@ -145,6 +224,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(); |
+} |
+ |
void HeadlessPrintManager::OnDidPrintPage( |
const PrintHostMsg_DidPrintPage_Params& params) { |
if (!callback_) { |
@@ -193,6 +279,8 @@ void HeadlessPrintManager::OnDidPrintPage( |
void HeadlessPrintManager::Reset() { |
printing_rfh_ = nullptr; |
callback_.Reset(); |
+ print_params_.reset(); |
+ page_ranges_text_.clear(); |
data_.clear(); |
expecting_first_page_ = true; |
number_pages_ = 0; |