0

Move margin processing code to the browser process.

It seems that this is where it is supposed to live and it was erroneously added to PrintWebViewHelper.

BUG=67091, 92045, 91880, 92000, 92218, 95905
TEST=NONE


Review URL: http://codereview.chromium.org/8201027

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105688 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
vandebo@chromium.org
2011-10-15 22:30:48 +00:00
parent 0374b16598
commit 1c23b4e86c
19 changed files with 272 additions and 216 deletions

@ -21,6 +21,7 @@
#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/browser_window.h"
#include "printing/metafile.h" #include "printing/metafile.h"
#include "printing/print_job_constants.h" #include "printing/print_job_constants.h"
#include "printing/print_settings.h"
#include "printing/print_settings_initializer_gtk.h" #include "printing/print_settings_initializer_gtk.h"
using printing::PageRanges; using printing::PageRanges;
@ -146,11 +147,13 @@ void PrintDialogGtk::UseDefaultSettings() {
// No page range to initialize for default settings. // No page range to initialize for default settings.
PageRanges ranges_vector; PageRanges ranges_vector;
InitPrintSettings(ranges_vector); PrintSettings settings;
InitPrintSettings(ranges_vector, &settings);
} }
bool PrintDialogGtk::UpdateSettings(const DictionaryValue& settings, bool PrintDialogGtk::UpdateSettings(const DictionaryValue& job_settings,
const printing::PageRanges& ranges) { const printing::PageRanges& ranges,
printing::PrintSettings* settings) {
bool collate; bool collate;
int color; int color;
bool landscape; bool landscape;
@ -159,13 +162,13 @@ bool PrintDialogGtk::UpdateSettings(const DictionaryValue& settings,
int duplex_mode; int duplex_mode;
std::string device_name; std::string device_name;
if (!settings.GetBoolean(printing::kSettingLandscape, &landscape) || if (!job_settings.GetBoolean(printing::kSettingLandscape, &landscape) ||
!settings.GetBoolean(printing::kSettingCollate, &collate) || !job_settings.GetBoolean(printing::kSettingCollate, &collate) ||
!settings.GetInteger(printing::kSettingColor, &color) || !job_settings.GetInteger(printing::kSettingColor, &color) ||
!settings.GetBoolean(printing::kSettingPrintToPDF, &print_to_pdf) || !job_settings.GetBoolean(printing::kSettingPrintToPDF, &print_to_pdf) ||
!settings.GetInteger(printing::kSettingDuplexMode, &duplex_mode) || !job_settings.GetInteger(printing::kSettingDuplexMode, &duplex_mode) ||
!settings.GetInteger(printing::kSettingCopies, &copies) || !job_settings.GetInteger(printing::kSettingCopies, &copies) ||
!settings.GetString(printing::kSettingDeviceName, &device_name)) { !job_settings.GetString(printing::kSettingDeviceName, &device_name)) {
return false; return false;
} }
@ -220,7 +223,7 @@ bool PrintDialogGtk::UpdateSettings(const DictionaryValue& settings,
landscape ? GTK_PAGE_ORIENTATION_LANDSCAPE : landscape ? GTK_PAGE_ORIENTATION_LANDSCAPE :
GTK_PAGE_ORIENTATION_PORTRAIT); GTK_PAGE_ORIENTATION_PORTRAIT);
InitPrintSettings(ranges); InitPrintSettings(ranges, settings);
return true; return true;
} }
@ -395,9 +398,9 @@ void PrintDialogGtk::OnJobCompleted(GtkPrintJob* print_job, GError* error) {
Release(); Release();
} }
void PrintDialogGtk::InitPrintSettings(const PageRanges& page_ranges) { void PrintDialogGtk::InitPrintSettings(const PageRanges& page_ranges,
PrintSettings settings; PrintSettings* settings) {
printing::PrintSettingsInitializerGtk::InitPrintSettings( printing::PrintSettingsInitializerGtk::InitPrintSettings(
gtk_settings_, page_setup_, page_ranges, false, &settings); gtk_settings_, page_setup_, page_ranges, false, settings);
context_->InitWithSettings(settings); context_->InitWithSettings(*settings);
} }

@ -9,6 +9,7 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gtk/gtkprintunixdialog.h> #include <gtk/gtkprintunixdialog.h>
#include "base/compiler_specific.h"
#include "base/file_path.h" #include "base/file_path.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
@ -19,6 +20,7 @@
namespace printing { namespace printing {
class Metafile; class Metafile;
class PrintSettings;
} }
using printing::PrintingContextCairo; using printing::PrintingContextCairo;
@ -34,15 +36,16 @@ class PrintDialogGtk
PrintingContextCairo* context); PrintingContextCairo* context);
// printing::PrintDialogGtkInterface implementation. // printing::PrintDialogGtkInterface implementation.
virtual void UseDefaultSettings(); virtual void UseDefaultSettings() OVERRIDE;
virtual bool UpdateSettings(const base::DictionaryValue& settings, virtual bool UpdateSettings(const base::DictionaryValue& job_settings,
const printing::PageRanges& ranges); const printing::PageRanges& ranges,
printing::PrintSettings* settings) OVERRIDE;
virtual void ShowDialog( virtual void ShowDialog(
PrintingContextCairo::PrintSettingsCallback* callback); PrintingContextCairo::PrintSettingsCallback* callback) OVERRIDE;
virtual void PrintDocument(const printing::Metafile* metafile, virtual void PrintDocument(const printing::Metafile* metafile,
const string16& document_name); const string16& document_name) OVERRIDE;
virtual void AddRefToDialog(); virtual void AddRefToDialog() OVERRIDE;
virtual void ReleaseDialog(); virtual void ReleaseDialog() OVERRIDE;
private: private:
friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
@ -64,8 +67,9 @@ class PrintDialogGtk
void OnJobCompleted(GtkPrintJob* print_job, GError* error); void OnJobCompleted(GtkPrintJob* print_job, GError* error);
// Helper function for initializing |context_|'s PrintSettings with a given // Helper function for initializing |context_|'s PrintSettings with a given
// set of |page_ranges|. // set of |page_ranges| and |settings|.
void InitPrintSettings(const printing::PageRanges& page_ranges); void InitPrintSettings(const printing::PageRanges& page_ranges,
printing::PrintSettings* settings);
// Printing dialog callback. // Printing dialog callback.
PrintingContextCairo::PrintSettingsCallback* callback_; PrintingContextCairo::PrintSettingsCallback* callback_;

