libgimpprint API Reference: src/main/print-ps.c Source File

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_8c-source.html,v 1.1.1.2 2004/12/22 23:49:09 jlovell 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