OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/printing/pdf_to_emf_converter.h" | 5 #include "chrome/browser/printing/pdf_to_emf_converter.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <queue> | 9 #include <queue> |
10 #include <utility> | 10 #include <utility> |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 typedef scoped_ptr<base::File, BrowserThread::DeleteOnFileThread> | 57 typedef scoped_ptr<base::File, BrowserThread::DeleteOnFileThread> |
58 ScopedTempFile; | 58 ScopedTempFile; |
59 | 59 |
60 // Wrapper for Emf to keep only file handle in memory, and load actual data only | 60 // Wrapper for Emf to keep only file handle in memory, and load actual data only |
61 // on playback. Emf::InitFromFile() can play metafile directly from disk, but it | 61 // on playback. Emf::InitFromFile() can play metafile directly from disk, but it |
62 // can't open file handles. We need file handles to reliably delete temporary | 62 // can't open file handles. We need file handles to reliably delete temporary |
63 // files, and to efficiently interact with utility process. | 63 // files, and to efficiently interact with utility process. |
64 class LazyEmf : public MetafilePlayer { | 64 class LazyEmf : public MetafilePlayer { |
65 public: | 65 public: |
66 LazyEmf(const scoped_refptr<RefCountedTempDir>& temp_dir, ScopedTempFile file) | 66 LazyEmf(const scoped_refptr<RefCountedTempDir>& temp_dir, ScopedTempFile file) |
67 : temp_dir_(temp_dir), file_(file.Pass()) { | 67 : temp_dir_(temp_dir), file_(std::move(file)) { |
68 CHECK(file_); | 68 CHECK(file_); |
69 } | 69 } |
70 ~LazyEmf() override { Close(); } | 70 ~LazyEmf() override { Close(); } |
71 | 71 |
72 bool SafePlayback(HDC hdc) const override; | 72 bool SafePlayback(HDC hdc) const override; |
73 bool SaveTo(base::File* file) const override; | 73 bool SaveTo(base::File* file) const override; |
74 | 74 |
75 private: | 75 private: |
76 void Close() const; | 76 void Close() const; |
77 bool LoadEmf(Emf* emf) const; | 77 bool LoadEmf(Emf* emf) const; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 page_number_ = rhs.page_number_; | 132 page_number_ = rhs.page_number_; |
133 callback_ = rhs.callback_; | 133 callback_ = rhs.callback_; |
134 emf_ = std::move(rhs.emf_); | 134 emf_ = std::move(rhs.emf_); |
135 return *this; | 135 return *this; |
136 } | 136 } |
137 | 137 |
138 int page_number() const { return page_number_; } | 138 int page_number() const { return page_number_; } |
139 const PdfToEmfConverter::GetPageCallback& callback() const { | 139 const PdfToEmfConverter::GetPageCallback& callback() const { |
140 return callback_; | 140 return callback_; |
141 } | 141 } |
142 ScopedTempFile TakeEmf() { return emf_.Pass(); } | 142 ScopedTempFile TakeEmf() { return std::move(emf_); } |
143 void set_emf(ScopedTempFile emf) { emf_ = emf.Pass(); } | 143 void set_emf(ScopedTempFile emf) { emf_ = std::move(emf); } |
144 | 144 |
145 private: | 145 private: |
146 int page_number_; | 146 int page_number_; |
147 PdfToEmfConverter::GetPageCallback callback_; | 147 PdfToEmfConverter::GetPageCallback callback_; |
148 ScopedTempFile emf_; | 148 ScopedTempFile emf_; |
149 }; | 149 }; |
150 | 150 |
151 ~PdfToEmfUtilityProcessHostClient() override; | 151 ~PdfToEmfUtilityProcessHostClient() override; |
152 | 152 |
153 bool Send(IPC::Message* msg); | 153 bool Send(IPC::Message* msg); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_; | 204 base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_; |
205 | 205 |
206 DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); | 206 DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); |
207 }; | 207 }; |
208 | 208 |
209 ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) { | 209 ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) { |
210 if (!temp_dir->get()) | 210 if (!temp_dir->get()) |
211 *temp_dir = new RefCountedTempDir(); | 211 *temp_dir = new RefCountedTempDir(); |
212 ScopedTempFile file; | 212 ScopedTempFile file; |
213 if (!(*temp_dir)->IsValid()) | 213 if (!(*temp_dir)->IsValid()) |
214 return file.Pass(); | 214 return file; |
215 base::FilePath path; | 215 base::FilePath path; |
216 if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path)) { | 216 if (!base::CreateTemporaryFileInDir((*temp_dir)->GetPath(), &path)) { |
217 PLOG(ERROR) << "Failed to create file in " | 217 PLOG(ERROR) << "Failed to create file in " |
218 << (*temp_dir)->GetPath().value(); | 218 << (*temp_dir)->GetPath().value(); |
219 return file.Pass(); | 219 return file; |
220 } | 220 } |
221 file.reset(new base::File(path, | 221 file.reset(new base::File(path, |
222 base::File::FLAG_CREATE_ALWAYS | | 222 base::File::FLAG_CREATE_ALWAYS | |
223 base::File::FLAG_WRITE | | 223 base::File::FLAG_WRITE | |
224 base::File::FLAG_READ | | 224 base::File::FLAG_READ | |
225 base::File::FLAG_DELETE_ON_CLOSE | | 225 base::File::FLAG_DELETE_ON_CLOSE | |
226 base::File::FLAG_TEMPORARY)); | 226 base::File::FLAG_TEMPORARY)); |
227 if (!file->IsValid()) { | 227 if (!file->IsValid()) { |
228 PLOG(ERROR) << "Failed to create " << path.value(); | 228 PLOG(ERROR) << "Failed to create " << path.value(); |
229 file.reset(); | 229 file.reset(); |
230 } | 230 } |
231 return file.Pass(); | 231 return file; |
232 } | 232 } |
233 | 233 |
234 ScopedTempFile CreateTempPdfFile( | 234 ScopedTempFile CreateTempPdfFile( |
235 const scoped_refptr<base::RefCountedMemory>& data, | 235 const scoped_refptr<base::RefCountedMemory>& data, |
236 scoped_refptr<RefCountedTempDir>* temp_dir) { | 236 scoped_refptr<RefCountedTempDir>* temp_dir) { |
237 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 237 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
238 | 238 |
239 ScopedTempFile pdf_file = CreateTempFile(temp_dir); | 239 ScopedTempFile pdf_file = CreateTempFile(temp_dir); |
240 if (!pdf_file || | 240 if (!pdf_file || |
241 static_cast<int>(data->size()) != | 241 static_cast<int>(data->size()) != |
242 pdf_file->WriteAtCurrentPos(data->front_as<char>(), data->size())) { | 242 pdf_file->WriteAtCurrentPos(data->front_as<char>(), data->size())) { |
243 pdf_file.reset(); | 243 pdf_file.reset(); |
244 return pdf_file.Pass(); | 244 return pdf_file; |
245 } | 245 } |
246 pdf_file->Seek(base::File::FROM_BEGIN, 0); | 246 pdf_file->Seek(base::File::FROM_BEGIN, 0); |
247 return pdf_file.Pass(); | 247 return pdf_file; |
248 } | 248 } |
249 | 249 |
250 bool LazyEmf::SafePlayback(HDC hdc) const { | 250 bool LazyEmf::SafePlayback(HDC hdc) const { |
251 Emf emf; | 251 Emf emf; |
252 bool result = LoadEmf(&emf) && emf.SafePlayback(hdc); | 252 bool result = LoadEmf(&emf) && emf.SafePlayback(hdc); |
253 // TODO(vitalybuka): Fix destruction of metafiles. For some reasons | 253 // TODO(vitalybuka): Fix destruction of metafiles. For some reasons |
254 // instances of Emf are not deleted. crbug.com/411683 | 254 // instances of Emf are not deleted. crbug.com/411683 |
255 // It's known that the Emf going to be played just once to a printer. So just | 255 // It's known that the Emf going to be played just once to a printer. So just |
256 // release file here. | 256 // release file here. |
257 Close(); | 257 Close(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 | 385 |
386 void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( | 386 void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( |
387 GetPageCallbackData* callback_data, | 387 GetPageCallbackData* callback_data, |
388 ScopedTempFile emf) { | 388 ScopedTempFile emf) { |
389 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 389 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
390 if (!utility_process_host_ || !emf) | 390 if (!utility_process_host_ || !emf) |
391 return OnFailed(); | 391 return OnFailed(); |
392 base::ProcessHandle process = utility_process_host_->GetData().handle; | 392 base::ProcessHandle process = utility_process_host_->GetData().handle; |
393 IPC::PlatformFileForTransit transit = | 393 IPC::PlatformFileForTransit transit = |
394 IPC::GetFileHandleForProcess(emf->GetPlatformFile(), process, false); | 394 IPC::GetFileHandleForProcess(emf->GetPlatformFile(), process, false); |
395 callback_data->set_emf(emf.Pass()); | 395 callback_data->set_emf(std::move(emf)); |
396 // Should reply with OnPageDone(). | 396 // Should reply with OnPageDone(). |
397 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( | 397 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( |
398 callback_data->page_number(), transit)); | 398 callback_data->page_number(), transit)); |
399 } | 399 } |
400 | 400 |
401 void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, | 401 void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, |
402 float scale_factor) { | 402 float scale_factor) { |
403 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 403 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
404 if (get_page_callbacks_.empty()) | 404 if (get_page_callbacks_.empty()) |
405 return OnFailed(); | 405 return OnFailed(); |
406 GetPageCallbackData& data = get_page_callbacks_.front(); | 406 GetPageCallbackData& data = get_page_callbacks_.front(); |
407 scoped_ptr<MetafilePlayer> emf; | 407 scoped_ptr<MetafilePlayer> emf; |
408 | 408 |
409 if (success) { | 409 if (success) { |
410 ScopedTempFile temp_emf = data.TakeEmf(); | 410 ScopedTempFile temp_emf = data.TakeEmf(); |
411 if (!temp_emf) // Unexpected message from utility process. | 411 if (!temp_emf) // Unexpected message from utility process. |
412 return OnFailed(); | 412 return OnFailed(); |
413 emf.reset(new LazyEmf(temp_dir_, temp_emf.Pass())); | 413 emf.reset(new LazyEmf(temp_dir_, std::move(temp_emf))); |
414 } | 414 } |
415 | 415 |
416 BrowserThread::PostTask(BrowserThread::UI, | 416 BrowserThread::PostTask(BrowserThread::UI, |
417 FROM_HERE, | 417 FROM_HERE, |
418 base::Bind(&PdfToEmfConverterImpl::RunCallback, | 418 base::Bind(&PdfToEmfConverterImpl::RunCallback, |
419 converter_, | 419 converter_, |
420 base::Bind(data.callback(), | 420 base::Bind(data.callback(), |
421 data.page_number(), | 421 data.page_number(), |
422 scale_factor, | 422 scale_factor, |
423 base::Passed(&emf)))); | 423 base::Passed(&emf)))); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 | 505 |
506 PdfToEmfConverter::~PdfToEmfConverter() { | 506 PdfToEmfConverter::~PdfToEmfConverter() { |
507 } | 507 } |
508 | 508 |
509 // static | 509 // static |
510 scoped_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { | 510 scoped_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { |
511 return scoped_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); | 511 return scoped_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); |
512 } | 512 } |
513 | 513 |
514 } // namespace printing | 514 } // namespace printing |
OLD | NEW |