Index: printing/backend/print_backend_cups.cc |
=================================================================== |
--- printing/backend/print_backend_cups.cc (revision 153539) |
+++ printing/backend/print_backend_cups.cc (working copy) |
@@ -93,6 +93,256 @@ |
} // namespace |
#endif // !defined(OS_MACOSX) |
+namespace { |
+ |
+// This section contains helper code for PPD parsing for semantic capabilities. |
+ |
+const char kColorDevice[] = "ColorDevice"; |
+const char kColorModel[] = "ColorModel"; |
+const char kColorMode[] = "ColorMode"; |
+const char kProcessColorModel[] = "ProcessColorModel"; |
+const char kPrintoutMode[] = "PrintoutMode"; |
+const char kDraftGray[] = "Draft.Gray"; |
+const char kHighGray[] = "High.Gray"; |
+ |
+const char kDuplex[] = "Duplex"; |
+const char kDuplexNone[] = "None"; |
+ |
+bool getBasicColorModelSettings( |
+ ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
+ bool* color_is_default) { |
+ ppd_option_t* color_model = ppdFindOption(ppd, kColorModel); |
+ if (!color_model) |
+ return false; |
+ |
+ if (ppdFindChoice(color_model, printing::kBlack)) |
+ *color_model_for_black = printing::BLACK; |
+ else if (ppdFindChoice(color_model, printing::kGray)) |
+ *color_model_for_black = printing::GRAY; |
+ else if (ppdFindChoice(color_model, printing::kGrayscale)) |
+ *color_model_for_black = printing::GRAYSCALE; |
+ |
+ if (ppdFindChoice(color_model, printing::kColor)) |
+ *color_model_for_color = printing::COLOR; |
+ else if (ppdFindChoice(color_model, printing::kCMYK)) |
+ *color_model_for_color = printing::CMYK; |
+ else if (ppdFindChoice(color_model, printing::kRGB)) |
+ *color_model_for_color = printing::RGB; |
+ else if (ppdFindChoice(color_model, printing::kRGBA)) |
+ *color_model_for_color = printing::RGBA; |
+ else if (ppdFindChoice(color_model, printing::kRGB16)) |
+ *color_model_for_color = printing::RGB16; |
+ else if (ppdFindChoice(color_model, printing::kCMY)) |
+ *color_model_for_color = printing::CMY; |
+ else if (ppdFindChoice(color_model, printing::kKCMY)) |
+ *color_model_for_color = printing::KCMY; |
+ else if (ppdFindChoice(color_model, printing::kCMY_K)) |
+ *color_model_for_color = printing::CMY_K; |
+ |
+ ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorModel); |
+ if (!marked_choice) |
+ marked_choice = ppdFindChoice(color_model, color_model->defchoice); |
+ |
+ if (marked_choice) { |
+ *color_is_default = |
+ (base::strcasecmp(marked_choice->choice, printing::kBlack) != 0) && |
+ (base::strcasecmp(marked_choice->choice, printing::kGray) != 0); |
+ } |
+ return true; |
+} |
+ |
+bool getPrintOutModeColorSettings( |
+ ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
+ bool* color_is_default) { |
+ ppd_option_t* printout_mode = ppdFindOption(ppd, kPrintoutMode); |
+ if (!printout_mode) |
+ return false; |
+ |
+ *color_model_for_color = printing::PRINTOUTMODE_NORMAL; |
+ *color_model_for_black = printing::PRINTOUTMODE_NORMAL; |
+ |
+ // Check to see if NORMAL_GRAY value is supported by PrintoutMode. |
+ // If NORMAL_GRAY is not supported, NORMAL value is used to |
+ // represent grayscale. If NORMAL_GRAY is supported, NORMAL is used to |
+ // represent color. |
+ if (ppdFindChoice(printout_mode, printing::kNormalGray)) |
+ *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; |
+ |
+ // Get the default marked choice to identify the default color setting |
+ // value. |
+ ppd_choice_t* printout_mode_choice = ppdFindMarkedChoice(ppd, kPrintoutMode); |
+ if (!printout_mode_choice) { |
+ printout_mode_choice = ppdFindChoice(printout_mode, |
+ printout_mode->defchoice); |
+ } |
+ if (printout_mode_choice) { |
+ if ((base::strcasecmp(printout_mode_choice->choice, |
+ printing::kNormalGray) == 0) || |
+ (base::strcasecmp(printout_mode_choice->choice, kHighGray) == 0) || |
+ (base::strcasecmp(printout_mode_choice->choice, kDraftGray) == 0)) { |
+ *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; |
+ *color_is_default = false; |
+ } |
+ } |
+ return true; |
+} |
+ |
+bool getColorModeSettings( |
+ ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
+ bool* color_is_default) { |
+ // Samsung printers use "ColorMode" attribute in their ppds. |
+ ppd_option_t* color_mode_option = ppdFindOption(ppd, kColorMode); |
+ if (!color_mode_option) |
+ return false; |
+ |
+ if (ppdFindChoice(color_mode_option, printing::kColor)) |
+ *color_model_for_color = printing::COLORMODE_COLOR; |
+ |
+ if (ppdFindChoice(color_mode_option, printing::kMonochrome)) |
+ *color_model_for_black = printing::COLORMODE_MONOCHROME; |
+ |
+ ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); |
+ if (!mode_choice) { |
+ mode_choice = ppdFindChoice(color_mode_option, |
+ color_mode_option->defchoice); |
+ } |
+ |
+ if (mode_choice) { |
+ *color_is_default = |
+ (base::strcasecmp(mode_choice->choice, printing::kColor) == 0); |
+ } |
+ return true; |
+} |
+ |
+bool getHPColorSettings( |
+ ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
+ bool* color_is_default) { |
+ // HP printers use "Color/Color Model" attribute in their ppds. |
+ ppd_option_t* color_mode_option = ppdFindOption(ppd, printing::kColor); |
+ if (!color_mode_option) |
+ return false; |
+ |
+ if (ppdFindChoice(color_mode_option, printing::kColor)) |
+ *color_model_for_color = printing::HP_COLOR_COLOR; |
+ if (ppdFindChoice(color_mode_option, printing::kBlack)) |
+ *color_model_for_black = printing::HP_COLOR_BLACK; |
+ |
+ ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); |
+ if (!mode_choice) { |
+ mode_choice = ppdFindChoice(color_mode_option, |
+ color_mode_option->defchoice); |
+ } |
+ if (mode_choice) { |
+ *color_is_default = |
+ (base::strcasecmp(mode_choice->choice, printing::kColor) == 0); |
+ } |
+ return true; |
+} |
+ |
+bool getProcessColorModelSettings( |
+ ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
+ bool* color_is_default) { |
+ // Canon printers use "ProcessColorModel" attribute in their ppds. |
+ ppd_option_t* color_mode_option = ppdFindOption(ppd, kProcessColorModel); |
+ if (!color_mode_option) |
+ return false; |
+ |
+ if (ppdFindChoice(color_mode_option, printing::kRGB)) |
+ *color_model_for_color = printing::PROCESSCOLORMODEL_RGB; |
+ else if (ppdFindChoice(color_mode_option, printing::kCMYK)) |
+ *color_model_for_color = printing::PROCESSCOLORMODEL_CMYK; |
+ |
+ if (ppdFindChoice(color_mode_option, printing::kGreyscale)) |
+ *color_model_for_black = printing::PROCESSCOLORMODEL_GREYSCALE; |
+ |
+ ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kProcessColorModel); |
+ if (!mode_choice) { |
+ mode_choice = ppdFindChoice(color_mode_option, |
+ color_mode_option->defchoice); |
+ } |
+ |
+ if (mode_choice) { |
+ *color_is_default = |
+ (base::strcasecmp(mode_choice->choice, printing::kGreyscale) != 0); |
+ } |
+ return true; |
+} |
+ |
+bool getColorModelSettings( |
+ ppd_file_t* ppd, int* cm_black, int* cm_color, bool* is_color) { |
+ bool is_color_device = false; |
+ ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, NULL); |
+ if (attr && attr->value) |
+ is_color_device = ppd->color_device; |
+ |
+ *is_color = is_color_device; |
+ if (!((is_color_device && |
+ getBasicColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) || |
+ getPrintOutModeColorSettings(ppd, &cm_black, &cm_color, &is_color) || |
+ getColorModeSettings(ppd, &cm_black, &cm_color, &is_color) || |
+ getHPColorSettings(ppd, &cm_black, &cm_color, &is_color) || |
+ getProcessColorModelSettings(ppd, &cm_black, &cm_color, &is_color))) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+bool parsePpdPrinterCapabilities( |
+ const std::string& printer_capabilities, |
+ printing_internal::PrinterSemanticCapsAndDefaults* printer_info) { |
+ FilePath ppd_file_path; |
+ if (!file_util::CreateTemporaryFile(&ppd_file_path)) |
+ return false; |
+ |
+ int data_size = printer_capabilities.length(); |
+ if (data_size != file_util::WriteFile( |
+ ppd_file_path, |
+ printer_capabilities.data(), |
+ data_size)) { |
+ file_util::Delete(ppd_file_path, false); |
+ return false; |
+ } |
+ |
+ ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str()); |
+ if (!ppd) |
+ return false; |
+ |
+ PrinterSemanticCapsAndDefaults caps; |
+#if !defined(OS_MACOSX) |
+ printing_internal::mark_lpoptions(printer_name, &ppd); |
+#endif |
+ ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex); |
+ if (!duplex_choice) { |
+ ppd_option_t* option = ppdFindOption(ppd, kDuplex); |
+ if (option) |
+ duplex_choice = ppdFindChoice(option, option->defchoice); |
+ } |
+ |
+ if (duplex_choice) { |
+ caps.duplex_capable = true; |
+ if (base::strcasecmp(duplex_choice->choice, kDuplexNone) != 0) |
+ caps.duplex_default = printing::LONG_EDGE; |
+ else |
+ caps.duplex_default = printing::SIMPLEX; |
+ } |
+ |
+ bool is_color = false; |
+ int cm_color = 0, cm_black = 0; |
+ if (!getColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) { |
+ VLOG(1) << "Unknown printer color model"; |
+ } |
+ |
+ caps.color_capable = (cm_color && cm_black && (cm_color != cm_black)); |
+ caps.color_default = is_color; |
+ |
+ ppdClose(ppd); |
+ file_util::Delete(ppd_file_path, false); |
+ |
+ *printer_info = caps; |
+ return true; |
+} |
+} // namespace |
+ |
namespace printing { |
static const char kCUPSPrinterInfoOpt[] = "printer-info"; |
@@ -108,6 +358,9 @@ |
// PrintBackend implementation. |
virtual bool EnumeratePrinters(PrinterList* printer_list) OVERRIDE; |
virtual std::string GetDefaultPrinterName() OVERRIDE; |
+ virtual bool GetPrinterSemanticCapsAndDefaults( |
+ const std::string& printer_name, |
+ PrinterSemanticCapsAndDefaults* printer_info) OVERRIDE; |
virtual bool GetPrinterCapsAndDefaults( |
const std::string& printer_name, |
PrinterCapsAndDefaults* printer_info) OVERRIDE; |
@@ -210,6 +463,16 @@ |
return dest ? std::string(dest->name) : std::string(); |
} |
+bool PrintBackendCUPS::GetPrinterSemanticCapsAndDefaults( |
+ const std::string& printer_name, |
+ PrinterSemanticCapsAndDefaults* printer_info) { |
+ PrinterCapsAndDefaults info; |
+ if (!GetPrinterCapsAndDefaults(printer_name, &info) ) |
+ return false; |
+ |
+ return parsePpdPrinterCapabilities(info.printer_capabilities, printer_info); |
+} |
+ |
bool PrintBackendCUPS::GetPrinterCapsAndDefaults( |
const std::string& printer_name, |
PrinterCapsAndDefaults* printer_info) { |