@ -77,7 +77,7 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
gfx::NativeView parent_view, gfx::NativeView parent_view,
int document_page_count, int document_page_count,
bool has_selection, bool has_selection,
bool use_overlays) { MarginType margin_type) {
DCHECK_EQ(message_loop(), MessageLoop::current()); DCHECK_EQ(message_loop(), MessageLoop::current());
DCHECK_EQ(page_number_, PageNumber::npos()); DCHECK_EQ(page_number_, PageNumber::npos());
@ -87,7 +87,7 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
// on the thread where the PrintDlgEx is called, and definitely both calls // on the thread where the PrintDlgEx is called, and definitely both calls
// should happen on the same thread. See http://crbug.com/73466 // should happen on the same thread. See http://crbug.com/73466
// MessageLoop::current()->SetNestableTasksAllowed(true); // MessageLoop::current()->SetNestableTasksAllowed(true);
printing_context_->set_use_overlays(use_overlays); printing_context_->set_margin_type(margin_type);
if (ask_user_for_settings) { if (ask_user_for_settings) {
BrowserThread::PostTask( BrowserThread::PostTask(

@ -12,6 +12,7 @@
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "printing/page_number.h" #include "printing/page_number.h"
#include "printing/printing_context.h" #include "printing/printing_context.h"
#include "printing/print_job_constants.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
namespace base { namespace base {
@ -44,7 +45,7 @@ class PrintJobWorker : public base::Thread {
gfx::NativeView parent_view, gfx::NativeView parent_view,
int document_page_count, int document_page_count,
bool has_selection, bool has_selection,
bool use_overlays); MarginType margin_type);
// Set the new print settings. This function takes ownership of // Set the new print settings. This function takes ownership of
// |new_settings|. // |new_settings|.

@ -75,7 +75,7 @@ void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings,
gfx::NativeView parent_view, gfx::NativeView parent_view,
int expected_page_count, int expected_page_count,
bool has_selection, bool has_selection,
bool use_overlays, MarginType margin_type,
CancelableTask* callback) { CancelableTask* callback) {
DCHECK_EQ(io_message_loop_, MessageLoop::current()); DCHECK_EQ(io_message_loop_, MessageLoop::current());
DCHECK(!is_print_dialog_box_shown_); DCHECK(!is_print_dialog_box_shown_);
@ -91,7 +91,7 @@ void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings,
parent_view, parent_view,
expected_page_count, expected_page_count,
has_selection, has_selection,
use_overlays)); margin_type));
} }
void PrinterQuery::SetSettings(const DictionaryValue& new_settings, void PrinterQuery::SetSettings(const DictionaryValue& new_settings,

@ -8,6 +8,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "chrome/browser/printing/print_job_worker_owner.h" #include "chrome/browser/printing/print_job_worker_owner.h"
#include "printing/print_job_constants.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
class CancelableTask; class CancelableTask;
@ -49,7 +50,7 @@ class PrinterQuery : public PrintJobWorkerOwner {
gfx::NativeView parent_view, gfx::NativeView parent_view,
int expected_page_count, int expected_page_count,
bool has_selection, bool has_selection,
bool use_overlays, MarginType margin_type,
CancelableTask* callback); CancelableTask* callback);
// Updates the current settings with |new_settings| dictionary values. // Updates the current settings with |new_settings| dictionary values.

@ -47,8 +47,8 @@ void RenderParamsFromPrintSettings(const printing::PrintSettings& settings,
params->printable_size.SetSize( params->printable_size.SetSize(
settings.page_setup_device_units().content_area().width(), settings.page_setup_device_units().content_area().width(),
settings.page_setup_device_units().content_area().height()); settings.page_setup_device_units().content_area().height());
params->margin_top = settings.page_setup_device_units().content_area().x(); params->margin_top = settings.page_setup_device_units().content_area().y();
params->margin_left = settings.page_setup_device_units().content_area().y(); params->margin_left = settings.page_setup_device_units().content_area().x();
params->dpi = settings.dpi(); params->dpi = settings.dpi();
// Currently hardcoded at 1.25. See PrintSettings' constructor. // Currently hardcoded at 1.25. See PrintSettings' constructor.
params->min_shrink = settings.min_shrink; params->min_shrink = settings.min_shrink;
@ -197,7 +197,7 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
NULL, NULL,
0, 0,
false, false,
true, printing::DEFAULT_MARGINS,
task); task);
} }
@ -248,7 +248,7 @@ void PrintingMessageFilter::OnScriptedPrint(
host_view, host_view,
params.expected_pages_count, params.expected_pages_count,
params.has_selection, params.has_selection,
params.use_overlays, params.margin_type,
task); task);
} }

