Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

src/main/print-ps.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: print-ps.c,v 1.78 2004/06/13 14:34:16 rlk Exp $"
00003  *
00004  *   Print plug-in Adobe PostScript driver for the GIMP.
00005  *
00006  *   Copyright 1997-2002 Michael Sweet (mike@easysw.com) and
00007  *      Robert Krawitz (rlk@alum.mit.edu)
00008  *
00009  *   This program is free software; you can redistribute it and/or modify it
00010  *   under the terms of the GNU General Public License as published by the Free
00011  *   Software Foundation; either version 2 of the License, or (at your option)
00012  *   any later version.
00013  *
00014  *   This program is distributed in the hope that it will be useful, but
00015  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00016  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017  *   for more details.
00018  *
00019  *   You should have received a copy of the GNU General Public License
00020  *   along with this program; if not, write to the Free Software
00021  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00022  */
00023 
00024 /*
00025  * This file must include only standard C header files.  The core code must
00026  * compile on generic platforms that don't support glib, gimp, gtk, etc.
00027  */
00028 
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 #include <gimp-print/gimp-print.h>
00033 #include <gimp-print/gimp-print-intl-internal.h>
00034 #include "gimp-print-internal.h"
00035 #include <time.h>
00036 #include <string.h>
00037 #ifdef HAVE_LIMITS_H
00038 #include <limits.h>
00039 #endif
00040 #include <stdio.h>
00041 
00042 #ifdef _MSC_VER
00043 #define strncasecmp(s,t,n) _strnicmp(s,t,n)
00044 #define strcasecmp(s,t) _stricmp(s,t)
00045 #endif
00046 
00047 /*
00048  * Local variables...
00049  */
00050 
00051 static FILE     *ps_ppd = NULL;
00052 static const char       *ps_ppd_file = NULL;
00053 
00054 
00055 /*
00056  * Local functions...
00057  */
00058 
00059 static void     ps_hex(const stp_vars_t *, unsigned short *, int);
00060 static void     ps_ascii85(const stp_vars_t *, unsigned short *, int, int);
00061 static char     *ppd_find(const char *, const char *, const char *, int *);
00062 
00063 static const stp_parameter_t the_parameters[] =
00064 {
00065   {
00066     "PageSize", N_("Page Size"), N_("Basic Printer Setup"),
00067     N_("Size of the paper being printed to"),
00068     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
00069     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00070   },
00071   {
00072     "MediaType", N_("Media Type"), N_("Basic Printer Setup"),
00073     N_("Type of media (plain paper, photo paper, etc.)"),
00074     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00075     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00076   },
00077   {
00078     "InputSlot", N_("Media Source"), N_("Basic Printer Setup"),
00079     N_("Source (input slot) of the media"),
00080     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00081     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00082   },
00083   {
00084     "Resolution", N_("Resolution"), N_("Basic Printer Setup"),
00085     N_("Resolution and quality of the print"),
00086     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00087     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00088   },
00089   {
00090     "InkType", N_("Ink Type"), N_("Advanced Printer Setup"),
00091     N_("Type of ink in the printer"),
00092     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00093     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00094   },
00095   {
00096     "PPDFile", N_("PPDFile"), N_("Basic Printer Setup"),
00097     N_("PPD File"),
00098     STP_PARAMETER_TYPE_FILE, STP_PARAMETER_CLASS_FEATURE,
00099     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00100   },
00101   {
00102     "PrintingMode", N_("Printing Mode"), N_("Core Parameter"),
00103     N_("Printing Output Mode"),
00104     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
00105     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00106   },
00107 };
00108 
00109 static const int the_parameter_count =
00110 sizeof(the_parameters) / sizeof(const stp_parameter_t);
00111 
00112 /*
00113  * 'ps_parameters()' - Return the parameter values for the given parameter.
00114  */
00115 
00116 static stp_parameter_list_t
00117 ps_list_parameters(const stp_vars_t *v)
00118 {
00119   stp_parameter_list_t *ret = stp_parameter_list_create();
00120   int i;
00121   for (i = 0; i < the_parameter_count; i++)
00122     stp_parameter_list_add_param(ret, &(the_parameters[i]));
00123   return ret;
00124 }
00125 
00126 static void
00127 ps_parameters_internal(const stp_vars_t *v, const char *name,
00128                        stp_parameter_t *description)
00129 {
00130   int           i;
00131   char          line[1024],
00132                 lname[255],
00133                 loption[255],
00134                 *ltext;
00135   const char *ppd_file = stp_get_file_parameter(v, "PPDFile");
00136   description->p_type = STP_PARAMETER_TYPE_INVALID;
00137   description->deflt.str = 0;
00138 
00139   if (name == NULL)
00140     return;
00141 
00142   if (ppd_file != NULL && strlen(ppd_file) > 0 &&
00143       (ps_ppd_file == NULL || strcmp(ps_ppd_file, ppd_file) != 0))
00144   {
00145     if (ps_ppd != NULL)
00146       fclose(ps_ppd);
00147 
00148     ps_ppd = fopen(ppd_file, "r");
00149 
00150     if (ps_ppd == NULL)
00151       ps_ppd_file = NULL;
00152     else
00153       ps_ppd_file = ppd_file;
00154   }
00155 
00156   for (i = 0; i < the_parameter_count; i++)
00157     if (strcmp(name, the_parameters[i].name) == 0)
00158       {
00159         stp_fill_parameter_settings(description, &(the_parameters[i]));
00160         break;
00161       }
00162 
00163   if (strcmp(name, "PrintingMode") == 0)
00164     {
00165       description->bounds.str = stp_string_list_create();
00166       stp_string_list_add_string
00167         (description->bounds.str, "Color", _("Color"));
00168       stp_string_list_add_string
00169         (description->bounds.str, "BW", _("Black and White"));
00170       description->deflt.str =
00171         stp_string_list_param(description->bounds.str, 0)->name;
00172       return;
00173     }
00174 
00175   if (ps_ppd == NULL)
00176     {
00177       if (strcmp(name, "PageSize") == 0)
00178         {
00179           int papersizes = stp_known_papersizes();
00180           description->bounds.str = stp_string_list_create();
00181           for (i = 0; i < papersizes; i++)
00182             {
00183               const stp_papersize_t *pt = stp_get_papersize_by_index(i);
00184               if (strlen(pt->name) > 0)
00185                 stp_string_list_add_string
00186                   (description->bounds.str, pt->name, pt->text);
00187             }
00188           description->deflt.str =
00189             stp_string_list_param(description->bounds.str, 0)->name;
00190           description->is_active = 1;
00191         }
00192       else
00193         description->is_active = 0;
00194       return;
00195     }
00196 
00197   rewind(ps_ppd);
00198   description->bounds.str = stp_string_list_create();
00199 
00200   while (fgets(line, sizeof(line), ps_ppd) != NULL)
00201   {
00202     if (line[0] != '*')
00203       continue;
00204 
00205     if (sscanf(line, "*%s %[^:]", lname, loption) != 2)
00206       continue;
00207 
00208     if (strcasecmp(lname, name) == 0)
00209     {
00210       if ((ltext = strchr(loption, '/')) != NULL)
00211         *ltext++ = '\0';
00212       else
00213         ltext = loption;
00214 
00215       stp_string_list_add_string(description->bounds.str, loption, ltext);
00216     }
00217   }
00218 
00219   if (stp_string_list_count(description->bounds.str) > 0)
00220     description->deflt.str =
00221       stp_string_list_param(description->bounds.str, 0)->name;
00222   else
00223     description->is_active = 0;
00224   return;
00225 }
00226 
00227 static void
00228 ps_parameters(const stp_vars_t *v, const char *name,
00229               stp_parameter_t *description)
00230 {
00231   setlocale(LC_ALL, "C");
00232   ps_parameters_internal(v, name, description);
00233   setlocale(LC_ALL, "");
00234 }
00235 
00236 /*
00237  * 'ps_media_size()' - Return the size of the page.
00238  */
00239 
00240 static void
00241 ps_media_size_internal(const stp_vars_t *v,             /* I */
00242                        int  *width,             /* O - Width in points */
00243                        int  *height)            /* O - Height in points */
00244 {
00245   char  *dimensions;                    /* Dimensions of media size */
00246   const char *pagesize = stp_get_string_parameter(v, "PageSize");
00247   const char *ppd_file_name = stp_get_file_parameter(v, "PPDFile");
00248   float fwidth, fheight;
00249   if (!pagesize)
00250     pagesize = "";
00251 
00252   stp_dprintf(STP_DBG_PS, v,
00253               "ps_media_size(%d, \'%s\', \'%s\', %p, %p)\n",
00254               stp_get_model_id(v), ppd_file_name, pagesize,
00255               (void *) width, (void *) height);
00256 
00257   if ((dimensions = ppd_find(ppd_file_name, "PaperDimension", pagesize, NULL))
00258       != NULL)
00259     {
00260       sscanf(dimensions, "%f%f", &fwidth, &fheight);
00261       *width = fwidth;
00262       *height = fheight;
00263       stp_dprintf(STP_DBG_PS, v, "dimensions '%s' %f %f %d %d\n",
00264                   dimensions, fwidth, fheight, *width, *height);
00265     }
00266   else
00267     stp_default_media_size(v, width, height);
00268 }
00269 
00270 static void
00271 ps_media_size(const stp_vars_t *v, int *width, int *height)
00272 {
00273   setlocale(LC_ALL, "C");
00274   ps_media_size_internal(v, width, height);
00275   setlocale(LC_ALL, "");
00276 }
00277 
00278 /*
00279  * 'ps_imageable_area()' - Return the imageable area of the page.
00280  */
00281 
00282 static void
00283 ps_imageable_area_internal(const stp_vars_t *v,      /* I */
00284                            int  *left,  /* O - Left position in points */
00285                            int  *right, /* O - Right position in points */
00286                            int  *bottom, /* O - Bottom position in points */
00287                            int  *top)   /* O - Top position in points */
00288 {
00289   char  *area;                          /* Imageable area of media */
00290   float fleft,                          /* Floating point versions */
00291         fright,
00292         fbottom,
00293         ftop;
00294   int width, height;
00295   const char *pagesize = stp_get_string_parameter(v, "PageSize");
00296   if (!pagesize)
00297     pagesize = "";
00298   ps_media_size(v, &width, &height);
00299 
00300   if ((area = ppd_find(stp_get_file_parameter(v, "PPDFile"),
00301                        "ImageableArea", pagesize, NULL))
00302       != NULL)
00303     {
00304       stp_dprintf(STP_DBG_PS, v, "area = \'%s\'\n", area);
00305       if (sscanf(area, "%f%f%f%f", &fleft, &fbottom, &fright, &ftop) == 4)
00306         {
00307           *left   = (int)fleft;
00308           *right  = (int)fright;
00309           *bottom = height - (int)fbottom;
00310           *top    = height - (int)ftop;
00311         }
00312       else
00313         *left = *right = *bottom = *top = 0;
00314       stp_dprintf(STP_DBG_PS, v, "l %d r %d b %d t %d h %d w %d\n",
00315                   *left, *right, *bottom, *top, width, height);
00316     }
00317   else
00318     {
00319       *left   = 18;
00320       *right  = width - 18;
00321       *top    = 36;
00322       *bottom = height - 36;
00323     }
00324 }
00325 
00326 static void
00327 ps_imageable_area(const stp_vars_t *v,      /* I */
00328                   int  *left,           /* O - Left position in points */
00329                   int  *right,          /* O - Right position in points */
00330                   int  *bottom,         /* O - Bottom position in points */
00331                   int  *top)            /* O - Top position in points */
00332 {
00333   setlocale(LC_ALL, "C");
00334   ps_imageable_area_internal(v, left, right, bottom, top);
00335   setlocale(LC_ALL, "");
00336 }
00337 
00338 static void
00339 ps_limit(const stp_vars_t *v,           /* I */
00340          int *width,
00341          int *height,
00342          int *min_width,
00343          int *min_height)
00344 {
00345   *width =      INT_MAX;
00346   *height =     INT_MAX;
00347   *min_width =  1;
00348   *min_height = 1;
00349 }
00350 
00351 /*
00352  * This is really bogus...
00353  */
00354 static void
00355 ps_describe_resolution_internal(const stp_vars_t *v, int *x, int *y)
00356 {
00357   const char *resolution = stp_get_string_parameter(v, "Resolution");
00358   *x = -1;
00359   *y = -1;
00360   if (resolution)
00361     sscanf(resolution, "%dx%d", x, y);
00362   return;
00363 }
00364 
00365 static void
00366 ps_describe_resolution(const stp_vars_t *v, int *x, int *y)
00367 {
00368   setlocale(LC_ALL, "C");
00369   ps_describe_resolution_internal(v, x, y);
00370   setlocale(LC_ALL, "");
00371 }
00372 
00373 static const char *
00374 ps_describe_output(const stp_vars_t *v)
00375 {
00376   const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
00377   if (print_mode && strcmp(print_mode, "Color") == 0)
00378     return "RGB";
00379   else
00380     return "Whitescale";
00381 }
00382 
00383 /*
00384  * 'ps_print()' - Print an image to a PostScript printer.
00385  */
00386 
00387 static int
00388 ps_print_internal(const stp_vars_t *v, stp_image_t *image)
00389 {
00390   int           status = 1;
00391   int           model = stp_get_model_id(v);
00392   const char    *ppd_file = stp_get_file_parameter(v, "PPDFile");
00393   const char    *resolution = stp_get_string_parameter(v, "Resolution");
00394   const char    *media_size = stp_get_string_parameter(v, "PageSize");
00395   const char    *media_type = stp_get_string_parameter(v, "MediaType");
00396   const char    *media_source = stp_get_string_parameter(v, "InputSlot");
00397   const char    *print_mode = stp_get_string_parameter(v, "PrintingMode");
00398   unsigned short *out = NULL;
00399   int           top = stp_get_top(v);
00400   int           left = stp_get_left(v);
00401   int           i, j;           /* Looping vars */
00402   int           y;              /* Looping vars */
00403   int           page_left,      /* Left margin of page */
00404                 page_right,     /* Right margin of page */
00405                 page_top,       /* Top of page */
00406                 page_bottom,    /* Bottom of page */
00407                 page_width,     /* Width of page */
00408                 page_height,    /* Height of page */
00409                 out_width,      /* Width of image on page */
00410                 out_height,     /* Height of image on page */
00411                 out_channels,   /* Output bytes per pixel */
00412                 out_ps_height,  /* Output height (Level 2 output) */
00413                 out_offset;     /* Output offset (Level 2 output) */
00414   time_t        curtime;        /* Current time of day */
00415   unsigned      zero_mask;
00416   char          *command;       /* PostScript command */
00417   const char    *temp;          /* Temporary string pointer */
00418   int           order,          /* Order of command */
00419                 num_commands;   /* Number of commands */
00420   struct                        /* PostScript commands... */
00421   {
00422     const char  *keyword, *choice;
00423     char        *command;
00424     int         order;
00425   }             commands[4];
00426   int           image_height,
00427                 image_width;
00428   stp_vars_t    *nv = stp_vars_create_copy(v);
00429   if (!resolution)
00430     resolution = "";
00431   if (!media_size)
00432     media_size = "";
00433   if (!media_type)
00434     media_type = "";
00435   if (!media_source)
00436     media_source = "";
00437 
00438   stp_prune_inactive_options(nv);
00439   if (!stp_verify(nv))
00440     {
00441       stp_eprintf(nv, "Print options not verified; cannot print.\n");
00442       return 0;
00443     }
00444 
00445   stp_image_init(image);
00446 
00447  /*
00448   * Compute the output size...
00449   */
00450 
00451   out_width = stp_get_width(v);
00452   out_height = stp_get_height(v);
00453 
00454   ps_imageable_area(nv, &page_left, &page_right, &page_bottom, &page_top);
00455   left -= page_left;
00456   top -= page_top;
00457   page_width = page_right - page_left;
00458   page_height = page_bottom - page_top;
00459 
00460   image_height = stp_image_height(image);
00461   image_width = stp_image_width(image);
00462 
00463  /*
00464   * Output a standard PostScript header with DSC comments...
00465   */
00466 
00467   curtime = time(NULL);
00468 
00469   left += page_left;
00470 
00471   top = page_height - top;
00472 
00473   stp_dprintf(STP_DBG_PS, v,
00474               "out_width = %d, out_height = %d\n", out_width, out_height);
00475   stp_dprintf(STP_DBG_PS, v,
00476               "page_left = %d, page_right = %d, page_bottom = %d, page_top = %d\n",
00477               page_left, page_right, page_bottom, page_top);
00478   stp_dprintf(STP_DBG_PS, v, "left = %d, top = %d\n", left, top);
00479 
00480   stp_puts("%!PS-Adobe-3.0\n", v);
00481 #ifdef HAVE_CONFIG_H
00482   stp_zprintf(v, "%%%%Creator: %s/Gimp-Print %s (%s)\n",
00483               stp_image_get_appname(image), VERSION, RELEASE_DATE);
00484 #else
00485   stp_zprintf(v, "%%%%Creator: %s/Gimp-Print\n", stp_image_get_appname(image));
00486 #endif
00487   stp_zprintf(v, "%%%%CreationDate: %s", ctime(&curtime));
00488   stp_puts("%Copyright: 1997-2002 by Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu)\n", v);
00489   stp_zprintf(v, "%%%%BoundingBox: %d %d %d %d\n",
00490               left, top - out_height, left + out_width, top);
00491   stp_puts("%%DocumentData: Clean7Bit\n", v);
00492   stp_zprintf(v, "%%%%LanguageLevel: %d\n", model + 1);
00493   stp_puts("%%Pages: 1\n", v);
00494   stp_puts("%%Orientation: Portrait\n", v);
00495   stp_puts("%%EndComments\n", v);
00496 
00497  /*
00498   * Find any printer-specific commands...
00499   */
00500 
00501   num_commands = 0;
00502 
00503   if ((command = ppd_find(ppd_file, "PageSize", media_size, &order)) != NULL)
00504   {
00505     commands[num_commands].keyword = "PageSize";
00506     commands[num_commands].choice  = media_size;
00507     commands[num_commands].command = stp_malloc(strlen(command) + 1);
00508     strcpy(commands[num_commands].command, command);
00509     commands[num_commands].order   = order;
00510     num_commands ++;
00511   }
00512 
00513   if ((command = ppd_find(ppd_file, "InputSlot", media_source, &order)) != NULL)
00514   {
00515     commands[num_commands].keyword = "InputSlot";
00516     commands[num_commands].choice  = media_source;
00517     commands[num_commands].command = stp_malloc(strlen(command) + 1);
00518     strcpy(commands[num_commands].command, command);
00519     commands[num_commands].order   = order;
00520     num_commands ++;
00521   }
00522 
00523   if ((command = ppd_find(ppd_file, "MediaType", media_type, &order)) != NULL)
00524   {
00525     commands[num_commands].keyword = "MediaType";
00526     commands[num_commands].choice  = media_type;
00527     commands[num_commands].command = stp_malloc(strlen(command) + 1);
00528     strcpy(commands[num_commands].command, command);
00529     commands[num_commands].order   = order;
00530     num_commands ++;
00531   }
00532 
00533   if ((command = ppd_find(ppd_file, "Resolution", resolution, &order)) != NULL)
00534   {
00535     commands[num_commands].keyword = "Resolution";
00536     commands[num_commands].choice  = resolution;
00537     commands[num_commands].command = stp_malloc(strlen(command) + 1);
00538     strcpy(commands[num_commands].command, command);
00539     commands[num_commands].order   = order;
00540     num_commands ++;
00541   }
00542 
00543  /*
00544   * Sort the commands using the OrderDependency value...
00545   */
00546 
00547   for (i = 0; i < (num_commands - 1); i ++)
00548     for (j = i + 1; j < num_commands; j ++)
00549       if (commands[j].order < commands[i].order)
00550       {
00551         temp                = commands[i].keyword;
00552         commands[i].keyword = commands[j].keyword;
00553         commands[j].keyword = temp;
00554 
00555         temp                = commands[i].choice;
00556         commands[i].choice  = commands[j].choice;
00557         commands[j].choice  = temp;
00558 
00559         order               = commands[i].order;
00560         commands[i].order   = commands[j].order;
00561         commands[j].order   = order;
00562 
00563         command             = commands[i].command;
00564         commands[i].command = commands[j].command;
00565         commands[j].command = command;
00566       }
00567 
00568  /*
00569   * Send the commands...
00570   */
00571 
00572   if (num_commands > 0)
00573   {
00574     stp_puts("%%BeginSetup\n", v);
00575 
00576     for (i = 0; i < num_commands; i ++)
00577     {
00578       stp_puts("[{\n", v);
00579       stp_zprintf(v, "%%%%BeginFeature: *%s %s\n", commands[i].keyword,
00580                   commands[i].choice);
00581       if (commands[i].command[0])
00582       {
00583         stp_puts(commands[i].command, v);
00584         if (commands[i].command[strlen(commands[i].command) - 1] != '\n')
00585           stp_puts("\n", v);
00586       }
00587 
00588       stp_puts("%%EndFeature\n", v);
00589       stp_puts("} stopped cleartomark\n", v);
00590       stp_free(commands[i].command);
00591     }
00592 
00593     stp_puts("%%EndSetup\n", v);
00594   }
00595 
00596  /*
00597   * Output the page...
00598   */
00599 
00600   stp_puts("%%Page: 1 1\n", v);
00601   stp_puts("gsave\n", v);
00602 
00603   stp_zprintf(v, "%d %d translate\n", left, top);
00604 
00605   /* Force locale to "C", because decimal numbers in Postscript must
00606      always be printed with a decimal point rather than the
00607      locale-specific setting. */
00608 
00609   setlocale(LC_ALL, "C");
00610   stp_zprintf(v, "%.3f %.3f scale\n",
00611               (double)out_width / ((double)image_width),
00612               (double)out_height / ((double)image_height));
00613   setlocale(LC_ALL, "");
00614 
00615   stp_channel_reset(nv);
00616   stp_channel_add(nv, 0, 0, 1.0);
00617   if (strcmp(print_mode, "Color") == 0)
00618     {
00619       stp_channel_add(nv, 1, 0, 1.0);
00620       stp_channel_add(nv, 2, 0, 1.0);
00621       stp_set_string_parameter(nv, "STPIOutputType", "RGB");
00622     }
00623   else
00624     stp_set_string_parameter(nv, "STPIOutputType", "Whitescale");
00625 
00626   out_channels = stp_color_init(nv, image, 256);
00627 
00628   if (model == 0)
00629   {
00630     stp_zprintf(v, "/picture %d string def\n", image_width * out_channels);
00631 
00632     stp_zprintf(v, "%d %d 8\n", image_width, image_height);
00633 
00634     stp_puts("[ 1 0 0 -1 0 1 ]\n", v);
00635 
00636     if (strcmp(print_mode, "Color") == 0)
00637       stp_puts("{currentfile picture readhexstring pop} false 3 colorimage\n", v);
00638     else
00639       stp_puts("{currentfile picture readhexstring pop} image\n", v);
00640 
00641     for (y = 0; y < image_height; y ++)
00642     {
00643       if (stp_color_get_row(nv, image, y, &zero_mask))
00644         {
00645           status = 2;
00646           break;
00647         }
00648 
00649       out = stp_channel_get_input(nv);
00650       ps_hex(v, out, image_width * out_channels);
00651     }
00652   }
00653   else
00654   {
00655     if (strcmp(print_mode, "Color") == 0)
00656       stp_puts("/DeviceRGB setcolorspace\n", v);
00657     else
00658       stp_puts("/DeviceGray setcolorspace\n", v);
00659 
00660     stp_puts("<<\n", v);
00661     stp_puts("\t/ImageType 1\n", v);
00662 
00663     stp_zprintf(v, "\t/Width %d\n", image_width);
00664     stp_zprintf(v, "\t/Height %d\n", image_height);
00665     stp_puts("\t/BitsPerComponent 8\n", v);
00666 
00667     if (strcmp(print_mode, "Color") == 0)
00668       stp_puts("\t/Decode [ 0 1 0 1 0 1 ]\n", v);
00669     else
00670       stp_puts("\t/Decode [ 0 1 ]\n", v);
00671 
00672     stp_puts("\t/DataSource currentfile /ASCII85Decode filter\n", v);
00673 
00674     if ((image_width * 72 / out_width) < 100)
00675       stp_puts("\t/Interpolate true\n", v);
00676 
00677     stp_puts("\t/ImageMatrix [ 1 0 0 -1 0 1 ]\n", v);
00678 
00679     stp_puts(">>\n", v);
00680     stp_puts("image\n", v);
00681 
00682     for (y = 0, out_offset = 0; y < image_height; y ++)
00683     {
00684       /* FIXME!!! */
00685       if (stp_color_get_row(nv, image, y /*, out + out_offset */ , &zero_mask))
00686         {
00687           status = 2;
00688           break;
00689         }
00690       out = stp_channel_get_input(nv);
00691 
00692       out_ps_height = out_offset + image_width * out_channels;
00693 
00694       if (y < (image_height - 1))
00695       {
00696         ps_ascii85(v, out, out_ps_height & ~3, 0);
00697         out_offset = out_ps_height & 3;
00698       }
00699       else
00700       {
00701         ps_ascii85(v, out, out_ps_height, 1);
00702         out_offset = 0;
00703       }
00704 
00705       if (out_offset > 0)
00706         memcpy(out, out + out_ps_height - out_offset, out_offset);
00707     }
00708   }
00709   stp_image_conclude(image);
00710 
00711   stp_puts("grestore\n", v);
00712   stp_puts("showpage\n", v);
00713   stp_puts("%%Trailer\n", v);
00714   stp_puts("%%EOF\n", v);
00715   stp_vars_destroy(nv);
00716   return status;
00717 }
00718 
00719 static int
00720 ps_print(const stp_vars_t *v, stp_image_t *image)
00721 {
00722   int status;
00723   setlocale(LC_ALL, "C");
00724   status = ps_print_internal(v, image);
00725   setlocale(LC_ALL, "");
00726   return status;
00727 }
00728 
00729 
00730 /*
00731  * 'ps_hex()' - Print binary data as a series of hexadecimal numbers.
00732  */
00733 
00734 static void
00735 ps_hex(const stp_vars_t *v,     /* I - File to print to */
00736        unsigned short   *data,  /* I - Data to print */
00737        int              length) /* I - Number of bytes to print */
00738 {
00739   int           col;            /* Current column */
00740   static const char     *hex = "0123456789ABCDEF";
00741 
00742 
00743   col = 0;
00744   while (length > 0)
00745   {
00746     unsigned char pixel = (*data & 0xff00) >> 8;
00747    /*
00748     * Put the hex chars out to the file; note that we don't use stp_zprintf()
00749     * for speed reasons...
00750     */
00751 
00752     stp_putc(hex[pixel >> 4], v);
00753     stp_putc(hex[pixel & 15], v);
00754 
00755     data ++;
00756     length --;
00757 
00758     col += 2;
00759     if (col >= 72)
00760     {
00761       col = 0;
00762       stp_putc('\n', v);
00763     }
00764   }
00765 
00766   if (col > 0)
00767     stp_putc('\n', v);
00768 }
00769 
00770 
00771 /*
00772  * 'ps_ascii85()' - Print binary data as a series of base-85 numbers.
00773  */
00774 
00775 static void
00776 ps_ascii85(const stp_vars_t *v, /* I - File to print to */
00777            unsigned short *data,        /* I - Data to print */
00778            int            length,       /* I - Number of bytes to print */
00779            int            last_line)    /* I - Last line of raster data? */
00780 {
00781   int           i;                      /* Looping var */
00782   unsigned      b;                      /* Binary data word */
00783   unsigned char c[5];                   /* ASCII85 encoded chars */
00784   static int    column = 0;             /* Current column */
00785 
00786 
00787   while (length > 3)
00788   {
00789     unsigned char d0 = (data[0] & 0xff00) >> 8;
00790     unsigned char d1 = (data[1] & 0xff00) >> 8;
00791     unsigned char d2 = (data[2] & 0xff00) >> 8;
00792     unsigned char d3 = (data[3] & 0xff00) >> 8;
00793     b = (((((d0 << 8) | d1) << 8) | d2) << 8) | d3;
00794 
00795     if (b == 0)
00796     {
00797       stp_putc('z', v);
00798       column ++;
00799     }
00800     else
00801     {
00802       c[4] = (b % 85) + '!';
00803       b /= 85;
00804       c[3] = (b % 85) + '!';
00805       b /= 85;
00806       c[2] = (b % 85) + '!';
00807       b /= 85;
00808       c[1] = (b % 85) + '!';
00809       b /= 85;
00810       c[0] = b + '!';
00811 
00812       stp_zfwrite((const char *)c, 5, 1, v);
00813       column += 5;
00814     }
00815 
00816     if (column > 72)
00817     {
00818       stp_putc('\n', v);
00819       column = 0;
00820     }
00821 
00822     data += 4;
00823     length -= 4;
00824   }
00825 
00826   if (last_line)
00827   {
00828     if (length > 0)
00829     {
00830       for (b = 0, i = length; i > 0; b = (b << 8) | data[0], data ++, i --);
00831 
00832       c[4] = (b % 85) + '!';
00833       b /= 85;
00834       c[3] = (b % 85) + '!';
00835       b /= 85;
00836       c[2] = (b % 85) + '!';
00837       b /= 85;
00838       c[1] = (b % 85) + '!';
00839       b /= 85;
00840       c[0] = b + '!';
00841 
00842       stp_zfwrite((const char *)c, length + 1, 1, v);
00843     }
00844 
00845     stp_puts("~>\n", v);
00846     column = 0;
00847   }
00848 }
00849 
00850 
00851 /*
00852  * 'ppd_find()' - Find a control string with the specified name & parameters.
00853  */
00854 
00855 static char *                   /* O - Control string */
00856 ppd_find(const char *ppd_file,  /* I - Name of PPD file */
00857          const char *name,      /* I - Name of parameter */
00858          const char *option,    /* I - Value of parameter */
00859          int  *order)           /* O - Order of the control string */
00860 {
00861   char          line[1024],     /* Line from file */
00862                 lname[255],     /* Name from line */
00863                 loption[255],   /* Value from line */
00864                 *opt;           /* Current control string pointer */
00865   static char   *value = NULL;  /* Current control string value */
00866 
00867 
00868   if (ppd_file == NULL || name == NULL || option == NULL)
00869     return (NULL);
00870   if (!value)
00871     value = stp_zalloc(32768);
00872 
00873   if (ps_ppd_file == NULL || strcmp(ps_ppd_file, ppd_file) != 0)
00874   {
00875     if (ps_ppd != NULL)
00876       fclose(ps_ppd);
00877 
00878     ps_ppd = fopen(ppd_file, "r");
00879 
00880     if (ps_ppd == NULL)
00881       ps_ppd_file = NULL;
00882     else
00883       ps_ppd_file = ppd_file;
00884   }
00885 
00886   if (ps_ppd == NULL)
00887     return (NULL);
00888 
00889   if (order != NULL)
00890     *order = 1000;
00891 
00892   rewind(ps_ppd);
00893   while (fgets(line, sizeof(line), ps_ppd) != NULL)
00894   {
00895     if (line[0] != '*')
00896       continue;
00897 
00898     if (strncasecmp(line, "*OrderDependency:", 17) == 0 && order != NULL)
00899     {
00900       sscanf(line, "%*s%d", order);
00901       continue;
00902     }
00903     else if (sscanf(line, "*%s %[^/:]", lname, loption) != 2)
00904       continue;
00905 
00906     if (strcasecmp(lname, name) == 0 &&
00907         strcasecmp(loption, option) == 0)
00908     {
00909       opt = strchr(line, ':') + 1;
00910       while (*opt == ' ' || *opt == '\t')
00911         opt ++;
00912       if (*opt != '\"')
00913         continue;
00914 
00915       strcpy(value, opt + 1);
00916       if ((opt = strchr(value, '\"')) == NULL)
00917       {
00918         while (fgets(line, sizeof(line), ps_ppd) != NULL)
00919         {
00920           strcat(value, line);
00921           if (strchr(line, '\"') != NULL)
00922           {
00923             strcpy(strchr(value, '\"'), "\n");
00924             break;
00925           }
00926         }
00927       }
00928       else
00929         *opt = '\0';
00930 
00931       return (value);
00932     }
00933   }
00934 
00935   return (NULL);
00936 }
00937 
00938 static const stp_printfuncs_t print_ps_printfuncs =
00939 {
00940   ps_list_parameters,
00941   ps_parameters,
00942   ps_media_size,
00943   ps_imageable_area,
00944   ps_limit,
00945   ps_print,
00946   ps_describe_resolution,
00947   ps_describe_output,
00948   stp_verify_printer_params,
00949   NULL,
00950   NULL
00951 };
00952 
00953 
00954 static stp_family_t print_ps_module_data =
00955   {
00956     &print_ps_printfuncs,
00957     NULL
00958   };
00959 
00960 
00961 static int
00962 print_ps_module_init(void)
00963 {
00964   return stp_family_register(print_ps_module_data.printer_list);
00965 }
00966 
00967 
00968 static int
00969 print_ps_module_exit(void)
00970 {
00971   return stp_family_unregister(print_ps_module_data.printer_list);
00972 }
00973 
00974 
00975 /* Module header */
00976 #define stp_module_version print_ps_LTX_stp_module_version
00977 #define stp_module_data print_ps_LTX_stp_module_data
00978 
00979 stp_module_version_t stp_module_version = {0, 0};
00980 
00981 stp_module_t stp_module_data =
00982   {
00983     "ps",
00984     VERSION,
00985     "Postscript family driver",
00986     STP_MODULE_CLASS_FAMILY,
00987     NULL,
00988     print_ps_module_init,
00989     print_ps_module_exit,
00990     (void *) &print_ps_module_data
00991   };
00992 

Generated on Wed Aug 25 07:56:14 2004 for libgimpprint API Reference by doxygen 1.3.6