Add PDF printing support (issue #1478).

This commit is contained in:
Alexei Bykov 2015-03-24 18:40:08 +03:00 committed by Marshall Greenblatt
parent b6e5310bce
commit 85f83680d7
42 changed files with 1039 additions and 24 deletions

View File

@ -216,6 +216,8 @@
'libcef_dll/cpptoc/navigation_entry_cpptoc.h',
'libcef_dll/ctocpp/navigation_entry_visitor_ctocpp.cc',
'libcef_dll/ctocpp/navigation_entry_visitor_ctocpp.h',
'libcef_dll/ctocpp/pdf_print_callback_ctocpp.cc',
'libcef_dll/ctocpp/pdf_print_callback_ctocpp.h',
'libcef_dll/cpptoc/post_data_cpptoc.cc',
'libcef_dll/cpptoc/post_data_cpptoc.h',
'libcef_dll/cpptoc/post_data_element_cpptoc.cc',
@ -408,6 +410,8 @@
'libcef_dll/ctocpp/navigation_entry_ctocpp.h',
'libcef_dll/cpptoc/navigation_entry_visitor_cpptoc.cc',
'libcef_dll/cpptoc/navigation_entry_visitor_cpptoc.h',
'libcef_dll/cpptoc/pdf_print_callback_cpptoc.cc',
'libcef_dll/cpptoc/pdf_print_callback_cpptoc.h',
'libcef_dll/ctocpp/post_data_ctocpp.cc',
'libcef_dll/ctocpp/post_data_ctocpp.h',
'libcef_dll/ctocpp/post_data_element_ctocpp.cc',

View File

@ -230,6 +230,27 @@ typedef struct _cef_navigation_entry_visitor_t {
} cef_navigation_entry_visitor_t;
///
// Callback structure for cef_browser_host_t::PrintToPDF. The functions of this
// structure will be called on the browser process UI thread.
///
typedef struct _cef_pdf_print_callback_t {
///
// Base structure.
///
cef_base_t base;
///
// Method that will be executed when the PDF printing has completed. |path| is
// the output path. |ok| will be true (1) if the printing completed
// successfully or false (0) otherwise.
///
void (CEF_CALLBACK *on_pdf_print_finished)(
struct _cef_pdf_print_callback_t* self, const cef_string_t* path,
int ok);
} cef_pdf_print_callback_t;
///
// Structure used to represent the browser process aspects of a browser window.
// The functions of this structure can only be called in the browser process.
@ -346,6 +367,17 @@ typedef struct _cef_browser_host_t {
///
void (CEF_CALLBACK *print)(struct _cef_browser_host_t* self);
///
// Print the current browser contents to the PDF file specified by |path| and
// execute |callback| on completion. The caller is responsible for deleting
// |path| when done. For PDF printing to work on Linux you must implement the
// cef_print_handler_t::GetPdfPaperSize function.
///
void (CEF_CALLBACK *print_to_pdf)(struct _cef_browser_host_t* self,
const cef_string_t* path,
const struct _cef_pdf_print_settings_t* settings,
struct _cef_pdf_print_callback_t* callback);
///
// Search for |searchText|. |identifier| can be used to have multiple searches
// running simultaniously. |forward| indicates whether to search forward or

View File

@ -124,6 +124,13 @@ typedef struct _cef_print_handler_t {
// Reset client state related to printing.
///
void (CEF_CALLBACK *on_print_reset)(struct _cef_print_handler_t* self);
///
// Return the PDF paper size in device units. Used in combination with
// cef_browser_host_t::print_to_pdf().
///
cef_size_t (CEF_CALLBACK *get_pdf_paper_size)(
struct _cef_print_handler_t* self, int device_units_per_inch);
} cef_print_handler_t;

View File

@ -234,6 +234,23 @@ class CefNavigationEntryVisitor : public virtual CefBase {
};
///
// Callback interface for CefBrowserHost::PrintToPDF. The methods of this class
// will be called on the browser process UI thread.
///
/*--cef(source=client)--*/
class CefPdfPrintCallback : public virtual CefBase {
public:
///
// Method that will be executed when the PDF printing has completed. |path|
// is the output path. |ok| will be true if the printing completed
// successfully or false otherwise.
///
/*--cef()--*/
virtual void OnPdfPrintFinished(const CefString& path, bool ok) =0;
};
///
// Class used to represent the browser process aspects of a browser window. The
// methods of this class can only be called in the browser process. They may be
@ -389,6 +406,17 @@ class CefBrowserHost : public virtual CefBase {
/*--cef()--*/
virtual void Print() =0;
///
// Print the current browser contents to the PDF file specified by |path| and
// execute |callback| on completion. The caller is responsible for deleting
// |path| when done. For PDF printing to work on Linux you must implement the
// CefPrintHandler::GetPdfPaperSize method.
///
/*--cef(optional_param=callback)--*/
virtual void PrintToPDF(const CefString& path,
const CefPdfPrintSettings& settings,
CefRefPtr<CefPdfPrintCallback> callback) =0;
///
// Search for |searchText|. |identifier| can be used to have multiple searches
// running simultaniously. |forward| indicates whether to search forward or

View File

@ -115,6 +115,15 @@ class CefPrintHandler : public virtual CefBase {
///
/*--cef()--*/
virtual void OnPrintReset() =0;
///
// Return the PDF paper size in device units. Used in combination with
// CefBrowserHost::PrintToPDF().
///
/*--cef()--*/
virtual CefSize GetPdfPaperSize(int device_units_per_inch) {
return CefSize();
}
};
#endif // CEF_INCLUDE_CEF_PRINT_HANDLER_H_

View File

@ -2194,6 +2194,92 @@ typedef enum {
JSON_WRITER_PRETTY_PRINT = 1 << 2,
} cef_json_writer_options_t;
///
// Margin type for PDF printing.
///
typedef enum {
///
// Default margins.
///
PDF_PRINT_MARGIN_DEFAULT,
///
// No margins.
///
PDF_PRINT_MARGIN_NONE,
///
// Minimum margins.
///
PDF_PRINT_MARGIN_MINIMUM,
///
// Custom margins using the |margin_*| values from cef_pdf_print_settings_t.
///
PDF_PRINT_MARGIN_CUSTOM,
} cef_pdf_print_margin_type_t;
///
// Structure representing PDF print settings.
///
typedef struct _cef_pdf_print_settings_t {
///
// Page title to display in the header. Only used if |header_footer_enabled|
// is set to true (1).
///
cef_string_t header_footer_title;
///
// URL to display in the footer. Only used if |header_footer_enabled| is set
// to true (1).
///
cef_string_t header_footer_url;
///
// Output page size in microns. If either of these values is less than or
// equal to zero then the default paper size (A4) will be used.
///
int page_width;
int page_height;
///
// Margins in millimeters. Only used if |margin_type| is set to
// PDF_PRINT_MARGIN_CUSTOM.
///
double margin_top;
double margin_right;
double margin_bottom;
double margin_left;
///
// Margin type.
///
cef_pdf_print_margin_type_t margin_type;
///
// Set to true (1) to print headers and footers or false (0) to not print
// headers and footers.
///
int header_footer_enabled;
///
// Set to true (1) to print the selection only or false (0) to print all.
///
int selection_only;
///
// Set to true (1) for landscape mode or false (0) for portrait mode.
///
int landscape;
///
// Set to true (1) to print background graphics or false (0) to not print
// background graphics.
///
int backgrounds_enabled;
} cef_pdf_print_settings_t;
#ifdef __cplusplus
}
#endif

View File

@ -822,7 +822,7 @@ class CefPageRange : public CefStructBase<CefPageRangeTraits> {
CefPageRange(const cef_page_range_t& r) // NOLINT(runtime/explicit)
: parent(r) {}
CefPageRange(const CefPageRange& r) // NOLINT(runtime/explicit)
: parent(r) {}
: parent(r) {}
CefPageRange(int from, int to) : parent() {
Set(from, to);
}
@ -862,4 +862,44 @@ struct CefCursorInfoTraits {
///
typedef CefStructBase<CefCursorInfoTraits> CefCursorInfo;
struct CefPdfPrintSettingsTraits {
typedef cef_pdf_print_settings_t struct_type;
static inline void init(struct_type* s) {}
static inline void clear(struct_type* s) {
cef_string_clear(&s->header_footer_title);
cef_string_clear(&s->header_footer_url);
}
static inline void set(const struct_type* src, struct_type* target,
bool copy) {
cef_string_set(src->header_footer_title.str,
src->header_footer_title.length, &target->header_footer_title, copy);
cef_string_set(src->header_footer_url.str, src->header_footer_url.length,
&target->header_footer_url, copy);
target->page_width = src->page_width;
target->page_height = src->page_height;
target->margin_top = src->margin_top;
target->margin_right = src->margin_right;
target->margin_bottom = src->margin_bottom;
target->margin_left = src->margin_left;
target->margin_type = src->margin_type;
target->header_footer_enabled = src->header_footer_enabled;
target->selection_only = src->selection_only;
target->landscape = src->landscape;
target->backgrounds_enabled = src->backgrounds_enabled;
}
};
///
// Class representing PDF print settings
///
typedef CefStructBase<CefPdfPrintSettingsTraits> CefPdfPrintSettings;
#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_

View File

@ -832,6 +832,27 @@ void CefBrowserHostImpl::Print() {
}
}
void CefBrowserHostImpl::PrintToPDF(const CefString& path,
const CefPdfPrintSettings& settings,
CefRefPtr<CefPdfPrintCallback> callback) {
if (CEF_CURRENTLY_ON_UIT()) {
if (!web_contents_)
return;
printing::PrintViewManager::PdfPrintCallback pdf_callback;
if (callback.get()) {
pdf_callback = base::Bind(&CefPdfPrintCallback::OnPdfPrintFinished,
callback.get(), path);
}
printing::PrintViewManager::FromWebContents(web_contents_.get())->
PrintToPDF(base::FilePath(path), settings, pdf_callback);
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::PrintToPDF, this, path, settings,
callback));
}
}
void CefBrowserHostImpl::Find(int identifier, const CefString& searchText,
bool forward, bool matchCase, bool findNext) {
if (CEF_CURRENTLY_ON_UIT()) {

View File

@ -162,6 +162,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
CefRefPtr<CefRunFileDialogCallback> callback) override;
void StartDownload(const CefString& url) override;
void Print() override;
void PrintToPDF(const CefString& path,
const CefPdfPrintSettings& settings,
CefRefPtr<CefPdfPrintCallback> callback) override;
void Find(int identifier, const CefString& searchText,
bool forward, bool matchCase, bool findNext) override;
void StopFinding(bool clearSelection) override;

View File

@ -93,6 +93,8 @@ void CefBrowserMainParts::PostMainMessageLoopStart() {
#if defined(OS_LINUX)
printing::PrintingContextLinux::SetCreatePrintDialogFunction(
&CefPrintDialogLinux::CreatePrintDialog);
printing::PrintingContextLinux::SetPdfPaperSizeFunction(
&CefPrintDialogLinux::GetPdfPaperSize);
#endif
}

View File

@ -106,6 +106,35 @@ printing::PrintDialogGtkInterface* CefPrintDialogLinux::CreatePrintDialog(
return new CefPrintDialogLinux(context);
}
// static
gfx::Size CefPrintDialogLinux::GetPdfPaperSize(
printing::PrintingContextLinux* context) {
CEF_REQUIRE_UIT();
gfx::Size size;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefBrowserProcessHandler> browser_handler =
app->GetBrowserProcessHandler();
if (browser_handler.get()) {
CefRefPtr<CefPrintHandler> handler = browser_handler->GetPrintHandler();
if (handler.get()) {
const printing::PrintSettings& settings = context->settings();
CefSize cef_size = handler->GetPdfPaperSize(
settings.device_units_per_inch());
size.SetSize(cef_size.width, cef_size.height);
}
}
}
if (size.IsEmpty()) {
LOG(ERROR) << "Empty size value returned in GetPdfPaperSize; "
"PDF printing will fail.";
}
return size;
}
CefPrintDialogLinux::CefPrintDialogLinux(PrintingContextLinux* context)
: context_(context) {
}
@ -192,10 +221,10 @@ void CefPrintDialogLinux::ReleaseDialog() {
}
void CefPrintDialogLinux::SetHandler() {
if (handler_.get())
return;
if (handler_.get())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefBrowserProcessHandler> browser_handler =
app->GetBrowserProcessHandler();

View File

@ -33,6 +33,10 @@ class CefPrintDialogLinux
static printing::PrintDialogGtkInterface* CreatePrintDialog(
PrintingContextLinux* context);
// Returns the paper size in device units.
static gfx::Size GetPdfPaperSize(
printing::PrintingContextLinux* context);
// printing::CefPrintDialogLinuxInterface implementation.
void UseDefaultSettings() override;
bool UpdateSettings(printing::PrintSettings* settings) override;

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "include/internal/cef_types_wrappers.h"
#include "libcef/browser/printing/print_view_manager.h"
#include <map>
@ -12,9 +13,11 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_preview_dialog_controller.h"
#include "chrome/browser/printing/printer_query.h"
#include "components/printing/common/print_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "printing/pdf_metafile_skia.h"
using content::BrowserThread;
@ -22,11 +25,140 @@ DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintViewManager);
namespace printing {
namespace {
const int PREVIEW_UIID = 12345678;
// Convert CefPdfPrintSettings into base::DictionaryValue.
void FillInDictionaryFromPdfPrintSettings(
const CefPdfPrintSettings& pdf_settings,
int request_id,
base::DictionaryValue& print_settings) {
// Fixed settings.
print_settings.SetBoolean(kSettingPrintToPDF, true);
print_settings.SetBoolean(kSettingCloudPrintDialog, false);
print_settings.SetBoolean(kSettingPrintWithPrivet, false);
print_settings.SetBoolean(kSettingPrintWithExtension, false);
print_settings.SetInteger(kSettingColor, GRAY);
print_settings.SetInteger(kSettingDuplexMode, SIMPLEX);
print_settings.SetInteger(kSettingCopies, 1);
print_settings.SetBoolean(kSettingCollate, false);
print_settings.SetString(kSettingDeviceName, "");
print_settings.SetBoolean(kSettingGenerateDraftData, false);
print_settings.SetBoolean(kSettingPreviewModifiable, false);
// User defined settings.
print_settings.SetBoolean(kSettingLandscape, !!pdf_settings.landscape);
print_settings.SetBoolean(kSettingShouldPrintSelectionOnly,
!!pdf_settings.selection_only);
print_settings.SetBoolean(kSettingShouldPrintBackgrounds,
!!pdf_settings.backgrounds_enabled);
print_settings.SetBoolean(kSettingHeaderFooterEnabled,
!!pdf_settings.header_footer_enabled);
if (pdf_settings.header_footer_enabled) {
print_settings.SetString(kSettingHeaderFooterTitle,
CefString(&pdf_settings.header_footer_title).ToString16());
print_settings.SetString(kSettingHeaderFooterURL,
CefString(&pdf_settings.header_footer_url).ToString16());
}
if (pdf_settings.page_width > 0 && pdf_settings.page_height > 0) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
dict->SetInteger(kSettingMediaSizeWidthMicrons, pdf_settings.page_width);
dict->SetInteger(kSettingMediaSizeHeightMicrons, pdf_settings.page_height);
print_settings.Set(kSettingMediaSize, dict.Pass());
}
int margin_type = DEFAULT_MARGINS;
switch (pdf_settings.margin_type) {
case PDF_PRINT_MARGIN_NONE:
margin_type = NO_MARGINS;
break;
case PDF_PRINT_MARGIN_MINIMUM:
margin_type = PRINTABLE_AREA_MARGINS;
break;
case PDF_PRINT_MARGIN_CUSTOM:
margin_type = CUSTOM_MARGINS;
break;
default:
break;
}
print_settings.SetInteger(kSettingMarginsType, margin_type);
if (margin_type == CUSTOM_MARGINS) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
dict->SetDouble(kSettingMarginTop, pdf_settings.margin_top);
dict->SetDouble(kSettingMarginRight, pdf_settings.margin_right);
dict->SetDouble(kSettingMarginBottom, pdf_settings.margin_bottom);
dict->SetDouble(kSettingMarginLeft, pdf_settings.margin_left);
print_settings.Set(kSettingMarginsCustom, dict.Pass());
}
// Service settings.
print_settings.SetInteger(kPreviewUIID, PREVIEW_UIID);
print_settings.SetInteger(kPreviewRequestID, request_id);
print_settings.SetBoolean(kIsFirstRequest, request_id != 0);
}
void StopWorker(int document_cookie) {
if (document_cookie <= 0)
return;
scoped_refptr<PrintQueriesQueue> queue =
g_browser_process->print_job_manager()->queue();
scoped_refptr<PrinterQuery> printer_query =
queue->PopPrinterQuery(document_cookie);
if (printer_query.get()) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&PrinterQuery::StopWorker,
printer_query));
}
}
scoped_refptr<base::RefCountedBytes>
GetDataFromHandle(base::SharedMemoryHandle handle, uint32 data_size) {
scoped_ptr<base::SharedMemory> shared_buf(
new base::SharedMemory(handle, true));
if (!shared_buf->Map(data_size)) {
NOTREACHED();
return NULL;
}
unsigned char* data = static_cast<unsigned char*>(shared_buf->memory());
std::vector<unsigned char> dataVector(data, data + data_size);
return base::RefCountedBytes::TakeVector(&dataVector);
}
// Write the PDF file to disk.
void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
const base::FilePath& path,
const PrintViewManager::PdfPrintCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK_GT(data->size(), 0U);
PdfMetafileSkia metafile;
metafile.InitFromData(static_cast<const void*>(data->front()), data->size());
base::File file(path,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
bool ok = file.IsValid() && metafile.SaveTo(&file);
if (!callback.is_null()) {
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(callback, ok));
}
}
} // namespace
PrintViewManager::PrintViewManager(content::WebContents* web_contents)
: PrintViewManagerBase(web_contents) {
}
PrintViewManager::~PrintViewManager() {
TerminatePdfPrintJob();
}
#if defined(ENABLE_BASIC_PRINTING)
@ -35,21 +167,104 @@ bool PrintViewManager::PrintForSystemDialogNow() {
}
#endif // ENABLE_BASIC_PRINTING
void PrintViewManager::RenderProcessGone(base::TerminationStatus status) {
PrintViewManagerBase::RenderProcessGone(status);
}
void PrintViewManager::OnDidShowPrintDialog() {
}
bool PrintViewManager::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PrintViewManager, message)
IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
OnRequestPrintPreview)
IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
OnMetafileReadyForPrinting)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled ? true : PrintViewManagerBase::OnMessageReceived(message);
}
void PrintViewManager::NavigationStopped() {
PrintViewManagerBase::NavigationStopped();
TerminatePdfPrintJob();
}
void PrintViewManager::RenderProcessGone(base::TerminationStatus status) {
PrintViewManagerBase::RenderProcessGone(status);
TerminatePdfPrintJob();
}
void PrintViewManager::PrintToPDF(const base::FilePath& path,
const CefPdfPrintSettings& settings,
const PdfPrintCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!web_contents() || pdf_print_settings_)
return;
pdf_output_path_ = path;
pdf_print_callback_ = callback;
pdf_print_settings_.reset(new base::DictionaryValue);
FillInDictionaryFromPdfPrintSettings(settings,
++next_pdf_request_id_,
*pdf_print_settings_);
Send(new PrintMsg_InitiatePrintPreview(routing_id(),
!!settings.selection_only));
}
void PrintViewManager::OnDidShowPrintDialog() {
}
void PrintViewManager::OnRequestPrintPreview(
const PrintHostMsg_RequestPrintPreview_Params&) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!web_contents() || !pdf_print_settings_)
return;
Send(new PrintMsg_PrintPreview(routing_id(), *pdf_print_settings_));
}
void PrintViewManager::OnMetafileReadyForPrinting(
const PrintHostMsg_DidPreviewDocument_Params& params) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
StopWorker(params.document_cookie);
scoped_refptr<base::RefCountedBytes> data_bytes =
GetDataFromHandle(params.metafile_data_handle, params.data_size);
if (!data_bytes || !data_bytes->size()) {
TerminatePdfPrintJob();
return;
}
base::FilePath pdf_output_path = pdf_output_path_;
PdfPrintCallback pdf_print_callback = pdf_print_callback_;
// Reset state information.
pdf_output_path_.clear();
pdf_print_callback_.Reset();
pdf_print_settings_.reset();
// Save the PDF file to disk and then execute the callback.
BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE,
base::Bind(&SavePdfFile, data_bytes, pdf_output_path,
pdf_print_callback));
}
void PrintViewManager::TerminatePdfPrintJob() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!pdf_print_settings_.get())
return;
if (!pdf_print_callback_.is_null()) {
// Execute the callback.
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(pdf_print_callback_, false));
}
// Reset state information.
pdf_output_path_.clear();
pdf_print_callback_.Reset();
pdf_print_settings_.reset();
}
} // namespace printing