@ -12,6 +12,7 @@
#include "base/shared_memory.h" #include "base/shared_memory.h"
#include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_macros.h"
#include "printing/page_size_margins.h" #include "printing/page_size_margins.h"
#include "printing/print_job_constants.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
@ -60,6 +61,8 @@ struct PrintMsg_PrintPages_Params {
#define IPC_MESSAGE_START PrintMsgStart #define IPC_MESSAGE_START PrintMsgStart
IPC_ENUM_TRAITS(printing::MarginType)
// Parameters for a render request. // Parameters for a render request.
IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params) IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params)
// Physical size of the page, including non-printable margins, // Physical size of the page, including non-printable margins,
@ -239,7 +242,7 @@ IPC_STRUCT_BEGIN(PrintHostMsg_ScriptedPrint_Params)
IPC_STRUCT_MEMBER(int, cookie) IPC_STRUCT_MEMBER(int, cookie)
IPC_STRUCT_MEMBER(int, expected_pages_count) IPC_STRUCT_MEMBER(int, expected_pages_count)
IPC_STRUCT_MEMBER(bool, has_selection) IPC_STRUCT_MEMBER(bool, has_selection)
IPC_STRUCT_MEMBER(bool, use_overlays) IPC_STRUCT_MEMBER(printing::MarginType, margin_type)
IPC_STRUCT_END() IPC_STRUCT_END()

