Windows: Make it possible to print text with GDI.
This only affects the printing of web pages directly on the host. - Renderer tells the browser if the print job is HTML. (AKA modifiable) -- Browser does lots of plumbing to get the bool into PrintSettings. -- Print preview already sends this info and it just needs extraction. - Add --disable-gdi-text-printing for reverting to old behavior. - Browser plumbs bool to PdfToEmfConverter to the utility process. - Utility plumbs bool into the PDF plugin code into PDFium. - Move unused PreCacheFontCharacters code out of RenderThreadImpl. -- Use it in PrintingHandler instead. - Remove dead code, fix lint errors / typos. BUG=409472 Review-Url: https://codereview.chromium.org/2114583002 Cr-Commit-Position: refs/heads/master@{#414209}
This commit is contained in:
build_overrides
chrome
browser
printing
common
service
utility
components/printing
content
browser
renderer_host
common
renderer
pdf
printing
@ -11,5 +11,5 @@ pdf_enable_xfa_override = false
|
||||
# Disable use of Skia backend.
|
||||
pdf_use_skia_override = false
|
||||
|
||||
# Disable experimental win32 APIs.
|
||||
pdf_use_win32_gdi_override = false
|
||||
# Enable experimental win32 GDI APIs.
|
||||
pdf_use_win32_gdi_override = true
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "chrome/browser/printing/pdf_to_emf_converter.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
@ -107,6 +108,7 @@ class PdfToEmfUtilityProcessHostClient
|
||||
const PdfRenderSettings& settings);
|
||||
|
||||
void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
||||
bool print_text_with_gdi,
|
||||
const PdfToEmfConverter::StartCallback& start_callback);
|
||||
|
||||
void GetPage(int page_number,
|
||||
@ -114,6 +116,10 @@ class PdfToEmfUtilityProcessHostClient
|
||||
|
||||
void Stop();
|
||||
|
||||
// Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters
|
||||
// sync message replies.
|
||||
bool Send(IPC::Message* msg);
|
||||
|
||||
// UtilityProcessHostClient implementation.
|
||||
void OnProcessCrashed(int exit_code) override;
|
||||
void OnProcessLaunchFailed(int exit_code) override;
|
||||
@ -154,14 +160,14 @@ class PdfToEmfUtilityProcessHostClient
|
||||
|
||||
~PdfToEmfUtilityProcessHostClient() override;
|
||||
|
||||
bool Send(IPC::Message* msg);
|
||||
|
||||
// Message handlers.
|
||||
void OnPageCount(int page_count);
|
||||
void OnPageDone(bool success, float scale_factor);
|
||||
void OnPreCacheFontCharacters(const LOGFONT& log_font,
|
||||
const base::string16& characters);
|
||||
|
||||
void OnFailed();
|
||||
void OnTempPdfReady(ScopedTempFile pdf);
|
||||
void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf);
|
||||
void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf);
|
||||
|
||||
scoped_refptr<RefCountedTempDir> temp_dir_;
|
||||
@ -193,6 +199,7 @@ class PdfToEmfConverterImpl : public PdfToEmfConverter {
|
||||
|
||||
void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfRenderSettings& conversion_settings,
|
||||
bool print_text_with_gdi,
|
||||
const StartCallback& start_callback) override;
|
||||
|
||||
void GetPage(int page_number,
|
||||
@ -297,14 +304,13 @@ PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::Start(
|
||||
const scoped_refptr<base::RefCountedMemory>& data,
|
||||
bool print_text_with_gdi,
|
||||
const PdfToEmfConverter::StartCallback& start_callback) {
|
||||
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
||||
BrowserThread::PostTask(BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::Start,
|
||||
this,
|
||||
data,
|
||||
start_callback));
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data,
|
||||
print_text_with_gdi, start_callback));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -321,20 +327,21 @@ void PdfToEmfUtilityProcessHostClient::Start(
|
||||
IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME));
|
||||
|
||||
BrowserThread::PostTaskAndReplyWithResult(
|
||||
BrowserThread::FILE,
|
||||
FROM_HERE,
|
||||
BrowserThread::FILE, FROM_HERE,
|
||||
base::Bind(&CreateTempPdfFile, data, &temp_dir_),
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this));
|
||||
base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this,
|
||||
print_text_with_gdi));
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) {
|
||||
void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi,
|
||||
ScopedTempFile pdf) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
if (!utility_process_host_ || !pdf)
|
||||
return OnFailed();
|
||||
// Should reply with OnPageCount().
|
||||
Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(
|
||||
IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false),
|
||||
settings_));
|
||||
IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_,
|
||||
print_text_with_gdi));
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) {
|
||||
@ -418,6 +425,38 @@ void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success,
|
||||
get_page_callbacks_.pop();
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
|
||||
const LOGFONT& font,
|
||||
const base::string16& str) {
|
||||
// TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
|
||||
// GDI fonts (http://crbug.com/383227), even when using DirectWrite.
|
||||
// Eventually this shouldn't be added and should be moved to
|
||||
// FontCacheDispatcher too. http://crbug.com/356346.
|
||||
|
||||
// First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
|
||||
// Except that for True Type fonts,
|
||||
// GetTextMetrics will not load the font in memory.
|
||||
// The only way windows seem to load properly, it is to create a similar
|
||||
// device (like the one in which we print), then do an ExtTextOut,
|
||||
// as we do in the printing thread, which is sandboxed.
|
||||
HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr);
|
||||
HFONT font_handle = CreateFontIndirect(&font);
|
||||
DCHECK(font_handle != nullptr);
|
||||
|
||||
HGDIOBJ old_font = SelectObject(hdc, font_handle);
|
||||
DCHECK(old_font != nullptr);
|
||||
|
||||
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), nullptr);
|
||||
|
||||
SelectObject(hdc, old_font);
|
||||
DeleteObject(font_handle);
|
||||
|
||||
HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
|
||||
|
||||
if (metafile)
|
||||
DeleteEnhMetaFile(metafile);
|
||||
}
|
||||
|
||||
void PdfToEmfUtilityProcessHostClient::Stop() {
|
||||
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
||||
BrowserThread::PostTask(
|
||||
@ -445,6 +484,8 @@ bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
|
||||
ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
|
||||
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
|
||||
OnPageDone)
|
||||
IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters,
|
||||
OnPreCacheFontCharacters)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
@ -477,11 +518,12 @@ PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
|
||||
void PdfToEmfConverterImpl::Start(
|
||||
const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfRenderSettings& conversion_settings,
|
||||
bool print_text_with_gdi,
|
||||
const StartCallback& start_callback) {
|
||||
DCHECK(!utility_client_.get());
|
||||
utility_client_ = new PdfToEmfUtilityProcessHostClient(
|
||||
weak_ptr_factory_.GetWeakPtr(), conversion_settings);
|
||||
utility_client_->Start(data, start_callback);
|
||||
utility_client_->Start(data, print_text_with_gdi, start_callback);
|
||||
}
|
||||
|
||||
void PdfToEmfConverterImpl::GetPage(int page_number,
|
||||
|
@ -35,6 +35,7 @@ class PdfToEmfConverter {
|
||||
// with positive |page_count|. |page_count| is 0 if initialization failed.
|
||||
virtual void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfRenderSettings& conversion_settings,
|
||||
bool print_text_with_gdi,
|
||||
const StartCallback& start_callback) = 0;
|
||||
|
||||
// Requests conversion of the page. |page_number| is 0-base page number in
|
||||
|
@ -234,8 +234,10 @@ class PrintJob::PdfToEmfState {
|
||||
|
||||
void Start(const scoped_refptr<base::RefCountedMemory>& data,
|
||||
const PdfRenderSettings& conversion_settings,
|
||||
bool print_text_with_gdi,
|
||||
const PdfToEmfConverter::StartCallback& start_callback) {
|
||||
converter_->Start(data, conversion_settings, start_callback);
|
||||
converter_->Start(data, conversion_settings, print_text_with_gdi,
|
||||
start_callback);
|
||||
}
|
||||
|
||||
void GetMorePages(
|
||||
@ -277,13 +279,14 @@ void PrintJob::AppendPrintedPage(int page_number) {
|
||||
void PrintJob::StartPdfToEmfConversion(
|
||||
const scoped_refptr<base::RefCountedMemory>& bytes,
|
||||
const gfx::Size& page_size,
|
||||
const gfx::Rect& content_area) {
|
||||
const gfx::Rect& content_area,
|
||||
bool print_text_with_gdi) {
|
||||
DCHECK(!pdf_to_emf_state_);
|
||||
pdf_to_emf_state_ = base::MakeUnique<PdfToEmfState>(page_size, content_area);
|
||||
const int kPrinterDpi = settings().dpi();
|
||||
pdf_to_emf_state_->Start(bytes,
|
||||
PdfRenderSettings(content_area, kPrinterDpi, true),
|
||||
base::Bind(&PrintJob::OnPdfToEmfStarted, this));
|
||||
pdf_to_emf_state_->Start(
|
||||
bytes, PdfRenderSettings(content_area, kPrinterDpi, true),
|
||||
print_text_with_gdi, base::Bind(&PrintJob::OnPdfToEmfStarted, this));
|
||||
}
|
||||
|
||||
void PrintJob::OnPdfToEmfStarted(int page_count) {
|
||||
|
@ -97,7 +97,8 @@ class PrintJob : public PrintJobWorkerOwner,
|
||||
void StartPdfToEmfConversion(
|
||||
const scoped_refptr<base::RefCountedMemory>& bytes,
|
||||
const gfx::Size& page_size,
|
||||
const gfx::Rect& content_area);
|
||||
const gfx::Rect& content_area,
|
||||
bool print_text_with_gdi);
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
protected:
|
||||
|
@ -134,12 +134,12 @@ void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) {
|
||||
owner_ = new_owner;
|
||||
}
|
||||
|
||||
void PrintJobWorker::GetSettings(
|
||||
bool ask_user_for_settings,
|
||||
int document_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
bool is_scripted) {
|
||||
void PrintJobWorker::GetSettings(bool ask_user_for_settings,
|
||||
int document_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
bool is_scripted,
|
||||
bool is_modifiable) {
|
||||
DCHECK(task_runner_->RunsTasksOnCurrentThread());
|
||||
DCHECK_EQ(page_number_, PageNumber::npos());
|
||||
|
||||
@ -150,6 +150,7 @@ void PrintJobWorker::GetSettings(
|
||||
// should happen on the same thread. See http://crbug.com/73466
|
||||
// MessageLoop::current()->SetNestableTasksAllowed(true);
|
||||
printing_context_->set_margin_type(margin_type);
|
||||
printing_context_->set_is_modifiable(is_modifiable);
|
||||
|
||||
// When we delegate to a destination, we don't ask the user for settings.
|
||||
// TODO(mad): Ask the destination for settings.
|
||||
|
@ -45,12 +45,13 @@ class PrintJobWorker {
|
||||
// Initializes the print settings. If |ask_user_for_settings| is true, a
|
||||
// Print... dialog box will be shown to ask the user his preference.
|
||||
// |is_scripted| should be true for calls coming straight from window.print().
|
||||
void GetSettings(
|
||||
bool ask_user_for_settings,
|
||||
int document_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
bool is_scripted);
|
||||
// |is_modifiable| implies HTML and not other formats like PDF.
|
||||
void GetSettings(bool ask_user_for_settings,
|
||||
int document_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
bool is_scripted,
|
||||
bool is_modifiable);
|
||||
|
||||
// Set the new print settings.
|
||||
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings);
|
||||
|
@ -41,6 +41,11 @@
|
||||
#include "chrome/browser/printing/print_error_dialog.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/command_line.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#endif
|
||||
|
||||
using base::TimeDelta;
|
||||
using content::BrowserThread;
|
||||
|
||||
@ -185,13 +190,17 @@ void PrintViewManagerBase::OnDidPrintPage(
|
||||
#if defined(OS_WIN)
|
||||
print_job_->AppendPrintedPage(params.page_number);
|
||||
if (metafile_must_be_valid) {
|
||||
bool print_text_with_gdi =
|
||||
document->settings().print_text_with_gdi() &&
|
||||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kDisableGDITextPrinting);
|
||||
scoped_refptr<base::RefCountedBytes> bytes = new base::RefCountedBytes(
|
||||
reinterpret_cast<const unsigned char*>(shared_buf->memory()),
|
||||
params.data_size);
|
||||
|
||||
document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
|
||||
print_job_->StartPdfToEmfConversion(
|
||||
bytes, params.page_size, params.content_area);
|
||||
bytes, params.page_size, params.content_area, print_text_with_gdi);
|
||||
}
|
||||
#else
|
||||
// Update the rendered document. It will send notifications to the listener.
|
||||
|
@ -65,13 +65,13 @@ int PrinterQuery::cookie() const {
|
||||
return cookie_;
|
||||
}
|
||||
|
||||
void PrinterQuery::GetSettings(
|
||||
GetSettingsAskParam ask_user_for_settings,
|
||||
int expected_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
bool is_scripted,
|
||||
const base::Closure& callback) {
|
||||
void PrinterQuery::GetSettings(GetSettingsAskParam ask_user_for_settings,
|
||||
int expected_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
bool is_scripted,
|
||||
bool is_modifiable,
|
||||
const base::Closure& callback) {
|
||||
DCHECK(RunsTasksOnCurrentThread());
|
||||
DCHECK(!is_print_dialog_box_shown_ || !is_scripted);
|
||||
|
||||
@ -80,14 +80,11 @@ void PrinterQuery::GetSettings(
|
||||
// Real work is done in PrintJobWorker::GetSettings().
|
||||
is_print_dialog_box_shown_ =
|
||||
ask_user_for_settings == GetSettingsAskParam::ASK_USER;
|
||||
worker_->PostTask(FROM_HERE,
|
||||
base::Bind(&PrintJobWorker::GetSettings,
|
||||
base::Unretained(worker_.get()),
|
||||
is_print_dialog_box_shown_,
|
||||
expected_page_count,
|
||||
has_selection,
|
||||
margin_type,
|
||||
is_scripted));
|
||||
worker_->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&PrintJobWorker::GetSettings, base::Unretained(worker_.get()),
|
||||
is_print_dialog_box_shown_, expected_page_count, has_selection,
|
||||
margin_type, is_scripted, is_modifiable));
|
||||
}
|
||||
|
||||
void PrinterQuery::SetSettings(
|
||||
|
@ -44,13 +44,13 @@ class PrinterQuery : public PrintJobWorkerOwner {
|
||||
// times to reinitialize the settings. |web_contents_observer| can be queried
|
||||
// to find the owner of the print setting dialog box. It is unused when
|
||||
// |ask_for_user_settings| is DEFAULTS.
|
||||
void GetSettings(
|
||||
GetSettingsAskParam ask_user_for_settings,
|
||||
int expected_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
bool is_scripted,
|
||||
const base::Closure& callback);
|
||||
void GetSettings(GetSettingsAskParam ask_user_for_settings,
|
||||
int expected_page_count,
|
||||
bool has_selection,
|
||||
MarginType margin_type,
|
||||
bool is_scripted,
|
||||
bool is_modifiable,
|
||||
const base::Closure& callback);
|
||||
|
||||
// Updates the current settings with |new_settings| dictionary values.
|
||||
void SetSettings(std::unique_ptr<base::DictionaryValue> new_settings,
|
||||
|
@ -26,15 +26,6 @@
|
||||
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_CHROMEOS)
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "chrome/browser/printing/print_view_manager_basic.h"
|
||||
@ -163,15 +154,10 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
|
||||
// Loads default settings. This is asynchronous, only the IPC message sender
|
||||
// will hang until the settings are retrieved.
|
||||
printer_query->GetSettings(
|
||||
PrinterQuery::GetSettingsAskParam::DEFAULTS,
|
||||
0,
|
||||
false,
|
||||
DEFAULT_MARGINS,
|
||||
false,
|
||||
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply,
|
||||
this,
|
||||
printer_query,
|
||||
reply_msg));
|
||||
PrinterQuery::GetSettingsAskParam::DEFAULTS, 0, false, DEFAULT_MARGINS,
|
||||
false, false,
|
||||
base::Bind(&PrintingMessageFilter::OnGetDefaultPrintSettingsReply, this,
|
||||
printer_query, reply_msg));
|
||||
}
|
||||
|
||||
void PrintingMessageFilter::OnGetDefaultPrintSettingsReply(
|
||||
@ -208,15 +194,11 @@ void PrintingMessageFilter::OnScriptedPrint(
|
||||
queue_->CreatePrinterQuery(render_process_id_, reply_msg->routing_id());
|
||||
}
|
||||
printer_query->GetSettings(
|
||||
PrinterQuery::GetSettingsAskParam::ASK_USER,
|
||||
params.expected_pages_count,
|
||||
params.has_selection,
|
||||
params.margin_type,
|
||||
params.is_scripted,
|
||||
base::Bind(&PrintingMessageFilter::OnScriptedPrintReply,
|
||||
this,
|
||||
printer_query,
|
||||
reply_msg));
|
||||
PrinterQuery::GetSettingsAskParam::ASK_USER, params.expected_pages_count,
|
||||
params.has_selection, params.margin_type, params.is_scripted,
|
||||
params.is_modifiable,
|
||||
base::Bind(&PrintingMessageFilter::OnScriptedPrintReply, this,
|
||||
printer_query, reply_msg));
|
||||
}
|
||||
|
||||
void PrintingMessageFilter::OnScriptedPrintReply(
|
||||
|
@ -1198,6 +1198,10 @@ const char kRelauncherProcessDMGDevice[] = "dmg-device";
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Disables using GDI to print text as simply text. Fallback to printing text
|
||||
// as paths.
|
||||
const char kDisableGDITextPrinting[] = "disable-gdi-text-printing";
|
||||
|
||||
// Disables per monitor DPI for supported Windows versions.
|
||||
// This flag overrides kEnablePerMonitorDpi.
|
||||
const char kDisablePerMonitorDpi[] = "disable-per-monitor-dpi";
|
||||
|
@ -310,7 +310,7 @@ extern const char kWebApkServerUrl[];
|
||||
|
||||
#if defined(OS_CHROMEOS)
|
||||
extern const char kEnableNativeCups[];
|
||||
#endif // defined(OS_CHROMEOS)
|
||||
#endif // defined(OS_CHROMEOS)
|
||||
|
||||
#if defined(USE_ASH)
|
||||
extern const char kOpenAsh[];
|
||||
@ -348,6 +348,7 @@ extern const char kRelauncherProcessDMGDevice[];
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
extern const char kDisableGDITextPrinting[];
|
||||
extern const char kDisablePerMonitorDpi[];
|
||||
extern const char kEnableCloudPrintXps[];
|
||||
extern const char kEnablePerMonitorDpi[];
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/strings/string16.h"
|
||||
#include "build/build_config.h"
|
||||
#include "components/printing/common/printing_param_traits_macros.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
@ -16,6 +17,10 @@
|
||||
#include "printing/pdf_render_settings.h"
|
||||
#include "printing/pwg_raster_settings.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define IPC_MESSAGE_START ChromeUtilityPrintingMsgStart
|
||||
|
||||
// Preview and Cloud Print messages.
|
||||
@ -66,8 +71,8 @@ IPC_STRUCT_TRAITS_END()
|
||||
|
||||
// Tell the utility process to render the given PDF into a PWGRaster.
|
||||
IPC_MESSAGE_CONTROL4(ChromeUtilityMsg_RenderPDFPagesToPWGRaster,
|
||||
IPC::PlatformFileForTransit, /* Input PDF file */
|
||||
printing::PdfRenderSettings, /* PDF render settings */
|
||||
IPC::PlatformFileForTransit /* Input PDF file */,
|
||||
printing::PdfRenderSettings /* PDF render settings */,
|
||||
// PWG transform settings.
|
||||
printing::PwgRasterSettings,
|
||||
IPC::PlatformFileForTransit /* Output PWG file */)
|
||||
@ -93,9 +98,10 @@ IPC_MESSAGE_CONTROL1(ChromeUtilityMsg_GetPrinterSemanticCapsAndDefaults,
|
||||
// Tell the utility process to start rendering the given PDF into a metafile.
|
||||
// Utility process would be alive until
|
||||
// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message.
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles,
|
||||
IPC::PlatformFileForTransit, /* input_file */
|
||||
printing::PdfRenderSettings /* settings */)
|
||||
IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_RenderPDFPagesToMetafiles,
|
||||
IPC::PlatformFileForTransit /* input_file */,
|
||||
printing::PdfRenderSettings /* settings */,
|
||||
bool /* print_text_with_gdi */)
|
||||
|
||||
// Requests conversion of the next page.
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage,
|
||||
@ -152,4 +158,12 @@ IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount,
|
||||
IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
|
||||
bool /* success */,
|
||||
float /* scale_factor */)
|
||||
|
||||
// Request that the given font characters be loaded by the browser so it's
|
||||
// cached by the OS. Please see
|
||||
// PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters for details.
|
||||
IPC_SYNC_MESSAGE_CONTROL2_0(ChromeUtilityHostMsg_PreCacheFontCharacters,
|
||||
LOGFONT /* font_data */,
|
||||
base::string16 /* characters */)
|
||||
|
||||
#endif // ENABLE_PRINTING && OS_WIN
|
||||
|
@ -99,7 +99,7 @@ class ServiceUtilityProcessHost::PdfToEmfState {
|
||||
return false;
|
||||
return host_->Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(
|
||||
IPC::TakePlatformFileForTransit(std::move(pdf_file)),
|
||||
conversion_settings));
|
||||
conversion_settings, false /* print_text_with_gdi */));
|
||||
}
|
||||
|
||||
void GetMorePages() {
|
||||
|
@ -102,7 +102,7 @@ void CreateResourceUsageReporter(
|
||||
mojo::InterfaceRequest<mojom::ResourceUsageReporter> request) {
|
||||
new ResourceUsageReporterImpl(std::move(request));
|
||||
}
|
||||
#endif // OS_ANDROID
|
||||
#endif // !defined(OS_ANDROID)
|
||||
|
||||
void CreateImageDecoder(mojo::InterfaceRequest<mojom::ImageDecoder> request) {
|
||||
content::UtilityThread::Get()->EnsureBlinkInitialized();
|
||||
|
@ -40,9 +40,22 @@ void ReleaseProcessIfNeeded() {
|
||||
content::UtilityThread::Get()->ReleaseProcessIfNeeded();
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void PreCacheFontCharacters(const LOGFONT* logfont,
|
||||
const wchar_t* text,
|
||||
size_t text_length) {
|
||||
Send(new ChromeUtilityHostMsg_PreCacheFontCharacters(
|
||||
*logfont, base::string16(text, text_length)));
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
PrintingHandler::PrintingHandler() {}
|
||||
PrintingHandler::PrintingHandler() {
|
||||
#if defined(OS_WIN)
|
||||
chrome_pdf::SetPDFEnsureTypefaceCharactersAccessible(PreCacheFontCharacters);
|
||||
#endif
|
||||
}
|
||||
|
||||
PrintingHandler::~PrintingHandler() {}
|
||||
|
||||
@ -73,8 +86,10 @@ bool PrintingHandler::OnMessageReceived(const IPC::Message& message) {
|
||||
#if defined(OS_WIN)
|
||||
void PrintingHandler::OnRenderPDFPagesToMetafile(
|
||||
IPC::PlatformFileForTransit pdf_transit,
|
||||
const PdfRenderSettings& settings) {
|
||||
const PdfRenderSettings& settings,
|
||||
bool print_text_with_gdi) {
|
||||
pdf_rendering_settings_ = settings;
|
||||
chrome_pdf::SetPDFUseGDIPrinting(print_text_with_gdi);
|
||||
base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit);
|
||||
int page_count = LoadPDF(std::move(pdf_file));
|
||||
Send(
|
||||
|
@ -36,7 +36,8 @@ class PrintingHandler : public UtilityMessageHandler {
|
||||
// IPC message handlers.
|
||||
#if defined(OS_WIN)
|
||||
void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit,
|
||||
const PdfRenderSettings& settings);
|
||||
const PdfRenderSettings& settings,
|
||||
bool print_text_with_gdi);
|
||||
void OnRenderPDFPagesToMetafileGetPage(
|
||||
int page_number,
|
||||
IPC::PlatformFileForTransit output_file);
|
||||
|
@ -304,6 +304,7 @@ IPC_STRUCT_BEGIN(PrintHostMsg_ScriptedPrint_Params)
|
||||
IPC_STRUCT_MEMBER(int, expected_pages_count)
|
||||
IPC_STRUCT_MEMBER(bool, has_selection)
|
||||
IPC_STRUCT_MEMBER(bool, is_scripted)
|
||||
IPC_STRUCT_MEMBER(bool, is_modifiable)
|
||||
IPC_STRUCT_MEMBER(printing::MarginType, margin_type)
|
||||
IPC_STRUCT_END()
|
||||
|
||||
|
@ -1704,6 +1704,7 @@ bool PrintWebViewHelper::GetPrintSettingsFromUser(blink::WebLocalFrame* frame,
|
||||
}
|
||||
params.margin_type = margin_type;
|
||||
params.is_scripted = is_scripted;
|
||||
params.is_modifiable = !PrintingNodeOrPdfFrame(frame, node);
|
||||
|
||||
Send(new PrintHostMsg_DidShowPrintDialog(routing_id()));
|
||||
|
||||
|
@ -212,9 +212,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
|
||||
OnCacheableMetadataAvailableForCacheStorage)
|
||||
#if defined(OS_MACOSX)
|
||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(RenderProcessHostMsg_LoadFont, OnLoadFont)
|
||||
#elif defined(OS_WIN)
|
||||
IPC_MESSAGE_HANDLER(RenderProcessHostMsg_PreCacheFontCharacters,
|
||||
OnPreCacheFontCharacters)
|
||||
#endif
|
||||
IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvents, OnMediaLogEvents)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
@ -321,42 +318,7 @@ void RenderMessageFilter::SendLoadFontReply(IPC::Message* reply,
|
||||
Send(reply);
|
||||
}
|
||||
|
||||
#elif defined(OS_WIN)
|
||||
|
||||
void RenderMessageFilter::OnPreCacheFontCharacters(
|
||||
const LOGFONT& font,
|
||||
const base::string16& str) {
|
||||
// TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
|
||||
// GDI fonts (http://crbug.com/383227), even when using DirectWrite.
|
||||
// Eventually this shouldn't be added and should be moved to
|
||||
// FontCacheDispatcher too. http://crbug.com/356346.
|
||||
|
||||
// First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
|
||||
// Except that for True Type fonts,
|
||||
// GetTextMetrics will not load the font in memory.
|
||||
// The only way windows seem to load properly, it is to create a similar
|
||||
// device (like the one in which we print), then do an ExtTextOut,
|
||||
// as we do in the printing thread, which is sandboxed.
|
||||
HDC hdc = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
|
||||
HFONT font_handle = CreateFontIndirect(&font);
|
||||
DCHECK(NULL != font_handle);
|
||||
|
||||
HGDIOBJ old_font = SelectObject(hdc, font_handle);
|
||||
DCHECK(NULL != old_font);
|
||||
|
||||
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), NULL);
|
||||
|
||||
SelectObject(hdc, old_font);
|
||||
DeleteObject(font_handle);
|
||||
|
||||
HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
|
||||
|
||||
if (metafile)
|
||||
DeleteEnhMetaFile(metafile);
|
||||
}
|
||||
|
||||
|
||||
#endif // OS_*
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
void RenderMessageFilter::AllocateSharedMemoryOnFileThread(
|
||||
uint32_t buffer_size,
|
||||
|
@ -132,9 +132,6 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter {
|
||||
// Messages for OOP font loading.
|
||||
void OnLoadFont(const FontDescriptor& font, IPC::Message* reply_msg);
|
||||
void SendLoadFontReply(IPC::Message* reply, FontLoader::Result* result);
|
||||
#elif defined(OS_WIN)
|
||||
void OnPreCacheFontCharacters(const LOGFONT& log_font,
|
||||
const base::string16& characters);
|
||||
#endif
|
||||
|
||||
void OnGenerateRoutingID(int* route_id);
|
||||
|
@ -77,11 +77,4 @@ IPC_SYNC_MESSAGE_CONTROL1_3(RenderProcessHostMsg_LoadFont,
|
||||
uint32_t /* buffer size */,
|
||||
base::SharedMemoryHandle /* font data */,
|
||||
uint32_t /* font id */)
|
||||
#elif defined(OS_WIN)
|
||||
// Request that the given font characters be loaded by the browser so it's
|
||||
// cached by the OS. Please see RenderMessageFilter::OnPreCacheFontCharacters
|
||||
// for details.
|
||||
IPC_SYNC_MESSAGE_CONTROL2_0(RenderProcessHostMsg_PreCacheFontCharacters,
|
||||
LOGFONT /* font_data */,
|
||||
base::string16 /* characters */)
|
||||
#endif
|
||||
|
@ -1506,14 +1506,6 @@ base::WaitableEvent* RenderThreadImpl::GetShutdownEvent() {
|
||||
return ChildProcess::current()->GetShutDownEvent();
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void RenderThreadImpl::PreCacheFontCharacters(const LOGFONT& log_font,
|
||||
const base::string16& str) {
|
||||
Send(new RenderProcessHostMsg_PreCacheFontCharacters(log_font, str));
|
||||
}
|
||||
|
||||
#endif // OS_WIN
|
||||
|
||||
bool RenderThreadImpl::IsGpuRasterizationForced() {
|
||||
return is_gpu_rasterization_forced_;
|
||||
}
|
||||
|
@ -65,7 +65,8 @@ static_library("pdf") {
|
||||
]
|
||||
}
|
||||
|
||||
defines = [ "PDFIUM_PRINT_TEXT_WITH_GDI" ]
|
||||
if (pdf_enable_xfa) {
|
||||
defines = [ "PDF_ENABLE_XFA" ]
|
||||
defines += [ "PDF_ENABLE_XFA" ]
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,14 @@ bool RenderPDFPageToDC(const void* pdf_buffer,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SetPDFEnsureTypefaceCharactersAccessible(
|
||||
PDFEnsureTypefaceCharactersAccessible func) {
|
||||
PDFEngineExports::Get()->SetPDFEnsureTypefaceCharactersAccessible(func);
|
||||
}
|
||||
|
||||
void SetPDFUseGDIPrinting(bool enable) {
|
||||
PDFEngineExports::Get()->SetPDFUseGDIPrinting(enable);
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
bool GetPDFDocInfo(const void* pdf_buffer,
|
||||
|
18
pdf/pdf.h
18
pdf/pdf.h
@ -8,6 +8,16 @@
|
||||
#include "ppapi/c/ppb.h"
|
||||
#include "ppapi/cpp/module.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
typedef void (*PDFEnsureTypefaceCharactersAccessible)(const LOGFONT* font,
|
||||
const wchar_t* text,
|
||||
size_t text_length);
|
||||
#endif
|
||||
|
||||
namespace chrome_pdf {
|
||||
|
||||
class PDFModule : public pp::Module {
|
||||
@ -67,7 +77,13 @@ bool RenderPDFPageToDC(const void* pdf_buffer,
|
||||
bool keep_aspect_ratio,
|
||||
bool center_in_bounds,
|
||||
bool autorotate);
|
||||
#endif
|
||||
|
||||
void SetPDFEnsureTypefaceCharactersAccessible(
|
||||
PDFEnsureTypefaceCharactersAccessible func);
|
||||
|
||||
void SetPDFUseGDIPrinting(bool enable);
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
// |page_count| and |max_page_width| are optional and can be NULL.
|
||||
// Returns false if the document is not valid.
|
||||
bool GetPDFDocInfo(const void* pdf_buffer,
|
||||
|
@ -29,6 +29,12 @@
|
||||
#include "ppapi/cpp/var_array.h"
|
||||
#include "ui/base/window_open_disposition.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
typedef void (*PDFEnsureTypefaceCharactersAccessible)(const LOGFONT* font,
|
||||
const wchar_t* text,
|
||||
size_t text_length);
|
||||
#endif
|
||||
|
||||
namespace pp {
|
||||
class InputEvent;
|
||||
class VarDictionary;
|
||||
@ -329,7 +335,13 @@ class PDFEngineExports {
|
||||
int page_number,
|
||||
const RenderingSettings& settings,
|
||||
HDC dc) = 0;
|
||||
#endif // OS_WIN
|
||||
|
||||
virtual void SetPDFEnsureTypefaceCharactersAccessible(
|
||||
PDFEnsureTypefaceCharactersAccessible func) = 0;
|
||||
|
||||
virtual void SetPDFUseGDIPrinting(bool enable) = 0;
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
// See the definition of RenderPDFPageToBitmap in pdf.cc for details.
|
||||
virtual bool RenderPDFPageToBitmap(const void* pdf_buffer,
|
||||
int pdf_buffer_size,
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "third_party/pdfium/public/fpdf_searchex.h"
|
||||
#include "third_party/pdfium/public/fpdf_sysfontinfo.h"
|
||||
#include "third_party/pdfium/public/fpdf_transformpage.h"
|
||||
#include "third_party/pdfium/public/fpdfview.h"
|
||||
#include "ui/events/keycodes/keyboard_codes.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "v8/include/v8.h"
|
||||
@ -3876,6 +3877,16 @@ bool PDFiumEngineExports::RenderPDFPageToDC(const void* pdf_buffer,
|
||||
FPDF_CloseDocument(doc);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PDFiumEngineExports::SetPDFEnsureTypefaceCharactersAccessible(
|
||||
PDFEnsureTypefaceCharactersAccessible func) {
|
||||
FPDF_SetTypefaceAccessibleFunc(
|
||||
reinterpret_cast<PDFiumEnsureTypefaceCharactersAccessible>(func));
|
||||
}
|
||||
|
||||
void PDFiumEngineExports::SetPDFUseGDIPrinting(bool enable) {
|
||||
FPDF_SetPrintTextWithGDI(enable);
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
bool PDFiumEngineExports::RenderPDFPageToBitmap(
|
||||
|
@ -742,6 +742,10 @@ class PDFiumEngineExports : public PDFEngineExports {
|
||||
int page_number,
|
||||
const RenderingSettings& settings,
|
||||
HDC dc) override;
|
||||
void SetPDFEnsureTypefaceCharactersAccessible(
|
||||
PDFEnsureTypefaceCharactersAccessible func) override;
|
||||
|
||||
void SetPDFUseGDIPrinting(bool enable) override;
|
||||
#endif // defined(OS_WIN)
|
||||
bool RenderPDFPageToBitmap(const void* pdf_buffer,
|
||||
int pdf_buffer_size,
|
||||
|
@ -149,6 +149,9 @@ void PrintSettings::Clear() {
|
||||
color_ = UNKNOWN_COLOR_MODEL;
|
||||
copies_ = 0;
|
||||
duplex_mode_ = UNKNOWN_DUPLEX_MODE;
|
||||
#if defined(OS_WIN)
|
||||
print_text_with_gdi_ = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrintSettings::SetPrinterPrintableArea(
|
||||
|
@ -106,8 +106,8 @@ class PRINTING_EXPORT PrintSettings {
|
||||
#endif // defined(OS_MACOSX)
|
||||
}
|
||||
|
||||
void set_ranges(const PageRanges& ranges) { ranges_ = ranges; };
|
||||
const PageRanges& ranges() const { return ranges_; };
|
||||
void set_ranges(const PageRanges& ranges) { ranges_ = ranges; }
|
||||
const PageRanges& ranges() const { return ranges_; }
|
||||
|
||||
void set_selection_only(bool selection_only) {
|
||||
selection_only_ = selection_only;
|
||||
@ -144,6 +144,11 @@ class PRINTING_EXPORT PrintSettings {
|
||||
|
||||
int desired_dpi() const { return desired_dpi_; }
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void set_print_text_with_gdi(bool use_gdi) { print_text_with_gdi_ = use_gdi; }
|
||||
bool print_text_with_gdi() const { return print_text_with_gdi_; }
|
||||
#endif
|
||||
|
||||
// Cookie generator. It is used to initialize PrintedDocument with its
|
||||
// associated PrintSettings, to be sure that each generated PrintedPage is
|
||||
// correctly associated with its corresponding PrintedDocument.
|
||||
@ -204,6 +209,11 @@ class PRINTING_EXPORT PrintSettings {
|
||||
// True if this printer supports AlphaBlend.
|
||||
bool supports_alpha_blend_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// True to print text with GDI.
|
||||
bool print_text_with_gdi_;
|
||||
#endif
|
||||
|
||||
// If margin type is custom, this is what was requested.
|
||||
PageMargins requested_custom_margins_in_points_;
|
||||
};
|
||||
|
@ -191,6 +191,13 @@ bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings,
|
||||
settings->set_duplex_mode(static_cast<DuplexMode>(duplex_mode));
|
||||
settings->set_color(static_cast<ColorModel>(color));
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Modifiable implies HTML and not other formats like PDF.
|
||||
bool can_modify = false;
|
||||
if (job_settings.GetBoolean(kSettingPreviewModifiable, &can_modify))
|
||||
settings->set_print_text_with_gdi(can_modify);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,12 @@ void PrintingContext::set_margin_type(MarginType type) {
|
||||
settings_.set_margin_type(type);
|
||||
}
|
||||
|
||||
void PrintingContext::set_is_modifiable(bool is_modifiable) {
|
||||
#if defined(OS_WIN)
|
||||
settings_.set_print_text_with_gdi(is_modifiable);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrintingContext::ResetSettings() {
|
||||
ReleaseContext();
|
||||
|
||||
|
@ -29,8 +29,8 @@ class PRINTING_EXPORT PrintingContext {
|
||||
// Printing context delegate.
|
||||
class Delegate {
|
||||
public:
|
||||
Delegate() {};
|
||||
virtual ~Delegate() {};
|
||||
Delegate() {}
|
||||
virtual ~Delegate() {}
|
||||
|
||||
// Returns parent view to use for modal dialogs.
|
||||
virtual gfx::NativeView GetParentView() = 0;
|
||||
@ -121,6 +121,7 @@ class PRINTING_EXPORT PrintingContext {
|
||||
static std::unique_ptr<PrintingContext> Create(Delegate* delegate);
|
||||
|
||||
void set_margin_type(MarginType type);
|
||||
void set_is_modifiable(bool is_modifiable);
|
||||
|
||||
const PrintSettings& settings() const {
|
||||
return settings_;
|
||||
|
@ -13,14 +13,13 @@
|
||||
|
||||
namespace printing {
|
||||
|
||||
PrintingContextSytemDialogWin::PrintingContextSytemDialogWin(Delegate* delegate)
|
||||
: PrintingContextWin(delegate) {
|
||||
}
|
||||
PrintingContextSystemDialogWin::PrintingContextSystemDialogWin(
|
||||
Delegate* delegate)
|
||||
: PrintingContextWin(delegate) {}
|
||||
|
||||
PrintingContextSytemDialogWin::~PrintingContextSytemDialogWin() {
|
||||
}
|
||||
PrintingContextSystemDialogWin::~PrintingContextSystemDialogWin() {}
|
||||
|
||||
void PrintingContextSytemDialogWin::AskUserForSettings(
|
||||
void PrintingContextSystemDialogWin::AskUserForSettings(
|
||||
int max_pages,
|
||||
bool has_selection,
|
||||
bool is_scripted,
|
||||
@ -32,11 +31,9 @@ void PrintingContextSytemDialogWin::AskUserForSettings(
|
||||
|
||||
// Show the OS-dependent dialog box.
|
||||
// If the user press
|
||||
// - OK, the settings are reset and reinitialized with the new settings. OK
|
||||
// is
|
||||
// - OK, the settings are reset and reinitialized with the new settings. OK is
|
||||
// returned.
|
||||
// - Apply then Cancel, the settings are reset and reinitialized with the
|
||||
// new
|
||||
// - Apply then Cancel, the settings are reset and reinitialized with the new
|
||||
// settings. CANCEL is returned.
|
||||
// - Cancel, the settings are not changed, the previous setting, if it was
|
||||
// initialized before, are kept. CANCEL is returned.
|
||||
@ -77,7 +74,7 @@ void PrintingContextSytemDialogWin::AskUserForSettings(
|
||||
callback.Run(ParseDialogResultEx(dialog_options));
|
||||
}
|
||||
|
||||
HRESULT PrintingContextSytemDialogWin::ShowPrintDialog(PRINTDLGEX* options) {
|
||||
HRESULT PrintingContextSystemDialogWin::ShowPrintDialog(PRINTDLGEX* options) {
|
||||
// Runs always on the UI thread.
|
||||
static bool is_dialog_shown = false;
|
||||
if (is_dialog_shown)
|
||||
@ -97,7 +94,7 @@ HRESULT PrintingContextSytemDialogWin::ShowPrintDialog(PRINTDLGEX* options) {
|
||||
return PrintDlgEx(options);
|
||||
}
|
||||
|
||||
bool PrintingContextSytemDialogWin::InitializeSettingsWithRanges(
|
||||
bool PrintingContextSystemDialogWin::InitializeSettingsWithRanges(
|
||||
const DEVMODE& dev_mode,
|
||||
const std::wstring& new_device_name,
|
||||
const PRINTPAGERANGE* ranges,
|
||||
@ -143,12 +140,14 @@ bool PrintingContextSytemDialogWin::InitializeSettingsWithRanges(
|
||||
return true;
|
||||
}
|
||||
|
||||
PrintingContext::Result PrintingContextSytemDialogWin::ParseDialogResultEx(
|
||||
PrintingContext::Result PrintingContextSystemDialogWin::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.
|
||||
// Start fresh, but preserve GDI print setting.
|
||||
bool print_text_with_gdi = settings_.print_text_with_gdi();
|
||||
ResetSettings();
|
||||
settings_.set_print_text_with_gdi(print_text_with_gdi);
|
||||
|
||||
DEVMODE* dev_mode = NULL;
|
||||
if (dialog_options.hDevMode) {
|
||||
@ -218,53 +217,4 @@ PrintingContext::Result PrintingContextSytemDialogWin::ParseDialogResultEx(
|
||||
}
|
||||
}
|
||||
|
||||
PrintingContext::Result PrintingContextSytemDialogWin::ParseDialogResult(
|
||||
const PRINTDLG& dialog_options) {
|
||||
// If the user clicked OK or Apply then Cancel, but not only Cancel.
|
||||
// Start fresh.
|
||||
ResetSettings();
|
||||
|
||||
DEVMODE* dev_mode = NULL;
|
||||
if (dialog_options.hDevMode) {
|
||||
dev_mode = reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode));
|
||||
DCHECK(dev_mode);
|
||||
}
|
||||
|
||||
std::wstring device_name;
|
||||
if (dialog_options.hDevNames) {
|
||||
DEVNAMES* dev_names =
|
||||
reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames));
|
||||
DCHECK(dev_names);
|
||||
if (dev_names) {
|
||||
device_name = reinterpret_cast<const wchar_t*>(
|
||||
reinterpret_cast<const wchar_t*>(dev_names) +
|
||||
dev_names->wDeviceOffset);
|
||||
GlobalUnlock(dialog_options.hDevNames);
|
||||
}
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
if (dev_mode && !device_name.empty()) {
|
||||
set_context(dialog_options.hDC);
|
||||
success =
|
||||
InitializeSettingsWithRanges(*dev_mode, device_name, NULL, 0, false);
|
||||
}
|
||||
|
||||
if (!success && dialog_options.hDC) {
|
||||
DeleteDC(dialog_options.hDC);
|
||||
set_context(NULL);
|
||||
}
|
||||
|
||||
if (dev_mode) {
|
||||
GlobalUnlock(dialog_options.hDevMode);
|
||||
}
|
||||
|
||||
if (dialog_options.hDevMode != NULL)
|
||||
GlobalFree(dialog_options.hDevMode);
|
||||
if (dialog_options.hDevNames != NULL)
|
||||
GlobalFree(dialog_options.hDevNames);
|
||||
|
||||
return context() ? OK : FAILED;
|
||||
}
|
||||
|
||||
} // namespace printing
|
||||
|
@ -16,11 +16,11 @@
|
||||
|
||||
namespace printing {
|
||||
|
||||
class PRINTING_EXPORT PrintingContextSytemDialogWin
|
||||
class PRINTING_EXPORT PrintingContextSystemDialogWin
|
||||
: public PrintingContextWin {
|
||||
public:
|
||||
explicit PrintingContextSytemDialogWin(Delegate* delegate);
|
||||
~PrintingContextSytemDialogWin() override;
|
||||
explicit PrintingContextSystemDialogWin(Delegate* delegate);
|
||||
~PrintingContextSystemDialogWin() override;
|
||||
|
||||
// PrintingContext implementation.
|
||||
void AskUserForSettings(
|
||||
@ -44,9 +44,8 @@ class PRINTING_EXPORT PrintingContextSytemDialogWin
|
||||
|
||||
// Parses the result of a PRINTDLGEX result.
|
||||
Result ParseDialogResultEx(const PRINTDLGEX& dialog_options);
|
||||
Result ParseDialogResult(const PRINTDLG& dialog_options);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintingContextSytemDialogWin);
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintingContextSystemDialogWin);
|
||||
};
|
||||
|
||||
} // namespace printing
|
||||
|
@ -26,7 +26,7 @@ namespace printing {
|
||||
|
||||
namespace {
|
||||
|
||||
void AssingResult(PrintingContext::Result* out, PrintingContext::Result in) {
|
||||
void AssignResult(PrintingContext::Result* out, PrintingContext::Result in) {
|
||||
*out = in;
|
||||
}
|
||||
|
||||
@ -35,10 +35,10 @@ void AssingResult(PrintingContext::Result* out, PrintingContext::Result in) {
|
||||
// static
|
||||
std::unique_ptr<PrintingContext> PrintingContext::Create(Delegate* delegate) {
|
||||
#if defined(ENABLE_BASIC_PRINTING)
|
||||
return base::WrapUnique(new PrintingContextSytemDialogWin(delegate));
|
||||
#else // ENABLE_BASIC_PRINTING
|
||||
return base::WrapUnique(new PrintingContextSystemDialogWin(delegate));
|
||||
#else
|
||||
return base::WrapUnique(new PrintingContextWin(delegate));
|
||||
#endif // EENABLE_BASIC_PRINTING
|
||||
#endif
|
||||
}
|
||||
|
||||
PrintingContextWin::PrintingContextWin(Delegate* delegate)
|
||||
@ -209,12 +209,11 @@ PrintingContext::Result PrintingContextWin::UpdatePrinterSettings(
|
||||
if (show_system_dialog) {
|
||||
PrintingContext::Result result = PrintingContext::FAILED;
|
||||
AskUserForSettings(page_count, false, false,
|
||||
base::Bind(&AssingResult, &result));
|
||||
base::Bind(&AssignResult, &result));
|
||||
return result;
|
||||
} else {
|
||||
scoped_dev_mode = CreateDevMode(printer.Get(), scoped_dev_mode.get());
|
||||
}
|
||||
// Set printer then refresh printer settings.
|
||||
scoped_dev_mode = CreateDevMode(printer.Get(), scoped_dev_mode.get());
|
||||
return InitializeSettings(settings_.device_name(), scoped_dev_mode.get());
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ class PrintingContextTest : public PrintingTest<testing::Test>,
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
struct FreeHandleTraits {
|
||||
typedef HANDLE Handle;
|
||||
static void CloseHandle(HANDLE handle) { GlobalFree(handle); }
|
||||
@ -49,12 +50,13 @@ struct FreeHandleTraits {
|
||||
typedef base::win::GenericScopedHandle<FreeHandleTraits,
|
||||
base::win::DummyVerifierTraits>
|
||||
ScopedGlobalAlloc;
|
||||
}
|
||||
|
||||
class MockPrintingContextWin : public PrintingContextSytemDialogWin {
|
||||
} // namespace
|
||||
|
||||
class MockPrintingContextWin : public PrintingContextSystemDialogWin {
|
||||
public:
|
||||
MockPrintingContextWin(Delegate* delegate)
|
||||
: PrintingContextSytemDialogWin(delegate) {}
|
||||
explicit MockPrintingContextWin(Delegate* delegate)
|
||||
: PrintingContextSystemDialogWin(delegate) {}
|
||||
|
||||
protected:
|
||||
// This is a fake PrintDlgEx implementation that sets the right fields in
|
||||
|
Reference in New Issue
Block a user