View File

@ -8,6 +8,9 @@
#include "libcef/browser/printing/print_view_manager_base.h"
#include "content/public/browser/web_contents_user_data.h"
struct PrintHostMsg_DidPreviewDocument_Params;
struct PrintHostMsg_RequestPrintPreview_Params;
namespace content {
class RenderProcessHost;
}
@ -30,15 +33,36 @@ class PrintViewManager : public PrintViewManagerBase,
bool OnMessageReceived(const IPC::Message& message) override;
// content::WebContentsObserver implementation.
// Cancels the print job.
void NavigationStopped() override;
// Terminates or cancels the print job if one was pending.
void RenderProcessGone(base::TerminationStatus status) override;
// Callback executed on PDF printing completion.
typedef base::Callback<void(bool /*ok*/)> PdfPrintCallback;
// Print the current document to a PDF file. Execute |callback| on completion.
void PrintToPDF(const base::FilePath& path,
const CefPdfPrintSettings& settings,
const PdfPrintCallback& callback);
private:
explicit PrintViewManager(content::WebContents* web_contents);
friend class content::WebContentsUserData<PrintViewManager>;
// IPC Message handlers.
void OnDidShowPrintDialog();
void OnRequestPrintPreview(const PrintHostMsg_RequestPrintPreview_Params&);
void OnMetafileReadyForPrinting(
const PrintHostMsg_DidPreviewDocument_Params&);
void TerminatePdfPrintJob();
// Used for printing to PDF. Only accessed on the browser process UI thread.
int next_pdf_request_id_ = -1;
base::FilePath pdf_output_path_;
scoped_ptr<base::DictionaryValue> pdf_print_settings_;
PdfPrintCallback pdf_print_callback_;
DISALLOW_COPY_AND_ASSIGN(PrintViewManager);
};