@ -152,83 +152,17 @@ bool PrintingNodeOrPdfFrame(const WebFrame* frame, const WebNode& node) {
return mime == "application/pdf"; return mime == "application/pdf";
} }
void SetMarginsForPDF(PrintMsg_Print_Params* settings) { void SetMarginsForPdf(DictionaryValue* job_settings, bool force_no_margins) {
// This is the wrong way to do this. But the pipeline for the right way is // TODO(vandebo) When it's plumbed through, check if the plugin wants us to
// too long. This will be removed soon. http://crbug.com/92000 // scale or not. For now, assume the answer is yes.
settings->margin_top = 0; if (force_no_margins) {
settings->margin_left = 0; job_settings->SetInteger(printing::kSettingMarginsType,
settings->printable_size.set_width(settings->page_size.width()); printing::NO_MARGINS);
settings->printable_size.set_height(settings->page_size.height()); } else {
} job_settings->SetInteger(printing::kSettingMarginsType,
printing::PRINTABLE_AREA_MARGINS);
// Get the margins option selected and set custom margins appropriately.
void SetCustomMarginsIfSelected(const DictionaryValue& job_settings,
PrintMsg_PrintPages_Params* settings) {
int margin_type = printing::DEFAULT_MARGINS;
if (!job_settings.GetInteger(printing::kSettingMarginsType, &margin_type)) {
NOTREACHED();
} }
if (margin_type == printing::DEFAULT_MARGINS)
return;
double custom_margin_top_in_points = 0;
double custom_margin_left_in_points = 0;
double custom_margin_right_in_points = 0;
double custom_margin_bottom_in_points = 0;
if (margin_type == printing::CUSTOM_MARGINS) {
DictionaryValue* custom_margins;
if (!job_settings.GetDictionary(printing::kSettingMarginsCustom,
&custom_margins)) {
NOTREACHED();
return;
}
if (!custom_margins->GetDouble(printing::kSettingMarginTop,
&custom_margin_top_in_points) ||
!custom_margins->GetDouble(printing::kSettingMarginLeft,
&custom_margin_left_in_points) ||
!custom_margins->GetDouble(printing::kSettingMarginRight,
&custom_margin_right_in_points) ||
!custom_margins->GetDouble(printing::kSettingMarginBottom,
&custom_margin_bottom_in_points)) {
NOTREACHED();
return;
}
}
int dpi = GetDPI(&settings->params);
double custom_margin_top_in_dots = ConvertUnitDouble(
custom_margin_top_in_points, printing::kPointsPerInch, dpi);
double custom_margin_left_in_dots = ConvertUnitDouble(
custom_margin_left_in_points, printing::kPointsPerInch, dpi);
double custom_margin_right_in_dots = ConvertUnitDouble(
custom_margin_right_in_points, printing::kPointsPerInch, dpi);
double custom_margin_bottom_in_dots = ConvertUnitDouble(
custom_margin_bottom_in_points, printing::kPointsPerInch, dpi);
if (custom_margin_left_in_dots < 0 || custom_margin_right_in_dots < 0 ||
custom_margin_top_in_dots < 0 || custom_margin_bottom_in_dots < 0) {
NOTREACHED();
return;
}
if (settings->params.page_size.width() < custom_margin_left_in_dots +
custom_margin_right_in_dots ||
settings->params.page_size.height() < custom_margin_top_in_dots +
custom_margin_bottom_in_dots) {
NOTREACHED();
return;
}
settings->params.margin_top = custom_margin_top_in_dots;
settings->params.margin_left = custom_margin_left_in_dots;
settings->params.printable_size.set_width(
settings->params.page_size.width() - custom_margin_right_in_dots -
custom_margin_left_in_dots);
settings->params.printable_size.set_height(
settings->params.page_size.height() - custom_margin_bottom_in_dots -
custom_margin_top_in_dots);
} }
// Get the (x, y) coordinate from where printing of the current text should // Get the (x, y) coordinate from where printing of the current text should
@ -582,13 +516,13 @@ void PrintWebViewHelper::OnPrintForPrintPreview(
return; return;
} }
if (!UpdatePrintSettings(job_settings, false)) { WebFrame* pdf_frame = pdf_element.document().frame();
if (!UpdatePrintSettings(pdf_frame, pdf_element, job_settings, false)) {
LOG(ERROR) << "UpdatePrintSettings failed"; LOG(ERROR) << "UpdatePrintSettings failed";
DidFinishPrinting(FAIL_PRINT); DidFinishPrinting(FAIL_PRINT);
return; return;
} }
WebFrame* pdf_frame = pdf_element.document().frame();
scoped_ptr<PrepareFrameAndViewForPrint> prepare; scoped_ptr<PrepareFrameAndViewForPrint> prepare;
prepare.reset(new PrepareFrameAndViewForPrint(print_pages_params_->params, prepare.reset(new PrepareFrameAndViewForPrint(print_pages_params_->params,
pdf_frame, pdf_element)); pdf_frame, pdf_element));
@ -636,7 +570,8 @@ void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) {
DCHECK(is_preview_); DCHECK(is_preview_);
print_preview_context_.OnPrintPreview(); print_preview_context_.OnPrintPreview();
if (!UpdatePrintSettings(settings, true)) { if (!UpdatePrintSettings(print_preview_context_.frame(),
print_preview_context_.node(), settings, true)) {
if (print_preview_context_.last_error() != PREVIEW_ERROR_BAD_SETTING) { if (print_preview_context_.last_error() != PREVIEW_ERROR_BAD_SETTING) {
Send(new PrintHostMsg_PrintPreviewInvalidPrinterSettings( Send(new PrintHostMsg_PrintPreviewInvalidPrinterSettings(
routing_id(), print_pages_params_->params.document_cookie)); routing_id(), print_pages_params_->params.document_cookie));
@ -1109,20 +1044,35 @@ bool PrintWebViewHelper::InitPrintSettingsAndPrepareFrame(
} }
bool PrintWebViewHelper::UpdatePrintSettings( bool PrintWebViewHelper::UpdatePrintSettings(
const DictionaryValue& job_settings, bool generating_preview) { WebKit::WebFrame* frame, const WebKit::WebNode& node,
if (job_settings.empty()) { const DictionaryValue& passed_job_settings, bool generating_preview) {
DCHECK(is_preview_);
const DictionaryValue* job_settings = &passed_job_settings;
DictionaryValue modified_job_settings;
if (job_settings->empty()) {
if (generating_preview) if (generating_preview)
print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING); print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING);
return false; return false;
} }
bool is_pdf = PrintingNodeOrPdfFrame(frame, node);
if (is_pdf || !generating_preview) {
modified_job_settings.MergeDictionary(job_settings);
SetMarginsForPdf(&modified_job_settings, !generating_preview);
if (is_pdf) {
modified_job_settings.SetBoolean(printing::kSettingHeaderFooterEnabled,
false);
}
job_settings = &modified_job_settings;
}
// Send the cookie so that UpdatePrintSettings can reuse PrinterQuery when // Send the cookie so that UpdatePrintSettings can reuse PrinterQuery when
// possible. // possible.
int cookie = print_pages_params_.get() ? int cookie = print_pages_params_.get() ?
print_pages_params_->params.document_cookie : 0; print_pages_params_->params.document_cookie : 0;
PrintMsg_PrintPages_Params settings; PrintMsg_PrintPages_Params settings;
Send(new PrintHostMsg_UpdatePrintSettings(routing_id(), Send(new PrintHostMsg_UpdatePrintSettings(routing_id(),
cookie, job_settings, &settings)); cookie, *job_settings, &settings));
print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings));
if (PrintMsg_Print_Params_IsEmpty(settings.params)) { if (PrintMsg_Print_Params_IsEmpty(settings.params)) {
@ -1150,22 +1100,17 @@ bool PrintWebViewHelper::UpdatePrintSettings(
if (generating_preview) { if (generating_preview) {
// Validate expected print preview settings. // Validate expected print preview settings.
if (!job_settings.GetString(printing::kPreviewUIAddr, if (!job_settings->GetString(printing::kPreviewUIAddr,
&(settings.params.preview_ui_addr)) || &(settings.params.preview_ui_addr)) ||
!job_settings.GetInteger(printing::kPreviewRequestID, !job_settings->GetInteger(printing::kPreviewRequestID,
&(settings.params.preview_request_id)) || &(settings.params.preview_request_id)) ||
!job_settings.GetBoolean(printing::kIsFirstRequest, !job_settings->GetBoolean(printing::kIsFirstRequest,
&(settings.params.is_first_request))) { &(settings.params.is_first_request))) {
NOTREACHED(); NOTREACHED();
print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING); print_preview_context_.set_error(PREVIEW_ERROR_BAD_SETTING);
return false; return false;
} }
if (settings.params.is_first_request &&
!print_preview_context_.IsModifiable()) {
settings.params.display_header_footer = false;
}
// Margins: Send default page layout to browser process. // Margins: Send default page layout to browser process.
PageSizeMargins default_page_layout; PageSizeMargins default_page_layout;
GetPageSizeAndMarginsInPoints(NULL, -1, settings.params, GetPageSizeAndMarginsInPoints(NULL, -1, settings.params,
@ -1175,7 +1120,6 @@ bool PrintWebViewHelper::UpdatePrintSettings(
Send(new PrintHostMsg_DidGetDefaultPageLayout(routing_id(), Send(new PrintHostMsg_DidGetDefaultPageLayout(routing_id(),
default_page_layout)); default_page_layout));
} }
SetCustomMarginsIfSelected(job_settings, &settings);
// Header/Footer: Set |header_footer_info_|. // Header/Footer: Set |header_footer_info_|.
if (settings.params.display_header_footer) { if (settings.params.display_header_footer) {
@ -1189,12 +1133,6 @@ bool PrintWebViewHelper::UpdatePrintSettings(
} }
} }
if ((is_preview_ && !generating_preview) ||
PrintingNodeOrPdfFrame(print_preview_context_.frame(),
print_preview_context_.node())) {
SetMarginsForPDF(&settings.params);
}
print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings));
Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(), Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(),
settings.params.document_cookie)); settings.params.document_cookie));
@ -1218,7 +1156,7 @@ bool PrintWebViewHelper::GetPrintSettingsFromUser(WebKit::WebFrame* frame,
params.cookie = print_pages_params_->params.document_cookie; params.cookie = print_pages_params_->params.document_cookie;
params.has_selection = frame->hasSelection(); params.has_selection = frame->hasSelection();
params.expected_pages_count = expected_pages_count; params.expected_pages_count = expected_pages_count;
params.use_overlays = use_browser_overlays; params.margin_type = printing::DEFAULT_MARGINS;
Send(new PrintHostMsg_DidShowPrintDialog(routing_id())); Send(new PrintHostMsg_DidShowPrintDialog(routing_id()));

@ -178,7 +178,9 @@ class PrintWebViewHelper
// Update the current print settings with new |job_settings|. |job_settings| // Update the current print settings with new |job_settings|. |job_settings|
// dictionary contains print job details such as printer name, number of // dictionary contains print job details such as printer name, number of
// copies, page range, etc. // copies, page range, etc.
bool UpdatePrintSettings(const base::DictionaryValue& job_settings, bool UpdatePrintSettings(WebKit::WebFrame* frame,
const WebKit::WebNode& node,
const base::DictionaryValue& passed_job_settings,
bool generating_preview); bool generating_preview);
// Get final print settings from the user. // Get final print settings from the user.

@ -37,7 +37,8 @@ bool PageMargins::Equals(const PageMargins& rhs) const {
bottom == rhs.bottom; bottom == rhs.bottom;
} }
PageSetup::PageSetup() : text_height_(0) { PageSetup::PageSetup() {
Clear();
} }
PageSetup::~PageSetup() {} PageSetup::~PageSetup() {}
@ -75,56 +76,19 @@ void PageSetup::Init(const gfx::Size& physical_size,
printable_area_ = printable_area; printable_area_ = printable_area;
text_height_ = text_height; text_height_ = text_height;
// Calculate the effective margins. The tricky part. CalculateSizesWithinRect(printable_area_);
effective_margins_.header = std::max(requested_margins_.header,
printable_area_.y());
effective_margins_.footer = std::max(requested_margins_.footer,
physical_size.height() -
printable_area_.bottom());
effective_margins_.left = std::max(requested_margins_.left,
printable_area_.x());
effective_margins_.top = std::max(std::max(requested_margins_.top,
printable_area_.y()),
effective_margins_.header + text_height);
effective_margins_.right = std::max(requested_margins_.right,
physical_size.width() -
printable_area_.right());
effective_margins_.bottom = std::max(std::max(requested_margins_.bottom,
physical_size.height() -
printable_area_.bottom()),
effective_margins_.footer + text_height);
// Calculate the overlay area. If the margins are excessive, the overlay_area
// size will be (0, 0).
overlay_area_.set_x(effective_margins_.left);
overlay_area_.set_y(effective_margins_.header);
overlay_area_.set_width(std::max(0,
physical_size.width() -
effective_margins_.right -
overlay_area_.x()));
overlay_area_.set_height(std::max(0,
physical_size.height() -
effective_margins_.footer -
overlay_area_.y()));
// Calculate the content area. If the margins are excessive, the content_area
// size will be (0, 0).
content_area_.set_x(effective_margins_.left);
content_area_.set_y(effective_margins_.top);
content_area_.set_width(std::max(0,
physical_size.width() -
effective_margins_.right -
content_area_.x()));
content_area_.set_height(std::max(0,
physical_size.height() -
effective_margins_.bottom -
content_area_.y()));
} }
void PageSetup::SetRequestedMargins(const PageMargins& requested_margins) { void PageSetup::SetRequestedMargins(const PageMargins& requested_margins) {
requested_margins_ = requested_margins;
if (printable_area_.width() && printable_area_.height())
CalculateSizesWithinRect(printable_area_);
}
void PageSetup::ForceRequestedMargins(const PageMargins& requested_margins) {
requested_margins_ = requested_margins; requested_margins_ = requested_margins;
if (physical_size_.width() && physical_size_.height()) if (physical_size_.width() && physical_size_.height())
Init(physical_size_, printable_area_, text_height_); CalculateSizesWithinRect(gfx::Rect(physical_size_));
} }
void PageSetup::FlipOrientation() { void PageSetup::FlipOrientation() {
@ -140,4 +104,51 @@ void PageSetup::FlipOrientation() {
} }
} }
void PageSetup::CalculateSizesWithinRect(const gfx::Rect& bounds) {
// Calculate the effective margins. The tricky part.
effective_margins_.header = std::max(requested_margins_.header,
bounds.y());
effective_margins_.footer = std::max(requested_margins_.footer,
physical_size_.height() -
bounds.bottom());
effective_margins_.left = std::max(requested_margins_.left,
bounds.x());
effective_margins_.top = std::max(std::max(requested_margins_.top,
bounds.y()),
effective_margins_.header + text_height_);
effective_margins_.right = std::max(requested_margins_.right,
physical_size_.width() -
bounds.right());
effective_margins_.bottom =
std::max(std::max(requested_margins_.bottom,
physical_size_.height() - bounds.bottom()),
effective_margins_.footer + text_height_);
// Calculate the overlay area. If the margins are excessive, the overlay_area
// size will be (0, 0).
overlay_area_.set_x(effective_margins_.left);
overlay_area_.set_y(effective_margins_.header);
overlay_area_.set_width(std::max(0,
physical_size_.width() -
effective_margins_.right -
overlay_area_.x()));
overlay_area_.set_height(std::max(0,
physical_size_.height() -
effective_margins_.footer -
overlay_area_.y()));
// Calculate the content area. If the margins are excessive, the content_area
// size will be (0, 0).
content_area_.set_x(effective_margins_.left);
content_area_.set_y(effective_margins_.top);
content_area_.set_width(std::max(0,
physical_size_.width() -
effective_margins_.right -
content_area_.x()));
content_area_.set_height(std::max(0,
physical_size_.height() -
effective_margins_.bottom -
content_area_.y()));
}
} // namespace printing } // namespace printing

