Chromium Code Reviews| Index: chrome/browser/printing/pdf_to_emf_converter.cc |
| diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc |
| index fb0be329e76d0325e4b0c20645adf832fb1d3303..e79b5c86d2b9adb9ce48ee4218c572ac62ac5d56 100644 |
| --- a/chrome/browser/printing/pdf_to_emf_converter.cc |
| +++ b/chrome/browser/printing/pdf_to_emf_converter.cc |
| @@ -30,12 +30,12 @@ |
| #include "printing/pdf_render_settings.h" |
| #include "ui/base/l10n/l10n_util.h" |
| +using content::BrowserThread; |
| + |
| namespace printing { |
| namespace { |
| -using content::BrowserThread; |
| - |
| class PdfToEmfConverterImpl; |
| // Allows to delete temporary directory after all temporary files created inside |
| @@ -59,8 +59,8 @@ class RefCountedTempDir |
| DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir); |
| }; |
| -typedef std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread> |
| - ScopedTempFile; |
| +using ScopedTempFile = |
| + std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread>; |
| // Wrapper for Emf to keep only file handle in memory, and load actual data only |
| // on playback. Emf::InitFromFile() can play metafile directly from disk, but it |
| @@ -74,11 +74,12 @@ class LazyEmf : public MetafilePlayer { |
| } |
| ~LazyEmf() override { Close(); } |
| + private: |
| + // MetafilePlayer: |
| bool SafePlayback(HDC hdc) const override; |
| bool GetDataAsVector(std::vector<char>* buffer) const override; |
| bool SaveTo(base::File* file) const override; |
| - private: |
| void Close() const; |
| bool LoadEmf(Emf* emf) const; |
| @@ -109,7 +110,6 @@ 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, |
| @@ -168,7 +168,7 @@ class PdfToEmfUtilityProcessHostClient |
| const base::string16& characters); |
| void OnFailed(); |
| - void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf); |
| + void OnTempPdfReady(ScopedTempFile pdf); |
| void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf); |
| scoped_refptr<RefCountedTempDir> temp_dir_; |
| @@ -186,7 +186,7 @@ class PdfToEmfUtilityProcessHostClient |
| // Queue of callbacks for GetPage() requests. Utility process should reply |
| // with PageDone in the same order as requests were received. |
| // Use containers that keeps element pointers valid after push() and pop(). |
| - typedef std::queue<GetPageCallbackData> GetPageCallbacks; |
| + using GetPageCallbacks = std::queue<GetPageCallbackData>; |
| GetPageCallbacks get_page_callbacks_; |
| DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); |
| @@ -200,7 +200,6 @@ 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, |
| @@ -260,10 +259,10 @@ ScopedTempFile CreateTempPdfFile( |
| bool LazyEmf::SafePlayback(HDC hdc) const { |
| Emf emf; |
| bool result = LoadEmf(&emf) && emf.SafePlayback(hdc); |
| - // TODO(vitalybuka): Fix destruction of metafiles. For some reasons |
| - // instances of Emf are not deleted. crbug.com/411683 |
| + // TODO(thestig): Fix destruction of metafiles. For some reasons |
| + // instances of Emf are not deleted. https://crbug.com/260806 |
| // It's known that the Emf going to be played just once to a printer. So just |
| - // release file here. |
| + // release |file_| here. |
| Close(); |
| return result; |
| } |
| @@ -280,7 +279,7 @@ bool LazyEmf::SaveTo(base::File* file) const { |
| void LazyEmf::Close() const { |
| file_.reset(); |
| - temp_dir_ = NULL; |
| + temp_dir_ = nullptr; |
| } |
| bool LazyEmf::LoadEmf(Emf* emf) const { |
| @@ -305,13 +304,11 @@ 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, |
| - print_text_with_gdi, start_callback)); |
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| + base::Bind(&PdfToEmfUtilityProcessHostClient::Start, |
| + this, data, start_callback)); |
| return; |
| } |
| @@ -330,19 +327,17 @@ void PdfToEmfUtilityProcessHostClient::Start( |
| BrowserThread::PostTaskAndReplyWithResult( |
| BrowserThread::FILE, FROM_HERE, |
| base::Bind(&CreateTempPdfFile, data, &temp_dir_), |
| - base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this, |
| - print_text_with_gdi)); |
| + base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this)); |
| } |
| -void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi, |
| - ScopedTempFile pdf) { |
| +void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(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_, |
| - print_text_with_gdi)); |
| + IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), |
| + settings_)); |
| } |
| void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { |
| @@ -519,12 +514,11 @@ 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, print_text_with_gdi, start_callback); |
| + utility_client_->Start(data, start_callback); |
| } |
| void PdfToEmfConverterImpl::GetPage(int page_number, |
| @@ -537,14 +531,427 @@ void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) { |
| callback.Run(); |
| } |
| -} // namespace |
| +// See LazyEmf/RefCountedTempDir comments for why it is also needed here. |
| +// Maybe combine the two classes since they are so similar. |
| +class PostScriptMetaFile : public MetafilePlayer { |
| + public: |
|
Vitaly Buka (NO REVIEWS)
2017/01/17 19:29:16
To much of duplicated code.
Could you just do publ
|
| + PostScriptMetaFile(const scoped_refptr<RefCountedTempDir>& temp_dir, |
| + ScopedTempFile file) |
| + : temp_dir_(temp_dir), file_(std::move(file)) { |
| + CHECK(file_); |
| + } |
| + ~PostScriptMetaFile() override { Close(); } |
| + |
| + private: |
| + // MetafilePlayer: |
| + bool SafePlayback(HDC hdc) const override; |
| + bool GetDataAsVector(std::vector<char>* buffer) const override; |
| + bool SaveTo(base::File* file) const override; |
| + |
| + void Close() const; |
| + bool LoadEmf(Emf* emf) const; |
| + |
| + mutable scoped_refptr<RefCountedTempDir> temp_dir_; |
| + mutable ScopedTempFile file_; // Mutable because of consts in base class. |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PostScriptMetaFile); |
| +}; |
| + |
| +bool PostScriptMetaFile::SafePlayback(HDC hdc) const { |
| + // TODO(thestig): Fix destruction of metafiles. For some reasons |
| + // instances of Emf are not deleted. https://crbug.com/260806 |
| + // It's known that the Emf going to be played just once to a printer. So just |
| + // release |file_| before returning. |
| + Emf emf; |
| + if (!LoadEmf(&emf)) { |
| + Close(); |
| + return false; |
| + } |
| + |
| + { |
| + // Ensure enumerator destruction before calling Close() below. |
| + Emf::Enumerator emf_enum(emf, nullptr, nullptr); |
| + for (const Emf::Record& record : emf_enum) { |
| + auto* emf_record = record.record(); |
| + if (emf_record->iType != EMR_GDICOMMENT) |
| + continue; |
| + |
| + const EMRGDICOMMENT* comment = |
| + reinterpret_cast<const EMRGDICOMMENT*>(emf_record); |
| + const char* data = reinterpret_cast<const char*>(comment->Data); |
| + const uint16_t* ptr = reinterpret_cast<const uint16_t*>(data); |
| + int ret = ExtEscape(hdc, PASSTHROUGH, 2 + *ptr, data, 0, nullptr); |
| + DCHECK_EQ(*ptr, ret); |
| + } |
| + } |
| + Close(); |
| + return true; |
| +} |
| + |
| +bool PostScriptMetaFile::GetDataAsVector(std::vector<char>* buffer) const { |
| + NOTREACHED(); |
| + return false; |
| +} |
| + |
| +bool PostScriptMetaFile::SaveTo(base::File* file) const { |
| + Emf emf; |
| + return LoadEmf(&emf) && emf.SaveTo(file); |
| +} |
| -PdfToEmfConverter::~PdfToEmfConverter() { |
| +void PostScriptMetaFile::Close() const { |
| + file_.reset(); |
| + temp_dir_ = nullptr; |
| } |
| +bool PostScriptMetaFile::LoadEmf(Emf* emf) const { |
| + file_->Seek(base::File::FROM_BEGIN, 0); |
| + int64_t size = file_->GetLength(); |
| + if (size <= 0) |
| + return false; |
| + std::vector<char> data(size); |
| + if (file_->ReadAtCurrentPos(data.data(), data.size()) != size) |
| + return false; |
| + return emf->InitFromData(data.data(), data.size()); |
| +} |
| + |
| +class PdfToPostScriptConverterImpl; |
| + |
| +// Converts PDF into PostScript. |
| +// Class uses 3 threads: UI, IO and FILE. |
| +// Internal workflow is following: |
| +// 1. Create instance on the UI thread. (files_, settings_,) |
| +// 2. Create pdf file on the FILE thread. |
| +// 3. Start utility process and start conversion on the IO thread. |
| +// 4. Utility process returns page count. |
| +// 5. For each page: |
| +// 1. Clients requests page with file handle to a temp file. |
| +// 2. Utility converts the page, save it to the file and reply. |
| +// |
| +// All these steps work sequentially, so no data should be accessed |
| +// simultaneously by several threads. |
| +class PdfToPostScriptUtilityProcessHostClient |
| + : public content::UtilityProcessHostClient { |
| + public: |
| + PdfToPostScriptUtilityProcessHostClient( |
| + base::WeakPtr<PdfToPostScriptConverterImpl> converter, |
| + const PdfRenderSettings& settings); |
| + |
| + void Start(const scoped_refptr<base::RefCountedMemory>& data, |
| + const PdfToPostScriptConverter::StartCallback& start_callback); |
| + |
| + void GetPage( |
| + int page_number, |
| + const PdfToPostScriptConverter::GetPageCallback& get_page_callback); |
| + |
| + void Stop(); |
| + |
| + // UtilityProcessHostClient implementation. |
| + void OnProcessCrashed(int exit_code) override; |
| + void OnProcessLaunchFailed(int exit_code) override; |
| + bool OnMessageReceived(const IPC::Message& message) override; |
| + |
| + private: |
| + class GetPageCallbackData { |
| + public: |
| + GetPageCallbackData( |
| + int page_number, |
| + const PdfToPostScriptConverter::GetPageCallback& callback) |
| + : page_number_(page_number), callback_(callback) {} |
| + |
| + GetPageCallbackData(GetPageCallbackData&& other) { |
| + *this = std::move(other); |
| + } |
| + |
| + GetPageCallbackData& operator=(GetPageCallbackData&& rhs) { |
| + page_number_ = rhs.page_number_; |
| + callback_ = rhs.callback_; |
| + ps_ = std::move(rhs.ps_); |
| + return *this; |
| + } |
| + |
| + int page_number() const { return page_number_; } |
| + const PdfToPostScriptConverter::GetPageCallback& callback() const { |
| + return callback_; |
| + } |
| + ScopedTempFile TakePostScript() { return std::move(ps_); } |
| + void set_ps(ScopedTempFile ps) { ps_ = std::move(ps); } |
| + |
| + private: |
| + int page_number_; |
| + PdfToPostScriptConverter::GetPageCallback callback_; |
| + ScopedTempFile ps_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); |
| + }; |
| + |
| + ~PdfToPostScriptUtilityProcessHostClient() override; |
| + |
| + bool Send(IPC::Message* msg); |
| + |
| + // Message handlers. |
| + void OnPageCount(int page_count); |
| + void OnPageDone(bool success); |
| + |
| + void OnFailed(); |
| + void OnTempPdfReady(ScopedTempFile pdf); |
| + void OnTempPostScriptReady(GetPageCallbackData* callback_data, |
| + ScopedTempFile ps); |
| + |
| + scoped_refptr<RefCountedTempDir> temp_dir_; |
| + |
| + // Used to suppress callbacks after PdfToPostScriptConverterImpl is deleted. |
| + base::WeakPtr<PdfToPostScriptConverterImpl> converter_; |
| + PdfRenderSettings settings_; |
| + |
| + // Document loaded callback. |
| + PdfToPostScriptConverter::StartCallback start_callback_; |
| + |
| + // Process host for IPC. |
| + base::WeakPtr<content::UtilityProcessHost> utility_process_host_; |
| + |
| + // Queue of callbacks for GetPage() requests. Utility process should reply |
| + // with PageDone in the same order as requests were received. |
| + // Use containers that keeps element pointers valid after push() and pop(). |
| + using GetPageCallbacks = std::queue<GetPageCallbackData>; |
| + GetPageCallbacks get_page_callbacks_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PdfToPostScriptUtilityProcessHostClient); |
| +}; |
| + |
| +class PdfToPostScriptConverterImpl : public PdfToPostScriptConverter { |
| + public: |
| + PdfToPostScriptConverterImpl(); |
| + ~PdfToPostScriptConverterImpl() override; |
| + |
| + void Start(const scoped_refptr<base::RefCountedMemory>& data, |
| + const PdfRenderSettings& conversion_settings, |
| + const StartCallback& start_callback) override; |
| + |
| + void GetPage(int page_number, |
| + const GetPageCallback& get_page_callback) override; |
| + |
| + // Helps to cancel callbacks if this object is destroyed. |
| + void RunCallback(const base::Closure& callback); |
| + |
| + private: |
| + scoped_refptr<PdfToPostScriptUtilityProcessHostClient> utility_client_; |
| + base::WeakPtrFactory<PdfToPostScriptConverterImpl> weak_ptr_factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PdfToPostScriptConverterImpl); |
| +}; |
| + |
| +PdfToPostScriptUtilityProcessHostClient:: |
| + PdfToPostScriptUtilityProcessHostClient( |
| + base::WeakPtr<PdfToPostScriptConverterImpl> converter, |
| + const PdfRenderSettings& settings) |
| + : converter_(converter), settings_(settings) {} |
| + |
| +PdfToPostScriptUtilityProcessHostClient:: |
| + ~PdfToPostScriptUtilityProcessHostClient() {} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::Start( |
| + const scoped_refptr<base::RefCountedMemory>& data, |
| + const PdfToPostScriptConverter::StartCallback& start_callback) { |
| + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&PdfToPostScriptUtilityProcessHostClient::Start, this, data, |
| + start_callback)); |
| + return; |
| + } |
| + // Store callback before any OnFailed() call to make it called on failure. |
| + start_callback_ = start_callback; |
| + |
| + // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load |
| + // gdiplus.dll, change how rendering happens, and not be able to correctly |
| + // generate when sent to a metafile DC. |
| + utility_process_host_ = content::UtilityProcessHost::Create( |
| + this, base::ThreadTaskRunnerHandle::Get()) |
| + ->AsWeakPtr(); |
| + utility_process_host_->SetName( |
| + l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PS_CONVERTOR_NAME)); |
| + |
| + BrowserThread::PostTaskAndReplyWithResult( |
| + BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&CreateTempPdfFile, data, &temp_dir_), |
| + base::Bind(&PdfToPostScriptUtilityProcessHostClient::OnTempPdfReady, |
| + this)); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::OnTempPdfReady( |
| + ScopedTempFile pdf) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + if (!utility_process_host_ || !pdf) |
| + return OnFailed(); |
| + // Should reply with OnPageCount(). |
| + Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_Start( |
| + IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), |
| + settings_)); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::OnPageCount(int page_count) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + if (start_callback_.is_null()) |
| + return OnFailed(); |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(&PdfToPostScriptConverterImpl::RunCallback, converter_, |
| + base::Bind(start_callback_, page_count))); |
| + start_callback_.Reset(); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::GetPage( |
| + int page_number, |
| + const PdfToPostScriptConverter::GetPageCallback& get_page_callback) { |
| + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&PdfToPostScriptUtilityProcessHostClient::GetPage, this, |
| + page_number, get_page_callback)); |
| + return; |
| + } |
| + // Store callback before any OnFailed() call to make it called on failure. |
| + get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback)); |
| + |
| + if (!utility_process_host_) |
| + return OnFailed(); |
| + |
| + BrowserThread::PostTaskAndReplyWithResult( |
| + BrowserThread::FILE, FROM_HERE, base::Bind(&CreateTempFile, &temp_dir_), |
| + base::Bind( |
| + &PdfToPostScriptUtilityProcessHostClient::OnTempPostScriptReady, this, |
| + &get_page_callbacks_.back())); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::OnTempPostScriptReady( |
| + GetPageCallbackData* callback_data, |
| + ScopedTempFile ps) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + if (!utility_process_host_ || !ps) |
| + return OnFailed(); |
| + IPC::PlatformFileForTransit transit = |
| + IPC::GetPlatformFileForTransit(ps->GetPlatformFile(), false); |
| + callback_data->set_ps(std::move(ps)); |
| + // Should reply with OnPageDone(). |
| + Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_GetPage( |
| + callback_data->page_number(), transit)); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::OnPageDone(bool success) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + if (get_page_callbacks_.empty()) |
| + return OnFailed(); |
| + GetPageCallbackData& data = get_page_callbacks_.front(); |
| + std::unique_ptr<PostScriptMetaFile> ps_metafile; |
| + |
| + if (success) { |
| + ScopedTempFile temp_ps = data.TakePostScript(); |
| + if (!temp_ps) // Unexpected message from utility process. |
| + return OnFailed(); |
| + ps_metafile = |
| + base::MakeUnique<PostScriptMetaFile>(temp_dir_, std::move(temp_ps)); |
| + } |
| + |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(&PdfToPostScriptConverterImpl::RunCallback, converter_, |
| + base::Bind(data.callback(), data.page_number(), |
| + base::Passed(&ps_metafile)))); |
| + get_page_callbacks_.pop(); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::Stop() { |
| + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&PdfToPostScriptUtilityProcessHostClient::Stop, this)); |
| + return; |
| + } |
| + Send(new ChromeUtilityMsg_RenderPDFPagesToPostScript_Stop()); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::OnProcessCrashed(int exit_code) { |
| + OnFailed(); |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::OnProcessLaunchFailed( |
| + int exit_code) { |
| + OnFailed(); |
| +} |
| + |
| +bool PdfToPostScriptUtilityProcessHostClient::OnMessageReceived( |
| + const IPC::Message& message) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(PdfToPostScriptUtilityProcessHostClient, message) |
| + IPC_MESSAGE_HANDLER( |
| + ChromeUtilityHostMsg_RenderPDFPagesToPostScript_PageCount, OnPageCount) |
| + IPC_MESSAGE_HANDLER( |
| + ChromeUtilityHostMsg_RenderPDFPagesToPostScript_PageDone, OnPageDone) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +bool PdfToPostScriptUtilityProcessHostClient::Send(IPC::Message* msg) { |
| + if (utility_process_host_) |
| + return utility_process_host_->Send(msg); |
| + delete msg; |
| + return false; |
| +} |
| + |
| +void PdfToPostScriptUtilityProcessHostClient::OnFailed() { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + if (!start_callback_.is_null()) |
| + OnPageCount(0); |
| + while (!get_page_callbacks_.empty()) |
| + OnPageDone(false); |
| + utility_process_host_.reset(); |
| +} |
| + |
| +PdfToPostScriptConverterImpl::PdfToPostScriptConverterImpl() |
| + : weak_ptr_factory_(this) {} |
| + |
| +PdfToPostScriptConverterImpl::~PdfToPostScriptConverterImpl() { |
| + if (utility_client_.get()) |
| + utility_client_->Stop(); |
| +} |
| + |
| +void PdfToPostScriptConverterImpl::Start( |
| + const scoped_refptr<base::RefCountedMemory>& data, |
| + const PdfRenderSettings& conversion_settings, |
| + const StartCallback& start_callback) { |
| + DCHECK(!utility_client_.get()); |
| + utility_client_ = new PdfToPostScriptUtilityProcessHostClient( |
| + weak_ptr_factory_.GetWeakPtr(), conversion_settings); |
| + utility_client_->Start(data, start_callback); |
| +} |
| + |
| +void PdfToPostScriptConverterImpl::GetPage( |
| + int page_number, |
| + const GetPageCallback& get_page_callback) { |
| + utility_client_->GetPage(page_number, get_page_callback); |
| +} |
| + |
| +void PdfToPostScriptConverterImpl::RunCallback(const base::Closure& callback) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + callback.Run(); |
| +} |
| + |
| +} // namespace |
| + |
| +PdfToEmfConverter::~PdfToEmfConverter() {} |
| + |
| // static |
| std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { |
| - return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); |
| + return base::MakeUnique<PdfToEmfConverterImpl>(); |
| +} |
| + |
| +PdfToPostScriptConverter::~PdfToPostScriptConverter() {} |
| + |
| +// static |
| +std::unique_ptr<PdfToPostScriptConverter> |
| +PdfToPostScriptConverter::CreateDefault() { |
| + return base::MakeUnique<PdfToPostScriptConverterImpl>(); |
| } |
| } // namespace printing |