View File

@ -34,10 +34,6 @@ using content::BrowserThread;
namespace printing {
namespace {
} // namespace
PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
number_pages_(0),

View File

@ -54,6 +54,9 @@ class PrintViewManagerBase : public content::NotificationObserver,
// Helper method for Print*Now().
bool PrintNowInternal(IPC::Message* message);
// Cancels the print job.
void NavigationStopped() override;
// Terminates or cancels the print job if one was pending.
void RenderProcessGone(base::TerminationStatus status) override;
@ -72,9 +75,6 @@ class PrintViewManagerBase : public content::NotificationObserver,
// content::WebContentsObserver implementation.
void DidStartLoading() override;
// Cancels the print job.
void NavigationStopped() override;
// IPC Message handlers.
void OnDidGetPrintedPagesCount(int cookie, int number_pages);
void OnDidGetDocumentCookie(int cookie);

View File

@ -126,6 +126,7 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings,
OnUpdatePrintSettings)
IPC_MESSAGE_HANDLER(PrintHostMsg_CheckForCancel, OnCheckForCancel)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@ -420,4 +421,10 @@ void PrintingMessageFilter::OnUpdatePrintSettingsReply(
}
}
void PrintingMessageFilter::OnCheckForCancel(int32 preview_ui_id,
int preview_request_id,
bool* cancel) {
*cancel = false;
}
} // namespace printing

