Skip to content
This repository has been archived by the owner on Jan 4, 2019. It is now read-only.

Commit

Permalink
fix print to pdf on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
bridiver committed Nov 1, 2017
1 parent 0b572b8 commit 91bf9e3
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 31 deletions.
135 changes: 107 additions & 28 deletions chromium_src/chrome/browser/printing/print_preview_message_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/printing/print_view_manager_common.h"
#include "chrome/browser/printing/printer_query.h"
#include "components/printing/common/print_messages.h"
#include "content/public/browser/browser_thread.h"
Expand All @@ -25,6 +26,7 @@
#include "printing/page_size_margins.h"
#include "printing/pdf_metafile_skia.h"
#include "printing/print_job_constants.h"
#include "printing/units.h"

#include "atom/common/node_includes.h"

Expand Down Expand Up @@ -65,6 +67,19 @@ char* CopyPDFDataOnIOThread(
return pdf_data;
}

std::pair<int, int> GetKey(content::RenderFrameHost* rfh) {
if (!rfh)
return std::make_pair(-1, -1);

return std::make_pair(rfh->GetProcess()->GetID(), rfh->GetRoutingID());
}

int GetRequestID(const base::DictionaryValue& options) {
int request_id = -1;
options.GetInteger(kPreviewRequestID, &request_id);
return request_id;
}

} // namespace

PrintPreviewMessageHandler::PrintPreviewMessageHandler(
Expand All @@ -77,6 +92,7 @@ PrintPreviewMessageHandler::PrintPreviewMessageHandler(
PrintPreviewMessageHandler::~PrintPreviewMessageHandler() {}

void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
content::RenderFrameHost* rfh,
const PrintHostMsg_DidPreviewDocument_Params& params) {
// Always try to stop the worker.
StopWorker(params.document_cookie);
Expand All @@ -86,6 +102,10 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
return;
}

auto key = GetKey(rfh);
if (base::ContainsKey(print_to_pdf_options_map_, key))
print_to_pdf_options_map_.erase(key);

BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::IO,
FROM_HERE,
Expand All @@ -96,8 +116,56 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
params.data_size));
}

void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) {
void PrintPreviewMessageHandler::OnPrintPreviewFailed(
content::RenderFrameHost* rfh,
int document_cookie) {
StopWorker(document_cookie);

auto key = GetKey(rfh);
if (base::ContainsKey(print_to_pdf_options_map_, key)) {
auto options = print_to_pdf_options_map_[key].get();
RunPrintToPDFCallback(GetRequestID(*options), 0, nullptr);
print_to_pdf_options_map_.erase(key);
}
}

void PrintPreviewMessageHandler::OnPrintingFailed(
content::RenderFrameHost* rfh,
int document_cookie) {
StopWorker(document_cookie);

auto key = GetKey(rfh);
if (base::ContainsKey(print_to_pdf_options_map_, key)) {
auto options = print_to_pdf_options_map_[key].get();
RunPrintToPDFCallback(GetRequestID(*options), 0, nullptr);
print_to_pdf_options_map_.erase(key);
}
}

void PrintPreviewMessageHandler::OnPrintPreviewCancelled(
content::RenderFrameHost* rfh,
int document_cookie) {
StopWorker(document_cookie);

auto key = GetKey(rfh);
if (base::ContainsKey(print_to_pdf_options_map_, key)) {
auto options = print_to_pdf_options_map_[key].get();
RunPrintToPDFCallback(GetRequestID(*options), 0, nullptr);
print_to_pdf_options_map_.erase(key);
}
}

void PrintPreviewMessageHandler::OnPrintPreviewInvalidPrinterSettings(
content::RenderFrameHost* rfh,
int document_cookie) {
StopWorker(document_cookie);

auto key = GetKey(rfh);
if (base::ContainsKey(print_to_pdf_options_map_, key)) {
auto options = print_to_pdf_options_map_[key].get();
RunPrintToPDFCallback(GetRequestID(*options), 0, nullptr);
print_to_pdf_options_map_.erase(key);
}
}

bool PrintPreviewMessageHandler::OnMessageReceived(
Expand All @@ -109,55 +177,66 @@ bool PrintPreviewMessageHandler::OnMessageReceived(
render_frame_host)
IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
OnRequestPrintPreview)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
if (handled)
return true;

IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message)
IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
OnMetafileReadyForPrinting)
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed,
OnPrintPreviewFailed)
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintingFailed,
OnPrintingFailed)
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled,
OnPrintPreviewCancelled)
IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
OnPrintPreviewInvalidPrinterSettings)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()

