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

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

Powered by Google App Engine
This is Rietveld 408576698