Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: chrome/browser/printing/pdf_to_emf_converter.cc

Issue 2646523003: Refactor pdf_to_emf_converter (Closed)
Patch Set: Format Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/printing/pdf_to_emf_converter.h ('k') | chrome/browser/printing/print_job.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <windows.h> 8 #include <windows.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 12 matching lines...) Expand all
23 #include "chrome/common/chrome_utility_printing_messages.h" 23 #include "chrome/common/chrome_utility_printing_messages.h"
24 #include "chrome/grit/generated_resources.h" 24 #include "chrome/grit/generated_resources.h"
25 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/child_process_data.h" 26 #include "content/public/browser/child_process_data.h"
27 #include "content/public/browser/utility_process_host.h" 27 #include "content/public/browser/utility_process_host.h"
28 #include "content/public/browser/utility_process_host_client.h" 28 #include "content/public/browser/utility_process_host_client.h"
29 #include "printing/emf_win.h" 29 #include "printing/emf_win.h"
30 #include "printing/pdf_render_settings.h" 30 #include "printing/pdf_render_settings.h"
31 #include "ui/base/l10n/l10n_util.h" 31 #include "ui/base/l10n/l10n_util.h"
32 32
33 using content::BrowserThread;
34
33 namespace printing { 35 namespace printing {
34 36
35 namespace { 37 namespace {
36 38
37 using content::BrowserThread; 39 class PdfConverterImpl;
38
39 class PdfToEmfConverterImpl;
40 40
41 // Allows to delete temporary directory after all temporary files created inside 41 // Allows to delete temporary directory after all temporary files created inside
42 // are closed. Windows cannot delete directory with opened files. Directory is 42 // are closed. Windows cannot delete directory with opened files. Directory is
43 // used to store PDF and metafiles. PDF should be gone by the time utility 43 // used to store PDF and metafiles. PDF should be gone by the time utility
44 // process exits. Metafiles should be gone when all LazyEmf destroyed. 44 // process exits. Metafiles should be gone when all LazyEmf destroyed.
45 class RefCountedTempDir 45 class RefCountedTempDir
46 : public base::RefCountedThreadSafe<RefCountedTempDir, 46 : public base::RefCountedThreadSafe<RefCountedTempDir,
47 BrowserThread::DeleteOnFileThread> { 47 BrowserThread::DeleteOnFileThread> {
48 public: 48 public:
49 RefCountedTempDir() { ignore_result(temp_dir_.CreateUniqueTempDir()); } 49 RefCountedTempDir() { ignore_result(temp_dir_.CreateUniqueTempDir()); }
50 bool IsValid() const { return temp_dir_.IsValid(); } 50 bool IsValid() const { return temp_dir_.IsValid(); }
51 const base::FilePath& GetPath() const { return temp_dir_.GetPath(); } 51 const base::FilePath& GetPath() const { return temp_dir_.GetPath(); }
52 52
53 private: 53 private:
54 friend struct BrowserThread::DeleteOnThread<BrowserThread::FILE>; 54 friend struct BrowserThread::DeleteOnThread<BrowserThread::FILE>;
55 friend class base::DeleteHelper<RefCountedTempDir>; 55 friend class base::DeleteHelper<RefCountedTempDir>;
56 ~RefCountedTempDir() {} 56 ~RefCountedTempDir() {}
57 57
58 base::ScopedTempDir temp_dir_; 58 base::ScopedTempDir temp_dir_;
59 DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir); 59 DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir);
60 }; 60 };
61 61
62 typedef std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread> 62 using ScopedTempFile =
63 ScopedTempFile; 63 std::unique_ptr<base::File, BrowserThread::DeleteOnFileThread>;
64 64
65 // Wrapper for Emf to keep only file handle in memory, and load actual data only 65 // Wrapper for Emf to keep only file handle in memory, and load actual data only
66 // on playback. Emf::InitFromFile() can play metafile directly from disk, but it 66 // on playback. Emf::InitFromFile() can play metafile directly from disk, but it
67 // can't open file handles. We need file handles to reliably delete temporary 67 // can't open file handles. We need file handles to reliably delete temporary
68 // files, and to efficiently interact with utility process. 68 // files, and to efficiently interact with utility process.
69 class LazyEmf : public MetafilePlayer { 69 class LazyEmf : public MetafilePlayer {
70 public: 70 public:
71 LazyEmf(const scoped_refptr<RefCountedTempDir>& temp_dir, ScopedTempFile file) 71 LazyEmf(const scoped_refptr<RefCountedTempDir>& temp_dir, ScopedTempFile file)
72 : temp_dir_(temp_dir), file_(std::move(file)) { 72 : temp_dir_(temp_dir), file_(std::move(file)) {
73 CHECK(file_); 73 CHECK(file_);
74 } 74 }
75 ~LazyEmf() override { Close(); } 75 ~LazyEmf() override { Close(); }
76 76
77 protected:
78 // MetafilePlayer:
77 bool SafePlayback(HDC hdc) const override; 79 bool SafePlayback(HDC hdc) const override;
78 bool GetDataAsVector(std::vector<char>* buffer) const override;
79 bool SaveTo(base::File* file) const override;
80 80
81 private:
82 void Close() const; 81 void Close() const;
83 bool LoadEmf(Emf* emf) const; 82 bool LoadEmf(Emf* emf) const;
84 83
84 private:
85 mutable scoped_refptr<RefCountedTempDir> temp_dir_; 85 mutable scoped_refptr<RefCountedTempDir> temp_dir_;
86 mutable ScopedTempFile file_; // Mutable because of consts in base class. 86 mutable ScopedTempFile file_; // Mutable because of consts in base class.
87 87
88 bool GetDataAsVector(std::vector<char>* buffer) const override;
89 bool SaveTo(base::File* file) const override;
90
88 DISALLOW_COPY_AND_ASSIGN(LazyEmf); 91 DISALLOW_COPY_AND_ASSIGN(LazyEmf);
89 }; 92 };
90 93
91 // Converts PDF into EMF. 94 // Class for converting PDF to another format for printing (Emf, Postscript).
92 // Class uses 3 threads: UI, IO and FILE. 95 // Class uses 3 threads: UI, IO and FILE.
93 // Internal workflow is following: 96 // Internal workflow is following:
94 // 1. Create instance on the UI thread. (files_, settings_,) 97 // 1. Create instance on the UI thread. (files_, settings_,)
95 // 2. Create pdf file on the FILE thread. 98 // 2. Create pdf file on the FILE thread.
96 // 3. Start utility process and start conversion on the IO thread. 99 // 3. Start utility process and start conversion on the IO thread.
97 // 4. Utility process returns page count. 100 // 4. Utility process returns page count.
98 // 5. For each page: 101 // 5. For each page:
99 // 1. Clients requests page with file handle to a temp file. 102 // 1. Clients requests page with file handle to a temp file.
100 // 2. Utility converts the page, save it to the file and reply. 103 // 2. Utility converts the page, save it to the file and reply.
101 // 104 //
102 // All these steps work sequentially, so no data should be accessed 105 // All these steps work sequentially, so no data should be accessed
103 // simultaneously by several threads. 106 // simultaneously by several threads.
104 class PdfToEmfUtilityProcessHostClient 107 class PdfConverterUtilityProcessHostClient
105 : public content::UtilityProcessHostClient { 108 : public content::UtilityProcessHostClient {
106 public: 109 public:
107 PdfToEmfUtilityProcessHostClient( 110 PdfConverterUtilityProcessHostClient(
108 base::WeakPtr<PdfToEmfConverterImpl> converter, 111 base::WeakPtr<PdfConverterImpl> converter,
109 const PdfRenderSettings& settings); 112 const PdfRenderSettings& settings);
110 113
111 void Start(const scoped_refptr<base::RefCountedMemory>& data, 114 void Start(const scoped_refptr<base::RefCountedMemory>& data,
112 bool print_text_with_gdi, 115 bool print_text_with_gdi,
113 const PdfToEmfConverter::StartCallback& start_callback); 116 const PdfConverter::StartCallback& start_callback);
114 117
115 void GetPage(int page_number, 118 void GetPage(int page_number,
116 const PdfToEmfConverter::GetPageCallback& get_page_callback); 119 const PdfConverter::GetPageCallback& get_page_callback);
117 120
118 void Stop(); 121 void Stop();
119 122
123 // UtilityProcessHostClient implementation.
124 void OnProcessCrashed(int exit_code) override;
125 void OnProcessLaunchFailed(int exit_code) override;
126
120 // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters 127 // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters
121 // sync message replies. 128 // sync message replies.
122 bool Send(IPC::Message* msg); 129 bool Send(IPC::Message* msg);
123 130
124 // UtilityProcessHostClient implementation. 131 protected:
125 void OnProcessCrashed(int exit_code) override;
126 void OnProcessLaunchFailed(int exit_code) override;
127 bool OnMessageReceived(const IPC::Message& message) override;
128
129 private:
130 class GetPageCallbackData { 132 class GetPageCallbackData {
131 public: 133 public:
132 GetPageCallbackData(int page_number, 134 GetPageCallbackData(int page_number, PdfConverter::GetPageCallback callback)
133 PdfToEmfConverter::GetPageCallback callback)
134 : page_number_(page_number), callback_(callback) {} 135 : page_number_(page_number), callback_(callback) {}
135 136
136 GetPageCallbackData(GetPageCallbackData&& other) { 137 GetPageCallbackData(GetPageCallbackData&& other) {
137 *this = std::move(other); 138 *this = std::move(other);
138 } 139 }
139 140
140 GetPageCallbackData& operator=(GetPageCallbackData&& rhs) { 141 GetPageCallbackData& operator=(GetPageCallbackData&& rhs) {
141 page_number_ = rhs.page_number_; 142 page_number_ = rhs.page_number_;
142 callback_ = rhs.callback_; 143 callback_ = rhs.callback_;
143 emf_ = std::move(rhs.emf_); 144 file_ = std::move(rhs.file_);
144 return *this; 145 return *this;
145 } 146 }
146 147
147 int page_number() const { return page_number_; } 148 int page_number() const { return page_number_; }
148 const PdfToEmfConverter::GetPageCallback& callback() const { 149 const PdfConverter::GetPageCallback& callback() const { return callback_; }
149 return callback_; 150 ScopedTempFile TakeFile() { return std::move(file_); }
150 } 151 void set_file(ScopedTempFile file) { file_ = std::move(file); }
151 ScopedTempFile TakeEmf() { return std::move(emf_); }
152 void set_emf(ScopedTempFile emf) { emf_ = std::move(emf); }
153 152
154 private: 153 private:
155 int page_number_; 154 int page_number_;
156 PdfToEmfConverter::GetPageCallback callback_; 155
157 ScopedTempFile emf_; 156 PdfConverter::GetPageCallback callback_;
157 ScopedTempFile file_;
158 158
159 DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); 159 DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData);
160 }; 160 };
161 161
162 ~PdfToEmfUtilityProcessHostClient() override; 162 ~PdfConverterUtilityProcessHostClient() override;
163 163
164 // Message handlers. 164 // Helper functions: must be overridden by subclasses
165 // Set the process name
166 virtual base::string16 GetName() const = 0;
167 // Create a metafileplayer subclass file from a temporary file.
168 virtual std::unique_ptr<MetafilePlayer> GetFileFromTemp(
169 std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
170 temp_file) = 0;
171 // Send the messages to Start, GetPage, and Stop.
172 virtual void SendStartMessage(IPC::PlatformFileForTransit transit,
173 bool print_text_with_gdi) = 0;
174 virtual void SendGetPageMessage(int page_number,
175 IPC::PlatformFileForTransit transit) = 0;
176 virtual void SendStopMessage() = 0;
177
178 // Message handlers:
165 void OnPageCount(int page_count); 179 void OnPageCount(int page_count);
166 void OnPageDone(bool success, float scale_factor); 180 void OnPageDone(bool success, float scale_factor);
167 void OnPreCacheFontCharacters(const LOGFONT& log_font,
168 const base::string16& characters);
169 181
170 void OnFailed(); 182 void OnFailed();
171 void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf); 183 void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf);
172 void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf); 184 void OnTempFileReady(GetPageCallbackData* callback_data,
185 ScopedTempFile temp_file);
173 186
174 scoped_refptr<RefCountedTempDir> temp_dir_; 187 scoped_refptr<RefCountedTempDir> temp_dir_;
175 188
176 // Used to suppress callbacks after PdfToEmfConverterImpl is deleted. 189 // Used to suppress callbacks after PdfConverter is deleted.
177 base::WeakPtr<PdfToEmfConverterImpl> converter_; 190 base::WeakPtr<PdfConverterImpl> converter_;
178 PdfRenderSettings settings_; 191 PdfRenderSettings settings_;
179 192
180 // Document loaded callback. 193 // Document loaded callback.
181 PdfToEmfConverter::StartCallback start_callback_; 194 PdfConverter::StartCallback start_callback_;
182 195
183 // Process host for IPC. 196 // Process host for IPC.
184 base::WeakPtr<content::UtilityProcessHost> utility_process_host_; 197 base::WeakPtr<content::UtilityProcessHost> utility_process_host_;
185 198
186 // Queue of callbacks for GetPage() requests. Utility process should reply 199 // Queue of callbacks for GetPage() requests. Utility process should reply
187 // with PageDone in the same order as requests were received. 200 // with PageDone in the same order as requests were received.
188 // Use containers that keeps element pointers valid after push() and pop(). 201 // Use containers that keeps element pointers valid after push() and pop().
189 typedef std::queue<GetPageCallbackData> GetPageCallbacks; 202 using GetPageCallbacks = std::queue<GetPageCallbackData>;
190 GetPageCallbacks get_page_callbacks_; 203 GetPageCallbacks get_page_callbacks_;
204 };
205
206 // Converts PDF into Emf.
207 class PdfToEmfUtilityProcessHostClient
208 : public PdfConverterUtilityProcessHostClient {
209 public:
210 PdfToEmfUtilityProcessHostClient(base::WeakPtr<PdfConverterImpl> converter,
211 const PdfRenderSettings& settings)
212 : PdfConverterUtilityProcessHostClient(converter, settings) {}
213
214 bool OnMessageReceived(const IPC::Message& message) override;
215
216 private:
217 ~PdfToEmfUtilityProcessHostClient() override;
218 // Helpers to send messages and set process name
219 base::string16 GetName() const override;
220 std::unique_ptr<MetafilePlayer> GetFileFromTemp(
221 std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
222 temp_file) override;
223 void SendStartMessage(IPC::PlatformFileForTransit transit,
224 bool print_text_with_gdi) override;
225 void SendGetPageMessage(int page_number,
226 IPC::PlatformFileForTransit transit) override;
227 void SendStopMessage() override;
228
229 // Additional message handler needed for Pdf to Emf
230 void OnPreCacheFontCharacters(const LOGFONT& log_font,
231 const base::string16& characters);
191 232
192 DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); 233 DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient);
193 }; 234 };
194 235
195 class PdfToEmfConverterImpl : public PdfToEmfConverter { 236 class PdfConverterImpl : public PdfConverter {
196 public: 237 public:
197 PdfToEmfConverterImpl(); 238 PdfConverterImpl();
198 239
199 ~PdfToEmfConverterImpl() override; 240 ~PdfConverterImpl() override;
200 241
201 void Start(const scoped_refptr<base::RefCountedMemory>& data, 242 void Start(const scoped_refptr<base::RefCountedMemory>& data,
202 const PdfRenderSettings& conversion_settings, 243 const PdfRenderSettings& conversion_settings,
203 bool print_text_with_gdi, 244 bool print_text_with_gdi,
204 const StartCallback& start_callback) override; 245 const StartCallback& start_callback) override;
205 246
206 void GetPage(int page_number, 247 void GetPage(int page_number,
207 const GetPageCallback& get_page_callback) override; 248 const GetPageCallback& get_page_callback) override;
208 249
209 // Helps to cancel callbacks if this object is destroyed. 250 // Helps to cancel callbacks if this object is destroyed.
210 void RunCallback(const base::Closure& callback); 251 void RunCallback(const base::Closure& callback);
211 252
253 protected:
254 scoped_refptr<PdfConverterUtilityProcessHostClient> utility_client_;
255
212 private: 256 private:
213 scoped_refptr<PdfToEmfUtilityProcessHostClient> utility_client_; 257 DISALLOW_COPY_AND_ASSIGN(PdfConverterImpl);
258 };
259
260 class PdfToEmfConverterImpl : public PdfConverterImpl {
261 public:
262 PdfToEmfConverterImpl();
263
264 ~PdfToEmfConverterImpl() override;
265
266 void Start(const scoped_refptr<base::RefCountedMemory>& data,
267 const PdfRenderSettings& conversion_settings,
268 bool print_text_with_gdi,
269 const StartCallback& start_callback) override;
270
271 private:
214 base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_; 272 base::WeakPtrFactory<PdfToEmfConverterImpl> weak_ptr_factory_;
215 273
216 DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); 274 DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl);
217 }; 275 };
218 276
219 ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) { 277 ScopedTempFile CreateTempFile(scoped_refptr<RefCountedTempDir>* temp_dir) {
220 if (!temp_dir->get()) 278 if (!temp_dir->get())
221 *temp_dir = new RefCountedTempDir(); 279 *temp_dir = new RefCountedTempDir();
222 ScopedTempFile file; 280 ScopedTempFile file;
223 if (!(*temp_dir)->IsValid()) 281 if (!(*temp_dir)->IsValid())
(...skipping 29 matching lines...) Expand all
253 pdf_file.reset(); 311 pdf_file.reset();
254 return pdf_file; 312 return pdf_file;
255 } 313 }
256 pdf_file->Seek(base::File::FROM_BEGIN, 0); 314 pdf_file->Seek(base::File::FROM_BEGIN, 0);
257 return pdf_file; 315 return pdf_file;
258 } 316 }
259 317
260 bool LazyEmf::SafePlayback(HDC hdc) const { 318 bool LazyEmf::SafePlayback(HDC hdc) const {
261 Emf emf; 319 Emf emf;
262 bool result = LoadEmf(&emf) && emf.SafePlayback(hdc); 320 bool result = LoadEmf(&emf) && emf.SafePlayback(hdc);
263 // TODO(vitalybuka): Fix destruction of metafiles. For some reasons 321 // TODO(thestig): Fix destruction of metafiles. For some reasons
264 // instances of Emf are not deleted. crbug.com/411683 322 // instances of Emf are not deleted. https://crbug.com/260806
265 // It's known that the Emf going to be played just once to a printer. So just 323 // It's known that the Emf going to be played just once to a printer. So just
266 // release file here. 324 // release |file_| here.
267 Close(); 325 Close();
268 return result; 326 return result;
269 } 327 }
270 328
271 bool LazyEmf::GetDataAsVector(std::vector<char>* buffer) const { 329 bool LazyEmf::GetDataAsVector(std::vector<char>* buffer) const {
272 NOTREACHED(); 330 NOTREACHED();
273 return false; 331 return false;
274 } 332 }
275 333
276 bool LazyEmf::SaveTo(base::File* file) const { 334 bool LazyEmf::SaveTo(base::File* file) const {
277 Emf emf; 335 Emf emf;
278 return LoadEmf(&emf) && emf.SaveTo(file); 336 return LoadEmf(&emf) && emf.SaveTo(file);
279 } 337 }
280 338
281 void LazyEmf::Close() const { 339 void LazyEmf::Close() const {
282 file_.reset(); 340 file_.reset();
283 temp_dir_ = NULL; 341 temp_dir_ = nullptr;
284 } 342 }
285 343
286 bool LazyEmf::LoadEmf(Emf* emf) const { 344 bool LazyEmf::LoadEmf(Emf* emf) const {
287 file_->Seek(base::File::FROM_BEGIN, 0); 345 file_->Seek(base::File::FROM_BEGIN, 0);
288 int64_t size = file_->GetLength(); 346 int64_t size = file_->GetLength();
289 if (size <= 0) 347 if (size <= 0)
290 return false; 348 return false;
291 std::vector<char> data(size); 349 std::vector<char> data(size);
292 if (file_->ReadAtCurrentPos(data.data(), data.size()) != size) 350 if (file_->ReadAtCurrentPos(data.data(), data.size()) != size)
293 return false; 351 return false;
294 return emf->InitFromData(data.data(), data.size()); 352 return emf->InitFromData(data.data(), data.size());
295 } 353 }
296 354
297 PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( 355 PdfConverterUtilityProcessHostClient::PdfConverterUtilityProcessHostClient(
298 base::WeakPtr<PdfToEmfConverterImpl> converter, 356 base::WeakPtr<PdfConverterImpl> converter,
299 const PdfRenderSettings& settings) 357 const PdfRenderSettings& settings)
300 : converter_(converter), settings_(settings) { 358 : converter_(converter), settings_(settings) {}
301 }
302 359
303 PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { 360 PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {}
304 }
305 361
306 void PdfToEmfUtilityProcessHostClient::Start( 362 void PdfConverterUtilityProcessHostClient::Start(
307 const scoped_refptr<base::RefCountedMemory>& data, 363 const scoped_refptr<base::RefCountedMemory>& data,
308 bool print_text_with_gdi, 364 bool print_text_with_gdi,
309 const PdfToEmfConverter::StartCallback& start_callback) { 365 const PdfConverter::StartCallback& start_callback) {
310 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 366 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
311 BrowserThread::PostTask( 367 BrowserThread::PostTask(
312 BrowserThread::IO, FROM_HERE, 368 BrowserThread::IO, FROM_HERE,
313 base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data, 369 base::Bind(&PdfConverterUtilityProcessHostClient::Start, this, data,
314 print_text_with_gdi, start_callback)); 370 print_text_with_gdi, start_callback));
315 return; 371 return;
316 } 372 }
317 373
318 // Store callback before any OnFailed() call to make it called on failure. 374 // Store callback before any OnFailed() call to make it called on failure.
319 start_callback_ = start_callback; 375 start_callback_ = start_callback;
320 376
321 // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load 377 // NOTE: This process _must_ be sandboxed, otherwise the pdf dll will load
322 // gdiplus.dll, change how rendering happens, and not be able to correctly 378 // gdiplus.dll, change how rendering happens, and not be able to correctly
323 // generate when sent to a metafile DC. 379 // generate when sent to a metafile DC.
324 utility_process_host_ = content::UtilityProcessHost::Create( 380 utility_process_host_ = content::UtilityProcessHost::Create(
325 this, base::ThreadTaskRunnerHandle::Get()) 381 this, base::ThreadTaskRunnerHandle::Get())
326 ->AsWeakPtr(); 382 ->AsWeakPtr();
327 utility_process_host_->SetName(l10n_util::GetStringUTF16( 383 utility_process_host_->SetName(GetName());
328 IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME));
329 384
330 BrowserThread::PostTaskAndReplyWithResult( 385 BrowserThread::PostTaskAndReplyWithResult(
331 BrowserThread::FILE, FROM_HERE, 386 BrowserThread::FILE, FROM_HERE,
332 base::Bind(&CreateTempPdfFile, data, &temp_dir_), 387 base::Bind(&CreateTempPdfFile, data, &temp_dir_),
333 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this, 388 base::Bind(&PdfConverterUtilityProcessHostClient::OnTempPdfReady, this,
334 print_text_with_gdi)); 389 print_text_with_gdi));
335 } 390 }
336 391
337 void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi, 392 void PdfConverterUtilityProcessHostClient::OnTempPdfReady(
338 ScopedTempFile pdf) { 393 bool print_text_with_gdi,
394 ScopedTempFile pdf) {
339 DCHECK_CURRENTLY_ON(BrowserThread::IO); 395 DCHECK_CURRENTLY_ON(BrowserThread::IO);
340 if (!utility_process_host_ || !pdf) 396 if (!utility_process_host_ || !pdf)
341 return OnFailed(); 397 return OnFailed();
342 // Should reply with OnPageCount(). 398 // Should reply with OnPageCount().
343 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( 399 SendStartMessage(
344 IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_, 400 IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false),
345 print_text_with_gdi)); 401 print_text_with_gdi);
346 } 402 }
347 403
348 void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { 404 void PdfConverterUtilityProcessHostClient::OnPageCount(int page_count) {
349 DCHECK_CURRENTLY_ON(BrowserThread::IO); 405 DCHECK_CURRENTLY_ON(BrowserThread::IO);
350 if (start_callback_.is_null()) 406 if (start_callback_.is_null())
351 return OnFailed(); 407 return OnFailed();
352 BrowserThread::PostTask(BrowserThread::UI, 408 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
353 FROM_HERE, 409 base::Bind(&PdfConverterImpl::RunCallback, converter_,
354 base::Bind(&PdfToEmfConverterImpl::RunCallback,
355 converter_,
356 base::Bind(start_callback_, page_count))); 410 base::Bind(start_callback_, page_count)));
357 start_callback_.Reset(); 411 start_callback_.Reset();
358 } 412 }
359 413
360 void PdfToEmfUtilityProcessHostClient::GetPage( 414 void PdfConverterUtilityProcessHostClient::GetPage(
361 int page_number, 415 int page_number,
362 const PdfToEmfConverter::GetPageCallback& get_page_callback) { 416 const PdfConverter::GetPageCallback& get_page_callback) {
363 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 417 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
364 BrowserThread::PostTask( 418 BrowserThread::PostTask(
365 BrowserThread::IO, 419 BrowserThread::IO, FROM_HERE,
366 FROM_HERE, 420 base::Bind(&PdfConverterUtilityProcessHostClient::GetPage, this,
367 base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage, 421 page_number, get_page_callback));
368 this,
369 page_number,
370 get_page_callback));
371 return; 422 return;
372 } 423 }
373 424
374 // Store callback before any OnFailed() call to make it called on failure. 425 // Store callback before any OnFailed() call to make it called on failure.
375 get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback)); 426 get_page_callbacks_.push(GetPageCallbackData(page_number, get_page_callback));
376 427
377 if (!utility_process_host_) 428 if (!utility_process_host_)
378 return OnFailed(); 429 return OnFailed();
379 430
380 BrowserThread::PostTaskAndReplyWithResult( 431 BrowserThread::PostTaskAndReplyWithResult(
381 BrowserThread::FILE, 432 BrowserThread::FILE, FROM_HERE, base::Bind(&CreateTempFile, &temp_dir_),
382 FROM_HERE, 433 base::Bind(&PdfConverterUtilityProcessHostClient::OnTempFileReady, this,
383 base::Bind(&CreateTempFile, &temp_dir_),
384 base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady,
385 this,
386 &get_page_callbacks_.back())); 434 &get_page_callbacks_.back()));
387 } 435 }
388 436
389 void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( 437 void PdfConverterUtilityProcessHostClient::OnTempFileReady(
390 GetPageCallbackData* callback_data, 438 GetPageCallbackData* callback_data,
391 ScopedTempFile emf) { 439 ScopedTempFile temp_file) {
392 DCHECK_CURRENTLY_ON(BrowserThread::IO); 440 DCHECK_CURRENTLY_ON(BrowserThread::IO);
393 if (!utility_process_host_ || !emf) 441 if (!utility_process_host_ || !temp_file)
394 return OnFailed(); 442 return OnFailed();
395 IPC::PlatformFileForTransit transit = 443 IPC::PlatformFileForTransit transit =
396 IPC::GetPlatformFileForTransit(emf->GetPlatformFile(), false); 444 IPC::GetPlatformFileForTransit(temp_file->GetPlatformFile(), false);
397 callback_data->set_emf(std::move(emf)); 445 callback_data->set_file(std::move(temp_file));
398 // Should reply with OnPageDone(). 446 // Should reply with OnPageDone().
399 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( 447 SendGetPageMessage(callback_data->page_number(), transit);
400 callback_data->page_number(), transit));
401 } 448 }
402 449
403 void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, 450 void PdfConverterUtilityProcessHostClient::OnPageDone(bool success,
404 float scale_factor) { 451 float scale_factor) {
405 DCHECK_CURRENTLY_ON(BrowserThread::IO); 452 DCHECK_CURRENTLY_ON(BrowserThread::IO);
406 if (get_page_callbacks_.empty()) 453 if (get_page_callbacks_.empty())
407 return OnFailed(); 454 return OnFailed();
408 GetPageCallbackData& data = get_page_callbacks_.front(); 455 GetPageCallbackData& data = get_page_callbacks_.front();
409 std::unique_ptr<MetafilePlayer> emf; 456 std::unique_ptr<MetafilePlayer> file;
410 457
411 if (success) { 458 if (success) {
412 ScopedTempFile temp_emf = data.TakeEmf(); 459 ScopedTempFile temp_file = data.TakeFile();
413 if (!temp_emf) // Unexpected message from utility process. 460 if (!temp_file) // Unexpected message from utility process.
414 return OnFailed(); 461 return OnFailed();
415 emf = base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_emf)); 462 file = GetFileFromTemp(std::move(temp_file));
416 } 463 }
417 464
418 BrowserThread::PostTask(BrowserThread::UI, 465 BrowserThread::PostTask(
419 FROM_HERE, 466 BrowserThread::UI, FROM_HERE,
420 base::Bind(&PdfToEmfConverterImpl::RunCallback, 467 base::Bind(&PdfConverterImpl::RunCallback, converter_,
421 converter_, 468 base::Bind(data.callback(), data.page_number(), scale_factor,
422 base::Bind(data.callback(), 469 base::Passed(&file))));
423 data.page_number(),
424 scale_factor,
425 base::Passed(&emf))));
426 get_page_callbacks_.pop(); 470 get_page_callbacks_.pop();
427 } 471 }
428 472
473 void PdfConverterUtilityProcessHostClient::Stop() {
474 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
475 BrowserThread::PostTask(
476 BrowserThread::IO, FROM_HERE,
477 base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this));
478 return;
479 }
480 SendStopMessage();
481 }
482
483 void PdfConverterUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
484 OnFailed();
485 }
486
487 void PdfConverterUtilityProcessHostClient::OnProcessLaunchFailed(
488 int exit_code) {
489 OnFailed();
490 }
491
492 bool PdfConverterUtilityProcessHostClient::Send(IPC::Message* msg) {
493 if (utility_process_host_)
494 return utility_process_host_->Send(msg);
495 delete msg;
496 return false;
497 }
498
499 void PdfConverterUtilityProcessHostClient::OnFailed() {
500 DCHECK_CURRENTLY_ON(BrowserThread::IO);
501 if (!start_callback_.is_null())
502 OnPageCount(0);
503 while (!get_page_callbacks_.empty())
504 OnPageDone(false, 0.0f);
505 utility_process_host_.reset();
506 }
507
508 // PDF to Emf
509 PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() {}
510
429 void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters( 511 void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters(
430 const LOGFONT& font, 512 const LOGFONT& font,
431 const base::string16& str) { 513 const base::string16& str) {
432 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache 514 // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache
433 // GDI fonts (http://crbug.com/383227), even when using DirectWrite. 515 // GDI fonts (http://crbug.com/383227), even when using DirectWrite.
434 // Eventually this shouldn't be added and should be moved to 516 // Eventually this shouldn't be added and should be moved to
435 // FontCacheDispatcher too. http://crbug.com/356346. 517 // FontCacheDispatcher too. http://crbug.com/356346.
436 518
437 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too. 519 // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
438 // Except that for True Type fonts, 520 // Except that for True Type fonts,
(...skipping 12 matching lines...) Expand all
451 533
452 SelectObject(hdc, old_font); 534 SelectObject(hdc, old_font);
453 DeleteObject(font_handle); 535 DeleteObject(font_handle);
454 536
455 HENHMETAFILE metafile = CloseEnhMetaFile(hdc); 537 HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
456 538
457 if (metafile) 539 if (metafile)
458 DeleteEnhMetaFile(metafile); 540 DeleteEnhMetaFile(metafile);
459 } 541 }
460 542
461 void PdfToEmfUtilityProcessHostClient::Stop() {
462 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
463 BrowserThread::PostTask(
464 BrowserThread::IO,
465 FROM_HERE,
466 base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this));
467 return;
468 }
469 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
470 }
471
472 void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) {
473 OnFailed();
474 }
475
476 void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed(int exit_code) {
477 OnFailed();
478 }
479
480 bool PdfToEmfUtilityProcessHostClient::OnMessageReceived( 543 bool PdfToEmfUtilityProcessHostClient::OnMessageReceived(
481 const IPC::Message& message) { 544 const IPC::Message& message) {
482 bool handled = true; 545 bool handled = true;
483 IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message) 546 IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message)
484 IPC_MESSAGE_HANDLER( 547 IPC_MESSAGE_HANDLER(
485 ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount) 548 ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount)
486 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, 549 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone,
487 OnPageDone) 550 OnPageDone)
488 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters, 551 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_PreCacheFontCharacters,
489 OnPreCacheFontCharacters) 552 OnPreCacheFontCharacters)
490 IPC_MESSAGE_UNHANDLED(handled = false) 553 IPC_MESSAGE_UNHANDLED(handled = false)
491 IPC_END_MESSAGE_MAP() 554 IPC_END_MESSAGE_MAP()
492 return handled; 555 return handled;
493 } 556 }
494 557
495 bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) { 558 base::string16 PdfToEmfUtilityProcessHostClient::GetName() const {
496 if (utility_process_host_) 559 return l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME);
497 return utility_process_host_->Send(msg);
498 delete msg;
499 return false;
500 } 560 }
501 561
502 void PdfToEmfUtilityProcessHostClient::OnFailed() { 562 std::unique_ptr<MetafilePlayer>
503 DCHECK_CURRENTLY_ON(BrowserThread::IO); 563 PdfToEmfUtilityProcessHostClient::GetFileFromTemp(
504 if (!start_callback_.is_null()) 564 std::unique_ptr<base::File, content::BrowserThread::DeleteOnFileThread>
505 OnPageCount(0); 565 temp_file) {
506 while (!get_page_callbacks_.empty()) 566 return base::MakeUnique<LazyEmf>(temp_dir_, std::move(temp_file));
507 OnPageDone(false, 0.0f);
508 utility_process_host_.reset();
509 } 567 }
510 568
511 PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) { 569 void PdfToEmfUtilityProcessHostClient::SendGetPageMessage(
570 int page_number,
571 IPC::PlatformFileForTransit transit) {
572 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(page_number,
573 transit));
512 } 574 }
513 575
576 void PdfToEmfUtilityProcessHostClient::SendStartMessage(
577 IPC::PlatformFileForTransit transit,
578 bool print_text_with_gdi) {
579 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_,
580 print_text_with_gdi));
581 }
582
583 void PdfToEmfUtilityProcessHostClient::SendStopMessage() {
584 Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop());
585 }
586
587 // Pdf Converter Impl and subclasses
588 PdfConverterImpl::PdfConverterImpl() {}
589
590 PdfConverterImpl::~PdfConverterImpl() {}
591
592 void PdfConverterImpl::Start(const scoped_refptr<base::RefCountedMemory>& data,
593 const PdfRenderSettings& conversion_settings,
594 bool print_text_with_gdi,
595 const StartCallback& start_callback) {
596 DCHECK(!utility_client_.get());
597 }
598
599 void PdfConverterImpl::GetPage(int page_number,
600 const GetPageCallback& get_page_callback) {
601 utility_client_->GetPage(page_number, get_page_callback);
602 }
603
604 void PdfConverterImpl::RunCallback(const base::Closure& callback) {
605 DCHECK_CURRENTLY_ON(BrowserThread::UI);
606 callback.Run();
607 }
608
609 PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) {}
610
514 PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { 611 PdfToEmfConverterImpl::~PdfToEmfConverterImpl() {
515 if (utility_client_.get()) 612 if (utility_client_.get())
516 utility_client_->Stop(); 613 utility_client_->Stop();
517 } 614 }
518 615
519 void PdfToEmfConverterImpl::Start( 616 void PdfToEmfConverterImpl::Start(
520 const scoped_refptr<base::RefCountedMemory>& data, 617 const scoped_refptr<base::RefCountedMemory>& data,
521 const PdfRenderSettings& conversion_settings, 618 const PdfRenderSettings& conversion_settings,
522 bool print_text_with_gdi, 619 bool print_text_with_gdi,
523 const StartCallback& start_callback) { 620 const StartCallback& start_callback) {
524 DCHECK(!utility_client_.get()); 621 DCHECK(!utility_client_.get());
525 utility_client_ = new PdfToEmfUtilityProcessHostClient( 622 utility_client_ = new PdfToEmfUtilityProcessHostClient(
526 weak_ptr_factory_.GetWeakPtr(), conversion_settings); 623 weak_ptr_factory_.GetWeakPtr(), conversion_settings);
527 utility_client_->Start(data, print_text_with_gdi, start_callback); 624 utility_client_->Start(data, print_text_with_gdi, start_callback);
528 } 625 }
529 626
530 void PdfToEmfConverterImpl::GetPage(int page_number,
531 const GetPageCallback& get_page_callback) {
532 utility_client_->GetPage(page_number, get_page_callback);
533 }
534
535 void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) {
536 DCHECK_CURRENTLY_ON(BrowserThread::UI);
537 callback.Run();
538 }
539
540 } // namespace 627 } // namespace
541 628
542 PdfToEmfConverter::~PdfToEmfConverter() { 629 PdfConverter::~PdfConverter() {}
543 }
544 630
545 // static 631 // static
546 std::unique_ptr<PdfToEmfConverter> PdfToEmfConverter::CreateDefault() { 632 std::unique_ptr<PdfConverter> PdfConverter::CreatePdfToEmfConverter() {
547 return std::unique_ptr<PdfToEmfConverter>(new PdfToEmfConverterImpl()); 633 return base::MakeUnique<PdfToEmfConverterImpl>();
548 } 634 }
549 635
550 } // namespace printing 636 } // namespace printing
OLDNEW
« no previous file with comments | « chrome/browser/printing/pdf_to_emf_converter.h ('k') | chrome/browser/printing/print_job.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698