View File

@ -105,6 +105,10 @@ class PrintingMessageFilter : public content::BrowserMessageFilter {
void OnUpdatePrintSettingsReply(scoped_refptr<PrinterQuery> printer_query,
IPC::Message* reply_msg);
void OnCheckForCancel(int32 preview_ui_id,
int preview_request_id,
bool* cancel);
const int render_process_id_;
scoped_refptr<PrintQueriesQueue> queue_;

View File

@ -14,7 +14,6 @@
<include name="IDR_CEF_CREDITS_JS" file="..\..\..\chrome\browser\resources\about_credits.js" type="BINDATA" />
<include name="IDR_CEF_LICENSE_TXT" file="..\..\LICENSE.txt" type="BINDATA" />
<include name="IDR_CEF_VERSION_HTML" file="about_version.html" type="BINDATA" />
<include name="IDR_PRINT_PREVIEW_PAGE" file="print_preview_page_stub.html" type="BINDATA" />
</includes>
</release>
</grit>

View File

@ -1 +0,0 @@
<html></html>

View File

@ -16,6 +16,7 @@
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
#include "libcef_dll/ctocpp/client_ctocpp.h"
#include "libcef_dll/ctocpp/navigation_entry_visitor_ctocpp.h"
#include "libcef_dll/ctocpp/pdf_print_callback_ctocpp.h"
#include "libcef_dll/ctocpp/run_file_dialog_callback_ctocpp.h"
#include "libcef_dll/transfer_util.h"
@ -307,6 +308,36 @@ void CEF_CALLBACK browser_host_print(struct _cef_browser_host_t* self) {
CefBrowserHostCppToC::Get(self)->Print();
}
void CEF_CALLBACK browser_host_print_to_pdf(struct _cef_browser_host_t* self,
const cef_string_t* path, const struct _cef_pdf_print_settings_t* settings,
cef_pdf_print_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: path; type: string_byref_const
DCHECK(path);
if (!path)
return;
// Verify param: settings; type: struct_byref_const
DCHECK(settings);
if (!settings)
return;
// Unverified params: callback
// Translate param: settings; type: struct_byref_const
CefPdfPrintSettings settingsObj;
if (settings)
settingsObj.Set(*settings, false);
// Execute
CefBrowserHostCppToC::Get(self)->PrintToPDF(
CefString(path),
settingsObj,
CefPdfPrintCallbackCToCpp::Wrap(callback));
}
void CEF_CALLBACK browser_host_find(struct _cef_browser_host_t* self,
int identifier, const cef_string_t* searchText, int forward, int matchCase,
int findNext) {
@ -881,6 +912,7 @@ CefBrowserHostCppToC::CefBrowserHostCppToC() {
GetStruct()->run_file_dialog = browser_host_run_file_dialog;
GetStruct()->start_download = browser_host_start_download;
GetStruct()->print = browser_host_print;
GetStruct()->print_to_pdf = browser_host_print_to_pdf;
GetStruct()->find = browser_host_find;
GetStruct()->stop_finding = browser_host_stop_finding;
GetStruct()->show_dev_tools = browser_host_show_dev_tools;

View File

@ -0,0 +1,61 @@
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/pdf_print_callback_cpptoc.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK pdf_print_callback_on_pdf_print_finished(
struct _cef_pdf_print_callback_t* self, const cef_string_t* path, int ok) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: path; type: string_byref_const
DCHECK(path);
if (!path)
return;
// Execute
CefPdfPrintCallbackCppToC::Get(self)->OnPdfPrintFinished(
CefString(path),
ok?true:false);
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefPdfPrintCallbackCppToC::CefPdfPrintCallbackCppToC() {
GetStruct()->on_pdf_print_finished = pdf_print_callback_on_pdf_print_finished;
}
template<> CefRefPtr<CefPdfPrintCallback> CefCppToC<CefPdfPrintCallbackCppToC,
CefPdfPrintCallback, cef_pdf_print_callback_t>::UnwrapDerived(
CefWrapperType type, cef_pdf_print_callback_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return NULL;
}
#ifndef NDEBUG
template<> base::AtomicRefCount CefCppToC<CefPdfPrintCallbackCppToC,
CefPdfPrintCallback, cef_pdf_print_callback_t>::DebugObjCt = 0;
#endif
template<> CefWrapperType CefCppToC<CefPdfPrintCallbackCppToC,
CefPdfPrintCallback, cef_pdf_print_callback_t>::kWrapperType =
WT_PDF_PRINT_CALLBACK;

View File

@ -0,0 +1,37 @@
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_PDF_PRINT_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_PDF_PRINT_CALLBACK_CPPTOC_H_
#pragma once
#ifndef USING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
#else // USING_CEF_SHARED
#include "include/cef_browser.h"
#include "include/capi/cef_browser_capi.h"
#include "include/cef_client.h"
#include "include/capi/cef_client_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefPdfPrintCallbackCppToC
: public CefCppToC<CefPdfPrintCallbackCppToC, CefPdfPrintCallback,
cef_pdf_print_callback_t> {
public:
CefPdfPrintCallbackCppToC();
};
#endif // USING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CPPTOC_PDF_PRINT_CALLBACK_CPPTOC_H_

View File

@ -104,6 +104,22 @@ void CEF_CALLBACK print_handler_on_print_reset(
CefPrintHandlerCppToC::Get(self)->OnPrintReset();
}
cef_size_t CEF_CALLBACK print_handler_get_pdf_paper_size(
struct _cef_print_handler_t* self, int device_units_per_inch) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return CefSize();
// Execute
cef_size_t _retval = CefPrintHandlerCppToC::Get(self)->GetPdfPaperSize(
device_units_per_inch);
// Return type: simple
return _retval;
}
} // namespace
@ -114,6 +130,7 @@ CefPrintHandlerCppToC::CefPrintHandlerCppToC() {
GetStruct()->on_print_dialog = print_handler_on_print_dialog;
GetStruct()->on_print_job = print_handler_on_print_job;
GetStruct()->on_print_reset = print_handler_on_print_reset;
GetStruct()->get_pdf_paper_size = print_handler_get_pdf_paper_size;
}
template<> CefRefPtr<CefPrintHandler> CefCppToC<CefPrintHandlerCppToC,

View File

@ -12,6 +12,7 @@
#include "libcef_dll/cpptoc/client_cpptoc.h"
#include "libcef_dll/cpptoc/navigation_entry_visitor_cpptoc.h"
#include "libcef_dll/cpptoc/pdf_print_callback_cpptoc.h"
#include "libcef_dll/cpptoc/run_file_dialog_callback_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
@ -265,6 +266,28 @@ void CefBrowserHostCToCpp::Print() {
_struct->print(_struct);
}
void CefBrowserHostCToCpp::PrintToPDF(const CefString& path,
const CefPdfPrintSettings& settings,
CefRefPtr<CefPdfPrintCallback> callback) {
cef_browser_host_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, print_to_pdf))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: path; type: string_byref_const
DCHECK(!path.empty());
if (path.empty())
return;
// Unverified params: callback
// Execute
_struct->print_to_pdf(_struct,
path.GetStruct(),
&settings,
CefPdfPrintCallbackCppToC::Wrap(callback));
}
void CefBrowserHostCToCpp::Find(int identifier, const CefString& searchText,
bool forward, bool matchCase, bool findNext) {
cef_browser_host_t* _struct = GetStruct();

View File

@ -50,6 +50,8 @@ class CefBrowserHostCToCpp
CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE;
void StartDownload(const CefString& url) OVERRIDE;
void Print() OVERRIDE;
void PrintToPDF(const CefString& path, const CefPdfPrintSettings& settings,
CefRefPtr<CefPdfPrintCallback> callback) OVERRIDE;
void Find(int identifier, const CefString& searchText, bool forward,
bool matchCase, bool findNext) OVERRIDE;
void StopFinding(bool clearSelection) OVERRIDE;

View File

@ -0,0 +1,57 @@
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/ctocpp/pdf_print_callback_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
void CefPdfPrintCallbackCToCpp::OnPdfPrintFinished(const CefString& path,
bool ok) {
cef_pdf_print_callback_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_pdf_print_finished))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: path; type: string_byref_const
DCHECK(!path.empty());
if (path.empty())
return;
// Execute
_struct->on_pdf_print_finished(_struct,
path.GetStruct(),
ok);
}
// CONSTRUCTOR - Do not edit by hand.
CefPdfPrintCallbackCToCpp::CefPdfPrintCallbackCToCpp() {
}
template<> cef_pdf_print_callback_t* CefCToCpp<CefPdfPrintCallbackCToCpp,
CefPdfPrintCallback, cef_pdf_print_callback_t>::UnwrapDerived(
CefWrapperType type, CefPdfPrintCallback* c) {
NOTREACHED() << "Unexpected class type: " << type;
return NULL;
}
#ifndef NDEBUG
template<> base::AtomicRefCount CefCToCpp<CefPdfPrintCallbackCToCpp,
CefPdfPrintCallback, cef_pdf_print_callback_t>::DebugObjCt = 0;
#endif
template<> CefWrapperType CefCToCpp<CefPdfPrintCallbackCToCpp,
CefPdfPrintCallback, cef_pdf_print_callback_t>::kWrapperType =
WT_PDF_PRINT_CALLBACK;

