+ if ((ppd_attr = ppdFindAttr(ppd, "APPrinterPreset", NULL)) != NULL)
+ {
+ /*
+ * Copy and convert APPrinterPreset (output-mode + print-quality) data...
+ */
+
+ const char *quality, /* com.apple.print.preset.quality value */
+ *output_mode, /* com.apple.print.preset.output-mode value */
+ *color_model_val; /* ColorModel choice */
+
+
+ do
+ {
+ num_options = _ppdParseOptions(ppd_attr->value, 0, &options,
+ _PPD_PARSE_ALL);
+
+ if ((quality = cupsGetOption("com.apple.print.preset.quality",
+ num_options, options)) != NULL)
+ {
+ /*
+ * Get the print-quality for this preset...
+ */
+
+ if (!strcmp(quality, "low"))
+ pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT;
+ else if (!strcmp(quality, "high"))
+ pwg_print_quality = _PWG_PRINT_QUALITY_HIGH;
+ else
+ pwg_print_quality = _PWG_PRINT_QUALITY_NORMAL;
+
+ /*
+ * Get the output mode for this preset...
+ */
+
+ output_mode = cupsGetOption("com.apple.print.preset.output-mode",
+ num_options, options);
+ color_model_val = cupsGetOption("ColorModel", num_options, options);
+
+ if (output_mode)
+ {
+ if (!strcmp(output_mode, "monochrome"))
+ pwg_output_mode = _PWG_OUTPUT_MODE_MONOCHROME;
+ else
+ pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+ }
+ else if (color_model_val)
+ {
+ if (!strcasecmp(color_model_val, "Gray"))
+ pwg_output_mode = _PWG_OUTPUT_MODE_MONOCHROME;
+ else
+ pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+ }
+ else
+ pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+
+ /*
+ * Save the options for this combination as needed...
+ */
+
+ if (!pwg->num_presets[pwg_output_mode][pwg_print_quality])
+ pwg->num_presets[pwg_output_mode][pwg_print_quality] =
+ _ppdParseOptions(ppd_attr->value, 0,
+ pwg->presets[pwg_output_mode] +
+ pwg_print_quality, _PPD_PARSE_OPTIONS);
+ }
+
+ cupsFreeOptions(num_options, options);
+ }
+ while ((ppd_attr = ppdFindNextAttr(ppd, "APPrinterPreset", NULL)) != NULL);
+ }
+
+ if (!pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_DRAFT] &&
+ !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_NORMAL] &&
+ !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_HIGH] &&
+ (color_model = ppdFindOption(ppd, "ColorModel")) != NULL &&
+ ppdFindChoice(color_model, "Gray"))
+ {
+ /*
+ * Copy and convert ColorModel (output-mode) data...
+ */
+
+ cups_option_t *coption, /* Color option */
+ *moption; /* Monochrome option */
+
+ for (pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT;
+ pwg_print_quality < _PWG_PRINT_QUALITY_MAX;
+ pwg_print_quality ++)
+ {
+ if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][pwg_print_quality])
+ {
+ /*
+ * Copy the color options...
+ */
+
+ num_options = pwg->num_presets[_PWG_OUTPUT_MODE_COLOR]
+ [pwg_print_quality];
+ options = calloc(sizeof(cups_option_t), num_options);
+
+ if (options)
+ {
+ for (i = num_options, moption = options,
+ coption = pwg->presets[_PWG_OUTPUT_MODE_COLOR]
+ [pwg_print_quality];
+ i > 0;
+ i --, moption ++, coption ++)
+ {
+ moption->name = _cupsStrRetain(coption->name);
+ moption->value = _cupsStrRetain(coption->value);
+ }
+
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ num_options;
+ pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ options;
+ }
+ }
+ else if (pwg_print_quality != _PWG_PRINT_QUALITY_NORMAL)
+ continue;
+
+ /*
+ * Add ColorModel=Gray to the preset...
+ */
+
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ cupsAddOption("ColorModel", "Gray",
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME]
+ [pwg_print_quality],
+ pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME] +
+ pwg_print_quality);
+ }
+ }
+
+ /*
+ * Copy and convert Duplex (sides) data...
+ */
+
+ if ((duplex = ppdFindOption(ppd, "Duplex")) == NULL)
+ if ((duplex = ppdFindOption(ppd, "JCLDuplex")) == NULL)
+ if ((duplex = ppdFindOption(ppd, "EFDuplex")) == NULL)
+ if ((duplex = ppdFindOption(ppd, "EFDuplexing")) == NULL)
+ duplex = ppdFindOption(ppd, "KD03Duplex");
+
+ if (duplex)
+ {
+ pwg->sides_option = _cupsStrAlloc(duplex->keyword);
+
+ for (i = duplex->num_choices, choice = duplex->choices;
+ i > 0;
+ i --, choice ++)
+ {
+ if ((!strcasecmp(choice->choice, "None") ||
+ !strcasecmp(choice->choice, "False")) && !pwg->sides_1sided)
+ pwg->sides_1sided = _cupsStrAlloc(choice->choice);
+ else if ((!strcasecmp(choice->choice, "DuplexNoTumble") ||
+ !strcasecmp(choice->choice, "LongEdge") ||
+ !strcasecmp(choice->choice, "Top")) && !pwg->sides_2sided_long)
+ pwg->sides_2sided_long = _cupsStrAlloc(choice->choice);
+ else if ((!strcasecmp(choice->choice, "DuplexTumble") ||
+ !strcasecmp(choice->choice, "ShortEdge") ||
+ !strcasecmp(choice->choice, "Bottom")) &&
+ !pwg->sides_2sided_short)
+ pwg->sides_2sided_short = _cupsStrAlloc(choice->choice);
+ }
+ }
+