]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - ppdc/ppdc-driver.cxx
Merge changes from CUPS 1.5svn-r8849.
[thirdparty/cups.git] / ppdc / ppdc-driver.cxx
index 2321000a2ea71974cf31204cea4231e536b1892e..f720e0bf045b656221f84a76e6089a45536ef978 100644 (file)
 //
 // Contents:
 //
-//   ppdcDriver::ppdcDriver()       - Create a new printer driver.
-//   ppdcDriver::~ppdcDriver()      - Destroy a printer driver.
-//   ppdcDriver::find_attr()        - Find an attribute.
-//   ppdcDriver::find_group()       - Find a group.
-//   ppdcDriver::find_option()      - Find an option.
-//   ppdcDriver::set_default_size() - Set the default size name.
-//   ppdcDriver::set_file_name()    - Set the full filename.
-//   ppdcDriver::set_manufacturer() - Set the manufacturer name.
-//   ppdcDriver::set_model_name()   - Set the model name.
-//   ppdcDriver::set_pc_file_name() - Set the PC filename.
-//   ppdcDriver::set_version()      - Set the version string.
-//   ppdcDriver::write_ppd_file()   - Write a PPD file...
+//   ppdcDriver::ppdcDriver()           - Create a new printer driver.
+//   ppdcDriver::~ppdcDriver()          - Destroy a printer driver.
+//   ppdcDriver::find_attr()            - Find an attribute.
+//   ppdcDriver::find_group()           - Find a group.
+//   ppdcDriver::find_option()          - Find an option.
+//   ppdcDriver::find_option_group()    - Find an option and its group.
+//   ppdcDriver::set_custom_size_code() - Set the custom page size code.
+//   ppdcDriver::set_default_font()     - Set the default font name.
+//   ppdcDriver::set_default_size()     - Set the default size name.
+//   ppdcDriver::set_file_name()        - Set the full filename.
+//   ppdcDriver::set_manufacturer()     - Set the manufacturer name.
+//   ppdcDriver::set_model_name()       - Set the model name.
+//   ppdcDriver::set_pc_file_name()     - Set the PC filename.
+//   ppdcDriver::set_version()          - Set the version string.
+//   ppdcDriver::write_ppd_file()       - Write a PPD file...
 //
 
 //
 // Include necessary headers...
 //
 
-#include "ppdc.h"
+#include "ppdc-private.h"
 #include <cups/globals.h>
 
 
 //
 
 ppdcDriver::ppdcDriver(ppdcDriver *d)  // I - Printer driver template
