]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - ppdc/ppdc-import.cxx
Merge CUPS 1.4svn-r7319.
[thirdparty/cups.git] / ppdc / ppdc-import.cxx
diff --git a/ppdc/ppdc-import.cxx b/ppdc/ppdc-import.cxx
new file mode 100644 (file)
index 0000000..486f9b7
--- /dev/null
@@ -0,0 +1,283 @@
+//
+// "$Id$"
+//
+//   PPD file import methods for the CUPS PPD Compiler.
+//
+//   Copyright 2007 by Apple Inc.
+//   Copyright 2002-2006 by Easy Software Products.
+//
+//   These coded instructions, statements, and computer programs are the
+//   property of Apple Inc. and are protected by Federal copyright
+//   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+//   which should have been included with this file.  If this file is
+//   file is missing or damaged, see the license at "http://www.cups.org/".
+//
+// Contents:
+//
+//   ppdcSource::import_ppd() - Import a PPD file.
+//   ppd_gets()               - Get a line from a PPD file.
+//
+
+//
+// Include necessary headers...
+//
+
+#include "ppdc.h"
+#include <cups/ppd.h>
+
+
+//
+// 'ppdcSource::import_ppd()' - Import a PPD file.
+//
+
+int                                    // O - 1 on success, 0 on failure
+ppdcSource::import_ppd(const char *f)  // I - Filename
+{
+  int          i, j, k;                // Looping vars
+  cups_file_t  *fp;                    // File
+  char         line[256],              // Comment line
+               *ptr;                   // Pointer into line
+  ppd_file_t   *ppd;                   // PPD file data
+  ppd_group_t  *group;                 // PPD group
+  ppd_option_t *option;                // PPD option
+  ppd_choice_t *choice;                // PPD choice
+  ppd_attr_t   *attr;                  // PPD attribute
+  ppd_const_t  *constraint;            // PPD UI constraint
+  ppd_const_t  *constraint2;           // Temp PPD UI constraint
+  ppd_size_t   *size;                  // PPD page size
+  ppdcDriver   *driver;                // Driver
+  ppdcFont     *font;                  // Font
+  ppdcGroup    *cgroup;                // UI group
+  ppdcOption   *coption;               // UI option
+  ppdcChoice   *cchoice;               // UI choice
+  ppdcConstraint *cconstraint;         // UI constraint
+  ppdcMediaSize        *csize;                 // Media size
+
+
+  // Try opening the PPD file...
+  if ((ppd = ppdOpenFile(f)) == NULL)
+    return (0);
+
+  // All PPD files need a PCFileName attribute...
+  if (!ppd->pcfilename)
+  {
+    ppdClose(ppd);
+    return (0);
+  }
+
+  // See if the driver has already been imported...
+  if ((driver = find_driver(ppd->pcfilename)) == NULL)
+  {
+    // Create a new PPD file...
+    if ((fp = cupsFileOpen(f, "r")) == NULL)
+    {
+      ppdClose(ppd);
+      return (0);
+    }
+
+    driver       = new ppdcDriver();
+    driver->type = PPDC_DRIVER_PS;
+
+    drivers->add(driver);
+
+    // Read the initial comments from the PPD file and use them as the
+    // copyright/license text...
+    cupsFileGets(fp, line, sizeof(line));
+                                       // Skip *PPD-Adobe-M.m
+
+    while (cupsFileGets(fp, line, sizeof(line)))
+      if (strncmp(line, "*%", 2))
+        break;
+      else
+      {
+        for (ptr = line + 2; isspace(*ptr); ptr ++);
+
+        driver->add_copyright(ptr);
+      }
+
+    cupsFileClose(fp);
+
+    // Then add the stuff from the PPD file...
+    if (ppd->modelname && ppd->manufacturer &&
+        !strncasecmp(ppd->modelname, ppd->manufacturer,
+                     strlen(ppd->manufacturer)))
+    {
+      ptr = ppd->modelname + strlen(ppd->manufacturer);
+
+      while (isspace(*ptr))
+        ptr ++;
+    }
+    else
+      ptr = ppd->modelname;
+
+    driver->manufacturer  = new ppdcString(ppd->manufacturer);
+    driver->model_name    = new ppdcString(ptr);
+    driver->pc_file_name  = new ppdcString(ppd->pcfilename);
+    attr = ppdFindAttr(ppd, "FileVersion", NULL);
+    driver->version       = new ppdcString(attr ? attr->value : NULL);
+    driver->model_number  = ppd->model_number;
+    driver->manual_copies = ppd->manual_copies;
+    driver->color_device  = ppd->color_device;
+    driver->throughput    = ppd->throughput;
+
+    attr = ppdFindAttr(ppd, "DefaultFont", NULL);
+    driver->default_font  = new ppdcString(attr ? attr->value : NULL);
+
+    // Collect media sizes...
+    ppd_option_t       *region_option,         // PageRegion option
+                       *size_option;           // PageSize option
+    ppd_choice_t       *region_choice,         // PageRegion choice
+                       *size_choice;           // PageSize choice
+
+    region_option = ppdFindOption(ppd, "PageRegion");
+    size_option   = ppdFindOption(ppd, "PageSize");
+
+    for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
+    {
+      // Don't do custom size here...
+      if (!strcasecmp(size->name, "Custom"))
+        continue;
+
+      // Get the code for the PageSize and PageRegion options...
+      region_choice = ppdFindChoice(region_option, size->name);
+      size_choice   = ppdFindChoice(size_option, size->name);
+
+      // Create a new media size record and add it to the driver...
+      csize = new ppdcMediaSize(size->name, size_choice->text, size->width,
+                                size->length, size->left, size->bottom,
+                               size->width - size->right,
+                               size->length - size->top,
+                               size_choice->code, region_choice->code);
+
+       driver->add_size(csize);
+
+       if (!strcasecmp(size_option->defchoice, size->name))
+         driver->set_default_size(csize);
+    }
+
+    // Now all of the options...
+    for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
+    {
+      cgroup = new ppdcGroup(group->name, group->text);
+      driver->add_group(cgroup);
+
+      for (j = group->num_options, option = group->options; j > 0; j --, option ++)
+      {
+        if (!strcmp(option->keyword, "PageSize") || !strcmp(option->keyword, "PageRegion"))
+          continue;
+            
+        coption = new ppdcOption((ppdcOptType)option->ui, option->keyword,
+                                option->text, (ppdcOptSection)option->section,
+                                option->order);
+        cgroup->add_option(coption);
+
+        for (k = option->num_choices, choice = option->choices; k > 0; k --, choice ++)
+        {
+          cchoice = new ppdcChoice(choice->choice, choice->text, choice->code);
+          coption->add_choice(cchoice);
+
+          if (!strcasecmp(option->defchoice, choice->choice))
+            coption->set_defchoice(cchoice);
+        }
+      }
+    }
+
+    // Now the constraints...
+    for (i = ppd->num_consts, constraint = ppd->consts;
+         i > 0;
+        i --, constraint ++)
+    {
+      for (j = i - 1, constraint2 = constraint;
+           j > 0;
+          j --, constraint2 ++)
+       if (constraint != constraint2 &&
+           !strcmp(constraint->option1, constraint2->option2) &&
+           (constraint->choice1 == constraint2->choice2 ||
+            (constraint->choice1 && constraint2->choice2 &&
+             !strcmp(constraint->choice1, constraint2->choice2))) &&
+           !strcmp(constraint->option2, constraint2->option1) &&
+           (constraint->choice2 == constraint2->choice1 ||
+            (constraint->choice2 && constraint2->choice1 &&
+             !strcmp(constraint->choice2, constraint2->choice1))))
+          break;
+
+      if (j)
+        continue;
+
+      cconstraint = new ppdcConstraint(constraint->option1, constraint->choice1,
+                                       constraint->option2, constraint->choice2);
+      driver->add_constraint(cconstraint);
+    }
+
+    for (i = 0; i < ppd->num_attrs; i ++)
+    {
+      attr = ppd->attrs[i];
+
+      if (!strcmp(attr->name, "Font"))
+      {
+        // Font...
+       char            encoding[256],  // Encoding string
+                       version[256],   // Version string
+                       charset[256],   // Charset string
+                       status[256];    // Status string
+       ppdcFontStatus  fstatus;        // Status enumeration
+
+
+        if (sscanf(attr->value, "%s%*[^\"]\"%[^\"]\"%s%s", encoding, version,
+                  charset, status) != 4)
+       {
+         fprintf(stderr, "Bad font attribute: %s\n", attr->value);
+         continue;
+       }
+
+        if (!strcmp(status, "ROM"))
+         fstatus = PPDC_FONT_ROM;
+       else
+         fstatus = PPDC_FONT_DISK;
+
+        font = new ppdcFont(attr->spec, encoding, version, charset, fstatus);
+
+       driver->add_font(font);
+      }
+      else if ((strncmp(attr->name, "Default", 7) ||
+               !strcmp(attr->name, "DefaultColorSpace")) &&
+              strcmp(attr->name, "ColorDevice") &&
+              strcmp(attr->name, "Manufacturer") &&
+              strcmp(attr->name, "ModelName") &&
+              strcmp(attr->name, "MaxMediaHeight") &&
+              strcmp(attr->name, "MaxMediaWidth") &&
+              strcmp(attr->name, "NickName") &&
+              strcmp(attr->name, "ShortNickName") &&
+              strcmp(attr->name, "Throughput") &&
+              strcmp(attr->name, "PCFileName") &&
+              strcmp(attr->name, "FileVersion") &&
+              strcmp(attr->name, "FormatVersion") &&
+              strcmp(attr->name, "VariablePaperSize") &&
+              strcmp(attr->name, "LanguageEncoding") &&
+              strcmp(attr->name, "LanguageVersion"))
+      {
+        // Attribute...
+        driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text,
+                                     attr->value));
+      }
+      else if (!strncmp(attr->name, "Default", 7) &&
+               !ppdFindOption(ppd, attr->name + 7) &&
+              strcmp(attr->name, "DefaultFont") &&
+              strcmp(attr->name, "DefaultImageableArea") &&
+              strcmp(attr->name, "DefaultPaperDimension") &&
+              strcmp(attr->name, "DefaultFont"))
+      {
+        // Default attribute...
+        driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text,
+                                     attr->value));
+      }
+    }
+  }
+
+  return (1);
+}
+
+
+//
+// End of "$Id$".
+//