@ -46,8 +46,12 @@ class PRINTING_EXPORT PageSetup {
void Init(const gfx::Size& physical_size, const gfx::Rect& printable_area, void Init(const gfx::Size& physical_size, const gfx::Rect& printable_area,
int text_height); int text_height);
// Use |requested_margins| as long as they fall inside the printable area.
void SetRequestedMargins(const PageMargins& requested_margins); void SetRequestedMargins(const PageMargins& requested_margins);
// Ignore the printable area, and set the margins to |requested_margins|.
void ForceRequestedMargins(const PageMargins& requested_margins);
// Flips the orientation of the page and recalculates all page areas. // Flips the orientation of the page and recalculates all page areas.
void FlipOrientation(); void FlipOrientation();
@ -60,6 +64,10 @@ class PRINTING_EXPORT PageSetup {
} }
private: private:
// Calculate overlay_area_, effective_margins_, and content_area_, based on
// a constraint of |bounds|.
void CalculateSizesWithinRect(const gfx::Rect& bounds);
// Physical size of the page, including non-printable margins. // Physical size of the page, including non-printable margins.
gfx::Size physical_size_; gfx::Size physical_size_;

@ -11,6 +11,7 @@
namespace printing { namespace printing {
class Metafile; class Metafile;
class PrintSettings;
// An interface for GTK printing dialogs. Classes that live outside of // An interface for GTK printing dialogs. Classes that live outside of
// printing/ can implement this interface and get threading requirements // printing/ can implement this interface and get threading requirements
@ -20,12 +21,13 @@ class PrintDialogGtkInterface {
// Tell the dialog to use the default print setting. // Tell the dialog to use the default print setting.
virtual void UseDefaultSettings() = 0; virtual void UseDefaultSettings() = 0;
// Update the dialog to use |settings| and |ranges|, where |settings| is a // Update the dialog to use |job_settings| and |ranges|, where |job_settings|
// dictionary of settings with possible keys from // is a dictionary of settings with possible keys from
// printing/print_job_constants.h. Only used when printing without the system // printing/print_job_constants.h. Only used when printing without the system
// print dialog. E.g. for Print Preview. Returns false on error. // print dialog. E.g. for Print Preview. Returns false on error.
virtual bool UpdateSettings(const base::DictionaryValue& settings, virtual bool UpdateSettings(const base::DictionaryValue& job_settings,
const PageRanges& ranges) = 0; const PageRanges& ranges,
PrintSettings* settings) = 0;
// Shows the dialog and handles the response with |callback|. Only used when // Shows the dialog and handles the response with |callback|. Only used when
// printing with the native print dialog. // printing with the native print dialog.

@ -5,6 +5,7 @@
#include "printing/print_settings.h" #include "printing/print_settings.h"
#include "base/atomic_sequence_num.h" #include "base/atomic_sequence_num.h"
#include "base/logging.h"
#include "printing/print_job_constants.h" #include "printing/print_job_constants.h"
#include "printing/units.h" #include "printing/units.h"
@ -114,7 +115,7 @@ PrintSettings::PrintSettings()
max_shrink(2.0), max_shrink(2.0),
desired_dpi(72), desired_dpi(72),
selection_only(false), selection_only(false),
use_overlays(true), margin_type(DEFAULT_MARGINS),
display_header_footer(false), display_header_footer(false),
dpi_(0), dpi_(0),
landscape_(false), landscape_(false),
@ -146,34 +147,67 @@ void PrintSettings::SetPrinterPrintableArea(
gfx::Size const& physical_size_device_units, gfx::Size const& physical_size_device_units,
gfx::Rect const& printable_area_device_units, gfx::Rect const& printable_area_device_units,
int units_per_inch) { int units_per_inch) {
int header_footer_text_height = 0; int header_footer_text_height = 0;
int margin_printer_units = 0; if (display_header_footer) {
if (use_overlays) {
// Hard-code text_height = 0.5cm = ~1/5 of inch. // Hard-code text_height = 0.5cm = ~1/5 of inch.
header_footer_text_height = ConvertUnit(kSettingHeaderFooterInterstice, header_footer_text_height = ConvertUnit(kSettingHeaderFooterInterstice,
kPointsPerInch, units_per_inch); kPointsPerInch, units_per_inch);
// Default margins 1.0cm = ~2/5 of an inch.
margin_printer_units = ConvertUnit(1000, kHundrethsMMPerInch,
units_per_inch);
} }
// Start by setting the user configuration
page_setup_device_units_.Init(physical_size_device_units, page_setup_device_units_.Init(physical_size_device_units,
printable_area_device_units, printable_area_device_units,
header_footer_text_height); header_footer_text_height);
// Apply default margins (not user configurable just yet).
// Since the font height is half the margin we put the header and footers at
// the font height from the margins.
PageMargins margins; PageMargins margins;
margins.header = header_footer_text_height; margins.header = header_footer_text_height;
margins.footer = header_footer_text_height; margins.footer = header_footer_text_height;
margins.left = margin_printer_units; switch (margin_type) {
margins.top = margin_printer_units; case DEFAULT_MARGINS: {
margins.right = margin_printer_units; // Default margins 1.0cm = ~2/5 of an inch.
margins.bottom = margin_printer_units; int margin_printer_units = ConvertUnit(1000, kHundrethsMMPerInch,
page_setup_device_units_.SetRequestedMargins(margins); units_per_inch);
margins.top = margin_printer_units;
margins.bottom = margin_printer_units;
margins.left = margin_printer_units;
margins.right = margin_printer_units;
break;
}
case NO_MARGINS:
case PRINTABLE_AREA_MARGINS: {
margins.top = 0;
margins.bottom = 0;
margins.left = 0;
margins.right = 0;
break;
}
case CUSTOM_MARGINS: {
margins.top = ConvertUnitDouble(custom_margins_in_points_.top,
printing::kPointsPerInch,
units_per_inch);
margins.bottom = ConvertUnitDouble(custom_margins_in_points_.bottom,
printing::kPointsPerInch,
units_per_inch);
margins.left = ConvertUnitDouble(custom_margins_in_points_.left,
printing::kPointsPerInch,
units_per_inch);
margins.right = ConvertUnitDouble(custom_margins_in_points_.right,
printing::kPointsPerInch,
units_per_inch);
break;
}
default: {
NOTREACHED();
}
}
if (margin_type == DEFAULT_MARGINS || margin_type == PRINTABLE_AREA_MARGINS)
page_setup_device_units_.SetRequestedMargins(margins);
else
page_setup_device_units_.ForceRequestedMargins(margins);
}
void PrintSettings::SetCustomMargins(const PageMargins& margins_in_points) {
custom_margins_in_points_ = margins_in_points;
margin_type = CUSTOM_MARGINS;
} }
bool PrintSettings::Equals(const PrintSettings& rhs) const { bool PrintSettings::Equals(const PrintSettings& rhs) const {

@ -11,6 +11,7 @@
#include "base/string16.h" #include "base/string16.h"
#include "printing/page_range.h" #include "printing/page_range.h"
#include "printing/page_setup.h" #include "printing/page_setup.h"
#include "printing/print_job_constants.h"
#include "printing/printing_export.h" #include "printing/printing_export.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
@ -40,6 +41,8 @@ class PRINTING_EXPORT PrintSettings {
gfx::Rect const& printable_area_device_units, gfx::Rect const& printable_area_device_units,
int units_per_inch); int units_per_inch);
void SetCustomMargins(const PageMargins& margins_in_points);
// Equality operator. // Equality operator.
// NOTE: printer_name is NOT tested for equality since it doesn't affect the // NOTE: printer_name is NOT tested for equality since it doesn't affect the
// output. // output.
@ -95,10 +98,8 @@ class PRINTING_EXPORT PrintSettings {
// Indicates if the user only wants to print the current selection. // Indicates if the user only wants to print the current selection.
bool selection_only; bool selection_only;
// Indicates whether we should use browser-controlled page overlays // Indicates what kind of margins should be applied to the printable area.
// (header, footer, margins etc). If it is false, the overlays are MarginType margin_type;
// controlled by the renderer.
bool use_overlays;
// Cookie generator. It is used to initialize PrintedDocument with its // Cookie generator. It is used to initialize PrintedDocument with its
// associated PrintSettings, to be sure that each generated PrintedPage is // associated PrintSettings, to be sure that each generated PrintedPage is
@ -137,6 +138,9 @@ class PRINTING_EXPORT PrintSettings {
// True if this printer supports AlphaBlend. // True if this printer supports AlphaBlend.
bool supports_alpha_blend_; bool supports_alpha_blend_;
// If margin type is custom, these are the margins.
PageMargins custom_margins_in_points_;
}; };
} // namespace printing } // namespace printing

@ -4,7 +4,9 @@
#include "printing/printing_context.h" #include "printing/printing_context.h"
#include "base/logging.h"
#include "base/values.h" #include "base/values.h"
#include "printing/page_setup.h"
#include "printing/print_settings_initializer.h" #include "printing/print_settings_initializer.h"
namespace printing { namespace printing {
@ -19,6 +21,11 @@ PrintingContext::PrintingContext(const std::string& app_locale)
PrintingContext::~PrintingContext() { PrintingContext::~PrintingContext() {
} }
void PrintingContext::set_margin_type(MarginType type) {
DCHECK(type != CUSTOM_MARGINS);
settings_.margin_type = type;
}
void PrintingContext::ResetSettings() { void PrintingContext::ResetSettings() {
ReleaseContext(); ReleaseContext();
@ -37,6 +44,51 @@ PrintingContext::Result PrintingContext::OnError() {
PrintingContext::Result PrintingContext::UpdatePrintSettings( PrintingContext::Result PrintingContext::UpdatePrintSettings(
const base::DictionaryValue& job_settings, const base::DictionaryValue& job_settings,
const PageRanges& ranges) { const PageRanges& ranges) {
ResetSettings();
if (!job_settings.GetBoolean(printing::kSettingHeaderFooterEnabled,
&settings_.display_header_footer)) {
NOTREACHED();
}
int margin_type = DEFAULT_MARGINS;
if (!job_settings.GetInteger(printing::kSettingMarginsType, &margin_type) ||
(margin_type != DEFAULT_MARGINS &&
margin_type != NO_MARGINS &&
margin_type != CUSTOM_MARGINS &&
margin_type != PRINTABLE_AREA_MARGINS)) {
NOTREACHED();
}
settings_.margin_type = static_cast<MarginType>(margin_type);
if (margin_type == CUSTOM_MARGINS) {
double top_margin_in_points = 0;
double bottom_margin_in_points = 0;
double left_margin_in_points = 0;
double right_margin_in_points = 0;
DictionaryValue* custom_margins;
if (!job_settings.GetDictionary(printing::kSettingMarginsCustom,
&custom_margins) ||
!custom_margins->GetDouble(printing::kSettingMarginTop,
&top_margin_in_points) ||
!custom_margins->GetDouble(printing::kSettingMarginBottom,
&bottom_margin_in_points) ||
!custom_margins->GetDouble(printing::kSettingMarginLeft,
&left_margin_in_points) ||
!custom_margins->GetDouble(printing::kSettingMarginRight,
&right_margin_in_points)) {
NOTREACHED();
}
PageMargins margins_in_points;
margins_in_points.Clear();
margins_in_points.top = top_margin_in_points;
margins_in_points.bottom = bottom_margin_in_points;
margins_in_points.left = left_margin_in_points;
margins_in_points.right = right_margin_in_points;
settings_.SetCustomMargins(margins_in_points);
}
PrintingContext::Result result = UpdatePrinterSettings(job_settings, ranges); PrintingContext::Result result = UpdatePrinterSettings(job_settings, ranges);
printing::PrintSettingsInitializer::InitHeaderFooterStrings(job_settings, printing::PrintSettingsInitializer::InitHeaderFooterStrings(job_settings,
&settings_); &settings_);

@ -98,9 +98,7 @@ class PRINTING_EXPORT PrintingContext {
// caller owns the returned object. // caller owns the returned object.
static PrintingContext* Create(const std::string& app_locale); static PrintingContext* Create(const std::string& app_locale);
void set_use_overlays(bool use_overlays) { void set_margin_type(MarginType type);
settings_.use_overlays = use_overlays;
}
const PrintSettings& settings() const { const PrintSettings& settings() const {
return settings_; return settings_;

@ -163,7 +163,7 @@ PrintingContext::Result PrintingContextCairo::UpdatePrinterSettings(
print_dialog_->AddRefToDialog(); print_dialog_->AddRefToDialog();
} }
if (!print_dialog_->UpdateSettings(job_settings, ranges)) if (!print_dialog_->UpdateSettings(job_settings, ranges, &settings_))
return OnError(); return OnError();
return OK; return OK;

@ -383,11 +383,6 @@ PrintingContext::Result PrintingContextWin::UpdatePrinterSettings(
return OK; return OK;
} }
// Underlying |settings_| do not have these attributes, so we need to
// operate on printer directly, which involves reloading settings.
// Therefore, reset the settings anyway.
ResetSettings();
HANDLE printer; HANDLE printer;
LPWSTR device_name_wide = const_cast<wchar_t*>(device_name.c_str()); LPWSTR device_name_wide = const_cast<wchar_t*>(device_name.c_str());
if (!OpenPrinter(device_name_wide, &printer, NULL)) if (!OpenPrinter(device_name_wide, &printer, NULL))