mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-23 15:37:51 +01:00
Allow customization of print options via CefHandler::HandlePrintOptions() (issue #112).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@98 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
79134a77f2
commit
d51d871a52
@ -635,6 +635,19 @@ public:
|
||||
virtual RetVal HandleMenuAction(CefRefPtr<CefBrowser> browser,
|
||||
MenuId menuId) =0;
|
||||
|
||||
// Structure representing print options.
|
||||
typedef cef_print_options_t CefPrintOptions;
|
||||
|
||||
// Event called to allow customization of standard print options before the
|
||||
// print dialog is displayed. |printOptions| allows specification of paper
|
||||
// size, orientation and margins. Note that the specified margins may be
|
||||
// adjusted if they are outside the range supported by the printer. All units
|
||||
// are in inches. Return RV_CONTINUE to display the default print options or
|
||||
// RV_HANDLED to display the modified |printOptions|.
|
||||
/*--cef()--*/
|
||||
virtual RetVal HandlePrintOptions(CefRefPtr<CefBrowser> browser,
|
||||
CefPrintOptions& printOptions) = 0;
|
||||
|
||||
// Event called to format print headers and footers. |printInfo| contains
|
||||
// platform-specific information about the printer context. |url| is the
|
||||
// URL if the currently printing page, |title| is the title of the currently
|
||||
|
@ -461,6 +461,16 @@ typedef struct _cef_handler_t
|
||||
struct _cef_handler_t* self, struct _cef_browser_t* browser,
|
||||
enum cef_handler_menuid_t menuId);
|
||||
|
||||
// Event called to allow customization of standard print options before the
|
||||
// print dialog is displayed. |printOptions| allows specification of paper
|
||||
// size, orientation and margins. Note that the specified margins may be
|
||||
// adjusted if they are outside the range supported by the printer. All units
|
||||
// are in inches. Return RV_CONTINUE to display the default print options or
|
||||
// RV_HANDLED to display the modified |printOptions|.
|
||||
enum cef_retval_t (CEF_CALLBACK *handle_print_options)(
|
||||
struct _cef_handler_t* self, struct _cef_browser_t* browser,
|
||||
struct _cef_print_options_t* printOptions);
|
||||
|
||||
// Event called to format print headers and footers. |printInfo| contains
|
||||
// platform-specific information about the printer context. |url| is the URL
|
||||
// if the currently printing page, |title| is the title of the currently
|
||||
@ -534,9 +544,13 @@ typedef struct _cef_handler_t
|
||||
enum cef_handler_keyevent_type_t type, int code, int modifiers,
|
||||
int isSystemKey);
|
||||
|
||||
enum cef_retval_t (CEF_CALLBACK *handle_tooltip)(
|
||||
struct _cef_handler_t* self, struct _cef_browser_t* browser,
|
||||
cef_string_t* text);
|
||||
// Event called when the browser is about to display a tooltip. |text|
|
||||
// contains the text that will be displayed in the tooltip. To handle the
|
||||
// display of the tooltip yourself return RV_HANDLED. Otherwise, you can
|
||||
// optionally modify |text| and then return RV_CONTINUE to allow the browser
|
||||
// to display the tooltip.
|
||||
enum cef_retval_t (CEF_CALLBACK *handle_tooltip)(struct _cef_handler_t* self,
|
||||
struct _cef_browser_t* browser, cef_string_t* text);
|
||||
|
||||
// Called to display a console message. Return RV_HANDLED to stop the message
|
||||
// from being output to the console.
|
||||
|
@ -237,6 +237,55 @@ enum cef_thread_id_t
|
||||
TID_FILE = 2,
|
||||
};
|
||||
|
||||
// Paper type for printing.
|
||||
enum cef_paper_type_t
|
||||
{
|
||||
PT_LETTER = 0,
|
||||
PT_LEGAL,
|
||||
PT_EXECUTIVE,
|
||||
PT_A3,
|
||||
PT_A4,
|
||||
PT_CUSTOM
|
||||
};
|
||||
|
||||
// Paper metric information for printing.
|
||||
struct cef_paper_metrics
|
||||
{
|
||||
enum cef_paper_type_t paper_type;
|
||||
//Length and width needed if paper_type is custom_size
|
||||
//Units are in inches.
|
||||
double length;
|
||||
double width;
|
||||
};
|
||||
|
||||
// Paper print margins.
|
||||
struct cef_print_margins
|
||||
{
|
||||
//Margin size in inches for left/right/top/bottom (this is content margins).
|
||||
double left;
|
||||
double right;
|
||||
double top;
|
||||
double bottom;
|
||||
//Margin size (top/bottom) in inches for header/footer.
|
||||
double header;
|
||||
double footer;
|
||||
};
|
||||
|
||||
// Page orientation for printing
|
||||
enum cef_page_orientation
|
||||
{
|
||||
PORTRAIT = 0,
|
||||
LANDSCAPE
|
||||
};
|
||||
|
||||
// Printing options.
|
||||
typedef struct _cef_print_options_t
|
||||
{
|
||||
enum cef_page_orientation page_orientation;
|
||||
struct cef_paper_metrics paper_metrics;
|
||||
struct cef_print_margins paper_margins;
|
||||
} cef_print_options_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -237,13 +237,11 @@ void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
|
||||
const printing::PrintSettings &settings = print_context_.settings();
|
||||
settings.RenderParams(¶ms);
|
||||
|
||||
int src_size_x = canvas_size.width();
|
||||
int src_size_y = canvas_size.height();
|
||||
float src_margin = .1f * src_size_x;
|
||||
const int src_size_x = canvas_size.width();
|
||||
const int src_size_y = canvas_size.height();
|
||||
|
||||
int dest_size_x = settings.page_setup_pixels().physical_size().width();
|
||||
int dest_size_y = settings.page_setup_pixels().physical_size().height();
|
||||
float dest_margin = .1f * dest_size_x;
|
||||
const int dest_size_x = settings.page_setup_pixels().printable_area().width();
|
||||
const int dest_size_y = settings.page_setup_pixels().printable_area().height();
|
||||
|
||||
print_context_.NewPage();
|
||||
|
||||
@ -257,21 +255,26 @@ void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
|
||||
|
||||
skia::VectorCanvas canvas(hDC, dest_size_x, dest_size_y);
|
||||
|
||||
//The hDC 0 coord is the left most printeable area and not physical area of the paper
|
||||
//so subtract that out of our canvas translate.
|
||||
const int left_margin_offset = settings.page_setup_pixels().effective_margins().left -
|
||||
settings.page_setup_pixels().printable_area().x();
|
||||
const int top_margin_offset = settings.page_setup_pixels().effective_margins().top -
|
||||
settings.page_setup_pixels().printable_area().y();
|
||||
|
||||
// Adjust for the margin offset.
|
||||
canvas.translate(dest_margin, dest_margin);
|
||||
canvas.translate(static_cast<float>(left_margin_offset),
|
||||
static_cast<float>(top_margin_offset));
|
||||
|
||||
// Apply the print scaling factor.
|
||||
float print_scale = (dest_size_x - dest_margin * 2) / src_size_x;
|
||||
canvas.scale(print_scale, print_scale);
|
||||
|
||||
// Set the clipping region to be sure to not overflow.
|
||||
SkRect clip_rect;
|
||||
clip_rect.set(0, 0, static_cast<float>(src_size_x),
|
||||
static_cast<float>(src_size_y));
|
||||
canvas.clipRect(clip_rect);
|
||||
const float print_scale_x = static_cast<float>(settings.page_setup_pixels().content_area().width())
|
||||
/ src_size_x;
|
||||
const float print_scale_y = static_cast<float>(settings.page_setup_pixels().content_area().height())
|
||||
/ src_size_y;
|
||||
canvas.scale(print_scale_x, print_scale_y);
|
||||
|
||||
// Apply the WebKit scaling factor.
|
||||
float webkit_scale = frame->getPrintPageShrink(page_number);
|
||||
const float webkit_scale = frame->getPrintPageShrink(page_number);
|
||||
if (webkit_scale <= 0) {
|
||||
NOTREACHED() << "Printing page " << page_number << " failed.";
|
||||
}
|
||||
@ -288,12 +291,17 @@ void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
|
||||
|
||||
// Gather print header state information
|
||||
RECT rect;
|
||||
rect.left = (int)floor(dest_margin / 2);
|
||||
rect.top = rect.left;
|
||||
rect.right = (int)ceil(dest_size_x - dest_margin / 2);
|
||||
rect.bottom = (int)ceil(dest_size_y - dest_margin / 2);
|
||||
rect.left = left_margin_offset;
|
||||
rect.top = settings.page_setup_pixels().effective_margins().header -
|
||||
settings.page_setup_pixels().printable_area().y();
|
||||
rect.right = left_margin_offset + settings.page_setup_pixels().content_area().width();
|
||||
rect.bottom = settings.page_setup_pixels().printable_area().height() -
|
||||
(settings.page_setup_pixels().effective_margins().footer -
|
||||
(settings.page_setup_pixels().physical_size().height() -
|
||||
settings.page_setup_pixels().printable_area().bottom()));
|
||||
|
||||
double scale = (double)settings.dpi() / (double)settings.desired_dpi;
|
||||
const double scale = static_cast<double>(settings.dpi()) /
|
||||
static_cast<double>(settings.desired_dpi);
|
||||
|
||||
CefPrintInfo printInfo;
|
||||
|
||||
@ -374,13 +382,18 @@ void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
|
||||
void CefBrowserImpl::UIT_PrintPages(WebKit::WebFrame* frame) {
|
||||
REQUIRE_UIT();
|
||||
|
||||
TCHAR printername[512];
|
||||
DWORD size = sizeof(printername)-1;
|
||||
if(GetDefaultPrinter(printername, &size)) {
|
||||
printing::PrintSettings settings;
|
||||
settings.set_device_name(printername);
|
||||
// Initialize it.
|
||||
print_context_.InitWithSettings(settings);
|
||||
print_context_.Init();
|
||||
{
|
||||
// Make a copy of settings.
|
||||
printing::PrintSettings settings = print_context_.settings();
|
||||
cef_print_options_t print_options;
|
||||
settings.UpdatePrintOptions(print_options);
|
||||
|
||||
// Ask the handler if they want to update the print options.
|
||||
if (handler_.get() && RV_HANDLED == handler_->HandlePrintOptions(this, print_options)) {
|
||||
settings.UpdateFromPrintOptions(print_options);
|
||||
print_context_.InitWithSettings(settings);
|
||||
}
|
||||
}
|
||||
|
||||
if(print_context_.AskUserForSettings(
|
||||
@ -398,12 +411,12 @@ void CefBrowserImpl::UIT_PrintPages(WebKit::WebFrame* frame) {
|
||||
|
||||
canvas_size.set_width(
|
||||
printing::ConvertUnit(
|
||||
settings.page_setup_pixels().physical_size().width(),
|
||||
settings.page_setup_pixels().content_area().width(),
|
||||
static_cast<int>(params.dpi),
|
||||
params.desired_dpi));
|
||||
canvas_size.set_height(
|
||||
printing::ConvertUnit(
|
||||
settings.page_setup_pixels().physical_size().height(),
|
||||
settings.page_setup_pixels().content_area().height(),
|
||||
static_cast<int>(params.dpi),
|
||||
params.desired_dpi));
|
||||
page_count = frame->printBegin(WebSize(canvas_size));
|
||||
@ -412,19 +425,19 @@ void CefBrowserImpl::UIT_PrintPages(WebKit::WebFrame* frame) {
|
||||
bool old_state = MessageLoop::current()->NestableTasksAllowed();
|
||||
MessageLoop::current()->SetNestableTasksAllowed(false);
|
||||
|
||||
// TODO(cef): Use the page title as the document name
|
||||
print_context_.NewDocument(L"New Document");
|
||||
if(settings.ranges.size() > 0) {
|
||||
for (unsigned x = 0; x < settings.ranges.size(); ++x) {
|
||||
const printing::PageRange& range = settings.ranges[x];
|
||||
for(int i = range.from; i <= range.to; ++i)
|
||||
if (print_context_.NewDocument(title_) == printing::PrintingContext::OK) {
|
||||
if(settings.ranges.size() > 0) {
|
||||
for (unsigned x = 0; x < settings.ranges.size(); ++x) {
|
||||
const printing::PageRange& range = settings.ranges[x];
|
||||
for(int i = range.from; i <= range.to; ++i)
|
||||
UIT_PrintPage(i, page_count, canvas_size, frame);
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < page_count; ++i)
|
||||
UIT_PrintPage(i, page_count, canvas_size, frame);
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < page_count; ++i)
|
||||
UIT_PrintPage(i, page_count, canvas_size, frame);
|
||||
print_context_.DocumentDone();
|
||||
}
|
||||
print_context_.DocumentDone();
|
||||
|
||||
MessageLoop::current()->SetNestableTasksAllowed(old_state);
|
||||
}
|
||||
@ -450,12 +463,12 @@ int CefBrowserImpl::UIT_GetPagesCount(WebKit::WebFrame* frame)
|
||||
|
||||
canvas_size.set_width(
|
||||
printing::ConvertUnit(
|
||||
settings.page_setup_pixels().physical_size().width(),
|
||||
settings.page_setup_pixels().content_area().width(),
|
||||
static_cast<int>(params.dpi),
|
||||
params.desired_dpi));
|
||||
canvas_size.set_height(
|
||||
printing::ConvertUnit(
|
||||
settings.page_setup_pixels().physical_size().height(),
|
||||
settings.page_setup_pixels().content_area().height(),
|
||||
static_cast<int>(params.dpi),
|
||||
params.desired_dpi));
|
||||
page_count = frame->printBegin(WebSize(canvas_size));
|
||||
|
@ -13,6 +13,24 @@ namespace printing {
|
||||
// Global SequenceNumber used for generating unique cookie values.
|
||||
static base::AtomicSequenceNumber cookie_seq(base::LINKER_INITIALIZED);
|
||||
|
||||
PageMeasurements::PageMeasurements()
|
||||
: page_type(PT_LETTER),
|
||||
page_length(0.0f),
|
||||
page_width(0.0f) {
|
||||
}
|
||||
|
||||
void PageMeasurements::Clear() {
|
||||
page_type = PT_LETTER;
|
||||
page_length = 0.0f;
|
||||
page_width = 0.0f;
|
||||
}
|
||||
|
||||
bool PageMeasurements::Equals(const PageMeasurements& rhs) const {
|
||||
return page_type == rhs.page_type &&
|
||||
page_length == rhs.page_length &&
|
||||
page_width == rhs.page_width;
|
||||
}
|
||||
|
||||
PrintSettings::PrintSettings()
|
||||
: min_shrink(1.25),
|
||||
max_shrink(2.0),
|
||||
@ -20,7 +38,8 @@ PrintSettings::PrintSettings()
|
||||
selection_only(false),
|
||||
to_file(false),
|
||||
dpi_(0),
|
||||
landscape_(false) {
|
||||
landscape(false) {
|
||||
ResetRequestedPageMargins();
|
||||
}
|
||||
|
||||
void PrintSettings::Clear() {
|
||||
@ -34,7 +53,22 @@ void PrintSettings::Clear() {
|
||||
device_name_.clear();
|
||||
page_setup_pixels_.Clear();
|
||||
dpi_ = 0;
|
||||
landscape_ = false;
|
||||
landscape = false;
|
||||
page_measurements.Clear();
|
||||
ResetRequestedPageMargins();
|
||||
}
|
||||
|
||||
void PrintSettings::ResetRequestedPageMargins() {
|
||||
// Initial requested margins to = 1.0cm = ~2/5 of inch
|
||||
const int margin_printer_units = ConvertUnit(1000, kHundrethsMMPerInch, desired_dpi);
|
||||
// Initial requested header/footer margins to = 0.5cm = ~1/5 of inch
|
||||
const int header_footer_margins = ConvertUnit(500, kHundrethsMMPerInch, desired_dpi);
|
||||
requested_margins.header = header_footer_margins;
|
||||
requested_margins.footer = header_footer_margins;
|
||||
requested_margins.left = margin_printer_units;
|
||||
requested_margins.top = margin_printer_units;
|
||||
requested_margins.right = margin_printer_units;
|
||||
requested_margins.bottom = margin_printer_units;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
@ -48,10 +82,39 @@ void PrintSettings::Init(HDC hdc,
|
||||
printer_name_ = dev_mode.dmDeviceName;
|
||||
device_name_ = new_device_name;
|
||||
ranges = new_ranges;
|
||||
landscape_ = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;
|
||||
landscape = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;
|
||||
selection_only = print_selection_only;
|
||||
to_file = print_to_file;
|
||||
|
||||
bool is_custom_paper = true;
|
||||
if (dev_mode.dmFields & DM_PAPERSIZE) {
|
||||
switch(dev_mode.dmPaperSize) {
|
||||
case DMPAPER_LETTER:
|
||||
page_measurements.page_type = PT_LETTER;
|
||||
is_custom_paper = false;
|
||||
break;
|
||||
case DMPAPER_LEGAL:
|
||||
page_measurements.page_type = PT_LEGAL;
|
||||
is_custom_paper = false;
|
||||
break;
|
||||
case DMPAPER_EXECUTIVE:
|
||||
page_measurements.page_type = PT_EXECUTIVE;
|
||||
is_custom_paper = false;
|
||||
break;
|
||||
case DMPAPER_A3:
|
||||
page_measurements.page_type = PT_A3;
|
||||
is_custom_paper = false;
|
||||
break;
|
||||
case DMPAPER_A4:
|
||||
page_measurements.page_type = PT_A4;
|
||||
is_custom_paper = false;
|
||||
break;
|
||||
default:
|
||||
//we'll translate it as a custom paper size.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dpi_ = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||
// No printer device is known to advertise different dpi in X and Y axis; even
|
||||
// the fax device using the 200x100 dpi setting. It's ought to break so many
|
||||
@ -70,6 +133,22 @@ void PrintSettings::Init(HDC hdc,
|
||||
GetDeviceCaps(hdc, HORZRES),
|
||||
GetDeviceCaps(hdc, VERTRES));
|
||||
|
||||
if (is_custom_paper) {
|
||||
page_measurements.page_length = ConvertUnitDouble(
|
||||
static_cast<double>(physical_size_pixels.height()),
|
||||
static_cast<double>(dpi_),
|
||||
static_cast<double>(desired_dpi));
|
||||
page_measurements.page_width = ConvertUnitDouble(
|
||||
static_cast<double>(physical_size_pixels.width()),
|
||||
static_cast<double>(dpi_),
|
||||
static_cast<double>(desired_dpi));
|
||||
if (landscape) {
|
||||
double temp = page_measurements.page_length;
|
||||
page_measurements.page_length = page_measurements.page_width;
|
||||
page_measurements.page_width = temp;
|
||||
}
|
||||
|
||||
}
|
||||
SetPrinterPrintableArea(physical_size_pixels, printable_area_pixels);
|
||||
}
|
||||
#endif
|
||||
@ -78,22 +157,22 @@ void PrintSettings::SetPrinterPrintableArea(
|
||||
gfx::Size const& physical_size_pixels,
|
||||
gfx::Rect const& printable_area_pixels) {
|
||||
|
||||
int margin_printer_units = ConvertUnit(500, kHundrethsMMPerInch, dpi_);
|
||||
// Hard-code text_height = 0.5cm = ~1/5 of inch
|
||||
const int text_height = ConvertUnit(500, kHundrethsMMPerInch, dpi_);
|
||||
|
||||
// Start by setting the user configuration
|
||||
// Hard-code text_height = 0.5cm = ~1/5 of inch
|
||||
page_setup_pixels_.Init(physical_size_pixels,
|
||||
printable_area_pixels,
|
||||
margin_printer_units);
|
||||
text_height);
|
||||
|
||||
// Now apply user configured settings.
|
||||
// Now adjust requested margins to the appropriate dpi.
|
||||
PageMargins margins;
|
||||
margins.header = margin_printer_units;
|
||||
margins.footer = margin_printer_units;
|
||||
margins.left = margin_printer_units;
|
||||
margins.top = margin_printer_units;
|
||||
margins.right = margin_printer_units;
|
||||
margins.bottom = margin_printer_units;
|
||||
margins.header = ConvertUnit(requested_margins.header, desired_dpi, dpi_);
|
||||
margins.footer = ConvertUnit(requested_margins.footer, desired_dpi, dpi_);
|
||||
margins.left = ConvertUnit(requested_margins.left, desired_dpi, dpi_);
|
||||
margins.top = ConvertUnit(requested_margins.top, desired_dpi, dpi_);
|
||||
margins.right = ConvertUnit(requested_margins.right, desired_dpi, dpi_);
|
||||
margins.bottom = ConvertUnit(requested_margins.bottom, desired_dpi, dpi_);
|
||||
page_setup_pixels_.SetRequestedMargins(margins);
|
||||
}
|
||||
|
||||
@ -125,7 +204,9 @@ bool PrintSettings::Equals(const PrintSettings& rhs) const {
|
||||
device_name_ == rhs.device_name_ &&
|
||||
page_setup_pixels_.Equals(rhs.page_setup_pixels_) &&
|
||||
dpi_ == rhs.dpi_ &&
|
||||
landscape_ == rhs.landscape_;
|
||||
landscape == rhs.landscape &&
|
||||
page_measurements.Equals(rhs.page_measurements) &&
|
||||
requested_margins.Equals(rhs.requested_margins);
|
||||
}
|
||||
|
||||
int PrintSettings::NewCookie() {
|
||||
@ -133,5 +214,52 @@ int PrintSettings::NewCookie() {
|
||||
return cookie_seq.GetNext() + 1;
|
||||
}
|
||||
|
||||
void PrintSettings::UpdatePrintOptions(cef_print_options_t& print_options) {
|
||||
|
||||
print_options.page_orientation = (landscape) ? LANDSCAPE : PORTRAIT;
|
||||
print_options.paper_metrics.paper_type = page_measurements.page_type;
|
||||
|
||||
if (page_measurements.page_type == PT_CUSTOM) {
|
||||
print_options.paper_metrics.length = ConvertUnitDouble(
|
||||
page_measurements.page_length, desired_dpi, 1);
|
||||
print_options.paper_metrics.width = ConvertUnitDouble(
|
||||
page_measurements.page_width, desired_dpi, 1);
|
||||
}
|
||||
print_options.paper_margins.left = ConvertUnitDouble(
|
||||
requested_margins.left, desired_dpi, 1);
|
||||
print_options.paper_margins.top = ConvertUnitDouble(
|
||||
requested_margins.top, desired_dpi, 1);
|
||||
print_options.paper_margins.right = ConvertUnitDouble(
|
||||
requested_margins.right, desired_dpi, 1);
|
||||
print_options.paper_margins.bottom = ConvertUnitDouble(
|
||||
requested_margins.bottom, desired_dpi, 1);
|
||||
print_options.paper_margins.header = ConvertUnitDouble(
|
||||
requested_margins.header, desired_dpi, 1);
|
||||
print_options.paper_margins.footer = ConvertUnitDouble(
|
||||
requested_margins.footer, desired_dpi, 1);
|
||||
}
|
||||
void PrintSettings::UpdateFromPrintOptions(const cef_print_options_t& print_options) {
|
||||
landscape = print_options.page_orientation == LANDSCAPE;
|
||||
page_measurements.page_type = print_options.paper_metrics.paper_type;
|
||||
if (page_measurements.page_type == PT_CUSTOM) {
|
||||
page_measurements.page_length = ConvertUnitDouble(
|
||||
print_options.paper_metrics.length, 1, desired_dpi);
|
||||
page_measurements.page_width = ConvertUnitDouble(
|
||||
print_options.paper_metrics.width, 1, desired_dpi);
|
||||
}
|
||||
requested_margins.left = static_cast<int>(ConvertUnitDouble(
|
||||
print_options.paper_margins.left, 1, desired_dpi));
|
||||
requested_margins.top = static_cast<int>(ConvertUnitDouble(
|
||||
print_options.paper_margins.top, 1, desired_dpi));
|
||||
requested_margins.right = static_cast<int>(ConvertUnitDouble(
|
||||
print_options.paper_margins.right, 1, desired_dpi));
|
||||
requested_margins.bottom = static_cast<int>(ConvertUnitDouble(
|
||||
print_options.paper_margins.bottom, 1, desired_dpi));
|
||||
requested_margins.header = static_cast<int>(ConvertUnitDouble(
|
||||
print_options.paper_margins.header, 1, desired_dpi));
|
||||
requested_margins.footer = static_cast<int>(ConvertUnitDouble(
|
||||
print_options.paper_margins.footer, 1, desired_dpi));
|
||||
}
|
||||
|
||||
} // namespace printing
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef _PRINTING_PRINT_SETTINGS_H
|
||||
#define _PRINTING_PRINT_SETTINGS_H
|
||||
|
||||
#include "include/cef_types.h"
|
||||
|
||||
#include "gfx/rect.h"
|
||||
#include "printing/page_range.h"
|
||||
#include "printing/page_setup.h"
|
||||
@ -52,6 +54,22 @@ struct PrintParams {
|
||||
}
|
||||
};
|
||||
|
||||
// Page measurements information.
|
||||
class PageMeasurements {
|
||||
public:
|
||||
PageMeasurements();
|
||||
void Clear();
|
||||
|
||||
// Equality operator.
|
||||
bool Equals(const PageMeasurements& rhs) const;
|
||||
|
||||
enum cef_paper_type_t page_type;
|
||||
// Page length and width represented in inches.
|
||||
// These should be filled in if page_type is PT_CUSTOM.
|
||||
double page_length;
|
||||
double page_width;
|
||||
};
|
||||
|
||||
// OS-independent print settings.
|
||||
class PrintSettings {
|
||||
public:
|
||||
@ -92,6 +110,9 @@ class PrintSettings {
|
||||
int dpi() const { return dpi_; }
|
||||
const PageSetup& page_setup_pixels() const { return page_setup_pixels_; }
|
||||
|
||||
void UpdatePrintOptions(cef_print_options_t& print_options);
|
||||
void UpdateFromPrintOptions(const cef_print_options_t& print_options);
|
||||
|
||||
// Multi-page printing. Each PageRange describes a from-to page combination.
|
||||
// This permits printing selected pages only.
|
||||
PageRanges ranges;
|
||||
@ -124,7 +145,17 @@ class PrintSettings {
|
||||
// correctly associated with its corresponding PrintedDocument.
|
||||
static int NewCookie();
|
||||
|
||||
// Requested Page Margins in pixels based on desired_dpi.
|
||||
// These are in terms of desired_dpi since printer dpi may vary.
|
||||
PageMargins requested_margins;
|
||||
|
||||
// Is the orientation landscape or portrait.
|
||||
bool landscape;
|
||||
|
||||
// Page Measurements.
|
||||
PageMeasurements page_measurements;
|
||||
private:
|
||||
void ResetRequestedPageMargins();
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Settings that can't be changed without side-effects.
|
||||
|
||||
@ -139,9 +170,6 @@ class PrintSettings {
|
||||
|
||||
// Printer's device effective dots per inch in both axis.
|
||||
int dpi_;
|
||||
|
||||
// Is the orientation landscape or portrait.
|
||||
bool landscape_;
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "base/time.h"
|
||||
#include "skia/ext/platform_device_win.h"
|
||||
|
||||
#include "printing/units.h"
|
||||
|
||||
using base::Time;
|
||||
|
||||
namespace {
|
||||
@ -90,6 +92,17 @@ PrintingContext::Result PrintingContext::AskUserForSettings(
|
||||
dialog_options.Flags |= PD_NOPAGENUMS;
|
||||
}
|
||||
|
||||
// Adjust the default dev mode for the printdlg settings.
|
||||
DEVMODE dev_mode;
|
||||
memset(&dev_mode,0,sizeof(dev_mode));
|
||||
dev_mode.dmSpecVersion = DM_SPECVERSION;
|
||||
dev_mode.dmSize = sizeof(DEVMODE);
|
||||
AdjustDevMode(dev_mode);
|
||||
|
||||
dialog_options.hDevMode = GlobalAlloc(GMEM_MOVEABLE, sizeof(DEVMODE));
|
||||
DEVMODE* locked_dev_mode = reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode));
|
||||
memcpy(locked_dev_mode, &dev_mode, sizeof(DEVMODE));
|
||||
GlobalUnlock(dialog_options.hDevMode);
|
||||
{
|
||||
if (PrintDlgEx(&dialog_options) != S_OK) {
|
||||
ResetSettings();
|
||||
@ -111,20 +124,82 @@ PrintingContext::Result PrintingContext::UseDefaultSettings() {
|
||||
return ParseDialogResult(dialog_options);
|
||||
}
|
||||
|
||||
void PrintingContext::AdjustDevMode(DEVMODE& dev_mode)
|
||||
{
|
||||
dev_mode.dmFields |= DM_ORIENTATION;
|
||||
dev_mode.dmOrientation = (settings_.landscape) ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
|
||||
|
||||
dev_mode.dmFields |= DM_PAPERSIZE;
|
||||
switch(settings_.page_measurements.page_type) {
|
||||
case PT_LETTER:
|
||||
dev_mode.dmPaperSize = DMPAPER_LETTER;
|
||||
break;
|
||||
case PT_LEGAL:
|
||||
dev_mode.dmPaperSize = DMPAPER_LEGAL;
|
||||
break;
|
||||
case PT_EXECUTIVE:
|
||||
dev_mode.dmPaperSize = DMPAPER_EXECUTIVE;
|
||||
break;
|
||||
case PT_A3:
|
||||
dev_mode.dmPaperSize = DMPAPER_A3;
|
||||
break;
|
||||
case PT_A4:
|
||||
dev_mode.dmPaperSize = DMPAPER_A4;
|
||||
break;
|
||||
case PT_CUSTOM:
|
||||
{
|
||||
dev_mode.dmPaperSize = DMPAPER_USER;
|
||||
dev_mode.dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH;
|
||||
DCHECK_GT(settings_.page_measurements.page_length, 0);
|
||||
DCHECK_GT(settings_.page_measurements.page_width, 0);
|
||||
// Convert from desired_dpi to tenths of a mm.
|
||||
dev_mode.dmPaperLength = static_cast<short>(
|
||||
ConvertUnitDouble(abs(settings_.page_measurements.page_length),
|
||||
10.0 * settings_.desired_dpi,
|
||||
static_cast<double>(kHundrethsMMPerInch)) + 0.5);
|
||||
dev_mode.dmPaperWidth = static_cast<short>(
|
||||
ConvertUnitDouble(abs(settings_.page_measurements.page_width),
|
||||
10.0 * settings_.desired_dpi,
|
||||
static_cast<double>(kHundrethsMMPerInch)) + 0.5);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
//we shouldn't ever hit this case.
|
||||
DCHECK(false);
|
||||
dev_mode.dmPaperSize = DMPAPER_LETTER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PrintingContext::Result PrintingContext::Init() {
|
||||
DCHECK(!in_print_job_);
|
||||
TCHAR printername[512];
|
||||
DWORD size = sizeof(printername)-1;
|
||||
if(GetDefaultPrinter(printername, &size)) {
|
||||
return Init(std::wstring(printername), false);
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
PrintingContext::Result PrintingContext::InitWithSettings(
|
||||
const PrintSettings& settings) {
|
||||
DCHECK(!in_print_job_);
|
||||
settings_ = settings;
|
||||
// TODO(maruel): settings_->ToDEVMODE()
|
||||
|
||||
return Init(settings_.device_name().c_str(), true);
|
||||
}
|
||||
|
||||
PrintingContext::Result PrintingContext::Init(const std::wstring& device_name,
|
||||
bool adjust_dev_mode) {
|
||||
HANDLE printer;
|
||||
if (!OpenPrinter(const_cast<wchar_t*>(settings_.device_name().c_str()),
|
||||
if (!OpenPrinter(const_cast<wchar_t*>(device_name.c_str()),
|
||||
&printer,
|
||||
NULL))
|
||||
return FAILED;
|
||||
|
||||
Result status = OK;
|
||||
|
||||
if (!GetPrinterSettings(printer, settings_.device_name()))
|
||||
if (!GetPrinterSettings(printer, device_name, adjust_dev_mode))
|
||||
status = FAILED;
|
||||
|
||||
// Close the printer after retrieving the context.
|
||||
@ -314,7 +389,8 @@ bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode,
|
||||
}
|
||||
|
||||
bool PrintingContext::GetPrinterSettings(HANDLE printer,
|
||||
const std::wstring& device_name) {
|
||||
const std::wstring& device_name,
|
||||
bool adjust_dev_mode) {
|
||||
DCHECK(!in_print_job_);
|
||||
scoped_array<uint8> buffer;
|
||||
|
||||
@ -324,6 +400,8 @@ bool PrintingContext::GetPrinterSettings(HANDLE printer,
|
||||
if (buffer.get()) {
|
||||
PRINTER_INFO_9* info_9 = reinterpret_cast<PRINTER_INFO_9*>(buffer.get());
|
||||
if (info_9->pDevMode != NULL) {
|
||||
if (adjust_dev_mode)
|
||||
AdjustDevMode(*info_9->pDevMode);
|
||||
if (!AllocateContext(device_name, info_9->pDevMode)) {
|
||||
ResetSettings();
|
||||
return false;
|
||||
@ -339,6 +417,8 @@ bool PrintingContext::GetPrinterSettings(HANDLE printer,
|
||||
if (buffer.get()) {
|
||||
PRINTER_INFO_8* info_8 = reinterpret_cast<PRINTER_INFO_8*>(buffer.get());
|
||||
if (info_8->pDevMode != NULL) {
|
||||
if (adjust_dev_mode)
|
||||
AdjustDevMode(*info_8->pDevMode);
|
||||
if (!AllocateContext(device_name, info_8->pDevMode)) {
|
||||
ResetSettings();
|
||||
return false;
|
||||
@ -355,6 +435,8 @@ bool PrintingContext::GetPrinterSettings(HANDLE printer,
|
||||
if (buffer.get()) {
|
||||
PRINTER_INFO_2* info_2 = reinterpret_cast<PRINTER_INFO_2*>(buffer.get());
|
||||
if (info_2->pDevMode != NULL) {
|
||||
if (adjust_dev_mode)
|
||||
AdjustDevMode(*info_2->pDevMode);
|
||||
if (!AllocateContext(device_name, info_2->pDevMode)) {
|
||||
ResetSettings();
|
||||
return false;
|
||||
@ -380,8 +462,10 @@ PrintingContext::Result PrintingContext::ParseDialogResultEx(
|
||||
const PRINTDLGEX& dialog_options) {
|
||||
// If the user clicked OK or Apply then Cancel, but not only Cancel.
|
||||
if (dialog_options.dwResultAction != PD_RESULT_CANCEL) {
|
||||
// Start fresh.
|
||||
PageMargins requested_margins = settings_.requested_margins;
|
||||
// Start fresh except for page margins since that isn't controlled by this dialog.
|
||||
ResetSettings();
|
||||
settings_.requested_margins = requested_margins;
|
||||
|
||||
DEVMODE* dev_mode = NULL;
|
||||
if (dialog_options.hDevMode) {
|
||||
|
@ -38,6 +38,9 @@ class PrintingContext {
|
||||
// default device settings.
|
||||
Result UseDefaultSettings();
|
||||
|
||||
// Initializes with printer default's settings.
|
||||
Result Init();
|
||||
|
||||
// Initializes with predefined settings.
|
||||
Result InitWithSettings(const PrintSettings& settings);
|
||||
|
||||
@ -100,12 +103,19 @@ class PrintingContext {
|
||||
// Retrieves the printer's default low-level settings. hdc_ is allocated with
|
||||
// this call.
|
||||
bool GetPrinterSettings(HANDLE printer,
|
||||
const std::wstring& device_name);
|
||||
const std::wstring& device_name,
|
||||
bool adjust_dev_mode);
|
||||
|
||||
// Allocates the HDC for a specific DEVMODE.
|
||||
bool AllocateContext(const std::wstring& printer_name,
|
||||
const DEVMODE* dev_mode);
|
||||
|
||||
// Updates printer dev_mode with settings_
|
||||
void PrintingContext::AdjustDevMode(DEVMODE& dev_mode);
|
||||
|
||||
// Initializes the hdc_ either with setting_ or with just printer defaults.
|
||||
Result Init(const std::wstring& device_name, bool adjust_dev_mode);
|
||||
|
||||
// Parses the result of a PRINTDLGEX result.
|
||||
Result ParseDialogResultEx(const PRINTDLGEX& dialog_options);
|
||||
Result ParseDialogResult(const PRINTDLG& dialog_options);
|
||||
|
@ -276,6 +276,19 @@ enum cef_retval_t CEF_CALLBACK handler_handle_menu_action(
|
||||
CefBrowserCToCpp::Wrap(browser), menuId);
|
||||
}
|
||||
|
||||
enum cef_retval_t CEF_CALLBACK handler_handle_print_options(
|
||||
struct _cef_handler_t* self, cef_browser_t* browser,
|
||||
struct _cef_print_options_t* printOptions)
|
||||
{
|
||||
DCHECK(self);
|
||||
DCHECK(browser);
|
||||
DCHECK(printOptions);
|
||||
if(!self || !browser || !printOptions)
|
||||
return RV_CONTINUE;
|
||||
|
||||
return CefHandlerCppToC::Get(self)->HandlePrintOptions(CefBrowserCToCpp::Wrap(browser), *printOptions);
|
||||
}
|
||||
|
||||
enum cef_retval_t CEF_CALLBACK handler_handle_print_header_footer(
|
||||
struct _cef_handler_t* self, cef_browser_t* browser, cef_frame_t* frame,
|
||||
cef_print_info_t* printInfo, const wchar_t* url, const wchar_t* title,
|
||||
@ -458,8 +471,7 @@ enum cef_retval_t CEF_CALLBACK handler_handle_key_event(
|
||||
}
|
||||
|
||||
enum cef_retval_t CEF_CALLBACK handler_handle_tooltip(
|
||||
struct _cef_handler_t* self, struct _cef_browser_t* browser,
|
||||
cef_string_t* text)
|
||||
struct _cef_handler_t* self, cef_browser_t* browser, cef_string_t* text)
|
||||
{
|
||||
DCHECK(self);
|
||||
DCHECK(browser);
|
||||
@ -533,6 +545,7 @@ CefHandlerCppToC::CefHandlerCppToC(CefHandler* cls)
|
||||
struct_.struct_.handle_before_menu = handler_handle_before_menu;
|
||||
struct_.struct_.handle_get_menu_label = handler_handle_get_menu_label;
|
||||
struct_.struct_.handle_menu_action = handler_handle_menu_action;
|
||||
struct_.struct_.handle_print_options = handler_handle_print_options;
|
||||
struct_.struct_.handle_print_header_footer =
|
||||
handler_handle_print_header_footer;
|
||||
struct_.struct_.handle_jsalert = handler_handle_jsalert;
|
||||
|
@ -215,6 +215,16 @@ CefHandler::RetVal CefHandlerCToCpp::HandleMenuAction(
|
||||
menuId);
|
||||
}
|
||||
|
||||
CefHandler::RetVal CefHandlerCToCpp::HandlePrintOptions(
|
||||
CefRefPtr<CefBrowser> browser, CefPrintOptions& printOptions)
|
||||
{
|
||||
if (CEF_MEMBER_MISSING(struct_, handle_print_options))
|
||||
return RV_CONTINUE;
|
||||
|
||||
return struct_->handle_print_options(struct_, CefBrowserCppToC::Wrap(browser),
|
||||
&printOptions);
|
||||
}
|
||||
|
||||
CefHandler::RetVal CefHandlerCToCpp::HandlePrintHeaderFooter(
|
||||
CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
|
||||
CefPrintInfo& printInfo, const std::wstring& url,
|
||||
|
@ -58,6 +58,8 @@ public:
|
||||
virtual RetVal HandleGetMenuLabel(CefRefPtr<CefBrowser> browser,
|
||||
MenuId menuId, std::wstring& label);
|
||||
virtual RetVal HandleMenuAction(CefRefPtr<CefBrowser> browser, MenuId menuId);
|
||||
virtual RetVal HandlePrintOptions(CefRefPtr<CefBrowser> browser,
|
||||
CefPrintOptions& printOptions);
|
||||
virtual RetVal HandlePrintHeaderFooter(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame, CefPrintInfo& printInfo,
|
||||
const std::wstring& url, const std::wstring& title, int currentPage,
|
||||
|
@ -424,6 +424,18 @@ public:
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
// Event called to allow customization of standard print options before the
|
||||
// print dialog is displayed. |printOptions| allows specification of paper
|
||||
// size, orientation and margins. Note that the specified margins may be
|
||||
// adjusted if they are outside the range supported by the printer. All units
|
||||
// are in inches. Return RV_CONTINUE to display the default print options or
|
||||
// RV_HANDLED to display the modified |printOptions|.
|
||||
virtual RetVal HandlePrintOptions(CefRefPtr<CefBrowser> browser,
|
||||
CefPrintOptions& printOptions)
|
||||
{
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
// Event called to format print headers and footers. |printInfo| contains
|
||||
// platform-specific information about the printer context. |url| is the
|
||||
// URL if the currently printing page, |title| is the title of the currently
|
||||
|
@ -129,6 +129,12 @@ public:
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
virtual RetVal HandlePrintOptions(CefRefPtr<CefBrowser> browser,
|
||||
CefPrintOptions& printOptions)
|
||||
{
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
virtual RetVal HandlePrintHeaderFooter(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefPrintInfo& printInfo,
|
||||
|
Loading…
x
Reference in New Issue
Block a user