View File

@ -0,0 +1,40 @@
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_PDF_PRINT_CALLBACK_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_PDF_PRINT_CALLBACK_CTOCPP_H_
#pragma once
#ifndef BUILDING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
#else // BUILDING_CEF_SHARED
#include "include/cef_browser.h"
#include "include/capi/cef_browser_capi.h"
#include "include/cef_client.h"
#include "include/capi/cef_client_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefPdfPrintCallbackCToCpp
: public CefCToCpp<CefPdfPrintCallbackCToCpp, CefPdfPrintCallback,
cef_pdf_print_callback_t> {
public:
CefPdfPrintCallbackCToCpp();
// CefPdfPrintCallback methods.
void OnPdfPrintFinished(const CefString& path, bool ok) override;
};
#endif // BUILDING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CTOCPP_PDF_PRINT_CALLBACK_CTOCPP_H_

View File

@ -101,6 +101,21 @@ void CefPrintHandlerCToCpp::OnPrintReset() {
_struct->on_print_reset(_struct);
}
CefSize CefPrintHandlerCToCpp::GetPdfPaperSize(int device_units_per_inch) {
cef_print_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_pdf_paper_size))
return CefSize();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_size_t _retval = _struct->get_pdf_paper_size(_struct,
device_units_per_inch);
// Return type: simple
return _retval;
}
// CONSTRUCTOR - Do not edit by hand.

