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/utility/printing_handler.h" | 5 #include "chrome/utility/printing_handler.h" |
6 | 6 |
7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
10 #include "base/scoped_native_library.h" | 10 #include "base/scoped_native_library.h" |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 void PrintingHandler::PreSandboxStartup() { | 255 void PrintingHandler::PreSandboxStartup() { |
256 g_pdf_lib.Get().Init(); | 256 g_pdf_lib.Get().Init(); |
257 } | 257 } |
258 | 258 |
259 bool PrintingHandler::OnMessageReceived(const IPC::Message& message) { | 259 bool PrintingHandler::OnMessageReceived(const IPC::Message& message) { |
260 bool handled = true; | 260 bool handled = true; |
261 IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message) | 261 IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message) |
262 #if defined(OS_WIN) | 262 #if defined(OS_WIN) |
263 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles, | 263 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles, |
264 OnRenderPDFPagesToMetafile) | 264 OnRenderPDFPagesToMetafile) |
| 265 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage, |
| 266 OnRenderPDFPagesToMetafileGetPage) |
| 267 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop, |
| 268 OnRenderPDFPagesToMetafileStop) |
265 #endif // OS_WIN | 269 #endif // OS_WIN |
266 #if defined(ENABLE_FULL_PRINTING) | 270 #if defined(ENABLE_FULL_PRINTING) |
267 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToPWGRaster, | 271 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToPWGRaster, |
268 OnRenderPDFPagesToPWGRaster) | 272 OnRenderPDFPagesToPWGRaster) |
269 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterCapsAndDefaults, | 273 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterCapsAndDefaults, |
270 OnGetPrinterCapsAndDefaults) | 274 OnGetPrinterCapsAndDefaults) |
271 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterSemanticCapsAndDefaults, | 275 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterSemanticCapsAndDefaults, |
272 OnGetPrinterSemanticCapsAndDefaults) | 276 OnGetPrinterSemanticCapsAndDefaults) |
273 #endif // ENABLE_FULL_PRINTING | 277 #endif // ENABLE_FULL_PRINTING |
274 IPC_MESSAGE_UNHANDLED(handled = false) | 278 IPC_MESSAGE_UNHANDLED(handled = false) |
275 IPC_END_MESSAGE_MAP() | 279 IPC_END_MESSAGE_MAP() |
276 return handled; | 280 return handled; |
277 } | 281 } |
278 | 282 |
279 #if defined(OS_WIN) | 283 #if defined(OS_WIN) |
280 void PrintingHandler::OnRenderPDFPagesToMetafile( | 284 void PrintingHandler::OnRenderPDFPagesToMetafile( |
281 IPC::PlatformFileForTransit pdf_transit, | 285 IPC::PlatformFileForTransit pdf_transit, |
282 const base::FilePath& metafile_path, | 286 const printing::PdfRenderSettings& settings) { |
283 const printing::PdfRenderSettings& settings, | 287 pdf_rendering_settings_ = settings; |
284 const std::vector<printing::PageRange>& page_ranges_const) { | |
285 bool succeeded = false; | |
286 base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit); | 288 base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit); |
287 int highest_rendered_page_number = 0; | 289 int page_count = LoadPDF(pdf_file.Pass()); |
| 290 Send( |
| 291 new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count)); |
| 292 } |
| 293 |
| 294 void PrintingHandler::OnRenderPDFPagesToMetafileGetPage( |
| 295 int page_number, |
| 296 IPC::PlatformFileForTransit output_file) { |
| 297 base::File emf_file = IPC::PlatformFileForTransitToFile(output_file); |
288 double scale_factor = 1.0; | 298 double scale_factor = 1.0; |
289 std::vector<printing::PageRange> page_ranges = page_ranges_const; | 299 bool success = |
290 succeeded = RenderPDFToWinMetafile(pdf_file.Pass(), | 300 RenderPdfPageToMetafile(page_number, emf_file.Pass(), &scale_factor); |
291 metafile_path, | 301 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone( |
292 settings, | 302 success, scale_factor)); |
293 &page_ranges, | 303 } |
294 &highest_rendered_page_number, | 304 |
295 &scale_factor); | 305 void PrintingHandler::OnRenderPDFPagesToMetafileStop() { |
296 if (succeeded) { | |
297 // TODO(vitalybuka|scottmg): http://crbug.com/170859. These could | |
298 // potentially be sent as each page is converted so that the spool could | |
299 // start sooner. | |
300 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_Succeeded( | |
301 page_ranges, scale_factor)); | |
302 } else { | |
303 Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed()); | |
304 } | |
305 ReleaseProcessIfNeeded(); | 306 ReleaseProcessIfNeeded(); |
306 } | 307 } |
| 308 |
307 #endif // OS_WIN | 309 #endif // OS_WIN |
308 | 310 |
309 #if defined(ENABLE_FULL_PRINTING) | 311 #if defined(ENABLE_FULL_PRINTING) |
310 void PrintingHandler::OnRenderPDFPagesToPWGRaster( | 312 void PrintingHandler::OnRenderPDFPagesToPWGRaster( |
311 IPC::PlatformFileForTransit pdf_transit, | 313 IPC::PlatformFileForTransit pdf_transit, |
312 const printing::PdfRenderSettings& settings, | 314 const printing::PdfRenderSettings& settings, |
313 const printing::PwgRasterSettings& bitmap_settings, | 315 const printing::PwgRasterSettings& bitmap_settings, |
314 IPC::PlatformFileForTransit bitmap_transit) { | 316 IPC::PlatformFileForTransit bitmap_transit) { |
315 base::File pdf = IPC::PlatformFileForTransitToFile(pdf_transit); | 317 base::File pdf = IPC::PlatformFileForTransitToFile(pdf_transit); |
316 base::File bitmap = IPC::PlatformFileForTransitToFile(bitmap_transit); | 318 base::File bitmap = IPC::PlatformFileForTransitToFile(bitmap_transit); |
317 if (RenderPDFPagesToPWGRaster(pdf.Pass(), settings, bitmap_settings, | 319 if (RenderPDFPagesToPWGRaster(pdf.Pass(), settings, bitmap_settings, |
318 bitmap.Pass())) { | 320 bitmap.Pass())) { |
319 Send(new ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Succeeded()); | 321 Send(new ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Succeeded()); |
320 } else { | 322 } else { |
321 Send(new ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Failed()); | 323 Send(new ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Failed()); |
322 } | 324 } |
323 ReleaseProcessIfNeeded(); | 325 ReleaseProcessIfNeeded(); |
324 } | 326 } |
325 #endif // ENABLE_FULL_PRINTING | 327 #endif // ENABLE_FULL_PRINTING |
326 | 328 |
327 #if defined(OS_WIN) | 329 #if defined(OS_WIN) |
328 bool PrintingHandler::RenderPDFToWinMetafile( | 330 int PrintingHandler::LoadPDF(base::File pdf_file) { |
329 base::File pdf_file, | 331 if (!g_pdf_lib.Get().IsValid()) |
330 const base::FilePath& metafile_path, | 332 return 0; |
331 const printing::PdfRenderSettings& settings, | |
332 std::vector<printing::PageRange>* page_ranges, | |
333 int* highest_rendered_page_number, | |
334 double* scale_factor) { | |
335 DCHECK(page_ranges); | |
336 *highest_rendered_page_number = -1; | |
337 *scale_factor = 1.0; | |
338 | 333 |
339 if (!g_pdf_lib.Get().IsValid()) | |
340 return false; | |
341 | |
342 // TODO(sanjeevr): Add a method to the PDF DLL that takes in a file handle | |
343 // and a page range array. That way we don't need to read the entire PDF into | |
344 // memory. | |
345 int64 length = pdf_file.GetLength(); | 334 int64 length = pdf_file.GetLength(); |
346 if (length < 0) | 335 if (length < 0) |
347 return false; | 336 return 0; |
348 | 337 |
349 std::vector<char> buffer; | 338 pdf_data_.resize(length); |
350 buffer.resize(length); | 339 if (length != pdf_file.Read(0, pdf_data_.data(), pdf_data_.size())) |
351 if (length != pdf_file.Read(0, &buffer.front(), length)) | 340 return 0; |
352 return false; | |
353 | 341 |
354 int total_page_count = 0; | 342 int total_page_count = 0; |
355 if (!g_pdf_lib.Get().GetPDFDocInfo(&buffer.front(), buffer.size(), | 343 if (!g_pdf_lib.Get().GetPDFDocInfo( |
356 &total_page_count, NULL)) { | 344 &pdf_data_.front(), pdf_data_.size(), &total_page_count, NULL)) { |
| 345 return 0; |
| 346 } |
| 347 return total_page_count; |
| 348 } |
| 349 |
| 350 bool PrintingHandler::RenderPdfPageToMetafile(int page_number, |
| 351 base::File output_file, |
| 352 double* scale_factor) { |
| 353 printing::Emf metafile; |
| 354 metafile.Init(); |
| 355 |
| 356 // We need to scale down DC to fit an entire page into DC available area. |
| 357 // Current metafile is based on screen DC and have current screen size. |
| 358 // Writing outside of those boundaries will result in the cut-off output. |
| 359 // On metafiles (this is the case here), scaling down will still record |
| 360 // original coordinates and we'll be able to print in full resolution. |
| 361 // Before playback we'll need to counter the scaling up that will happen |
| 362 // in the service (print_system_win.cc). |
| 363 *scale_factor = |
| 364 gfx::CalculatePageScale(metafile.context(), |
| 365 pdf_rendering_settings_.area().right(), |
| 366 pdf_rendering_settings_.area().bottom()); |
| 367 gfx::ScaleDC(metafile.context(), *scale_factor); |
| 368 |
| 369 // The underlying metafile is of type Emf and ignores the arguments passed |
| 370 // to StartPage. |
| 371 metafile.StartPage(gfx::Size(), gfx::Rect(), 1); |
| 372 if (!g_pdf_lib.Get().RenderPDFPageToDC( |
| 373 &pdf_data_.front(), |
| 374 pdf_data_.size(), |
| 375 page_number, |
| 376 metafile.context(), |
| 377 pdf_rendering_settings_.dpi(), |
| 378 pdf_rendering_settings_.dpi(), |
| 379 pdf_rendering_settings_.area().x(), |
| 380 pdf_rendering_settings_.area().y(), |
| 381 pdf_rendering_settings_.area().width(), |
| 382 pdf_rendering_settings_.area().height(), |
| 383 true, |
| 384 false, |
| 385 true, |
| 386 true, |
| 387 pdf_rendering_settings_.autorotate())) { |
357 return false; | 388 return false; |
358 } | 389 } |
| 390 metafile.FinishPage(); |
| 391 metafile.FinishDocument(); |
| 392 return metafile.SaveTo(&output_file); |
| 393 } |
359 | 394 |
360 // If no range supplied, do all pages. | |
361 if (page_ranges->empty()) { | |
362 printing::PageRange page_range_all; | |
363 page_range_all.from = 0; | |
364 page_range_all.to = total_page_count - 1; | |
365 page_ranges->push_back(page_range_all); | |
366 } | |
367 | |
368 bool ret = false; | |
369 std::vector<printing::PageRange>::const_iterator iter; | |
370 for (iter = page_ranges->begin(); iter != page_ranges->end(); ++iter) { | |
371 for (int page_number = iter->from; page_number <= iter->to; ++page_number) { | |
372 if (page_number >= total_page_count) | |
373 break; | |
374 | |
375 printing::Emf metafile; | |
376 metafile.InitToFile(metafile_path.InsertBeforeExtensionASCII( | |
377 base::StringPrintf(".%d", page_number))); | |
378 | |
379 // We need to scale down DC to fit an entire page into DC available area. | |
380 // Current metafile is based on screen DC and have current screen size. | |
381 // Writing outside of those boundaries will result in the cut-off output. | |
382 // On metafiles (this is the case here), scaling down will still record | |
383 // original coordinates and we'll be able to print in full resolution. | |
384 // Before playback we'll need to counter the scaling up that will happen | |
385 // in the service (print_system_win.cc). | |
386 *scale_factor = gfx::CalculatePageScale(metafile.context(), | |
387 settings.area().right(), | |
388 settings.area().bottom()); | |
389 gfx::ScaleDC(metafile.context(), *scale_factor); | |
390 | |
391 // The underlying metafile is of type Emf and ignores the arguments passed | |
392 // to StartPage. | |
393 metafile.StartPage(gfx::Size(), gfx::Rect(), 1); | |
394 if (g_pdf_lib.Get().RenderPDFPageToDC( | |
395 &buffer.front(), buffer.size(), page_number, metafile.context(), | |
396 settings.dpi(), settings.dpi(), settings.area().x(), | |
397 settings.area().y(), settings.area().width(), | |
398 settings.area().height(), true, false, true, true, | |
399 settings.autorotate())) { | |
400 if (*highest_rendered_page_number < page_number) | |
401 *highest_rendered_page_number = page_number; | |
402 ret = true; | |
403 } | |
404 metafile.FinishPage(); | |
405 metafile.FinishDocument(); | |
406 } | |
407 } | |
408 return ret; | |
409 } | |
410 #endif // OS_WIN | 395 #endif // OS_WIN |
411 | 396 |
412 #if defined(ENABLE_FULL_PRINTING) | 397 #if defined(ENABLE_FULL_PRINTING) |
413 bool PrintingHandler::RenderPDFPagesToPWGRaster( | 398 bool PrintingHandler::RenderPDFPagesToPWGRaster( |
414 base::File pdf_file, | 399 base::File pdf_file, |
415 const printing::PdfRenderSettings& settings, | 400 const printing::PdfRenderSettings& settings, |
416 const printing::PwgRasterSettings& bitmap_settings, | 401 const printing::PwgRasterSettings& bitmap_settings, |
417 base::File bitmap_file) { | 402 base::File bitmap_file) { |
418 bool autoupdate = true; | 403 bool autoupdate = true; |
419 if (!g_pdf_lib.Get().IsValid()) | 404 if (!g_pdf_lib.Get().IsValid()) |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 &printer_info)) { | 518 &printer_info)) { |
534 Send(new ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Succeeded( | 519 Send(new ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Succeeded( |
535 printer_name, printer_info)); | 520 printer_name, printer_info)); |
536 } else { | 521 } else { |
537 Send(new ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Failed( | 522 Send(new ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Failed( |
538 printer_name)); | 523 printer_name)); |
539 } | 524 } |
540 ReleaseProcessIfNeeded(); | 525 ReleaseProcessIfNeeded(); |
541 } | 526 } |
542 #endif // ENABLE_FULL_PRINTING | 527 #endif // ENABLE_FULL_PRINTING |
OLD | NEW |