Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

src/main/print-ps.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: print-ps.c,v 1.77 2004/05/07 19:20:33 rleigh 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   if (!pagesize)
00249     pagesize = "";
00250 
00251   stp_dprintf(STP_DBG_PS, v,
00252               "ps_media_size(%d, \'%s\', \'%s\', %p, %p)\n",
00253               stp_get_model_id(v), ppd_file_name, pagesize,
00254               (void *) width, (void *) height);
00255 
00256   if ((dimensions = ppd_find(ppd_file_name, "PaperDimension", pagesize, NULL))
00257       != NULL)
00258     sscanf(dimensions, "%d%d", width, height);
00259   else
00260     stp_default_media_size(v, width, height);
00261 }
00262 
00263 static void
00264 ps_media_size(const stp_vars_t *v, int *width, int *height)
00265 {
00266   setlocale(LC_ALL, "C");
00267   ps_media_size_internal(v, width, height);
00268   setlocale(LC_ALL, "");
00269 }
00270 
00271 /*
00272  * 'ps_imageable_area()' - Return the imageable area of the page.
00273  */
00274 
00275 static void
00276 ps_imageable_area_internal(const stp_vars_t *v,      /* I */
00277                            int  *left,  /* O - Left position in points */
00278                            int  *right, /* O - Right position in points */
00279                            int  *bottom, /* O - Bottom position in points */
00280                            int  *top)   /* O - Top position in points */
00281 {
00282   char  *area;                          /* Imageable area of media */
00283   float fleft,                          /* Floating point versions */
00284         fright,
00285         fbottom,
00286         ftop;
00287   int width, height;
00288   const char *pagesize = stp_get_string_parameter(v, "PageSize");
00289   if (!pagesize)
00290     pagesize = "";
00291   ps_media_size(v, &width, &height);
00292 
00293   if ((area = ppd_find(stp_get_file_parameter(v, "PPDFile"),
00294                        "ImageableArea", pagesize, NULL))
00295       != NULL)
00296     {
00297       stp_dprintf(STP_DBG_PS, v, "area = \'%s\'\n", area);
00298       if (sscanf(area, "%f%f%f%f", &fleft, &fbottom, &fright, &ftop) == 4)
00299         {
00300           *left   = (int)fleft;
00301           *right  = (int)fright;
00302           *bottom = height - (int)fbottom;
00303           *top    = height - (int)ftop;
00304         }
00305       else
00306         *left = *right = *bottom = *top = 0;
00307     }
00308   else
00309     {
00310       *left   = 18;
00311       *right  = width - 18;
00312       *top    = 36;
00313       *bottom = height - 36;
00314     }
00315 }
00316 
00317 static void
00318 ps_imageable_area(const stp_vars_t *v,      /* I */
00319                   int  *left,           /* O - Left position in points */
00320                   int  *right,          /* O - Right position in points */
00321                   int  *bottom,         /* O - Bottom position in points */
00322                   int  *top)            /* O - Top position in points */
00323 {
00324   setlocale(LC_ALL, "C");
00325   ps_imageable_area_internal(v, left, right, bottom, top);
00326   setlocale(LC_ALL, "");
00327 }
00328 
00329 static void
00330 ps_limit(const stp_vars_t *v,           /* I */
00331          int *width,
00332          int *height,
00333          int *min_width,
00334          int *min_height)
00335 {
00336   *width =      INT_MAX;
00337   *height =     INT_MAX;
00338   *min_width =  1;
00339   *min_height = 1;
00340 }
00341 
00342 /*
00343  * This is really bogus...
00344  */
00345 static void
00346 ps_describe_resolution_internal(const stp_vars_t *v, int *x, int *y)
00347 {
00348   const char *resolution = stp_get_string_parameter(v, "Resolution");
00349   *x = -1;
00350   *y = -1;
00351   if (resolution)
00352     sscanf(resolution, "%dx%d", x, y);
00353   return;
00354 }
00355 
00356 static void
00357 ps_describe_resolution(const stp_vars_t *v, int *x, int *y)
00358 {
00359   setlocale(LC_ALL, "C");
00360   ps_describe_resolution_internal(v, x, y);
00361   setlocale(LC_ALL, "");
00362 }
00363 
00364 static const char *
00365 ps_describe_output(const stp_vars_t *v)
00366 {
00367   const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
00368   if (print_mode && strcmp(print_mode, "Color") == 0)
00369     return "RGB";
00370   else
00371     return "Whitescale";
00372 }
00373 
00374 /*
00375  * 'ps_print()' - Print an image to a PostScript printer.
00376  */
00377 
00378 static int
00379 ps_print_internal(const stp_vars_t *v, stp_image_t *image)
00380 {
00381   int           status = 1;
00382   int           model = stp_get_model_id(v);
00383   const char    *ppd_file = stp_get_file_parameter(v, "PPDFile");
00384   const char    *resolution = stp_get_string_parameter(v, "Resolution");
00385   const char    *media_size = stp_get_string_parameter(v, "PageSize");
00386   const char    *media_type = stp_get_string_parameter(v, "MediaType");
00387   const char    *media_source = stp_get_string_parameter(v, "InputSlot");
00388   const char    *print_mode = stp_get_string_parameter(v, "PrintingMode");
00389   unsigned short *out = NULL;
00390   int           top = stp_get_top(v);
00391   int           left = stp_get_left(v);
00392   int           i, j;           /* Looping vars */
00393   int           y;              /* Looping vars */
00394   int           page_left,      /* Left margin of page */
00395                 page_right,     /* Right margin of page */
00396                 page_top,       /* Top of page */
00397                 page_bottom,    /* Bottom of page */
00398                 page_width,     /* Width of page */
00399                 page_height,    /* Height of page */
00400                 out_width,      /* Width of image on page */
00401                 out_height,     /* Height of image on page */
00402                 out_channels,   /* Output bytes per pixel */
00403                 out_ps_height,  /* Output height (Level 2 output) */
00404                 out_offset;     /* Output offset (Level 2 output) */
00405   time_t        curtime;        /* Current time of day */
00406   unsigned      zero_mask;
00407   char          *command;       /* PostScript command */
00408   const char    *temp;          /* Temporary string pointer */
00409   int           order,          /* Order of command */
00410                 num_commands;   /* Number of commands */
00411   struct                        /* PostScript commands... */
00412   {
00413     const char  *keyword, *choice;
00414     char        *command;
00415     int         order;
00416   }             commands[4];
00417   int           image_height,
00418                 image_width;
00419   stp_vars_t    *nv = stp_vars_create_copy(v);
00420   if (!resolution)
00421     resolution = "";
00422   if (!media_size)
00423     media_size = "";
00424   if (!media_type)
00425     media_type = "";
00426   if (!media_source)
00427     media_source = "";
00428 
00429   stp_prune_inactive_options(nv);
00430   if (!stp_verify(nv))
00431     {
00432       stp_eprintf(nv, "Print options not verified; cannot print.\n");
00433       return 0;
00434     }
00435 
00436   stp_image_init(image);
00437 
00438  /*
00439   * Compute the output size...
00440   */
00441 
00442   out_width = stp_get_width(v);
00443   out_height = stp_get_height(v);
00444 
00445   ps_imageable_area(nv, &page_left, &page_right, &page_bottom, &page_top);
00446   left -= page_left;
00447   top -= page_top;
00448   page_width = page_right - page_left;
00449   page_height = page_bottom - page_top;
00450 
00451   image_height = stp_image_height(image);
00452   image_width = stp_image_width(image);
00453 
00454  /*
00455   * Output a standard PostScript header with DSC comments...
00456   */
00457 
00458   curtime = time(NULL);
00459 
00460   left += page_left;
00461 
00462   top = page_height - top;
00463 
00464   stp_dprintf(STP_DBG_PS, v,
00465               "out_width = %d, out_height = %d\n", out_width, out_height);
00466   stp_dprintf(STP_DBG_PS, v,
00467               "page_left = %d, page_right = %d, page_bottom = %d, page_top = %d\n",
00468               page_left, page_right, page_bottom, page_top);
00469   stp_dprintf(STP_DBG_PS, v, "left = %d, top = %d\n", left, top);
00470 
00471   stp_puts("%!PS-Adobe-3.0\n", v);
00472 #ifdef HAVE_CONFIG_H
00473   stp_zprintf(v, "%%%%Creator: %s/Gimp-Print %s (%s)\n",
00474               stp_image_get_appname(image), VERSION, RELEASE_DATE);
00475 #else
00476   stp_zprintf(v, "%%%%Creator: %s/Gimp-Print\n", stp_image_get_appname(image));
00477 #endif
00478   stp_zprintf(v, "%%%%CreationDate: %s", ctime(&curtime));
00479   stp_puts("%Copyright: 1997-2002 by Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu)\n", v);
00480   stp_zprintf(v, "%%%%BoundingBox: %d %d %d %d\n",
00481               left, top - out_height, left + out_width, top);
00482   stp_puts("%%DocumentData: Clean7Bit\n", v);
00483   stp_zprintf(v, "%%%%LanguageLevel: %d\n", model + 1);
00484   stp_puts("%%Pages: 1\n", v);
00485   stp_puts("%%Orientation: Portrait\n", v);
00486   stp_puts("%%EndComments\n", v);
00487 
00488  /*
00489   * Find any printer-specific commands...
00490   */
00491 
00492   num_commands = 0;
00493 
00494   if ((command = ppd_find(ppd_file, "PageSize", media_size, &order)) != NULL)
00495   {
00496     commands[num_commands].keyword = "PageSize";
00497     commands[num_commands].choice  = media_size;
00498     commands[num_commands].command = stp_malloc(strlen(command) + 1);
00499     strcpy(commands[num_commands].command, command);
00500     commands[num_commands].order   = order;
00501     num_commands ++;
00502   }
00503 
00504   if ((command = ppd_find(ppd_file, "InputSlot", media_source, &order)) != NULL)
00505   {
00506     commands[num_commands].keyword = "InputSlot";
00507     commands[num_commands].choice  = media_source;
00508     commands[num_commands].command = stp_malloc(strlen(command) + 1);
00509     strcpy(commands[num_commands].command, command);
00510     commands[num_commands].order   = order;
00511     num_commands ++;
00512   }
00513 
00514   if ((command = ppd_find(ppd_file, "MediaType", media_type, &order)) != NULL)
00515   {
00516     commands[num_commands].keyword = "MediaType";
00517     commands[num_commands].choice  = media_type;
00518     commands[num_commands].command = stp_malloc(strlen(command) + 1);
00519     strcpy(commands[num_commands].command, command);
00520     commands[num_commands].order   = order;
00521     num_commands ++;
00522   }
00523 
00524   if ((command = ppd_find(ppd_file, "Resolution", resolution, &order)) != NULL)
00525   {
00526     commands[num_commands].keyword = "Resolution";
00527     commands[num_commands].choice  = resolution;
00528     commands[num_commands].command = stp_malloc(strlen(command) + 1);
00529     strcpy(commands[num_commands].command, command);
00530     commands[num_commands].order   = order;
00531     num_commands ++;
00532   }
00533 
00534  /*
00535   * Sort the commands using the OrderDependency value...
00536   */
00537 
00538   for (i = 0; i < (num_commands - 1); i ++)
00539     for (j = i + 1; j < num_commands; j ++)
00540       if (commands[j].order < commands[i].order)
00541       {
00542         temp                = commands[i].keyword;
00543         commands[i].keyword = commands[j].keyword;
00544         commands[j].keyword = temp;
00545 
00546         temp                = commands[i].choice;
00547         commands[i].choice  = commands[j].choice;
00548         commands[j].choice  = temp;
00549 
00550         order               = commands[i].order;
00551         commands[i].order   = commands[j].order;
00552         commands[j].order   = order;
00553 
00554         command             = commands[i].command;
00555         commands[i].command = commands[j].command;
00556         commands[j].command = command;
00557       }
00558 
00559  /*
00560   * Send the commands...
00561   */
00562 
00563   if (num_commands > 0)
00564   {
00565     stp_puts("%%BeginSetup\n", v);
00566 
00567     for (i = 0; i < num_commands; i ++)
00568     {
00569       stp_puts("[{\n", v);
00570       stp_zprintf(v, "%%%%BeginFeature: *%s %s\n", commands[i].keyword,
00571                   commands[i].choice);
00572       if (commands[i].command[0])
00573       {
00574         stp_puts(commands[i].command, v);
00575         if (commands[i].command[strlen(commands[i].command) - 1] != '\n')
00576           stp_puts("\n", v);
00577       }
00578 
00579       stp_puts("%%EndFeature\n", v);
00580       stp_puts("} stopped cleartomark\n", v);
00581       stp_free(commands[i].command);
00582     }
00583 
00584     stp_puts("%%EndSetup\n", v);
00585   }
00586 
00587  /*
00588   * Output the page...
00589   */
00590 
00591   stp_puts("%%Page: 1 1\n", v);
00592   stp_puts("gsave\n", v);
00593 
00594   stp_zprintf(v, "%d %d translate\n", left, top);
00595 
00596   /* Force locale to "C", because decimal numbers in Postscript must
00597      always be printed with a decimal point rather than the
00598      locale-specific setting. */
00599 
00600   setlocale(LC_ALL, "C");
00601   stp_zprintf(v, "%.3f %.3f scale\n",
00602               (double)out_width / ((double)image_width),
00603               (double)out_height / ((double)image_height));
00604   setlocale(LC_ALL, "");
00605 
00606   stp_channel_reset(nv);
00607   stp_channel_add(nv, 0, 0, 1.0);
00608   if (strcmp(print_mode, "Color") == 0)
00609     {
00610       stp_channel_add(nv, 1, 0, 1.0);
00611       stp_channel_add(nv, 2, 0, 1.0);
00612       stp_set_string_parameter(nv, "STPIOutputType", "RGB");
00613     }
00614   else
00615     stp_set_string_parameter(nv, "STPIOutputType", "Whitescale");
00616 
00617   out_channels = stp_color_init(nv, image, 256);
00618 
00619   if (model == 0)
00620   {
00621     stp_zprintf(v, "/picture %d string def\n", image_width * out_channels);
00622 
00623     stp_zprintf(v, "%d %d 8\n", image_width, image_height);
00624 
00625     stp_puts("[ 1 0 0 -1 0 1 ]\n", v);
00626 
00627     if (strcmp(print_mode, "Color") == 0)
00628       stp_puts("{currentfile picture readhexstring pop} false 3 colorimage\n", v);
00629     else
00630       stp_puts("{currentfile picture readhexstring pop} image\n", v);
00631 
00632     for (y = 0; y < image_height; y ++)
00633     {
00634       if (stp_color_get_row(nv, image, y, &zero_mask))
00635         {
00636           status = 2;
00637           break;
00638         }
00639 
00640       out = stp_channel_get_input(nv);
00641       ps_hex(v, out, image_width * out_channels);
00642     }
00643   }
00644   else
00645   {
00646     if (strcmp(print_mode, "Color") == 0)
00647       stp_puts("/DeviceRGB setcolorspace\n", v);
00648     else
00649       stp_puts("/DeviceGray setcolorspace\n", v);
00650 
00651     stp_puts("<<\n", v);
00652     stp_puts("\t/ImageType 1\n", v);
00653 
00654     stp_zprintf(v, "\t/Width %d\n", image_width);
00655     stp_zprintf(v, "\t/Height %d\n", image_height);
00656     stp_puts("\t/BitsPerComponent 8\n", v);
00657 
00658     if (strcmp(print_mode, "Color") == 0)
00659       stp_puts("\t/Decode [ 0 1 0 1 0 1 ]\n", v);
00660     else
00661       stp_puts("\t/Decode [ 0 1 ]\n", v);
00662 
00663     stp_puts("\t/DataSource currentfile /ASCII85Decode filter\n", v);
00664 
00665     if ((image_width * 72 / out_width) < 100)
00666       stp_puts("\t/Interpolate true\n", v);
00667 
00668     stp_puts("\t/ImageMatrix [ 1 0 0 -1 0 1 ]\n", v);
00669 
00670     stp_puts(">>\n", v);
00671     stp_puts("image\n", v);
00672 
00673     for (y = 0, out_offset = 0; y < image_height; y ++)
00674     {
00675       /* FIXME!!! */
00676       if (stp_color_get_row(nv, image, y /*, out + out_offset */ , &zero_mask))
00677         {
00678           status = 2;
00679           break;
00680         }
00681       out = stp_channel_get_input(nv);
00682 
00683       out_ps_height = out_offset + image_width * out_channels;
00684 
00685       if (y < (image_height - 1))
00686       {
00687         ps_ascii85(v, out, out_ps_height & ~3, 0);
00688         out_offset = out_ps_height & 3;
00689       }
00690       else
00691       {
00692         ps_ascii85(v, out, out_ps_height, 1);
00693         out_offset = 0;
00694       }
00695 
00696       if (out_offset > 0)
00697         memcpy(out, out + out_ps_height - out_offset, out_offset);
00698     }
00699   }
00700   stp_image_conclude(image);
00701 
00702   stp_puts("grestore\n", v);
00703   stp_puts("showpage\n", v);
00704   stp_puts("%%Trailer\n", v);
00705   stp_puts("%%EOF\n", v);
00706   stp_vars_destroy(nv);
00707   return status;
00708 }
00709 
00710 static int
00711 ps_print(const stp_vars_t *v, stp_image_t *image)
00712 {
00713   int status;
00714   setlocale(LC_ALL, "C");
00715   status = ps_print_internal(v, image);
00716   setlocale(LC_ALL, "");
00717   return status;
00718 }
00719 
00720 
00721 /*
00722  * 'ps_hex()' - Print binary data as a series of hexadecimal numbers.
00723  */
00724 
00725 static void
00726 ps_hex(const stp_vars_t *v,     /* I - File to print to */
00727        unsigned short   *data,  /* I - Data to print */
00728        int              length) /* I - Number of bytes to print */
00729 {
00730   int           col;            /* Current column */
00731   static const char     *hex = "0123456789ABCDEF";
00732 
00733 
00734   col = 0;
00735   while (length > 0)
00736   {
00737     unsigned char pixel = (*data & 0xff00) >> 8;
00738    /*
00739     * Put the hex chars out to the file; note that we don't use stp_zprintf()
00740     * for speed reasons...
00741     */
00742 
00743     stp_putc(hex[pixel >> 4], v);
00744     stp_putc(hex[pixel & 15], v);
00745 
00746     data ++;
00747     length --;
00748 
00749     col += 2;
00750     if (col >= 72)
00751     {
00752       col = 0;
00753       stp_putc('\n', v);
00754     }
00755   }
00756 
00757   if (col > 0)
00758     stp_putc('\n', v);
00759 }
00760 
00761 
00762 /*
00763  * 'ps_ascii85()' - Print binary data as a series of base-85 numbers.
00764  */
00765 
00766 static void
00767 ps_ascii85(const stp_vars_t *v, /* I - File to print to */
00768            unsigned short *data,        /* I - Data to print */
00769            int            length,       /* I - Number of bytes to print */
00770            int            last_line)    /* I - Last line of raster data? */
00771 {
00772   int           i;                      /* Looping var */
00773   unsigned      b;                      /* Binary data word */
00774   unsigned char c[5];                   /* ASCII85 encoded chars */
00775   static int    column = 0;             /* Current column */
00776 
00777 
00778   while (length > 3)
00779   {
00780     unsigned char d0 = (data[0] & 0xff00) >> 8;
00781     unsigned char d1 = (data[1] & 0xff00) >> 8;
00782     unsigned char d2 = (data[2] & 0xff00) >> 8;
00783     unsigned char d3 = (data[3] & 0xff00) >> 8;
00784     b = (((((d0 << 8) | d1) << 8) | d2) << 8) | d3;
00785 
00786     if (b == 0)
00787     {
00788       stp_putc('z', v);
00789       column ++;
00790     }
00791     else
00792     {
00793       c[4] = (b % 85) + '!';
00794       b /= 85;
00795       c[3] = (b % 85) + '!';
00796       b /= 85;
00797       c[2] = (b % 85) + '!';
00798       b /= 85;
00799       c[1] = (b % 85) + '!';
00800       b /= 85;
00801       c[0] = b + '!';
00802 
00803       stp_zfwrite((const char *)c, 5, 1, v);
00804       column += 5;
00805     }
00806 
00807     if (column > 72)
00808     {
00809       stp_putc('\n', v);
00810       column = 0;
00811     }
00812 
00813     data += 4;
00814     length -= 4;
00815   }
00816 
00817   if (last_line)
00818   {
00819     if (length > 0)
00820     {
00821       for (b = 0, i = length; i > 0; b = (b << 8) | data[0], data ++, i --);
00822 
00823       c[4] = (b % 85) + '!';
00824       b /= 85;
00825       c[3] = (b % 85) + '!';
00826       b /= 85;
00827       c[2] = (b % 85) + '!';
00828       b /= 85;
00829       c[1] = (b % 85) + '!';
00830       b /= 85;
00831       c[0] = b + '!';
00832 
00833       stp_zfwrite((const char *)c, length + 1, 1, v);
00834     }
00835 
00836     stp_puts("~>\n", v);
00837     column = 0;
00838   }
00839 }
00840 
00841 
00842 /*
00843  * 'ppd_find()' - Find a control string with the specified name & parameters.
00844  */
00845 
00846 static char *                   /* O - Control string */
00847 ppd_find(const char *ppd_file,  /* I - Name of PPD file */
00848          const char *name,      /* I - Name of parameter */
00849          const char *option,    /* I - Value of parameter */
00850          int  *order)           /* O - Order of the control string */
00851 {
00852   char          line[1024],     /* Line from file */
00853                 lname[255],     /* Name from line */
00854                 loption[255],   /* Value from line */
00855                 *opt;           /* Current control string pointer */
00856   static char   *value = NULL;  /* Current control string value */
00857 
00858 
00859   if (ppd_file == NULL || name == NULL || option == NULL)
00860     return (NULL);
00861   if (!value)
00862     value = stp_zalloc(32768);
00863 
00864   if (ps_ppd_file == NULL || strcmp(ps_ppd_file, ppd_file) != 0)
00865   {
00866     if (ps_ppd != NULL)
00867       fclose(ps_ppd);
00868 
00869     ps_ppd = fopen(ppd_file, "r");
00870 
00871     if (ps_ppd == NULL)
00872       ps_ppd_file = NULL;
00873     else
00874       ps_ppd_file = ppd_file;
00875   }
00876 
00877   if (ps_ppd == NULL)
00878     return (NULL);
00879 
00880   if (order != NULL)
00881     *order = 1000;
00882 
00883   rewind(ps_ppd);
00884   while (fgets(line, sizeof(line), ps_ppd) != NULL)
00885   {
00886     if (line[0] != '*')
00887       continue;
00888 
00889     if (strncasecmp(line, "*OrderDependency:", 17) == 0 && order != NULL)
00890     {
00891       sscanf(line, "%*s%d", order);
00892       continue;
00893     }
00894     else if (sscanf(line, "*%s %[^/:]", lname, loption) != 2)
00895       continue;
00896 
00897     if (strcasecmp(lname, name) == 0 &&
00898         strcasecmp(loption, option) == 0)
00899     {
00900       opt = strchr(line, ':') + 1;
00901       while (*opt == ' ' || *opt == '\t')
00902         opt ++;
00903       if (*opt != '\"')
00904         continue;
00905 
00906       strcpy(value, opt + 1);
00907       if ((opt = strchr(value, '\"')) == NULL)
00908       {
00909         while (fgets(line, sizeof(line), ps_ppd) != NULL)
00910         {
00911           strcat(value, line);
00912           if (strchr(line, '\"') != NULL)
00913           {
00914             strcpy(strchr(value, '\"'), "\n");
00915             break;
00916           }
00917         }
00918       }
00919       else
00920         *opt = '\0';
00921 
00922       return (value);
00923     }
00924   }
00925 
00926   return (NULL);
00927 }
00928 
00929 static const stp_printfuncs_t print_ps_printfuncs =
00930 {
00931   ps_list_parameters,
00932   ps_parameters,
00933   ps_media_size,
00934   ps_imageable_area,
00935   ps_limit,
00936   ps_print,
00937   ps_describe_resolution,
00938   ps_describe_output,
00939   stp_verify_printer_params,
00940   NULL,
00941   NULL
00942 };
00943 
00944 
00945 static stp_family_t print_ps_module_data =
00946   {
00947     &print_ps_printfuncs,
00948     NULL
00949   };
00950 
00951 
00952 static int
00953 print_ps_module_init(void)
00954 {
00955   return stp_family_register(print_ps_module_data.printer_list);
00956 }
00957 
00958 
00959 static int
00960 print_ps_module_exit(void)
00961 {
00962   return stp_family_unregister(print_ps_module_data.printer_list);
00963 }
00964 
00965 
00966 /* Module header */
00967 #define stp_module_version print_ps_LTX_stp_module_version
00968 #define stp_module_data print_ps_LTX_stp_module_data
00969 
00970 stp_module_version_t stp_module_version = {0, 0};
00971 
00972 stp_module_t stp_module_data =
00973   {
00974     "ps",
00975     VERSION,
00976     "Postscript family driver",
00977     STP_MODULE_CLASS_FAMILY,
00978     NULL,
00979     print_ps_module_init,
00980     print_ps_module_exit,
00981     (void *) &print_ps_module_data
00982   };
00983 

Generated on Wed May 12 20:21:33 2004 for libgimpprint API Reference by doxygen1.2.17