OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "printing/backend/cups_helper.h" | 5 #include "printing/backend/cups_helper.h" |
6 | 6 |
7 #include <cups/ppd.h> | 7 #include <cups/ppd.h> |
8 | 8 |
9 #include "base/base_paths.h" | 9 #include "base/base_paths.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "base/values.h" | 16 #include "base/values.h" |
17 #include "printing/backend/print_backend.h" | 17 #include "printing/backend/print_backend.h" |
18 #include "printing/backend/print_backend_consts.h" | 18 #include "printing/backend/print_backend_consts.h" |
| 19 #include "printing/units.h" |
19 #include "url/gurl.h" | 20 #include "url/gurl.h" |
20 | 21 |
21 namespace printing { | 22 namespace printing { |
22 | 23 |
23 // This section contains helper code for PPD parsing for semantic capabilities. | 24 // This section contains helper code for PPD parsing for semantic capabilities. |
24 namespace { | 25 namespace { |
25 | 26 |
26 const char kColorDevice[] = "ColorDevice"; | 27 const char kColorDevice[] = "ColorDevice"; |
27 const char kColorModel[] = "ColorModel"; | 28 const char kColorModel[] = "ColorModel"; |
28 const char kColorMode[] = "ColorMode"; | 29 const char kColorMode[] = "ColorMode"; |
29 const char kProcessColorModel[] = "ProcessColorModel"; | 30 const char kProcessColorModel[] = "ProcessColorModel"; |
30 const char kPrintoutMode[] = "PrintoutMode"; | 31 const char kPrintoutMode[] = "PrintoutMode"; |
31 const char kDraftGray[] = "Draft.Gray"; | 32 const char kDraftGray[] = "Draft.Gray"; |
32 const char kHighGray[] = "High.Gray"; | 33 const char kHighGray[] = "High.Gray"; |
33 | 34 |
34 const char kDuplex[] = "Duplex"; | 35 const char kDuplex[] = "Duplex"; |
35 const char kDuplexNone[] = "None"; | 36 const char kDuplexNone[] = "None"; |
| 37 const char kPageSize[] = "PageSize"; |
| 38 |
| 39 const double kMicronsPerPoint = kHundrethsMMPerInch / kPointsPerInch * 10; |
36 | 40 |
37 #if !defined(OS_MACOSX) | 41 #if !defined(OS_MACOSX) |
38 void ParseLpOptions(const base::FilePath& filepath, | 42 void ParseLpOptions(const base::FilePath& filepath, |
39 const std::string& printer_name, | 43 const std::string& printer_name, |
40 int* num_options, cups_option_t** options) { | 44 int* num_options, cups_option_t** options) { |
41 std::string content; | 45 std::string content; |
42 if (!base::ReadFileToString(filepath, &content)) | 46 if (!base::ReadFileToString(filepath, &content)) |
43 return; | 47 return; |
44 | 48 |
45 const char kDest[] = "dest"; | 49 const char kDest[] = "dest"; |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 int data_size = printer_capabilities.length(); | 355 int data_size = printer_capabilities.length(); |
352 if (data_size != base::WriteFile( | 356 if (data_size != base::WriteFile( |
353 ppd_file_path, | 357 ppd_file_path, |
354 printer_capabilities.data(), | 358 printer_capabilities.data(), |
355 data_size)) { | 359 data_size)) { |
356 base::DeleteFile(ppd_file_path, false); | 360 base::DeleteFile(ppd_file_path, false); |
357 return false; | 361 return false; |
358 } | 362 } |
359 | 363 |
360 ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str()); | 364 ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str()); |
361 if (!ppd) | 365 if (!ppd) { |
| 366 int line = 0; |
| 367 ppd_status_t ppd_status = ppdLastError(&line); |
| 368 LOG(ERROR) << "Failed to open PDD file: error " << ppd_status << " at line " |
| 369 << line << ", " << ppdErrorString(ppd_status); |
362 return false; | 370 return false; |
| 371 } |
363 | 372 |
364 printing::PrinterSemanticCapsAndDefaults caps; | 373 printing::PrinterSemanticCapsAndDefaults caps; |
365 #if !defined(OS_MACOSX) | 374 #if !defined(OS_MACOSX) |
366 MarkLpOptions(printer_name, &ppd); | 375 MarkLpOptions(printer_name, &ppd); |
367 #endif | 376 #endif |
368 caps.collate_capable = true; | 377 caps.collate_capable = true; |
369 caps.collate_default = true; | 378 caps.collate_default = true; |
370 caps.copies_capable = true; | 379 caps.copies_capable = true; |
371 | 380 |
372 ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex); | 381 ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex); |
(...skipping 17 matching lines...) Expand all Loading... |
390 VLOG(1) << "Unknown printer color model"; | 399 VLOG(1) << "Unknown printer color model"; |
391 } | 400 } |
392 | 401 |
393 caps.color_changeable = ((cm_color != UNKNOWN_COLOR_MODEL) && | 402 caps.color_changeable = ((cm_color != UNKNOWN_COLOR_MODEL) && |
394 (cm_black != UNKNOWN_COLOR_MODEL) && | 403 (cm_black != UNKNOWN_COLOR_MODEL) && |
395 (cm_color != cm_black)); | 404 (cm_color != cm_black)); |
396 caps.color_default = is_color; | 405 caps.color_default = is_color; |
397 caps.color_model = cm_color; | 406 caps.color_model = cm_color; |
398 caps.bw_model = cm_black; | 407 caps.bw_model = cm_black; |
399 | 408 |
| 409 if (ppd->num_sizes > 0 && ppd->sizes) { |
| 410 VLOG(1) << "Paper list size - " << ppd->num_sizes; |
| 411 ppd_option_t* paper_option = ppdFindOption(ppd, kPageSize); |
| 412 for (int i = 0; i < ppd->num_sizes; ++i) { |
| 413 gfx::Size paper_size_microns( |
| 414 static_cast<int>(ppd->sizes[i].width * kMicronsPerPoint + 0.5), |
| 415 static_cast<int>(ppd->sizes[i].length * kMicronsPerPoint + 0.5)); |
| 416 if (paper_size_microns.width() > 0 && paper_size_microns.height() > 0) { |
| 417 PrinterSemanticCapsAndDefaults::Paper paper; |
| 418 paper.size_um = paper_size_microns; |
| 419 paper.vendor_id = ppd->sizes[i].name; |
| 420 if (paper_option) { |
| 421 ppd_choice_t* paper_choice = |
| 422 ppdFindChoice(paper_option, ppd->sizes[i].name); |
| 423 // Human readable paper name should be UTF-8 encoded, but some PPDs |
| 424 // do not follow this standard. |
| 425 if (paper_choice && base::IsStringUTF8(paper_choice->text)) { |
| 426 paper.display_name = paper_choice->text; |
| 427 } |
| 428 } |
| 429 caps.papers.push_back(paper); |
| 430 if (i == 0 || ppd->sizes[i].marked) { |
| 431 caps.default_paper = paper; |
| 432 } |
| 433 } |
| 434 } |
| 435 } |
| 436 |
400 ppdClose(ppd); | 437 ppdClose(ppd); |
401 base::DeleteFile(ppd_file_path, false); | 438 base::DeleteFile(ppd_file_path, false); |
402 | 439 |
403 *printer_info = caps; | 440 *printer_info = caps; |
404 return true; | 441 return true; |
405 } | 442 } |
406 | 443 |
407 } // namespace printing | 444 } // namespace printing |
OLD | NEW |