View File

@ -39,6 +39,7 @@ class CefPrintHandlerCToCpp
const CefString& pdf_file_path,
CefRefPtr<CefPrintJobCallback> callback) override;
void OnPrintReset() override;
CefSize GetPdfPaperSize(int device_units_per_inch) override;
};
#endif // BUILDING_CEF_SHARED

View File

@ -95,6 +95,7 @@
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
#include "libcef_dll/ctocpp/load_handler_ctocpp.h"
#include "libcef_dll/ctocpp/navigation_entry_visitor_ctocpp.h"
#include "libcef_dll/ctocpp/pdf_print_callback_ctocpp.h"
#include "libcef_dll/ctocpp/print_handler_ctocpp.h"
#include "libcef_dll/ctocpp/read_handler_ctocpp.h"
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
@ -232,6 +233,7 @@ CEF_EXPORT void cef_shutdown() {
DCHECK(base::AtomicRefCountIsZero(&CefNavigationEntryCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(
&CefNavigationEntryVisitorCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefPdfPrintCallbackCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefPrintDialogCallbackCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefPrintHandlerCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefPrintJobCallbackCppToC::DebugObjCt));

View File

@ -54,6 +54,7 @@
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
#include "libcef_dll/cpptoc/load_handler_cpptoc.h"
#include "libcef_dll/cpptoc/navigation_entry_visitor_cpptoc.h"
#include "libcef_dll/cpptoc/pdf_print_callback_cpptoc.h"
#include "libcef_dll/cpptoc/print_handler_cpptoc.h"
#include "libcef_dll/cpptoc/read_handler_cpptoc.h"
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
@ -224,6 +225,7 @@ CEF_GLOBAL void CefShutdown() {
DCHECK(base::AtomicRefCountIsZero(&CefNavigationEntryCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(
&CefNavigationEntryVisitorCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefPdfPrintCallbackCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefPrintDialogCallbackCToCpp::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefPrintHandlerCppToC::DebugObjCt));
DCHECK(base::AtomicRefCountIsZero(&CefPrintJobCallbackCToCpp::DebugObjCt));

View File

@ -60,6 +60,7 @@ enum CefWrapperType {
WT_MENU_MODEL,
WT_NAVIGATION_ENTRY,
WT_NAVIGATION_ENTRY_VISITOR,
WT_PDF_PRINT_CALLBACK,
WT_POST_DATA,
WT_POST_DATA_ELEMENT,
WT_PRINT_DIALOG_CALLBACK,

View File

@ -155,4 +155,10 @@ patches = [
'name': 'ime_1610',
'path': '../ui/base/ime/',
},
{
# Enable support for print header and footer.
# https://bitbucket.org/chromiumembedded/cef/issue/1478
'name': 'print_header_footer_1478',
'path': '../components/',
},
]

View File

@ -0,0 +1,125 @@
diff --git printing/renderer/print_web_view_helper.cc printing/renderer/print_web_view_helper.cc
index cef7a95..f05255a 100644
--- printing/renderer/print_web_view_helper.cc
+++ printing/renderer/print_web_view_helper.cc
@@ -73,6 +73,7 @@ const double kMinDpi = 1.0;
bool g_is_preview_enabled_ = false;
#else
bool g_is_preview_enabled_ = true;
+#endif // !defined(ENABLE_PRINT_PREVIEW)
const char kPageLoadScriptFormat[] =
"document.open(); document.write(%s); document.close();";
@@ -87,7 +88,6 @@ void ExecuteScript(blink::WebFrame* frame,
std::string script = base::StringPrintf(script_format, json.c_str());
frame->executeScript(blink::WebString(base::UTF8ToUTF16(script)));
}
-#endif // !defined(ENABLE_PRINT_PREVIEW)
int GetDPI(const PrintMsg_Print_Params* print_params) {
#if defined(OS_MACOSX)
@@ -484,7 +484,6 @@ blink::WebView* FrameReference::view() {
return view_;
}
-#if defined(ENABLE_PRINT_PREVIEW)
// static - Not anonymous so that platform implementations can use it.
void PrintWebViewHelper::PrintHeaderAndFooter(
blink::WebCanvas* canvas,
@@ -541,7 +540,6 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
web_view->close();
frame->close();
}
-#endif // defined(ENABLE_PRINT_PREVIEW)
// static - Not anonymous so that platform implementations can use it.
float PrintWebViewHelper::RenderPageContent(blink::WebFrame* frame,
diff --git printing/renderer/print_web_view_helper.h printing/renderer/print_web_view_helper.h
index d040dbc..72dd76e 100644
--- printing/renderer/print_web_view_helper.h
+++ printing/renderer/print_web_view_helper.h
@@ -305,7 +305,6 @@ class PrintWebViewHelper
double* scale_factor,
PageSizeMargins* page_layout_in_points);
-#if defined(ENABLE_PRINT_PREVIEW)
// Given the |device| and |canvas| to draw on, prints the appropriate headers
// and footers using strings from |header_footer_info| on to the canvas.
static void PrintHeaderAndFooter(blink::WebCanvas* canvas,
@@ -315,7 +314,6 @@ class PrintWebViewHelper
float webkit_scale_factor,
const PageSizeMargins& page_layout_in_points,
const PrintMsg_Print_Params& params);
-#endif // defined(ENABLE_PRINT_PREVIEW)
bool GetPrintFrame(blink::WebLocalFrame** frame);
diff --git printing/renderer/print_web_view_helper_linux.cc printing/renderer/print_web_view_helper_linux.cc
index 79b82e9..8d1f6f4 100644
--- printing/renderer/print_web_view_helper_linux.cc
+++ printing/renderer/print_web_view_helper_linux.cc
@@ -169,7 +169,6 @@ void PrintWebViewHelper::PrintPageInternal(
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
-#if defined(ENABLE_PRINT_PREVIEW)
if (params.params.display_header_footer) {
// |page_number| is 0-based, so 1 is added.
// TODO(vitalybuka) : why does it work only with 1.25?
@@ -178,7 +177,6 @@ void PrintWebViewHelper::PrintPageInternal(
scale_factor / 1.25, page_layout_in_points,
params.params);
}
-#endif // defined(ENABLE_PRINT_PREVIEW)
RenderPageContent(frame, params.page_number, canvas_area, content_area,
scale_factor, canvas);
diff --git printing/renderer/print_web_view_helper_mac.mm printing/renderer/print_web_view_helper_mac.mm
index 7aa503c..a6413be 100644
--- printing/renderer/print_web_view_helper_mac.mm
+++ printing/renderer/print_web_view_helper_mac.mm
@@ -125,14 +125,12 @@ void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params,
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
skia::SetIsPreviewMetafile(*canvas, is_preview);
-#if defined(ENABLE_PRINT_PREVIEW)
if (params.display_header_footer) {
PrintHeaderAndFooter(static_cast<blink::WebCanvas*>(canvas),
page_number + 1,
print_preview_context_.total_page_count(), *frame,
scale_factor, page_layout_in_points, params);
}
-#endif // defined(ENABLE_PRINT_PREVIEW)
RenderPageContent(frame, page_number, canvas_area, content_area,
scale_factor, static_cast<blink::WebCanvas*>(canvas));
}
diff --git printing/renderer/print_web_view_helper_pdf_win.cc printing/renderer/print_web_view_helper_pdf_win.cc
index a121448..f2a1a0a 100644
--- printing/renderer/print_web_view_helper_pdf_win.cc
+++ printing/renderer/print_web_view_helper_pdf_win.cc
@@ -185,14 +185,12 @@ void PrintWebViewHelper::PrintPageInternal(
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
-#if defined(ENABLE_PRINT_PREVIEW)
if (params.params.display_header_footer) {
// |page_number| is 0-based, so 1 is added.
PrintHeaderAndFooter(canvas, params.page_number + 1,
print_preview_context_.total_page_count(), *frame,
scale_factor, page_layout_in_points, params.params);
}
-#endif // defined(ENABLE_PRINT_PREVIEW)
float webkit_scale_factor =
RenderPageContent(frame, params.page_number, canvas_area, content_area,
diff --git resources/printing_resources.grdp resources/printing_resources.grdp
index 7213746..32b8b1e 100644
--- resources/printing_resources.grdp
+++ resources/printing_resources.grdp
@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<grit-part>
- <if expr="enable_print_preview">
<include name="IDR_PRINT_PREVIEW_PAGE" file="../printing/resources/print_preview_page.html" flattenhtml="true" allowexternalscript="false" type="BINDATA" />
- </if>
</grit-part>

View File

@ -440,6 +440,17 @@ void ClientPrintHandlerGtk::OnPrintReset() {
}
}
CefSize ClientPrintHandlerGtk::GetPdfPaperSize(int device_units_per_inch) {
GtkPageSetup* page_setup = gtk_page_setup_new();
float width = gtk_page_setup_get_paper_width(page_setup, GTK_UNIT_INCH);
float height = gtk_page_setup_get_paper_height(page_setup, GTK_UNIT_INCH);
g_object_unref(page_setup);
return CefSize(width * device_units_per_inch, height * device_units_per_inch);
}
void ClientPrintHandlerGtk::OnDialogResponse(GtkDialog *dialog,
gint response_id) {
int num_matched_handlers = g_signal_handlers_disconnect_by_func(

View File

@ -28,6 +28,7 @@ class ClientPrintHandlerGtk : public CefPrintHandler {
const CefString& pdf_file_path,
CefRefPtr<CefPrintJobCallback> callback) OVERRIDE;
void OnPrintReset() OVERRIDE;
CefSize GetPdfPaperSize(int device_units_per_inch) OVERRIDE;
private:
void OnDialogResponse(GtkDialog *dialog,

View File

@ -41,7 +41,8 @@
#define ID_TESTS_FPS_INCREASE 32713
#define ID_TESTS_FPS_DECREASE 32714
#define ID_TESTS_FPS_RESET 32715
#define ID_TESTS_LAST 32715
#define ID_TESTS_PRINT_TO_PDF 32716
#define ID_TESTS_LAST 32716
#define IDC_STATIC -1
#define IDS_BINDING 1000
#define IDS_DIALOGS 1001

View File

@ -602,6 +602,7 @@ GtkWidget* RootWindowGtk::CreateMenuBar() {
AddMenuEntry(test_menu, "Begin Tracing", ID_TESTS_TRACING_BEGIN);
AddMenuEntry(test_menu, "End Tracing", ID_TESTS_TRACING_END);
AddMenuEntry(test_menu, "Print", ID_TESTS_PRINT);
AddMenuEntry(test_menu, "Print to PDF", ID_TESTS_PRINT_TO_PDF);
AddMenuEntry(test_menu, "Other Tests", ID_TESTS_OTHER_TESTS);
return menu_bar;

View File

@ -227,7 +227,8 @@ void EndTracing(CefRefPtr<CefBrowser> browser) {
// Results in a call to OnFileDialogDismissed.
browser_->GetHost()->RunFileDialog(
FILE_DIALOG_SAVE,
static_cast<cef_file_dialog_mode_t>(
FILE_DIALOG_SAVE | FILE_DIALOG_OVERWRITEPROMPT_FLAG),
CefString(), // title
path,
std::vector<CefString>(), // accept_filters
@ -235,7 +236,7 @@ void EndTracing(CefRefPtr<CefBrowser> browser) {
this);
}
virtual void OnFileDialogDismissed(
void OnFileDialogDismissed(
int selected_accept_filter,
const std::vector<CefString>& file_paths) OVERRIDE {
if (!file_paths.empty()) {
@ -247,7 +248,7 @@ void EndTracing(CefRefPtr<CefBrowser> browser) {
}
}
virtual void OnEndTracingComplete(
void OnEndTracingComplete(
const CefString& tracing_file) OVERRIDE {
Alert(browser_,
"File \"" + tracing_file.ToString() + "\" saved successfully.");
@ -262,6 +263,71 @@ void EndTracing(CefRefPtr<CefBrowser> browser) {
new Client(browser);
}
void PrintToPDF(CefRefPtr<CefBrowser> browser) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI, base::Bind(&PrintToPDF, browser));
return;
}
class Client : public CefPdfPrintCallback,
public CefRunFileDialogCallback {
public:
explicit Client(CefRefPtr<CefBrowser> browser)
: browser_(browser) {
RunDialog();
}
void RunDialog() {
static const char kDefaultFileName[] = "output.pdf";
std::string path = MainContext::Get()->GetDownloadPath(kDefaultFileName);
if (path.empty())
path = kDefaultFileName;
std::vector<CefString> accept_filters;
accept_filters.push_back(".pdf");
// Results in a call to OnFileDialogDismissed.
browser_->GetHost()->RunFileDialog(
static_cast<cef_file_dialog_mode_t>(
FILE_DIALOG_SAVE | FILE_DIALOG_OVERWRITEPROMPT_FLAG),
CefString(), // title
path,
accept_filters,
0, // selected_accept_filter
this);
}
void OnFileDialogDismissed(
int selected_accept_filter,
const std::vector<CefString>& file_paths) OVERRIDE {
if (!file_paths.empty()) {
CefPdfPrintSettings settings;
// Show the URL in the footer.
settings.header_footer_enabled = true;
CefString(&settings.header_footer_url) =
browser_->GetMainFrame()->GetURL();
// Print to the selected PDF file.
browser_->GetHost()->PrintToPDF(file_paths[0], settings, this);
}
}
void OnPdfPrintFinished(const CefString& path, bool ok) OVERRIDE {
Alert(browser_, "File \"" + path.ToString() +"\" " +
(ok ? "saved successfully." : "failed to save."));
}
private:
CefRefPtr<CefBrowser> browser_;
IMPLEMENT_REFCOUNTING(Client);
};
new Client(browser);
}
void RunOtherTests(CefRefPtr<CefBrowser> browser) {
browser->GetMainFrame()->LoadURL("http://tests/other_tests");
}
@ -389,6 +455,9 @@ void RunTest(CefRefPtr<CefBrowser> browser, int id) {
case ID_TESTS_PRINT:
browser->GetHost()->Print();
break;
case ID_TESTS_PRINT_TO_PDF:
PrintToPDF(browser);
break;
case ID_TESTS_OTHER_TESTS:
RunOtherTests(browser);
break;

View File

@ -143,6 +143,7 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
AddMenuItem(testMenu, @"Begin Tracing", ID_TESTS_TRACING_BEGIN);
AddMenuItem(testMenu, @"End Tracing", ID_TESTS_TRACING_END);
AddMenuItem(testMenu, @"Print", ID_TESTS_PRINT);
AddMenuItem(testMenu, @"Print to PDF", ID_TESTS_PRINT_TO_PDF);
AddMenuItem(testMenu, @"Other Tests", ID_TESTS_OTHER_TESTS);
[testItem setSubmenu:testMenu];
[menubar addItem:testItem];

View File

@ -86,6 +86,7 @@ BEGIN
MENUITEM "Begin Tracing", ID_TESTS_TRACING_BEGIN
MENUITEM "End Tracing", ID_TESTS_TRACING_END
MENUITEM "Print", ID_TESTS_PRINT
MENUITEM "Print to PDF", ID_TESTS_PRINT_TO_PDF
MENUITEM "Other Tests", ID_TESTS_OTHER_TESTS
END
END