+  : ppdcShared()
 {
   ppdcGroup    *g;                     // Current group
 
 
+  PPDC_NEW;
+
   if (d)
   {
     // Bump the use count of any strings we inherit...
@@ -140,6 +146,8 @@ ppdcDriver::ppdcDriver(ppdcDriver *d)       // I - Printer driver template
 
 ppdcDriver::~ppdcDriver()
 {
+  PPDC_DELETE;
+
   copyright->release();
 
   if (manufacturer)
@@ -183,7 +191,7 @@ ppdcDriver::find_attr(const char *k,        // I - Keyword string
   for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
     if (!strcmp(a->name->value, k) &&
         ((!s && (!a->selector->value || !a->selector->value[0])) ||
-        (!s && !a->selector->value && !strcmp(a->selector->value, s))))
+        (s && a->selector->value && !strcmp(a->selector->value, s))))
       return (a);
 
   return (NULL);
@@ -214,6 +222,19 @@ ppdcDriver::find_group(const char *n)      // I - Group name
 
 ppdcOption *                           // O - Matching option or NULL
 ppdcDriver::find_option(const char *n) // I - Option name
+{
+  return (find_option_group(n, (ppdcGroup **)0));
+}
+
+
+//
+// 'ppdcDriver::find_option_group()' - Find an option and its group.
+//
+
+ppdcOption *                           // O - Matching option or NULL
+ppdcDriver::find_option_group(
+    const char *n,                     // I - Option name
+    ppdcGroup  **mg)                   // O - Matching group or NULL
 {
   ppdcGroup    *g;                     // Current group
   ppdcOption   *o;                     // Current option
@@ -222,7 +243,15 @@ ppdcDriver::find_option(const char *n)     // I - Option name
   for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
     for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next())
       if (!strcasecmp(n, o->name->value))
+      {
+        if (mg)
+         *mg = g;
+
         return (o);
+      }
+
+  if (mg)
+    *mg = (ppdcGroup *)0;
 
   return (0);
 }
@@ -371,7 +400,8 @@ ppdcDriver::write_ppd_file(
     ppdcLineEnding le)                 // I - Line endings to use
 {
   bool                 delete_cat;     // Delete the catalog when we are done?
-  char                 query[42];      // Query attribute
+  char                 query[42],      // Query attribute
+                       custom[42];     // Custom attribute
   ppdcString           *s;             // Copyright string
   ppdcGroup            *g;             // Current group
   ppdcOption           *o;             // Current option
@@ -405,10 +435,11 @@ ppdcDriver::write_ppd_file(
 
   // Write the standard header stuff...
   cupsFilePrintf(fp, "*PPD-Adobe: \"4.3\"%s", lf);
-  cupsFilePrintf(fp, "*%% PPD file for %s with CUPS.%s", model_name->value, lf);
+  cupsFilePrintf(fp, "*%%%%%%%% PPD file for %s with CUPS.%s",
+                 model_name->value, lf);
   cupsFilePrintf(fp,
-                 "*%% Created by the CUPS PPD Compiler " CUPS_SVERSION ".%s",
-                lf);
+                 "*%%%%%%%% Created by the CUPS PPD Compiler " CUPS_SVERSION
+                ".%s", lf);
   for (s = (ppdcString *)copyright->first();
        s;
        s = (ppdcString *)copyright->next())
@@ -523,6 +554,8 @@ ppdcDriver::write_ppd_file(
   else if (type != PPDC_DRIVER_PS)
     cupsFilePrintf(fp, "*TTRasterizer: Type42%s", lf);
 
+  struct lconv *loc = localeconv();
+
   if (attrs->count)
   {
     // Write driver-defined attributes...
@@ -552,6 +585,14 @@ ppdcDriver::write_ppd_file(
           !strcmp(a->name->value, "?PaperDimension")))
         continue;
 
+      if (!strncmp(a->name->value, "Custom", 6) &&
+          find_option(a->name->value + 6))
+       continue;
+
+      if (!strncmp(a->name->value, "ParamCustom", 11) &&
+          find_option(a->name->value + 11))
+       continue;
+
       if (!a->selector->value || !a->selector->value[0])
        cupsFilePrintf(fp, "*%s", a->name->value);
       else if (!a->text->value || !a->text->value[0])
@@ -572,7 +613,7 @@ ppdcDriver::write_ppd_file(
       {
        cupsFilePrintf(fp, ": \"%s\"%s", a->value->value, lf);
 
-       if (strchr(a->value->value, '\n'))
+       if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r'))
           cupsFilePrintf(fp, "*End%s", lf);
       }
       else
@@ -640,16 +681,23 @@ ppdcDriver::write_ppd_file(
     for (p = (ppdcProfile *)profiles->first();
          p;
         p = (ppdcProfile *)profiles->next())
+    {
+      char density[255], gamma[255], profile[9][255];
+
+      _cupsStrFormatd(density, density + sizeof(density), p->density, loc);
+      _cupsStrFormatd(gamma, gamma + sizeof(gamma), p->gamma, loc);
+
+      for (int i = 0; i < 9; i ++)
+       _cupsStrFormatd(profile[i], profile[i] + sizeof(profile[0]),
+                       p->profile[i], loc);
+      
       cupsFilePrintf(fp,
-                     "*cupsColorProfile %s/%s: \"%.3f %.3f %.3f %.3f %.3f %.3f "
-                    "%.3f %.3f %.3f %.3f %.3f\"%s",
-                    p->resolution->value, p->media_type->value,
-                    p->density, p->gamma,
-                    p->profile[0], p->profile[1],
-                    p->profile[2], p->profile[3],
-                    p->profile[4], p->profile[5],
-                    p->profile[6], p->profile[7],
-                    p->profile[8], lf);
+                     "*cupsColorProfile %s/%s: \"%s %s %s %s %s %s %s %s %s %s "
+                    "%s\"%s", p->resolution->value, p->media_type->value,
+                    density, gamma, profile[0], profile[1], profile[2],
+                    profile[3], profile[4], profile[5], profile[6], profile[7],
+                    profile[8], lf);
+    }
   }
 
   if (locales)
@@ -681,7 +729,7 @@ ppdcDriver::write_ppd_file(
          // No, skip this one...
           _cupsLangPrintf(stderr,
                          _("ppdc: No message catalog provided for locale "
-                           "%s!\n"), locale->value);
+                           "%s\n"), locale->value);
           continue;
        }
 
@@ -832,13 +880,21 @@ ppdcDriver::write_ppd_file(
   cupsFilePrintf(fp, "*DefaultImageableArea: %s%s",
                  default_size ? default_size->value : "Letter", lf);
 
+  char left[255], right[255], bottom[255], top[255];
+
   for (m = (ppdcMediaSize *)sizes->first();
        m;
        m = (ppdcMediaSize *)sizes->next())
-    cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%.2f %.2f %.2f %.2f\"%s",
+  {
+    _cupsStrFormatd(left, left + sizeof(left), m->left, loc);
+    _cupsStrFormatd(bottom, bottom + sizeof(bottom), m->bottom, loc);
+    _cupsStrFormatd(right, right + sizeof(right), m->width - m->right, loc);
+    _cupsStrFormatd(top, top + sizeof(top), m->length - m->top, loc);
+
+    cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%s %s %s %s\"%s",
                    m->name->value, catalog->find_message(m->text->value),
-                  m->left, m->bottom, m->width - m->right, m->length - m->top,
-                  lf);
+                  left, bottom, right, top, lf);
+  }
 
   if ((a = find_attr("?ImageableArea", NULL)) != NULL)
   {
@@ -853,12 +909,19 @@ ppdcDriver::write_ppd_file(
   cupsFilePrintf(fp, "*DefaultPaperDimension: %s%s",
                  default_size ? default_size->value : "Letter", lf);
 
+  char width[255], length[255];
+
   for (m = (ppdcMediaSize *)sizes->first();
        m;
        m = (ppdcMediaSize *)sizes->next())
-    cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%.2f %.2f\"%s",
+  {
+    _cupsStrFormatd(width, width + sizeof(width), m->width, loc);
+    _cupsStrFormatd(length, length + sizeof(length), m->length, loc);
+
+    cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%s %s\"%s",
                    m->name->value, catalog->find_message(m->text->value),
-                  m->width, m->length, lf);
+                  width, length, lf);
+  }
 
   if ((a = find_attr("?PaperDimension", NULL)) != NULL)
   {
@@ -872,10 +935,18 @@ ppdcDriver::write_ppd_file(
   // Custom size support...
   if (variable_paper_size)
   {
-    cupsFilePrintf(fp, "*MaxMediaWidth: \"%.2f\"%s", max_width, lf);
-    cupsFilePrintf(fp, "*MaxMediaHeight: \"%.2f\"%s", max_length, lf);
-    cupsFilePrintf(fp, "*HWMargins: %.2f %.2f %.2f %.2f\n",
-                  left_margin, bottom_margin, right_margin, top_margin);
+    _cupsStrFormatd(width, width + sizeof(width), max_width, loc);
+    _cupsStrFormatd(length, length + sizeof(length), max_length, loc);
+
+    _cupsStrFormatd(left, left + sizeof(left), left_margin, loc);
+    _cupsStrFormatd(bottom, bottom + sizeof(bottom), bottom_margin, loc);
+    _cupsStrFormatd(right, right + sizeof(right), right_margin, loc);
+    _cupsStrFormatd(top, top + sizeof(top), top_margin, loc);
+
+    cupsFilePrintf(fp, "*MaxMediaWidth: \"%s\"%s", width, lf);
+    cupsFilePrintf(fp, "*MaxMediaHeight: \"%s\"%s", length, lf);
+    cupsFilePrintf(fp, "*HWMargins: %s %s %s %s%s", left, bottom, right, top,
+                   lf);
 
     if (custom_size_code && custom_size_code->value)
     {
@@ -895,15 +966,29 @@ ppdcDriver::write_ppd_file(
       cupsFilePrintf(fp, "*ParamCustomPageSize Width: %s%s", a->value->value,
                     lf);
     else
-      cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %.2f %.2f%s",
-                     min_width, max_width, lf);
+    {
+      char width0[255];
+
+      _cupsStrFormatd(width0, width0 + sizeof(width0), min_width, loc);
+      _cupsStrFormatd(width, width + sizeof(width), max_width, loc);
+
+      cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s%s",
+                     width0, width, lf);
+    }
 
     if ((a = find_attr("ParamCustomPageSize", "Height")) != NULL)
       cupsFilePrintf(fp, "*ParamCustomPageSize Height: %s%s", a->value->value,
                     lf);
     else
-      cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %.2f %.2f%s",
-                     min_length, max_length, lf);
+    {
+      char length0[255];
+
+      _cupsStrFormatd(length0, length0 + sizeof(length0), min_length, loc);
+      _cupsStrFormatd(length, length + sizeof(length), max_length, loc);
+
+      cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s%s",
+                     length0, length, lf);
+    }
 
     if ((a = find_attr("ParamCustomPageSize", "WidthOffset")) != NULL)
       cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: %s%s",
@@ -924,9 +1009,6 @@ ppdcDriver::write_ppd_file(
       cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: 5 int 0 0%s", lf);
   }
 
-  if (type != PPDC_DRIVER_PS && !find_attr("RequiresPageRegion", NULL))
-    cupsFilePrintf(fp, "*RequiresPageRegion All: True%s", lf);
-
   // All other options...
   for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next())
   {
@@ -964,7 +1046,10 @@ ppdcDriver::write_ppd_file(
            break;
       }
 
-      cupsFilePrintf(fp, "*OrderDependency: %.1f ", o->order);
+      char order[255];
+      _cupsStrFormatd(order, order + sizeof(order), o->order, loc);
+
+      cupsFilePrintf(fp, "*OrderDependency: %s ", order);
       switch (o->section)
       {
         default :
@@ -1027,7 +1112,7 @@ ppdcDriver::write_ppd_file(
 
       if ((a = find_attr(query, NULL)) != NULL)
       {
-       cupsFilePrintf(fp, "*%s: \"%s\"\n", query, a->value->value);
+       cupsFilePrintf(fp, "*%s: \"%s\"%s", query, a->value->value, lf);
 
        if (strchr(a->value->value, '\n') ||
             strchr(a->value->value, '\r'))
@@ -1035,6 +1120,32 @@ ppdcDriver::write_ppd_file(
       }
 
       cupsFilePrintf(fp, "*CloseUI: *%s%s", o->name->value, lf);
+
+      snprintf(custom, sizeof(custom), "Custom%s", o->name->value);
+      if ((a = find_attr(custom, "True")) != NULL)
+      {
+        // Output custom option information...
+        cupsFilePrintf(fp, "*%s True: \"%s\"%s", custom, a->value->value, lf);
+       if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r'))
+         cupsFilePrintf(fp, "*End%s", lf);
+
+        snprintf(custom, sizeof(custom), "ParamCustom%s", o->name->value);
+       for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next())
+       {
+         if (strcmp(a->name->value, custom))
+           continue;
+
+         if (!a->selector->value || !a->selector->value[0])
+           cupsFilePrintf(fp, "*%s", a->name->value);
+         else if (!a->text->value || !a->text->value[0])
+           cupsFilePrintf(fp, "*%s %s", a->name->value, a->selector->value);
+         else
+           cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value,
+                          a->text->value);
+
+          cupsFilePrintf(fp, ": %s%s", a->value->value, lf);
+       }
+      }
     }
 
     if (strcasecmp(g->name->value, "General"))