return handled;
}

void PrintPreviewMessageHandler::OnRequestPrintPreview(
content::RenderFrameHost* render_frame_host,
content::RenderFrameHost* rfh,
const PrintHostMsg_RequestPrintPreview_Params& params) {
if (params.webnode_only) {
PrintViewManager::FromWebContents(web_contents())->PrintPreviewForWebNode(
render_frame_host);
PrintViewManager::FromWebContents(
web_contents())->PrintPreviewForWebNode(rfh);
}

auto key = GetKey(rfh);
if (base::ContainsKey(print_to_pdf_options_map_, key)) {
auto options = print_to_pdf_options_map_[key].get();
options->SetBoolean(printing::kSettingPrintToPDF, true);
options->SetInteger(kPreviewInitiatorHostId,
rfh->GetProcess()->GetID());
options->SetInteger(printing::kPreviewInitiatorRoutingId,
rfh->GetRoutingID());
options->SetInteger(kSettingDpiHorizontal, kPointsPerInch);
options->SetInteger(kSettingDpiVertical, kPointsPerInch);

rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), *options));
}
}

void PrintPreviewMessageHandler::PrintToPDF(
const base::DictionaryValue& options,
const atom::api::WebContents::PrintToPDFCallback& callback) {
PrintViewManager::FromWebContents(web_contents())->PrintPreviewNow(
web_contents()->GetMainFrame(), false);

int request_id = -1;
options.GetInteger(kPreviewRequestID, &request_id);
int request_id = GetRequestID(options);
print_to_pdf_callback_map_[request_id] = callback;

WebContents* initiator = web_contents();
content::RenderFrameHost* rfh =
initiator
? PrintViewManager::FromWebContents(initiator)->print_preview_rfh()
: nullptr;

content::RenderFrameHost* rfh = printing::GetFrameToPrint(web_contents());
if (rfh) {
std::unique_ptr<base::DictionaryValue> new_options(options.DeepCopy());
new_options->SetBoolean(printing::kSettingPrintToPDF, true);
new_options->SetInteger(kPreviewInitiatorHostId,
rfh->GetProcess()->GetID());
new_options->SetInteger(kPreviewInitiatorRoutingId,
rfh->GetRoutingID());
rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), *new_options));
auto key = GetKey(rfh);
if (base::ContainsKey(print_to_pdf_options_map_, key)) {
RunPrintToPDFCallback(request_id, 0, nullptr);
return;
}

print_to_pdf_options_map_[key] = options.CreateDeepCopy();
} else {
RunPrintToPDFCallback(request_id, 0, nullptr);
return;
}

printing::StartPrint(web_contents(), false, false);
}

void PrintPreviewMessageHandler::RunPrintToPDFCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,36 @@ class PrintPreviewMessageHandler
private:
typedef std::map<int, atom::api::WebContents::PrintToPDFCallback>
PrintToPDFCallbackMap;
typedef std::map<std::pair<int, int>, std::unique_ptr<base::DictionaryValue>>
PrintToPDFOptionsMap;

explicit PrintPreviewMessageHandler(content::WebContents* web_contents);
friend class content::WebContentsUserData<PrintPreviewMessageHandler>;

// Message handlers.
void OnRequestPrintPreview(
content::RenderFrameHost* render_frame_host,
const PrintHostMsg_RequestPrintPreview_Params& params);
content::RenderFrameHost* render_frame_host,
const PrintHostMsg_RequestPrintPreview_Params& params);
void OnMetafileReadyForPrinting(
content::RenderFrameHost* render_frame_host,
const PrintHostMsg_DidPreviewDocument_Params& params);
void OnPrintPreviewFailed(int document_cookie);
void OnPrintPreviewFailed(
content::RenderFrameHost* render_frame_host,
int document_cookie);
void OnPrintingFailed(
content::RenderFrameHost* render_frame_host,
int document_cookie);
void OnPrintPreviewCancelled(
content::RenderFrameHost* render_frame_host,
int document_cookie);
void OnPrintPreviewInvalidPrinterSettings(
content::RenderFrameHost* render_frame_host,
int document_cookie);

void RunPrintToPDFCallback(int request_id, uint32_t data_size, char* data);

PrintToPDFCallbackMap print_to_pdf_callback_map_;
PrintToPDFOptionsMap print_to_pdf_options_map_;

base::WeakPtrFactory<PrintPreviewMessageHandler> weak_ptr_factory_;

Expand Down

0 comments on commit 91bf9e3

Please sign in to comment.