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

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

Issue 255543006: Printing on Windows via PDF (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tidy Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/print_view_manager_base.h" 5 #include "chrome/browser/printing/print_view_manager_base.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/memory/ref_counted_memory.h"
10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
11 #include "base/prefs/pref_service.h" 12 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
13 #include "base/timer/timer.h" 14 #include "base/timer/timer.h"
14 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/printing/pdf_to_emf_converter.h"
16 #include "chrome/browser/printing/print_job.h" 18 #include "chrome/browser/printing/print_job.h"
17 #include "chrome/browser/printing/print_job_manager.h" 19 #include "chrome/browser/printing/print_job_manager.h"
18 #include "chrome/browser/printing/printer_query.h" 20 #include "chrome/browser/printing/printer_query.h"
19 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/simple_message_box.h" 22 #include "chrome/browser/ui/simple_message_box.h"
21 #include "chrome/common/pref_names.h" 23 #include "chrome/common/pref_names.h"
22 #include "chrome/common/print_messages.h" 24 #include "chrome/common/print_messages.h"
23 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/notification_details.h" 26 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_service.h" 27 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/notification_source.h" 28 #include "content/public/browser/notification_source.h"
27 #include "content/public/browser/render_view_host.h" 29 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/web_contents.h" 30 #include "content/public/browser/web_contents.h"
29 #include "grit/generated_resources.h" 31 #include "grit/generated_resources.h"
30 #include "printing/metafile_impl.h" 32 #include "printing/metafile_impl.h"
33 #include "printing/pdf_render_settings.h"
31 #include "printing/printed_document.h" 34 #include "printing/printed_document.h"
32 #include "ui/base/l10n/l10n_util.h" 35 #include "ui/base/l10n/l10n_util.h"
33 36
34 #if defined(OS_WIN) 37 #if defined(OS_WIN)
35 #include "base/command_line.h" 38 #include "base/command_line.h"
36 #include "chrome/common/chrome_switches.h" 39 #include "chrome/common/chrome_switches.h"
37 #endif 40 #endif
38 41
39 #if defined(ENABLE_FULL_PRINTING) 42 #if defined(ENABLE_FULL_PRINTING)
40 #include "chrome/browser/printing/print_error_dialog.h" 43 #include "chrome/browser/printing/print_error_dialog.h"
41 #endif 44 #endif
42 45
43 using base::TimeDelta; 46 using base::TimeDelta;
44 using content::BrowserThread; 47 using content::BrowserThread;
45 48
46 #if defined(OS_WIN) 49 #if !defined(PRINTING_WIN_USES_PDF_AS_METAFILE)
47 // Limits memory usage by raster to 64 MiB. 50 // Limits memory usage by raster to 64 MiB.
48 const int kMaxRasterSizeInPixels = 16*1024*1024; 51 const int kMaxRasterSizeInPixels = 16*1024*1024;
49 #endif 52 #endif
50 53
51 namespace printing { 54 namespace printing {
52 55
53 PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents) 56 PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
54 : content::WebContentsObserver(web_contents), 57 : content::WebContentsObserver(web_contents),
55 number_pages_(0), 58 number_pages_(0),
56 printing_succeeded_(false), 59 printing_succeeded_(false),
57 inside_inner_message_loop_(false), 60 inside_inner_message_loop_(false),
58 cookie_(0), 61 cookie_(0),
59 queue_(g_browser_process->print_job_manager()->queue()) { 62 queue_(g_browser_process->print_job_manager()->queue()) {
60 DCHECK(queue_); 63 DCHECK(queue_);
61 #if defined(OS_POSIX) && !defined(OS_MACOSX) 64 #if (defined(OS_POSIX) && !defined(OS_MACOSX)) || \
65 defined(PRINTING_WIN_USES_PDF_AS_METAFILE)
62 expecting_first_page_ = true; 66 expecting_first_page_ = true;
63 #endif 67 #endif
64 Profile* profile = 68 Profile* profile =
65 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 69 Profile::FromBrowserContext(web_contents->GetBrowserContext());
66 printing_enabled_.Init( 70 printing_enabled_.Init(
67 prefs::kPrintingEnabled, 71 prefs::kPrintingEnabled,
68 profile->GetPrefs(), 72 profile->GetPrefs(),
69 base::Bind(&PrintViewManagerBase::UpdateScriptedPrintingBlocked, 73 base::Bind(&PrintViewManagerBase::UpdateScriptedPrintingBlocked,
70 base::Unretained(this))); 74 base::Unretained(this)));
71 } 75 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 DCHECK_GT(cookie, 0); 121 DCHECK_GT(cookie, 0);
118 DCHECK_GT(number_pages, 0); 122 DCHECK_GT(number_pages, 0);
119 number_pages_ = number_pages; 123 number_pages_ = number_pages;
120 OpportunisticallyCreatePrintJob(cookie); 124 OpportunisticallyCreatePrintJob(cookie);
121 } 125 }
122 126
123 void PrintViewManagerBase::OnDidGetDocumentCookie(int cookie) { 127 void PrintViewManagerBase::OnDidGetDocumentCookie(int cookie) {
124 cookie_ = cookie; 128 cookie_ = cookie;
125 } 129 }
126 130
131 #if defined(PRINTING_WIN_USES_PDF_AS_METAFILE)
132 void PrintViewManagerBase::OnPdfToEmfConverted(
133 const PrintHostMsg_DidPrintPage_Params& params,
134 double scale_factor,
135 const std::vector<base::FilePath>& emf_files) {
136 PrintedDocument* document = print_job_->document();
137 if (!document)
138 return;
139
140 int page_number = 0;
141 for (std::vector<base::FilePath>::const_iterator i(emf_files.begin());
Vitaly Buka (NO REVIEWS) 2014/05/13 23:54:33 I guess for (size_t i = ) is more appropriate here
scottmg 2014/05/14 00:34:48 Done.
142 i != emf_files.end();
143 ++i, ++page_number) {
144 scoped_ptr<printing::Emf> metafile(new printing::Emf);
145 if (!metafile->InitFromFile(*i)) {
146 NOTREACHED() << "Invalid metafile";
147 web_contents()->Stop();
148 return;
149 }
150 // Update the rendered document. It will send notifications to the listener.
151 document->SetPage(page_number,
152 metafile.release(),
153 scale_factor,
154 params.page_size,
155 params.content_area);
156 }
157
158 ShouldQuitFromInnerMessageLoop();
159 }
160 #endif // PRINTING_WIN_USES_PDF_AS_METAFILE
161
127 void PrintViewManagerBase::OnDidPrintPage( 162 void PrintViewManagerBase::OnDidPrintPage(
128 const PrintHostMsg_DidPrintPage_Params& params) { 163 const PrintHostMsg_DidPrintPage_Params& params) {
129 if (!OpportunisticallyCreatePrintJob(params.document_cookie)) 164 if (!OpportunisticallyCreatePrintJob(params.document_cookie))
130 return; 165 return;
131 166
132 PrintedDocument* document = print_job_->document(); 167 PrintedDocument* document = print_job_->document();
133 if (!document || params.document_cookie != document->cookie()) { 168 if (!document || params.document_cookie != document->cookie()) {
134 // Out of sync. It may happen since we are completely asynchronous. Old 169 // Out of sync. It may happen since we are completely asynchronous. Old
135 // spurious messages can be received if one of the processes is overloaded. 170 // spurious messages can be received if one of the processes is overloaded.
136 return; 171 return;
137 } 172 }
138 173
139 #if defined(OS_WIN) || defined(OS_MACOSX) 174 #if !defined(PRINTING_WIN_USES_PDF_AS_METAFILE) || defined(OS_MACOSX)
140 const bool metafile_must_be_valid = true; 175 const bool metafile_must_be_valid = true;
141 #elif defined(OS_POSIX) 176 #elif defined(OS_POSIX) || defined(PRINTING_WIN_USES_PDF_AS_METAFILE)
142 const bool metafile_must_be_valid = expecting_first_page_; 177 const bool metafile_must_be_valid = expecting_first_page_;
143 expecting_first_page_ = false; 178 expecting_first_page_ = false;
144 #endif 179 #endif
145 180
146 base::SharedMemory shared_buf(params.metafile_data_handle, true); 181 base::SharedMemory shared_buf(params.metafile_data_handle, true);
147 if (metafile_must_be_valid) { 182 if (metafile_must_be_valid) {
148 if (!shared_buf.Map(params.data_size)) { 183 if (!shared_buf.Map(params.data_size)) {
149 NOTREACHED() << "couldn't map"; 184 NOTREACHED() << "couldn't map";
150 web_contents()->Stop(); 185 web_contents()->Stop();
151 return; 186 return;
152 } 187 }
153 } 188 }
154 189
190 #if defined(OS_WIN) && !defined(PRINTING_WIN_USES_PDF_AS_METAFILE)
155 scoped_ptr<NativeMetafile> metafile(new NativeMetafile); 191 scoped_ptr<NativeMetafile> metafile(new NativeMetafile);
156 if (metafile_must_be_valid) { 192 if (metafile_must_be_valid) {
157 if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) { 193 if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) {
158 NOTREACHED() << "Invalid metafile header"; 194 NOTREACHED() << "Invalid metafile header";
159 web_contents()->Stop(); 195 web_contents()->Stop();
160 return; 196 return;
161 } 197 }
162 } 198 }
163 199
164 #if defined(OS_WIN)
165 bool big_emf = (params.data_size && params.data_size >= kMetafileMaxSize); 200 bool big_emf = (params.data_size && params.data_size >= kMetafileMaxSize);
166 int raster_size = std::min(params.page_size.GetArea(), 201 int raster_size = std::min(params.page_size.GetArea(),
167 kMaxRasterSizeInPixels); 202 kMaxRasterSizeInPixels);
Vitaly Buka (NO REVIEWS) 2014/05/13 23:54:33 missaligned
scottmg 2014/05/14 00:34:48 Done.
168 if (big_emf) { 203 if (big_emf) {
169 scoped_ptr<NativeMetafile> raster_metafile( 204 scoped_ptr<NativeMetafile> raster_metafile(
170 metafile->RasterizeMetafile(raster_size)); 205 metafile->RasterizeMetafile(raster_size));
171 if (raster_metafile.get()) { 206 if (raster_metafile.get()) {
172 metafile.swap(raster_metafile); 207 metafile.swap(raster_metafile);
173 } else if (big_emf) { 208 } else if (big_emf) {
174 // Don't fall back to emf here. 209 // Don't fall back to emf here.
175 NOTREACHED() << "size:" << params.data_size; 210 NOTREACHED() << "size:" << params.data_size;
176 TerminatePrintJob(true); 211 TerminatePrintJob(true);
177 web_contents()->Stop(); 212 web_contents()->Stop();
178 return; 213 return;
179 } 214 }
180 } 215 }
181 #endif 216 #endif // OS_WIN && !PRINTING_WIN_USES_PDF_AS_METAFILE
182 217
218 #if !defined(OS_WIN) || !defined(PRINTING_WIN_USES_PDF_AS_METAFILE)
183 // Update the rendered document. It will send notifications to the listener. 219 // Update the rendered document. It will send notifications to the listener.
184 document->SetPage(params.page_number, 220 document->SetPage(params.page_number,
185 metafile.release(), 221 metafile.release(),
186 params.actual_shrink, 222 params.actual_shrink,
Vitaly Buka (NO REVIEWS) 2014/05/13 23:54:33 missaligned
scottmg 2014/05/14 00:34:48 Done.
187 params.page_size, 223 params.page_size,
188 params.content_area); 224 params.content_area);
189 225
190 ShouldQuitFromInnerMessageLoop(); 226 ShouldQuitFromInnerMessageLoop();
227 #else
228 if (metafile_must_be_valid) {
229 base::RefCountedBytes* bytes = new base::RefCountedBytes(
Vitaly Buka (NO REVIEWS) 2014/05/13 23:54:33 scoped_refptr<base::RefCountedBytes>
scottmg 2014/05/14 00:34:48 Done.
230 reinterpret_cast<const unsigned char*>(shared_buf.memory()),
231 params.data_size);
232
233 if (!pdf_to_emf_converter_)
234 pdf_to_emf_converter_ = PdfToEmfConverter::CreateDefault();
235
236 const int printer_dpi = 600;
237 pdf_to_emf_converter_->Start(
238 bytes,
239 printing::PdfRenderSettings(params.content_area, printer_dpi, false),
240 base::Bind(&PrintViewManagerBase::OnPdfToEmfConverted,
241 base::Unretained(this),
242 params));
243 }
244 #endif // !PRINTING_WIN_USES_PDF_AS_METAFILE
191 } 245 }
192 246
193 void PrintViewManagerBase::OnPrintingFailed(int cookie) { 247 void PrintViewManagerBase::OnPrintingFailed(int cookie) {
194 if (cookie != cookie_) { 248 if (cookie != cookie_) {
195 NOTREACHED(); 249 NOTREACHED();
196 return; 250 return;
197 } 251 }
198 252
199 #if defined(ENABLE_FULL_PRINTING) 253 #if defined(ENABLE_FULL_PRINTING)
200 chrome::ShowPrintErrorDialog(); 254 chrome::ShowPrintErrorDialog();
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 if (print_job_.get() && 441 if (print_job_.get() &&
388 print_job_->document() && 442 print_job_->document() &&
389 !print_job_->document()->IsComplete()) { 443 !print_job_->document()->IsComplete()) {
390 DCHECK(!result); 444 DCHECK(!result);
391 // That failed. 445 // That failed.
392 TerminatePrintJob(true); 446 TerminatePrintJob(true);
393 } else { 447 } else {
394 // DO NOT wait for the job to finish. 448 // DO NOT wait for the job to finish.
395 ReleasePrintJob(); 449 ReleasePrintJob();
396 } 450 }
397 #if defined(OS_POSIX) && !defined(OS_MACOSX) 451 #if (defined(OS_POSIX) && !defined(OS_MACOSX)) || \
452 defined(PRINTING_WIN_USES_PDF_AS_METAFILE)
398 expecting_first_page_ = true; 453 expecting_first_page_ = true;
399 #endif 454 #endif
400 } 455 }
401 456
402 void PrintViewManagerBase::PrintingDone(bool success) { 457 void PrintViewManagerBase::PrintingDone(bool success) {
403 if (!print_job_.get()) 458 if (!print_job_.get())
404 return; 459 return;
405 Send(new PrintMsg_PrintingDone(routing_id(), success)); 460 Send(new PrintMsg_PrintingDone(routing_id(), success));
406 } 461 }
407 462
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 scoped_refptr<printing::PrinterQuery> printer_query; 586 scoped_refptr<printing::PrinterQuery> printer_query;
532 printer_query = queue_->PopPrinterQuery(cookie); 587 printer_query = queue_->PopPrinterQuery(cookie);
533 if (!printer_query) 588 if (!printer_query)
534 return; 589 return;
535 BrowserThread::PostTask( 590 BrowserThread::PostTask(
536 BrowserThread::IO, FROM_HERE, 591 BrowserThread::IO, FROM_HERE,
537 base::Bind(&PrinterQuery::StopWorker, printer_query.get())); 592 base::Bind(&PrinterQuery::StopWorker, printer_query.get()));
538 } 593 }
539 594
540 } // namespace printing 595 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698