From bea57c14aad7c897327c360a2859cb277d8f8b71 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Mon, 11 May 1998 19:53:31 +0000 Subject: [PATCH] Updated print plug-in to version 2.0 --Sven --- ChangeLog | 4 + plug-ins/print/print-escp2.c | 338 ++++++-- plug-ins/print/print-pcl.c | 493 ++++++++--- plug-ins/print/print-ps.c | 693 +++++++++++---- plug-ins/print/print-util.c | 257 +++--- plug-ins/print/print.c | 1547 ++++++++++++++++++++++++---------- plug-ins/print/print.h | 82 +- 7 files changed, 2455 insertions(+), 959 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35d4f98331..a7364f39c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Mon May 11 21:40:25 MEST 1998 Sven Neumann + + * updated print plug-in + Fri May 8 20:51:24 PDT 1998 Manish Singh * plug-ins/script-fu/script-fu-console.c: workaround for text diff --git a/plug-ins/print/print-escp2.c b/plug-ins/print/print-escp2.c index ed0e6b378a..a43477ff7b 100644 --- a/plug-ins/print/print-escp2.c +++ b/plug-ins/print/print-escp2.c @@ -21,46 +21,28 @@ * * Contents: * - * escp2_print() - Print an image to an EPSON printer. - * escp2_write() - Send ESC/P2 graphics using TIFF packbits compression. + * escp2_parameters() - Return the parameter values for the given + * parameter. + * escp2_imageable_area() - Return the imageable area of the page. + * escp2_print() - Print an image to an EPSON printer. + * escp2_write() - Send ESC/P2 graphics using TIFF packbits compression. * * Revision History: * * $Log$ - * Revision 1.6 1998/04/13 05:43:12 yosh - * Have fun recompiling gimp everyone. It's the great FSF address change! - * - * -Yosh - * - * Revision 1.5 1998/04/07 03:41:11 yosh - * configure.in: fix for $srcdir != $builddir for data. Tightened check for - * random() and add -lucb on systems that need it. Fix for xdelta.h check. Find - * xemacs as well as emacs. Properly define settings for print plugin. - * - * app/Makefile.am: ditch -DNDEBUG, since nothing uses it - * - * flame: properly handle random() and friends - * - * pnm: workaround for systems with old sprintfs - * - * print, sgi: fold back in portability fixes - * - * threshold_alpha: properly get params in non-interactive mode - * - * bmp: updated and merged in - * - * -Yosh - * - * Revision 1.4 1998/04/01 22:14:44 neo - * Added checks for print spoolers to configure.in as suggested by Michael - * Sweet. The print plug-in still needs some changes to Makefile.am to make - * make use of this. - * - * Updated print and sgi plug-ins to version on the registry. + * Revision 1.7 1998/05/11 19:49:56 neo + * Updated print plug-in to version 2.0 * * * --Sven * + * Revision 1.10 1998/05/08 21:18:34 mike + * Now enable microweaving in 720 DPI mode. + * + * Revision 1.9 1998/05/08 20:49:43 mike + * Updated to support media size, imageable area, and parameter functions. + * Added support for scaling modes - scale by percent or scale by PPI. + * * Revision 1.8 1998/01/21 21:33:47 mike * Updated copyright. * @@ -109,26 +91,131 @@ static void escp2_write(FILE *, unsigned char *, int, int, int, int, int, int); +/* + * 'escp2_parameters()' - Return the parameter values for the given parameter. + */ + +char ** /* O - Parameter values */ +escp2_parameters(int model, /* I - Printer model */ + char *ppd_file, /* I - PPD file (not used) */ + char *name, /* I - Name of parameter */ + int *count) /* O - Number of values */ +{ + int i; + char **p, + **valptrs; + static char *media_sizes[] = + { + "Letter", + "Legal", + "A4", + "Tabloid", + "A3", + "12x18" + }; + static char *resolutions[] = + { + "360 DPI", + "720 DPI" + }; + + + if (count == NULL) + return (NULL); + + *count = 0; + + if (name == NULL) + return (NULL); + + if (strcmp(name, "PageSize") == 0) + { + if (model == 5 || model == 2) + *count = 6; + else + *count = 3; + + p = media_sizes; + } + else if (strcmp(name, "Resolution") == 0) + { + *count = 2; + p = resolutions; + } + else + return (NULL); + + valptrs = g_new(char *, *count); + for (i = 0; i < *count; i ++) + valptrs[i] = strdup(p[i]); + + return (valptrs); +} + + +/* + * 'escp2_imageable_area()' - Return the imageable area of the page. + */ + +void +escp2_imageable_area(int model, /* I - Printer model */ + char *ppd_file, /* I - PPD file (not used) */ + char *media_size, /* I - Media size */ + int *left, /* O - Left position in points */ + int *right, /* O - Right position in points */ + int *bottom, /* O - Bottom position in points */ + int *top) /* O - Top position in points */ +{ + int width, length; /* Size of page */ + + + default_media_size(model, ppd_file, media_size, &width, &length); + + switch (model) + { + default : + *left = 14; + *right = width - 14; + *top = length - 14; + *bottom = 40; + break; + + case 3 : + case 4 : + case 5 : + *left = 8; + *right = width - 9; + *top = length - 32; + *bottom = 40; + break; + }; +} + + /* * 'escp2_print()' - Print an image to an EPSON printer. */ void -escp2_print(FILE *prn, /* I - Print file or command */ - GDrawable *drawable, /* I - Image to print */ - int media_size, /* I - Output size */ - int xdpi, /* I - Horizontal resolution */ - int ydpi, /* I - Vertical resolution */ - int output_type, /* I - Color or grayscale? */ - int model, /* I - Model of printer */ - guchar *lut, /* I - Brightness lookup table */ - guchar *cmap, /* I - Colormap (for indexed images) */ +escp2_print(int model, /* I - Model */ + char *ppd_file, /* I - PPD file (not used) */ + char *resolution, /* I - Resolution */ + char *media_size, /* I - Media size */ + char *media_type, /* I - Media type */ + char *media_source, /* I - Media source */ + int output_type, /* I - Output type (color/grayscale) */ int orientation, /* I - Orientation of image */ - int scaling, /* I - Scaling of image */ - int left, /* I - Left offset of image (10ths) */ - int top) /* I - Top offset of image (10ths) */ + float scaling, /* I - Scaling of image */ + int left, /* I - Left offset of image (points) */ + int top, /* I - Top offset of image (points) */ + int copies, /* I - Number of copies */ + FILE *prn, /* I - File to print to */ + GDrawable *drawable, /* I - Image to print */ + guchar *lut, /* I - Brightness lookup table */ + guchar *cmap) /* I - Colormap (for indexed images) */ { int x, y; /* Looping vars */ + int xdpi, ydpi; /* Resolution */ int n; /* Output number */ GPixelRgn rgn; /* Image region */ unsigned char *in, /* Input pixels */ @@ -137,8 +224,13 @@ escp2_print(FILE *prn, /* I - Print file or command */ *cyan, /* Cyan bitmap data */ *magenta, /* Magenta bitmap data */ *yellow; /* Yellow bitmap data */ - int page_width, /* Width of page */ + int page_left, /* Left margin of page */ + page_right, /* Right margin of page */ + page_top, /* Top of page */ + page_bottom, /* Bottom of page */ + page_width, /* Width of page */ page_height, /* Height of page */ + page_length, /* True length of page */ out_width, /* Width of image on page */ out_height, /* Height of image on page */ out_bpp, /* Output bytes per pixel */ @@ -189,44 +281,106 @@ escp2_print(FILE *prn, /* I - Print file or command */ colorfunc = indexed_to_gray; }; + /* + * Figure out the output resolution... + */ + + xdpi = ydpi = atoi(resolution); + /* * Compute the output size... */ landscape = 0; - page_width = media_width(media_size, xdpi); - page_height = media_height(media_size, ydpi); + escp2_imageable_area(model, ppd_file, media_size, &page_left, &page_right, + &page_bottom, &page_top); + + page_width = page_right - page_left; + page_height = page_top - page_bottom; + + default_media_size(model, ppd_file, media_size, &n, &page_length); /* * Portrait width/height... */ - out_width = page_width * scaling / 100; - out_height = out_width * ydpi / xdpi * drawable->height / drawable->width; - if (out_height > page_height) + if (scaling < 0.0) { - out_height = page_height; - out_width = out_height * xdpi / ydpi * drawable->width / drawable->height; + /* + * Scale to pixels per inch... + */ + + out_width = drawable->width * -72.0 / scaling; + out_height = drawable->height * -72.0 / scaling; + } + else + { + /* + * Scale by percent... + */ + + out_width = page_width * scaling / 100.0; + out_height = out_width * drawable->height / drawable->width; + if (out_height > page_height) + { + out_height = page_height * scaling / 100.0; + out_width = out_height * drawable->width / drawable->height; + }; }; /* * Landscape width/height... */ - temp_width = page_width * scaling / 100; - temp_height = temp_width * ydpi / xdpi * drawable->width / drawable->height; - if (temp_height > page_height) + if (scaling < 0.0) { - temp_height = page_height; - temp_width = temp_height * xdpi / ydpi * drawable->height / drawable->width; + /* + * Scale to pixels per inch... + */ + + temp_width = drawable->height * -72.0 / scaling; + temp_height = drawable->width * -72.0 / scaling; + } + else + { + /* + * Scale by percent... + */ + + temp_width = page_width * scaling / 100.0; + temp_height = temp_width * drawable->width / drawable->height; + if (temp_height > page_height) + { + temp_height = page_height; + temp_width = temp_height * drawable->height / drawable->width; + }; }; /* - * See which orientation has the greatest area... + * See which orientation has the greatest area (or if we need to rotate the + * image to fit it on the page...) */ - if ((temp_width * temp_height) > (out_width * out_height) && - orientation != ORIENT_PORTRAIT) + if (orientation == ORIENT_AUTO) + { + if (scaling < 0.0) + { + if ((out_width > page_width && out_height < page_width) || + (out_height > page_height && out_width < page_height)) + orientation = ORIENT_LANDSCAPE; + else + orientation = ORIENT_PORTRAIT; + } + else + { + if ((temp_width * temp_height) > (out_width * out_height)) + orientation = ORIENT_LANDSCAPE; + else + orientation = ORIENT_PORTRAIT; + }; + }; + + if (orientation == ORIENT_LANDSCAPE) { out_width = temp_width; out_height = temp_height; @@ -241,6 +395,12 @@ escp2_print(FILE *prn, /* I - Print file or command */ left = x; }; + if (top < 0 || left < 0) + { + left = (page_width - out_width) / 2; + top = (page_height + out_height) / 2; + }; + /* * Let the user know what we're doing... */ @@ -270,60 +430,68 @@ escp2_print(FILE *prn, /* I - Print file or command */ }; fwrite("\033(C\002\000", 5, 1, prn); /* Page length */ - n = page_height + ydpi; + n = ydpi * page_length / 72; putc(n & 255, prn); putc(n >> 8, prn); - if (left < 0 || top < 0) - { - left = (page_width - out_width) / 2; - top = (page_height - out_height + ydpi) / 2; - } - else - { - left *= xdpi / 10; - top = top * ydpi / 10 + ydpi / 2; - }; - fwrite("\033(c\004\000", 5, 1, prn); /* Top/bottom margins */ - putc(top & 255, prn); - putc(top >> 8, prn); - n = page_height + ydpi / 2; + n = ydpi * (page_length - page_top) / 72; + putc(n & 255, prn); + putc(n >> 8, prn); + n = ydpi * (page_length - page_bottom) / 72; + putc(n & 255, prn); + putc(n >> 8, prn); + + fwrite("\033(V\002\000", 5, 1, prn); /* Absolute vertical position */ + n = ydpi * (page_length - top) / 72; putc(n & 255, prn); putc(n >> 8, prn); switch (model) /* Printer specific initialization */ { case 0 : /* ESC */ + if (output_type == OUTPUT_COLOR && ydpi > 360) + fwrite("\033(i\001\000\001", 6, 1, prn); /* Microweave mode on */ break; case 1 : /* ESC Pro, Pro XL, 400, 500 */ fwrite("\033(e\002\000\000\001", 7, 1, prn); /* Small dots */ + + if (ydpi > 360) + fwrite("\033(i\001\000\001", 6, 1, prn); /* Microweave mode on */ break; case 2 : /* ESC 1500 */ fwrite("\033(e\002\000\000\001", 7, 1, prn); /* Small dots */ + + if (ydpi > 360) + fwrite("\033(i\001\000\001", 6, 1, prn); /* Microweave mode on */ break; case 3 : /* ESC 600 */ - if (output_type == OUTPUT_GRAY) - fwrite("\033(K\002\000\000\001", 7, 1, prn); /* Fast black printing */ - else - fwrite("\033(K\002\000\000\002", 7, 1, prn); /* Color printing */ - - fwrite("\033(e\002\000\000\003", 7, 1, prn); /* Small dots */ - break; - - case 4 : /* ESC 800, 1520, 3000 */ + case 4 : /* ESC 800 */ + case 5 : /* 1520, 3000 */ if (output_type == OUTPUT_GRAY) fwrite("\033(K\002\000\000\001", 7, 1, prn); /* Fast black printing */ else fwrite("\033(K\002\000\000\002", 7, 1, prn); /* Color printing */ fwrite("\033(e\002\000\000\002", 7, 1, prn); /* Small dots */ + + if (ydpi > 360) + fwrite("\033(i\001\000\001", 6, 1, prn); /* Microweave mode on */ break; }; + /* + * Convert image size to printer resolution... + */ + + out_width = xdpi * out_width / 72; + out_height = ydpi * out_height / 72; + + left = ydpi * left / 72; + /* * Allocate memory for the raster data... */ @@ -493,7 +661,7 @@ escp2_print(FILE *prn, /* I - Print file or command */ * 'escp2_write()' - Send ESC/P2 graphics using TIFF packbits compression. */ -static void +void escp2_write(FILE *prn, /* I - Print file or command */ unsigned char *line, /* I - Output bitmap data */ int length, /* I - Length of bitmap data */ diff --git a/plug-ins/print/print-pcl.c b/plug-ins/print/print-pcl.c index 4fa3b44ed2..ee34f70cd6 100644 --- a/plug-ins/print/print-pcl.c +++ b/plug-ins/print/print-pcl.c @@ -21,47 +21,30 @@ * * Contents: * - * pcl_print() - Print an image to an HP printer. - * pcl_mode0() - Send PCL graphics using mode 0 (no) compression. - * pcl_mode2() - Send PCL graphics using mode 2 (TIFF) compression. + * pcl_parameters() - Return the parameter values for the given + * parameter. + * pcl_imageable_area() - Return the imageable area of the page. + * pcl_print() - Print an image to an HP printer. + * pcl_mode0() - Send PCL graphics using mode 0 (no) compression. + * pcl_mode2() - Send PCL graphics using mode 2 (TIFF) compression. * * Revision History: * * $Log$ - * Revision 1.6 1998/04/13 05:43:13 yosh - * Have fun recompiling gimp everyone. It's the great FSF address change! - * - * -Yosh - * - * Revision 1.5 1998/04/07 03:41:12 yosh - * configure.in: fix for $srcdir != $builddir for data. Tightened check for - * random() and add -lucb on systems that need it. Fix for xdelta.h check. Find - * xemacs as well as emacs. Properly define settings for print plugin. - * - * app/Makefile.am: ditch -DNDEBUG, since nothing uses it - * - * flame: properly handle random() and friends - * - * pnm: workaround for systems with old sprintfs - * - * print, sgi: fold back in portability fixes - * - * threshold_alpha: properly get params in non-interactive mode - * - * bmp: updated and merged in - * - * -Yosh - * - * Revision 1.4 1998/04/01 22:14:45 neo - * Added checks for print spoolers to configure.in as suggested by Michael - * Sweet. The print plug-in still needs some changes to Makefile.am to make - * make use of this. - * - * Updated print and sgi plug-ins to version on the registry. + * Revision 1.7 1998/05/11 19:50:36 neo + * Updated print plug-in to version 2.0 * * * --Sven * + * Revision 1.10 1998/05/08 21:22:00 mike + * Added quality mode command for DeskJet printers (high quality for 300 + * DPI or higher). + * + * Revision 1.9 1998/05/08 19:20:50 mike + * Updated to support media size, imageable area, and parameter functions. + * Added support for scaling modes - scale by percent or scale by PPI. + * * Revision 1.8 1998/01/21 21:33:47 mike * Updated copyright. * @@ -108,26 +91,198 @@ static void pcl_mode0(FILE *, unsigned char *, int, int); static void pcl_mode2(FILE *, unsigned char *, int, int); +/* + * 'pcl_parameters()' - Return the parameter values for the given parameter. + */ + +char ** /* O - Parameter values */ +pcl_parameters(int model, /* I - Printer model */ + char *ppd_file, /* I - PPD file (not used) */ + char *name, /* I - Name of parameter */ + int *count) /* O - Number of values */ +{ + int i; + char **p, + **valptrs; + static char *media_sizes[] = + { + "Letter", + "Legal", + "A4", + "Tabloid", + "A3", + "12x18" + }; + static char *media_types[] = + { + "Plain", + "Premium", + "Glossy", + "Transparency" + }; + static char *media_sources[] = + { + "Manual", + "Tray 1", + "Tray 2", + "Tray 3", + "Tray 4", + }; + static char *resolutions[] = + { + "150 DPI", + "300 DPI", + "600 DPI" + }; + + + if (count == NULL) + return (NULL); + + *count = 0; + + if (name == NULL) + return (NULL); + + if (strcmp(name, "PageSize") == 0) + { + if (model == 5 || model == 1100) + *count = 6; + else + *count = 3; + + p = media_sizes; + } + else if (strcmp(name, "MediaType") == 0) + { + if (model < 500) + { + *count = 0; + return (NULL); + } + else + { + *count = 4; + p = media_types; + }; + } + else if (strcmp(name, "InputSlot") == 0) + { + if (model < 500) + { + *count = 5; + p = media_sources; + } + else + { + *count = 0; + return (NULL); + }; + } + else if (strcmp(name, "Resolution") == 0) + { + if (model == 4 || model == 5 || model == 800 || model == 600) + *count = 3; + else + *count = 2; + + p = resolutions; + } + else + return (NULL); + + valptrs = g_new(char *, *count); + for (i = 0; i < *count; i ++) + valptrs[i] = strdup(p[i]); + + return (valptrs); +} + + +/* + * 'pcl_imageable_area()' - Return the imageable area of the page. + */ + +void +pcl_imageable_area(int model, /* I - Printer model */ + char *ppd_file, /* I - PPD file (not used) */ + char *media_size, /* I - Media size */ + int *left, /* O - Left position in points */ + int *right, /* O - Right position in points */ + int *bottom, /* O - Bottom position in points */ + int *top) /* O - Top position in points */ +{ + int width, length; /* Size of page */ + + + default_media_size(model, ppd_file, media_size, &width, &length); + + switch (model) + { + default : + *left = 18; + *right = width - 18; + *top = length - 12; + *bottom = 12; + break; + + case 500 : + *left = 18; + *right = width - 18; + *top = length - 7; + *bottom = 41; + break; + + case 501 : + *left = 18; + *right = width - 18; + *top = length - 7; + *bottom = 33; + break; + + case 550 : + case 800 : + case 1100 : + *left = 18; + *right = width - 18; + *top = length - 3; + *bottom = 33; + break; + + case 600 : + *left = 18; + *right = width - 18; + *top = length - 0; + *bottom = 33; + break; + }; +} + + /* * 'pcl_print()' - Print an image to an HP printer. */ void -pcl_print(FILE *prn, /* I - Print file or command */ - GDrawable *drawable, /* I - Image to print */ - int media_size, /* I - Output size */ - int xdpi, /* I - Horizontal resolution */ - int ydpi, /* I - Vertical resolution */ - int output_type, /* I - Color or grayscale? */ - int model, /* I - Model of printer */ - guchar *lut, /* I - Brightness lookup table */ - guchar *cmap, /* I - Colormap (for indexed images) */ +pcl_print(int model, /* I - Model */ + char *ppd_file, /* I - PPD file (not used) */ + char *resolution, /* I - Resolution */ + char *media_size, /* I - Media size */ + char *media_type, /* I - Media type */ + char *media_source, /* I - Media source */ + int output_type, /* I - Output type (color/grayscale) */ int orientation, /* I - Orientation of image */ - int scaling, /* I - Scaling of image */ - int left, /* I - Left offset of image (10ths) */ - int top) /* I - Top offset of image (10ths) */ + float scaling, /* I - Scaling of image */ + int left, /* I - Left offset of image (points) */ + int top, /* I - Top offset of image (points) */ + int copies, /* I - Number of copies */ + FILE *prn, /* I - File to print to */ + GDrawable *drawable, /* I - Image to print */ + guchar *lut, /* I - Brightness lookup table */ + guchar *cmap) /* I - Colormap (for indexed images) */ { int x, y; /* Looping vars */ + int xdpi, ydpi; /* Resolution */ GPixelRgn rgn; /* Image region */ unsigned char *in, /* Input pixels */ *out, /* Output pixels */ @@ -135,7 +290,11 @@ pcl_print(FILE *prn, /* I - Print file or command */ *cyan, /* Cyan bitmap data */ *magenta, /* Magenta bitmap data */ *yellow; /* Yellow bitmap data */ - int page_width, /* Width of page */ + int page_left, /* Left margin of page */ + page_right, /* Right margin of page */ + page_top, /* Top of page */ + page_bottom, /* Bottom of page */ + page_width, /* Width of page */ page_height, /* Height of page */ out_width, /* Width of image on page */ out_height, /* Height of image on page */ @@ -192,44 +351,113 @@ pcl_print(FILE *prn, /* I - Print file or command */ colorfunc = indexed_to_gray; }; + /* + * Figure out the output resolution... + */ + + xdpi = atoi(resolution); + + if ((model == 800 || model == 1100) && + output_type == OUTPUT_COLOR && xdpi == 600) + xdpi = 300; + + if (model == 600 && xdpi == 600) + ydpi = 300; + else + ydpi = xdpi; + /* * Compute the output size... */ - landscape = 0; - page_width = media_width(media_size, xdpi); - page_height = media_height(media_size, ydpi); + landscape = 0; + pcl_imageable_area(model, ppd_file, media_size, &page_left, &page_right, + &page_bottom, &page_top); + + page_width = page_right - page_left; + page_height = page_top - page_bottom; /* * Portrait width/height... */ - out_width = page_width * scaling / 100; - out_height = out_width * ydpi / xdpi * drawable->height / drawable->width; - if (out_height > page_height) + if (scaling < 0.0) { - out_height = page_height; - out_width = out_height * xdpi / ydpi * drawable->width / drawable->height; + /* + * Scale to pixels per inch... + */ + + out_width = drawable->width * -72.0 / scaling; + out_height = drawable->height * -72.0 / scaling; + } + else + { + /* + * Scale by percent... + */ + + out_width = page_width * scaling / 100.0; + out_height = out_width * drawable->height / drawable->width; + if (out_height > page_height) + { + out_height = page_height * scaling / 100.0; + out_width = out_height * drawable->width / drawable->height; + }; }; /* * Landscape width/height... */ - temp_width = page_width * scaling / 100; - temp_height = temp_width * ydpi / xdpi * drawable->width / drawable->height; - if (temp_height > page_height) + if (scaling < 0.0) { - temp_height = page_height; - temp_width = temp_height * xdpi / ydpi * drawable->height / drawable->width; + /* + * Scale to pixels per inch... + */ + + temp_width = drawable->height * -72.0 / scaling; + temp_height = drawable->width * -72.0 / scaling; + } + else + { + /* + * Scale by percent... + */ + + temp_width = page_width * scaling / 100.0; + temp_height = temp_width * drawable->width / drawable->height; + if (temp_height > page_height) + { + temp_height = page_height; + temp_width = temp_height * drawable->height / drawable->width; + }; }; /* - * See which orientation has the greatest area... + * See which orientation has the greatest area (or if we need to rotate the + * image to fit it on the page...) */ - if ((temp_width * temp_height) > (out_width * out_height) && - orientation != ORIENT_PORTRAIT) + if (orientation == ORIENT_AUTO) + { + if (scaling < 0.0) + { + if ((out_width > page_width && out_height < page_width) || + (out_height > page_height && out_width < page_height)) + orientation = ORIENT_LANDSCAPE; + else + orientation = ORIENT_PORTRAIT; + } + else + { + if ((temp_width * temp_height) > (out_width * out_height)) + orientation = ORIENT_LANDSCAPE; + else + orientation = ORIENT_PORTRAIT; + }; + }; + + if (orientation == ORIENT_LANDSCAPE) { out_width = temp_width; out_height = temp_height; @@ -244,6 +472,18 @@ pcl_print(FILE *prn, /* I - Print file or command */ left = x; }; + if (top < 0 || left < 0) + { + left = (page_width - out_width) / 2; + top = (page_height + out_height) / 2; + }; + +#ifdef DEBUG + printf("page_width = %d, page_height = %d\n", page_width, page_height); + printf("out_width = %d, out_height = %d\n", out_width, out_height); + printf("xdpi = %d, ydpi = %d, landscape = %d\n", xdpi, ydpi, landscape); +#endif /* DEBUG */ + /* * Let the user know what we're doing... */ @@ -254,28 +494,63 @@ pcl_print(FILE *prn, /* I - Print file or command */ * Send PCL initialization commands... */ - fputs("\033E", prn); /* PCL reset */ + fputs("\033E", prn); /* PCL reset */ - switch (media_size) /* Set media size... */ + if (strcmp(media_size, "Letter") == 0) /* Set media size */ { - case MEDIA_LETTER : - fputs("\033&l2A", prn); - break; - case MEDIA_LEGAL : - fputs("\033&l3A", prn); - break; - case MEDIA_TABLOID : - fputs("\033&l6A", prn); - break; - case MEDIA_A4 : - fputs("\033&l26A", prn); - break; - case MEDIA_A3 : - fputs("\033&l27A", prn); - break; + fputs("\033&l2A", prn); + top = 792 - top; + } + else if (strcmp(media_size, "Legal") == 0) + { + fputs("\033&l3A", prn); + top = 1008 - top; + } + else if (strcmp(media_size, "Tabloid") == 0) + { + fputs("\033&l6A", prn); + top = 1214 - top; + } + else if (strcmp(media_size, "A4") == 0) + { + fputs("\033&l26A", prn); + top = 842 - top; + } + else if (strcmp(media_size, "A3") == 0) + { + fputs("\033&l27A", prn); + top = 1191 - top; }; - if (xdpi != ydpi) /* Set resolution */ + fputs("\033&l0L", prn); /* Turn off perforation skip */ + fputs("\033&l0E", prn); /* Reset top margin to 0 */ + + if (strcmp(media_type, "Plain") == 0) /* Set media type */ + fputs("\033&l0M", prn); + else if (strcmp(media_type, "Premium") == 0) + fputs("\033&l2M", prn); + else if (strcmp(media_type, "Glossy") == 0) + fputs("\033&l3M", prn); + else if (strcmp(media_type, "Transparency") == 0) + fputs("\033&l4M", prn); + + if (strcmp(media_type, "Manual") == 0) /* Set media source */ + fputs("\033&l2H", prn); + else if (strcmp(media_type, "Tray 1") == 0) + fputs("\033&l8H", prn); + else if (strcmp(media_type, "Tray 2") == 0) + fputs("\033&l1H", prn); + else if (strcmp(media_type, "Tray 3") == 0) + fputs("\033&l4H", prn); + else if (strcmp(media_type, "Tray 4") == 0) + fputs("\033&l5H", prn); + + if (model >= 500 && model < 1200 && xdpi >= 300) + fputs("\033*r2Q", prn); + else if (model == 1200 && xdpi >= 300) + fputs("\033*o1Q", prn); + + if (xdpi != ydpi) /* Set resolution */ { /* * Send 26-byte configure image data command with horizontal and @@ -283,74 +558,70 @@ pcl_print(FILE *prn, /* I - Print file or command */ */ fputs("\033*g26W", prn); - putc(2, prn); /* Format 2 */ + putc(2, prn); /* Format 2 */ if (output_type == OUTPUT_COLOR) - putc(4, prn); /* # output planes */ + putc(4, prn); /* # output planes */ else - putc(1, prn); /* # output planes */ + putc(1, prn); /* # output planes */ - putc(xdpi >> 8, prn); /* Black resolution */ + putc(xdpi >> 8, prn); /* Black resolution */ putc(xdpi, prn); putc(ydpi >> 8, prn); putc(ydpi, prn); putc(0, prn); - putc(2, prn); /* # of black levels */ + putc(2, prn); /* # of black levels */ - putc(xdpi >> 8, prn); /* Cyan resolution */ + putc(xdpi >> 8, prn); /* Cyan resolution */ putc(xdpi, prn); putc(ydpi >> 8, prn); putc(ydpi, prn); putc(0, prn); - putc(2, prn); /* # of cyan levels */ + putc(2, prn); /* # of cyan levels */ - putc(xdpi >> 8, prn); /* Magenta resolution */ + putc(xdpi >> 8, prn); /* Magenta resolution */ putc(xdpi, prn); putc(ydpi >> 8, prn); putc(ydpi, prn); putc(0, prn); - putc(2, prn); /* # of magenta levels */ + putc(2, prn); /* # of magenta levels */ - putc(xdpi >> 8, prn); /* Yellow resolution */ + putc(xdpi >> 8, prn); /* Yellow resolution */ putc(xdpi, prn); putc(ydpi >> 8, prn); putc(ydpi, prn); putc(0, prn); - putc(2, prn); /* # of yellow levels */ + putc(2, prn); /* # of yellow levels */ } else { - fprintf(prn, "\033*t%dR", xdpi); /* Simple resolution */ + fprintf(prn, "\033*t%dR", xdpi); /* Simple resolution */ if (output_type == OUTPUT_COLOR) { if (model == 501 || model == 1200) - fputs("\033*r-3U", prn); /* Simple CMY color */ + fputs("\033*r-3U", prn); /* Simple CMY color */ else - fputs("\033*r-4U", prn); /* Simple KCMY color */ + fputs("\033*r-4U", prn); /* Simple KCMY color */ }; }; if (model < 3 || model == 500) - fputs("\033*b0M", prn); /* Mode 0 (no compression) */ + fputs("\033*b0M", prn); /* Mode 0 (no compression) */ else - fputs("\033*b2M", prn); /* Mode 2 (TIFF) */ + fputs("\033*b2M", prn); /* Mode 2 (TIFF) */ - if (left < 0 || top < 0) - { - left = (page_width - out_width) / 2; - top = (page_height - out_height) / 2; - } - else - { - left *= 30; - top *= 30; - }; + /* + * Convert image size to printer resolution and setup the page for printing... + */ - fprintf(prn, "\033&a%dH", 720 * left / xdpi); /* Set left raster position */ - fprintf(prn, "\033&a%dV", 720 * top / ydpi); /* Set top raster position */ + out_width = xdpi * out_width / 72; + out_height = ydpi * out_height / 72; + + fprintf(prn, "\033&a%dH", 10 * left); /* Set left raster position */ + fprintf(prn, "\033&a%dV", 10 * top); /* Set top raster position */ fprintf(prn, "\033*r%dS", out_width); /* Set raster width */ fprintf(prn, "\033*r%dT", out_height); /* Set raster height */ - fputs("\033*r1A", prn); /* Start GFX */ + fputs("\033*r1A", prn); /* Start GFX */ /* * Allocate memory for the raster data... @@ -535,7 +806,7 @@ pcl_print(FILE *prn, /* I - Print file or command */ * 'pcl_mode0()' - Send PCL graphics using mode 0 (no) compression. */ -static void +void pcl_mode0(FILE *prn, /* I - Print file or command */ unsigned char *line, /* I - Output bitmap data */ int length, /* I - Length of bitmap data */ @@ -550,7 +821,7 @@ pcl_mode0(FILE *prn, /* I - Print file or command */ * 'pcl_mode2()' - Send PCL graphics using mode 2 (TIFF) compression. */ -static void +void pcl_mode2(FILE *prn, /* I - Print file or command */ unsigned char *line, /* I - Output bitmap data */ int length, /* I - Length of bitmap data */ diff --git a/plug-ins/print/print-ps.c b/plug-ins/print/print-ps.c index 08a53f58c3..2801aae3d2 100644 --- a/plug-ins/print/print-ps.c +++ b/plug-ins/print/print-ps.c @@ -21,47 +21,32 @@ * * Contents: * - * ps_print() - Print an image to a PostScript printer. - * ps_hex() - Print binary data as a series of hexadecimal numbers. - * ps_ascii85() - Print binary data as a series of base-85 numbers. + * ps_parameters() - Return the parameter values for the given + * parameter. + * ps_media_size() - Return the size of the page. + * ps_imageable_area() - Return the imageable area of the page. + * ps_print() - Print an image to a PostScript printer. + * ps_hex() - Print binary data as a series of hexadecimal numbers. + * ps_ascii85() - Print binary data as a series of base-85 numbers. * * Revision History: * * $Log$ - * Revision 1.6 1998/04/13 05:43:14 yosh - * Have fun recompiling gimp everyone. It's the great FSF address change! - * - * -Yosh - * - * Revision 1.5 1998/04/07 03:41:14 yosh - * configure.in: fix for $srcdir != $builddir for data. Tightened check for - * random() and add -lucb on systems that need it. Fix for xdelta.h check. Find - * xemacs as well as emacs. Properly define settings for print plugin. - * - * app/Makefile.am: ditch -DNDEBUG, since nothing uses it - * - * flame: properly handle random() and friends - * - * pnm: workaround for systems with old sprintfs - * - * print, sgi: fold back in portability fixes - * - * threshold_alpha: properly get params in non-interactive mode - * - * bmp: updated and merged in - * - * -Yosh - * - * Revision 1.4 1998/04/01 22:14:46 neo - * Added checks for print spoolers to configure.in as suggested by Michael - * Sweet. The print plug-in still needs some changes to Makefile.am to make - * make use of this. - * - * Updated print and sgi plug-ins to version on the registry. + * Revision 1.7 1998/05/11 19:51:06 neo + * Updated print plug-in to version 2.0 * * * --Sven * + * Revision 1.11 1998/05/08 19:20:50 mike + * Updated to support PPD files, media size, imageable area, and parameter + * functions. + * Added support for scaling modes - scale by percent or scale by PPI. + * Updated Ascii85 output - some Level 2 printers are buggy and won't accept + * whitespace in the data stream. + * Now use image dictionaries with Level 2 printers - allows interpolation + * flag to be sent (not all printers use this flag). + * * Revision 1.10 1998/01/22 15:38:46 mike * Updated copyright notice. * Whoops - wasn't encoding correctly for portrait output to level 2 printers! @@ -106,6 +91,15 @@ #include "print.h" #include +/*#define DEBUG*/ + + +/* + * Local variables... + */ + +static FILE *ps_ppd = NULL; +static char *ps_ppd_file = NULL; /* @@ -114,6 +108,166 @@ static void ps_hex(FILE *, guchar *, int); static void ps_ascii85(FILE *, guchar *, int, int); +static char *ppd_find(char *, char *, char *, int *); + + +/* + * 'ps_parameters()' - Return the parameter values for the given parameter. + */ + +char ** /* O - Parameter values */ +ps_parameters(int model, /* I - Printer model */ + char *ppd_file, /* I - PPD file (not used) */ + char *name, /* I - Name of parameter */ + int *count) /* O - Number of values */ +{ + int i; + char line[1024], + lname[255], + loption[255]; + char **valptrs; + static char *media_sizes[] = + { + "Letter", + "Legal", + "A4", + "Tabloid", + "A3", + "12x18" + }; + + + if (count == NULL) + return (NULL); + + *count = 0; + + if (ppd_file == NULL || name == NULL) + return (NULL); + + if (ps_ppd_file == NULL || strcmp(ps_ppd_file, ppd_file) != 0) + { + if (ps_ppd != NULL) + fclose(ps_ppd); + + ps_ppd = fopen(ppd_file, "r"); + + if (ps_ppd == NULL) + ps_ppd_file = NULL; + else + ps_ppd_file = ppd_file; + }; + + if (ps_ppd == NULL) + { + if (strcmp(name, "PageSize") == 0) + { + *count = 6; + + valptrs = g_new(char *, 6); + for (i = 0; i < 6; i ++) + valptrs[i] = strdup(media_sizes[i]); + + return (valptrs); + } + else + return (NULL); + }; + + rewind(ps_ppd); + *count = 0; + + valptrs = g_new(char *, 100); + + while (fgets(line, sizeof(line), ps_ppd) != NULL) + { + if (line[0] != '*') + continue; + + if (sscanf(line, "*%s %[^/:]", lname, loption) != 2) + continue; + + if (strcasecmp(lname, name) == 0) + { + valptrs[*count] = strdup(loption); + (*count) ++; + }; + }; + + if (*count == 0) + { + g_free(valptrs); + return (NULL); + } + else + return (valptrs); +} + + +/* + * 'ps_media_size()' - Return the size of the page. + */ + +void +ps_media_size(int model, /* I - Printer model */ + char *ppd_file, /* I - PPD file (not used) */ + char *media_size, /* I - Media size */ + int *width, /* O - Width in points */ + int *length) /* O - Length in points */ +{ + char *dimensions; /* Dimensions of media size */ + + +#ifdef DEBUG + printf("ps_media_size(%d, \'%s\', \'%s\', %08x, %08x)\n", model, ppd_file, + media_size, width, length); +#endif /* DEBUG */ + + if ((dimensions = ppd_find(ppd_file, "PaperDimension", media_size, NULL)) != NULL) + sscanf(dimensions, "%d%d", width, length); + else + default_media_size(model, ppd_file, media_size, width, length); +} + + +/* + * 'ps_imageable_area()' - Return the imageable area of the page. + */ + +void +ps_imageable_area(int model, /* I - Printer model */ + char *ppd_file, /* I - PPD file (not used) */ + char *media_size, /* I - Media size */ + int *left, /* O - Left position in points */ + int *right, /* O - Right position in points */ + int *bottom, /* O - Bottom position in points */ + int *top) /* O - Top position in points */ +{ + char *area; /* Imageable area of media */ + float fleft, /* Floating point versions */ + fright, + fbottom, + ftop; + + + if ((area = ppd_find(ppd_file, "ImageableArea", media_size, NULL)) != NULL) + { +#ifdef DEBUG + printf("area = \'%s\'\n", area); +#endif /* DEBUG */ + if (sscanf(area, "%f%f%f%f", &fleft, &fbottom, &fright, &ftop) == 4) + { + *left = (int)fleft; + *right = (int)fright; + *bottom = (int)fbottom; + *top = (int)ftop; + } + else + *left = *right = *bottom = *top = 0; + } + else + *left = *right = *bottom = *top = 0; +} /* @@ -121,25 +275,34 @@ static void ps_ascii85(FILE *, guchar *, int, int); */ void -ps_print(FILE *prn, /* I - File to print to */ - GDrawable *drawable, /* I - Image to print */ - int media_size, /* I - Size of output */ - int xdpi, /* I - Horizontal resolution (always 72) */ - int ydpi, /* I - Vertical resolution (always 72) */ - int output_type, /* I - Output type (color/grayscale) */ - int model, /* I - Model (ignored) */ - guchar *lut, /* I - Brightness lookup table */ - guchar *cmap, /* I - Colormap (for indexed images) */ - int orientation, /* I - Orientation of image */ - int scaling, /* I - Scaling of image */ - int left, /* I - Left offset of image (10ths) */ - int top) /* I - Top offset of image (10ths) */ +ps_print(int model, /* I - Model (Level 1 or 2) */ + char *ppd_file, /* I - PPD file */ + char *resolution, /* I - Resolution */ + char *media_size, /* I - Media size */ + char *media_type, /* I - Media type */ + char *media_source, /* I - Media source */ + int output_type, /* I - Output type (color/grayscale) */ + int orientation, /* I - Orientation of image */ + float scaling, /* I - Scaling of image */ + int left, /* I - Left offset of image (points) */ + int top, /* I - Top offset of image (points) */ + int copies, /* I - Number of copies */ + FILE *prn, /* I - File to print to */ + GDrawable *drawable, /* I - Image to print */ + guchar *lut, /* I - Brightness lookup table */ + guchar *cmap) /* I - Colormap (for indexed images) */ { + int i, j; /* Looping vars */ int x, y; /* Looping vars */ GPixelRgn rgn; /* Image region */ guchar *in, /* Input pixels from image */ - *out; /* Output pixels for printer */ - int page_width, /* Width of page */ + *out, /* Output pixels for printer */ + *outptr; /* Current output pixel */ + int page_left, /* Left margin of page */ + page_right, /* Right margin of page */ + page_top, /* Top of page */ + page_bottom, /* Bottom of page */ + page_width, /* Width of page */ page_height, /* Height of page */ out_width, /* Width of image on page */ out_height, /* Height of image on page */ @@ -151,11 +314,14 @@ ps_print(FILE *prn, /* I - File to print to */ landscape; /* True if we rotate the output 90 degrees */ time_t curtime; /* Current time of day */ convert_t colorfunc; /* Color conversion function... */ - static char *filters[2] = /* PostScript image filters... */ - { - "{currentfile picture readhexstring pop}", /* Level 1 */ - "currentfile /ASCII85Decode filter" /* Level 2 */ - }; + char *command; /* PostScript command */ + int order, /* Order of command */ + num_commands; /* Number of commands */ + struct /* PostScript commands... */ + { + char *command; + int order; + } commands[4]; /* @@ -197,40 +363,100 @@ ps_print(FILE *prn, /* I - File to print to */ * Compute the output size... */ - landscape = 0; - page_width = media_width(media_size, xdpi); - page_height = media_height(media_size, ydpi); + landscape = 0; + ps_imageable_area(model, ppd_file, media_size, &page_left, &page_right, + &page_bottom, &page_top); + + page_width = page_right - page_left; + page_height = page_top - page_bottom; + +#ifdef DEBUG + printf("page_width = %d, page_height = %d\n", page_width, page_height); + printf("drawable->width = %d, drawable->height = %d\n", drawable->width, drawable->height); + printf("scaling = %.1f\n", scaling); +#endif /* DEBUG */ /* * Portrait width/height... */ - out_width = page_width * scaling / 100; - out_height = out_width * ydpi / xdpi * drawable->height / drawable->width; - if (out_height > page_height) + if (scaling < 0.0) { - out_height = page_height; - out_width = out_height * xdpi / ydpi * drawable->width / drawable->height; + /* + * Scale to pixels per inch... + */ + + out_width = drawable->width * -72.0 / scaling; + out_height = drawable->height * -72.0 / scaling; + } + else + { + /* + * Scale by percent... + */ + + out_width = page_width * scaling / 100.0; + out_height = out_width * drawable->height / drawable->width; + if (out_height > page_height) + { + out_height = page_height * scaling / 100.0; + out_width = out_height * drawable->width / drawable->height; + }; }; /* * Landscape width/height... */ - temp_width = page_width * scaling / 100; - temp_height = temp_width * ydpi / xdpi * drawable->width / drawable->height; - if (temp_height > page_height) + if (scaling < 0.0) { - temp_height = page_height; - temp_width = temp_height * xdpi / ydpi * drawable->height / drawable->width; + /* + * Scale to pixels per inch... + */ + + temp_width = drawable->height * -72.0 / scaling; + temp_height = drawable->width * -72.0 / scaling; + } + else + { + /* + * Scale by percent... + */ + + temp_width = page_width * scaling / 100.0; + temp_height = temp_width * drawable->width / drawable->height; + if (temp_height > page_height) + { + temp_height = page_height; + temp_width = temp_height * drawable->height / drawable->width; + }; }; /* - * See which orientation has the greatest area... + * See which orientation has the greatest area (or if we need to rotate the + * image to fit it on the page...) */ - if ((temp_width * temp_height) > (out_width * out_height) && - orientation != ORIENT_PORTRAIT) + if (orientation == ORIENT_AUTO) + { + if (scaling < 0.0) + { + if ((out_width > page_width && out_height < page_width) || + (out_height > page_height && out_width < page_height)) + orientation = ORIENT_LANDSCAPE; + else + orientation = ORIENT_PORTRAIT; + } + else + { + if ((temp_width * temp_height) > (out_width * out_height)) + orientation = ORIENT_LANDSCAPE; + else + orientation = ORIENT_PORTRAIT; + }; + }; + + if (orientation == ORIENT_LANDSCAPE) { out_width = temp_width; out_height = temp_height; @@ -257,19 +483,98 @@ ps_print(FILE *prn, /* I - File to print to */ curtime = time(NULL); + if (top < 0 || left < 0) + { + left = (page_width - out_width) / 2 + page_left; + top = (page_height + out_height) / 2 + page_bottom; + }; + +#ifdef DEBUG + printf("out_width = %d, out_height = %d\n", out_width, out_height); + printf("page_left = %d, page_right = %d, page_bottom = %d, page_top = %d\n", + page_left, page_right, page_bottom, page_top); + printf("left = %d, top = %d\n", left, top); +#endif /* DEBUG */ + fputs("%!PS-Adobe-3.0\n", prn); fputs("%%Creator: " PLUG_IN_NAME " plug-in V" PLUG_IN_VERSION " for GIMP.\n", prn); fprintf(prn, "%%%%CreationDate: %s", ctime(&curtime)); fputs("%%Copyright: 1997-1998 by Michael Sweet (mike@easysw.com)\n", prn); fprintf(prn, "%%%%BoundingBox: %d %d %d %d\n", - (page_width - out_width) / 2 + 18, (page_height - out_height) / 2 + 36, - (page_width + out_width) / 2 + 18, (page_height + out_height) / 2 + 36); + left, top - out_height, left + out_width, top); fputs("%%DocumentData: Clean7Bit\n", prn); fprintf(prn, "%%%%LanguageLevel: %d\n", model + 1); fputs("%%Pages: 1\n", prn); fputs("%%Orientation: Portrait\n", prn); fputs("%%EndComments\n", prn); + /* + * Find any printer-specific commands... + */ + + num_commands = 0; + + if ((command = ppd_find(ppd_file, "PageSize", media_size, &order)) != NULL) + { + commands[num_commands].command = strdup(command); + commands[num_commands].order = order; + num_commands ++; + }; + + if ((command = ppd_find(ppd_file, "InputSlot", media_source, &order)) != NULL) + { + commands[num_commands].command = strdup(command); + commands[num_commands].order = order; + num_commands ++; + }; + + if ((command = ppd_find(ppd_file, "MediaType", media_type, &order)) != NULL) + { + commands[num_commands].command = strdup(command); + commands[num_commands].order = order; + num_commands ++; + }; + + if ((command = ppd_find(ppd_file, "Resolution", resolution, &order)) != NULL) + { + commands[num_commands].command = strdup(command); + commands[num_commands].order = order; + num_commands ++; + }; + + /* + * Sort the commands using the OrderDependency value... + */ + + for (i = 0; i < (num_commands - 1); i ++) + for (j = i + 1; j < num_commands; j ++) + if (commands[j].order < commands[i].order) + { + order = commands[i].order; + command = commands[i].command; + commands[i].command = commands[j].command; + commands[i].order = commands[j].order; + commands[j].command = command; + commands[j].order = order; + }; + + /* + * Send the commands... + */ + + if (num_commands > 0) + { + fputs("%%BeginProlog\n", prn); + + for (i = 0; i < num_commands; i ++) + { + fputs(commands[i].command, prn); + free(commands[i].command); + }; + + fputs("%%EndProlog\n", prn); + }; + /* * Output the page, rotating as necessary... */ @@ -277,87 +582,82 @@ ps_print(FILE *prn, /* I - File to print to */ fputs("%%Page: 1\n", prn); fputs("gsave\n", prn); - if (top < 0 || left < 0) + if (landscape) { - left = (page_width - out_width) / 2 + 18; - top = (page_height - out_height) / 2 + 36; + fprintf(prn, "%d %d translate\n", left, top - out_height); + fprintf(prn, "%.3f %.3f scale\n", + (float)out_width / ((float)drawable->height), + (float)out_height / ((float)drawable->width)); } else { - left = 72 * left / 10 + 18; - top = page_height - out_height - 72 * top / 10 + 36; + fprintf(prn, "%d %d translate\n", left, top); + fprintf(prn, "%.3f %.3f scale\n", + (float)out_width / ((float)drawable->width), + (float)out_height / ((float)drawable->height)); }; - fprintf(prn, "%d %d translate\n", left, top); - fprintf(prn, "%d %d scale\n", out_width, out_height); + in = g_malloc(drawable->width * drawable->bpp); + out = g_malloc(drawable->width * out_bpp + 3); - if (landscape) + if (model == 0) { - in = g_malloc(drawable->height * drawable->bpp); - out = g_malloc(drawable->height * out_bpp + 3); + fprintf(prn, "/picture %d string def\n", drawable->width * out_bpp); - if (model == 0) - fprintf(prn, "/picture %d string def\n", drawable->height * out_bpp); + fprintf(prn, "%d %d 8\n", drawable->width, drawable->height); + + if (landscape) + fputs("[ 0 1 1 0 0 0 ]\n", prn); + else + fputs("[ 1 0 0 -1 0 1 ]\n", prn); if (output_type == OUTPUT_GRAY) - fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] %s image\n", - drawable->height, drawable->width, - drawable->height, drawable->width, 0, - filters[model]); + fputs("{currentfile picture readhexstring pop} image\n", prn); else - fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] %s false 3 colorimage\n", - drawable->height, drawable->width, - drawable->height, drawable->width, 0, - filters[model]); + fputs("{currentfile picture readhexstring pop} false 3 colorimage\n", prn); - for (x = 0, out_offset = 0; x < drawable->width; x ++) + for (y = 0; y < drawable->height; y ++) { - if ((x & 15) == 0) - gimp_progress_update((double)x / (double)drawable->width); + if ((y & 15) == 0) + gimp_progress_update((double)y / (double)drawable->height); - gimp_pixel_rgn_get_col(&rgn, in, x, 0, drawable->height); - (*colorfunc)(in, out + out_offset, drawable->height, drawable->bpp, lut, cmap); + gimp_pixel_rgn_get_row(&rgn, in, 0, y, drawable->width); + (*colorfunc)(in, out, drawable->width, drawable->bpp, lut, cmap); - if (model) - { - out_length = out_offset + drawable->height * out_bpp; - - if (x < (drawable->width - 1)) - { - ps_ascii85(prn, out, out_length & ~3, 0); - out_offset = out_length & 3; - } - else - { - ps_ascii85(prn, out, out_length, 1); - out_offset = 0; - }; - - if (out_offset > 0) - memcpy(out, out + out_length - out_offset, out_offset); - } - else - ps_hex(prn, out, drawable->height * out_bpp); + ps_hex(prn, out, drawable->width * out_bpp); }; } else { - in = g_malloc(drawable->width * drawable->bpp); - out = g_malloc(drawable->width * out_bpp + 3); + if (output_type == OUTPUT_GRAY) + fputs("/DeviceGray setcolorspace\n", prn); + else + fputs("/DeviceRGB setcolorspace\n", prn); - if (model == 0) - fprintf(prn, "/picture %d string def\n", drawable->width * out_bpp); + fputs("<<\n", prn); + fputs("\t/ImageType 1\n", prn); + + fprintf(prn, "\t/Width %d\n", drawable->width); + fprintf(prn, "\t/Height %d\n", drawable->height); + fputs("\t/BitsPerComponent 8\n", prn); if (output_type == OUTPUT_GRAY) - fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] %s image\n", - drawable->width, drawable->height, - drawable->width, -drawable->height, drawable->height, - filters[model]); + fputs("\t/Decode [ 0 1 ]\n", prn); else - fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] %s false 3 colorimage\n", - drawable->width, drawable->height, - drawable->width, -drawable->height, drawable->height, - filters[model]); + fputs("\t/Decode [ 0 1 0 1 0 1 ]\n", prn); + + fputs("\t/DataSource currentfile /ASCII85Decode filter\n", prn); + + if ((drawable->width * 72 / out_width) < 100) + fputs("\t/Interpolate true\n", prn); + + if (landscape) + fputs("\t/ImageMatrix [ 0 1 1 0 0 0 ]\n", prn); + else + fputs("\t/ImageMatrix [ 1 0 0 -1 0 1 ]\n", prn); + + fputs(">>\n", prn); + fputs("image\n", prn); for (y = 0, out_offset = 0; y < drawable->height; y ++) { @@ -367,26 +667,21 @@ ps_print(FILE *prn, /* I - File to print to */ gimp_pixel_rgn_get_row(&rgn, in, 0, y, drawable->width); (*colorfunc)(in, out + out_offset, drawable->width, drawable->bpp, lut, cmap); - if (model) + out_length = out_offset + drawable->width * out_bpp; + + if (y < (drawable->height - 1)) { - out_length = out_offset + drawable->width * out_bpp; - - if (y < (drawable->height - 1)) - { - ps_ascii85(prn, out, out_length & ~3, 0); - out_offset = out_length & 3; - } - else - { - ps_ascii85(prn, out, out_length, 1); - out_offset = 0; - }; - - if (out_offset > 0) - memcpy(out, out + out_length - out_offset, out_offset); + ps_ascii85(prn, out, out_length & ~3, 0); + out_offset = out_length & 3; } else - ps_hex(prn, out, drawable->width * out_bpp); + { + ps_ascii85(prn, out, out_length, 1); + out_offset = 0; + }; + + if (out_offset > 0) + memcpy(out, out + out_length - out_offset, out_offset); }; }; @@ -409,9 +704,11 @@ ps_hex(FILE *prn, /* I - File to print to */ guchar *data, /* I - Data to print */ int length) /* I - Number of bytes to print */ { + int col; /* Current column */ static char *hex = "0123456789ABCDEF"; + col = 0; while (length > 0) { /* @@ -424,9 +721,14 @@ ps_hex(FILE *prn, /* I - File to print to */ data ++; length --; + + col = (col + 1) & 31; + if (col == 0) + putc('\n', prn); }; - putc('\n', prn); + if (col > 0) + putc('\n', prn); } @@ -440,12 +742,11 @@ ps_ascii85(FILE *prn, /* I - File to print to */ int length, /* I - Number of bytes to print */ int last_line) /* I - Last line of raster data? */ { + int i; /* Looping var */ unsigned b; /* Binary data word */ unsigned char c[5]; /* ASCII85 encoded chars */ - int col; /* Current column */ - col = 0; while (length > 3) { b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; @@ -469,17 +770,13 @@ ps_ascii85(FILE *prn, /* I - File to print to */ data += 4; length -= 4; - - col = (col + 1) & 15; - if (col == 0 && length > 0) - putc('\n', prn); }; if (last_line) { if (length > 0) { - for (b = 0, col = length; col > 0; b = (b << 8) | data[0], data ++, col --); + for (b = 0, i = length; i > 0; b = (b << 8) | data[0], data ++, i --); c[4] = (b % 85) + '!'; b /= 85; @@ -495,9 +792,93 @@ ps_ascii85(FILE *prn, /* I - File to print to */ }; fputs("~>\n", prn); - } - else - putc('\n', prn); + }; +} + + +/* + * 'ppd_find()' - Find a control string with the specified name & parameters. + */ + +static char * /* O - Control string */ +ppd_find(char *ppd_file, /* I - Name of PPD file */ + char *name, /* I - Name of parameter */ + char *option, /* I - Value of parameter */ + int *order) /* O - Order of the control string */ +{ + char line[1024], /* Line from file */ + lname[255], /* Name from line */ + loption[255], /* Value from line */ + *opt; /* Current control string pointer */ + static char value[32768]; /* Current control string value */ + + + if (ppd_file == NULL || name == NULL || option == NULL) + return (NULL); + + if (ps_ppd_file == NULL || strcmp(ps_ppd_file, ppd_file) != 0) + { + if (ps_ppd != NULL) + fclose(ps_ppd); + + ps_ppd = fopen(ppd_file, "r"); + + if (ps_ppd == NULL) + ps_ppd_file = NULL; + else + ps_ppd_file = ppd_file; + }; + + if (ps_ppd == NULL) + return (NULL); + + if (order != NULL) + *order = 1000; + + rewind(ps_ppd); + while (fgets(line, sizeof(line), ps_ppd) != NULL) + { + if (line[0] != '*') + continue; + + if (strncasecmp(line, "*OrderDependency:", 17) == 0 && order != NULL) + { + sscanf(line, "%*s%d", order); + continue; + } + else if (sscanf(line, "*%s %[^/:]", lname, loption) != 2) + continue; + + if (strcasecmp(lname, name) == 0 && + strcasecmp(loption, option) == 0) + { + opt = strchr(line, ':') + 1; + while (*opt == ' ' || *opt == '\t') + opt ++; + if (*opt != '\"') + continue; + + strcpy(value, opt + 1); + if ((opt = strchr(value, '\"')) == NULL) + { + while (fgets(line, sizeof(line), ps_ppd) != NULL) + { + strcat(value, line); + if (strchr(line, '\"') != NULL) + { + strcpy(strchr(value, '\"'), "\n"); + break; + }; + }; + } + else + *opt = '\0'; + + return (value); + }; + }; + + return (NULL); } diff --git a/plug-ins/print/print-util.c b/plug-ins/print/print-util.c index 6f6f2698e1..3ece899552 100644 --- a/plug-ins/print/print-util.c +++ b/plug-ins/print/print-util.c @@ -21,73 +21,30 @@ * * Contents: * - * dither_black() - Dither grayscale pixels to black. - * dither_cmyk() - Dither RGB pixels to cyan, magenta, yellow, and black. - * gray_to_gray() - Convert grayscale image data to grayscale. - * indexed_to_gray() - Convert indexed image data to grayscale. - * indexed_to_rgb() - Convert indexed image data to RGB. - * media_width() - Get the addressable width of the page. - * media_height() - Get the addressable height of the page. - * rgb_to_gray() - Convert RGB image data to grayscale. - * rgb_to_rgb() - Convert RGB image data to RGB. + * dither_black() - Dither grayscale pixels to black. + * dither_cmyk() - Dither RGB pixels to cyan, magenta, yellow, and + * black. + * gray_to_gray() - Convert grayscale image data to grayscale. + * indexed_to_gray() - Convert indexed image data to grayscale. + * indexed_to_rgb() - Convert indexed image data to RGB. + * rgb_to_gray() - Convert RGB image data to grayscale. + * rgb_to_rgb() - Convert RGB image data to RGB. + * default_media_size() - Return the size of a default page size. * * Revision History: * * $Log$ - * Revision 1.7 1998/04/13 05:43:15 yosh - * Have fun recompiling gimp everyone. It's the great FSF address change! - * - * -Yosh - * - * Revision 1.6 1998/04/11 05:07:46 yosh - * * app/app_procs.c: fixed up idle handler for file open (look like testgtk - * idle demo) - * - * * app/colomaps.c: fixup for visual test and use of gdk_color_alloc for some - * fixed colors (from Owen Taylor) - * - * * app/errors.h - * * app/errors.c - * * app/main.c - * * libgimp/gimp.c: redid the signal handlers so we only get a debug prompt on - * SIGSEGV, SIGBUS, and SIGFPE. - * - * * applied gimp-jbuhler-980408-0 and gimp-joke-980409-0 (warning fixups) - * - * * applied gimp-monnaux-980409-0 for configurable plugin path for multiarch - * setups - * - * -Yosh - * - * Revision 1.5 1998/04/07 03:41:15 yosh - * configure.in: fix for $srcdir != $builddir for data. Tightened check for - * random() and add -lucb on systems that need it. Fix for xdelta.h check. Find - * xemacs as well as emacs. Properly define settings for print plugin. - * - * app/Makefile.am: ditch -DNDEBUG, since nothing uses it - * - * flame: properly handle random() and friends - * - * pnm: workaround for systems with old sprintfs - * - * print, sgi: fold back in portability fixes - * - * threshold_alpha: properly get params in non-interactive mode - * - * bmp: updated and merged in - * - * -Yosh - * - * Revision 1.4 1998/04/01 22:14:47 neo - * Added checks for print spoolers to configure.in as suggested by Michael - * Sweet. The print plug-in still needs some changes to Makefile.am to make - * make use of this. - * - * Updated print and sgi plug-ins to version on the registry. + * Revision 1.8 1998/05/11 19:51:25 neo + * Updated print plug-in to version 2.0 * * * --Sven * + * Revision 1.12 1998/05/08 19:20:50 mike + * Updated CMYK generation code to use new method. + * Updated dithering algorithm (slightly more uniform now, less speckling) + * Added default media size function. + * * Revision 1.11 1998/03/01 18:03:27 mike * Whoops - need to add 255 - alpha to the output values (transparent to white * and not transparent to black...) @@ -152,15 +109,16 @@ /* - * Error buffer for dither functions. This needs to be at least 11xMAXDPI + * Error buffer for dither functions. This needs to be at least 14xMAXDPI * (currently 720) to avoid problems... */ -int error[2][4][11*720+4] = +int error[2][4][14*720+4] = { { { 0 }, { 0 }, { 0 } , { 0 } }, { { 0 }, { 0 }, { 0 } , { 0 } } - }; + }; + /* * 'dither_black()' - Dither grayscale pixels to black. @@ -203,7 +161,7 @@ dither_black(guchar *gray, /* I - Grayscale pixels */ x < dst_width; x ++, kerror0 ++, kerror1 ++) { - k = 255 - *gray + ditherk / 4; + k = 255 - *gray + ditherk / 8; if (k > 127) { *kptr |= bit; @@ -212,13 +170,13 @@ dither_black(guchar *gray, /* I - Grayscale pixels */ if (ditherbit & bit) { - kerror1[0] = 3 * k; - ditherk = kerror0[1] + k; + kerror1[0] = 5 * k; + ditherk = kerror0[1] + 3 * k; } else { - kerror1[0] = k; - ditherk = kerror0[1] + 3 * k; + kerror1[0] = 3 * k; + ditherk = kerror0[1] + 5 * k; }; if (bit == 1) @@ -349,12 +307,12 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */ * CMY as necessary to give better blues, greens, and reds... :) */ - c = (255 - (rgb[1] + rgb[2]) / 8) * (c - k) / divk; - m = (255 - (rgb[0] + rgb[2]) / 8) * (m - k) / divk; - y = (255 - (rgb[0] + rgb[1]) / 8) * (y - k) / divk; + c = (255 - rgb[1] / 4) * (c - k) / divk; + m = (255 - rgb[2] / 4) * (m - k) / divk; + y = (255 - rgb[0] / 4) * (y - k) / divk; }; - k += ditherk / 4; + k += ditherk / 8; if (k > 127) { *kptr |= bit; @@ -363,13 +321,13 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */ if (ditherbit & bit) { - kerror1[0] = 3 * k; - ditherk = kerror0[1] + k; + kerror1[0] = 5 * k; + ditherk = kerror0[1] + 3 * k; } else { - kerror1[0] = k; - ditherk = kerror0[1] + 3 * k; + kerror1[0] = 3 * k; + ditherk = kerror0[1] + 5 * k; }; if (bit == 1) @@ -382,12 +340,12 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */ * better reds, greens, and blues... */ - c = (255 - (rgb[1] + rgb[2]) / 8) * (c - k) / 255 + k; - m = (255 - (rgb[0] + rgb[2]) / 8) * (m - k) / 255 + k; - y = (255 - (rgb[0] + rgb[1]) / 8) * (y - k) / 255 + k; + c = (255 - rgb[1] / 4) * (c - k) / 255 + k; + m = (255 - rgb[2] / 4) * (m - k) / 255 + k; + y = (255 - rgb[0] / 4) * (y - k) / 255 + k; }; - c += ditherc / 4; + c += ditherc / 8; if (c > 127) { *cptr |= bit; @@ -396,16 +354,16 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */ if (ditherbit & bit) { - cerror1[0] = 3 * c; - ditherc = cerror0[1] + c; + cerror1[0] = 5 * c; + ditherc = cerror0[1] + 3 * c; } else { - cerror1[0] = c; - ditherc = cerror0[1] + 3 * c; + cerror1[0] = 3 * c; + ditherc = cerror0[1] + 5 * c; }; - m += ditherm / 4; + m += ditherm / 8; if (m > 127) { *mptr |= bit; @@ -414,16 +372,16 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */ if (ditherbit & bit) { - merror1[0] = 3 * m; - ditherm = merror0[1] + m; + merror1[0] = 5 * m; + ditherm = merror0[1] + 3 * m; } else { - merror1[0] = m; - ditherm = merror0[1] + 3 * m; + merror1[0] = 3 * m; + ditherm = merror0[1] + 5 * m; }; - y += dithery / 4; + y += dithery / 8; if (y > 127) { *yptr |= bit; @@ -432,13 +390,13 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */ if (ditherbit & bit) { - yerror1[0] = 3 * y; - dithery = yerror0[1] + y; + yerror1[0] = 5 * y; + dithery = yerror0[1] + 3 * y; } else { - yerror1[0] = y; - dithery = yerror0[1] + 3 * y; + yerror1[0] = 3 * y; + dithery = yerror0[1] + 5 * y; }; if (bit == 1) @@ -606,70 +564,6 @@ indexed_to_rgb(guchar *indexed, /* I - Indexed pixels */ } -/* - * 'media_width()' - Get the addressable width of the page. - * - * This function assumes a standard left/right margin of 0.25". - */ - -int -media_width(int media_size, /* I - Media size code */ - int dpi) /* I - Resolution in dots-per-inch */ -{ - switch (media_size) - { - case MEDIA_LETTER : - case MEDIA_LEGAL : - return (8 * dpi); - - case MEDIA_TABLOID : - return ((int)(10.5 * dpi + 0.5)); - - case MEDIA_A4 : - return ((int)(7.77 * dpi + 0.5)); - - case MEDIA_A3 : - return ((int)(11.09 * dpi + 0.5)); - - default : - return (0); - }; -} - - -/* - * 'media_height()' - Get the addressable height of the page. - * - * This function assumes a standard top/bottom margin of 0.5". - */ - -int -media_height(int media_size, /* I - Media size code */ - int dpi) /* I - Resolution in dots-per-inch */ -{ - switch (media_size) - { - case MEDIA_LETTER : - return (10 * dpi); - - case MEDIA_LEGAL : - return (13 * dpi); - - case MEDIA_TABLOID : - return (16 * dpi); - - case MEDIA_A4 : - return ((int)(10.69 * dpi + 0.5)); - - case MEDIA_A3 : - return ((int)(15.54 * dpi + 0.5)); - - default : - return (0); - }; -} - - /* * 'rgb_to_gray()' - Convert RGB image data to grayscale. */ @@ -761,6 +655,55 @@ rgb_to_rgb(guchar *rgbin, /* I - RGB pixels */ } +/* + * 'default_media_size()' - Return the size of a default page size. + */ + +void +default_media_size(int model, /* I - Printer model */ + char *ppd_file, /* I - PPD file (not used) */ + char *media_size, /* I - Media size */ + int *width, /* O - Width in points */ + int *length) /* O - Length in points */ +{ + if (strcmp(media_size, "Letter") == 0) + { + *width = 612; + *length = 792; + } + else if (strcmp(media_size, "Legal") == 0) + { + *width = 612; + *length = 1008; + } + else if (strcmp(media_size, "Tabloid") == 0) + { + *width = 792; + *length = 1214; + } + else if (strcmp(media_size, "12x18") == 0) + { + *width = 864; + *length = 1296; + } + else if (strcmp(media_size, "A4") == 0) + { + *width = 595; + *length = 842; + } + else if (strcmp(media_size, "A3") == 0) + { + *width = 842; + *length = 1191; + } + else + { + *width = 0; + *length = 0; + }; +} + + /* * End of "$Id$". */ diff --git a/plug-ins/print/print.c b/plug-ins/print/print.c index e64572aa99..3851aea25e 100644 --- a/plug-ins/print/print.c +++ b/plug-ins/print/print.c @@ -39,40 +39,22 @@ * Revision History: * * $Log$ - * Revision 1.7 1998/04/13 05:43:16 yosh - * Have fun recompiling gimp everyone. It's the great FSF address change! - * - * -Yosh - * - * Revision 1.6 1998/04/07 03:41:16 yosh - * configure.in: fix for $srcdir != $builddir for data. Tightened check for - * random() and add -lucb on systems that need it. Fix for xdelta.h check. Find - * xemacs as well as emacs. Properly define settings for print plugin. - * - * app/Makefile.am: ditch -DNDEBUG, since nothing uses it - * - * flame: properly handle random() and friends - * - * pnm: workaround for systems with old sprintfs - * - * print, sgi: fold back in portability fixes - * - * threshold_alpha: properly get params in non-interactive mode - * - * bmp: updated and merged in - * - * -Yosh - * - * Revision 1.5 1998/04/01 22:14:48 neo - * Added checks for print spoolers to configure.in as suggested by Michael - * Sweet. The print plug-in still needs some changes to Makefile.am to make - * make use of this. - * - * Updated print and sgi plug-ins to version on the registry. + * Revision 1.8 1998/05/11 19:52:36 neo + * Updated print plug-in to version 2.0 * * * --Sven * + * Revision 1.16 1998/05/08 20:52:55 mike + * Whoops, wasn't showing/hiding PPD file browse button. + * + * Revision 1.15 1998/05/08 19:20:50 mike + * Updated for new driver interface. + * Added GUI for printer driver setup, PPD files. + * Now display file chooser when user selects "print to file" + * Added PPI/percent-of-page toggle for scaling. + * Added options for media type, resolution, and media source. + * * Revision 1.14 1998/03/01 17:29:42 mike * Added LPC/LPR/LP/LPSTAT_COMMAND definitions for portability. * @@ -140,7 +122,7 @@ #define SCALE_WIDTH 64 #define ENTRY_WIDTH 64 -#define PREVIEW_SIZE 180 /* Assuming max media size of 18" */ +#define PREVIEW_SIZE 220 /* Assuming max media size of 22" */ #define MAX_PLIST 100 @@ -150,10 +132,15 @@ typedef struct /**** Printer List ****/ { - char name[17], /* Name of printer */ - command[255], /* Printer command */ - driver[33]; /* Short name of printer driver */ - int output_type; /* Color/B&W */ + char name[17], /* Name of printer */ + command[255], /* Printer command */ + driver[33], /* Short name of printer driver */ + ppd_file[255]; /* PPD file for printer */ + int output_type; /* Color/B&W */ + char resolution[33], /* Resolution */ + media_size[33], /* Media size */ + media_type[33], /* Media type */ + media_source[33]; /* Media source */ } plist_t; @@ -168,19 +155,33 @@ static void get_printers(void); static void query(void); static void run(char *, int, GParam *, int *, GParam **); -static int print_dialog(void); -static void dialog_create_ivalue(char *, GtkTable *, int, gint *, int, int); -static void dialog_iscale_update(GtkAdjustment *, gint *); -static void dialog_ientry_update(GtkWidget *, gint *); +static int do_print_dialog(void); +static void brightness_update(GtkAdjustment *); +static void brightness_callback(GtkWidget *); +static void scaling_update(GtkAdjustment *); +static void scaling_callback(GtkWidget *); static void plist_callback(GtkWidget *, gint); -static void print_driver_callback(GtkWidget *, gint); static void media_size_callback(GtkWidget *, gint); -static void print_command_callback(GtkWidget *, gpointer); +static void media_type_callback(GtkWidget *, gint); +static void media_source_callback(GtkWidget *, gint); +static void resolution_callback(GtkWidget *, gint); static void output_type_callback(GtkWidget *, gint); static void orientation_callback(GtkWidget *, gint); -static void print_callback(GtkWidget *, gpointer); -static void cancel_callback(GtkWidget *, gpointer); -static void close_callback(GtkWidget *, gpointer); +static void print_callback(void); +static void cancel_callback(void); +static void close_callback(void); + +static void setup_open_callback(void); +static void setup_ok_callback(void); +static void setup_cancel_callback(void); +static void ppd_browse_callback(void); +static void ppd_ok_callback(void); +static void ppd_cancel_callback(void); +static void print_driver_callback(GtkWidget *, gint); + +static void file_ok_callback(void); +static void file_cancel_callback(void); + static void preview_update(void); static void preview_button_callback(GtkWidget *, GdkEventButton *); static void preview_motion_callback(GtkWidget *, GdkEventMotion *); @@ -201,31 +202,72 @@ GPlugInInfo PLUG_IN_INFO = /* Plug-in information */ struct /* Plug-in variables */ { char output_to[255], /* Name of file or command to print to */ - short_name[33]; /* Name of printer "driver" */ - gint media_size, /* Size of output media */ - output_type, /* Color or grayscale output */ - brightness, /* Output brightness */ - scaling, /* Scaling, percent of printable area */ - orientation, /* Orientation - 0 = port., 1 = land., -1 = auto */ - left, /* Offset from lower-lefthand corner, 10ths */ + short_name[33], /* Name of printer "driver" */ + ppd_file[255]; /* PPD file */ + gint output_type; /* Color or grayscale output */ + char resolution[33], /* Resolution */ + media_size[33], /* Media size */ + media_type[33], /* Media type */ + media_source[33]; /* Media source */ + gint brightness; /* Output brightness */ + float scaling; /* Scaling, percent of printable area */ + gint orientation, /* Orientation - 0 = port., 1 = land., -1 = auto */ + left, /* Offset from lower-lefthand corner, points */ top; /* ... */ } vars = { "", /* Name of file or command to print to */ "ps2", /* Name of printer "driver" */ - MEDIA_LETTER, /* Size of output media */ + "", /* Name of PPD file */ OUTPUT_COLOR, /* Color or grayscale output */ + "", /* Output resolution */ + "", /* Size of output media */ + "", /* Type of output media */ + "", /* Source of output media */ 100, /* Output brightness */ - 100, /* Scaling (100% means entire printable area */ + 100.0, /* Scaling (100% means entire printable area, */ + /* -XXX means scale by PPI) */ -1, /* Orientation (-1 = automatic) */ -1, /* X offset (-1 = center) */ -1 /* Y offset (-1 = center) */ }; -GtkWidget *printer_driver, /* Printer driver widget */ +GtkWidget *print_dialog, /* Print dialog window */ + *media_size, /* Media size option button */ + *media_size_menu=NULL, /* Media size menu */ + *media_type, /* Media type option button */ + *media_type_menu=NULL, /* Media type menu */ + *media_source, /* Media source option button */ + *media_source_menu=NULL,/* Media source menu */ + *resolution, /* Resolution option button */ + *resolution_menu=NULL, /* Resolution menu */ + *scaling_scale, /* Scale widget for scaling */ + *scaling_entry, /* Text entry widget for scaling */ + *scaling_percent, /* Scale by percent */ + *scaling_ppi, /* Scale by pixels-per-inch */ + *brightness_scale, /* Scale for brightness */ + *brightness_entry, /* Text entry widget for brightness */ *output_gray, /* Output type toggle, black */ *output_color, /* Output type toggle, color */ - *output_to; /* Output file/command text entry */ + *setup_dialog, /* Setup dialog window */ + *printer_driver, /* Printer driver widget */ + *ppd_file, /* PPD file entry */ + *ppd_button, /* PPD file browse button */ + *output_cmd, /* Output command text entry */ + *ppd_browser, /* File selection dialog for PPD files */ + *file_browser; /* FSD for print files */ + +GtkObject *scaling_adjustment, /* Adjustment object for scaling */ + *brightness_adjustment; /* Adjustment object for brightness */ + +int num_media_sizes=0; /* Number of media sizes */ +char **media_sizes; /* Media size strings */ +int num_media_types=0; /* Number of media types */ +char **media_types; /* Media type strings */ +int num_media_sources=0; /* Number of media sources */ +char **media_sources; /* Media source strings */ +int num_resolutions=0; /* Number of resolutions */ +char **resolutions; /* Resolution strings */ GtkDrawingArea *preview; /* Preview drawing area widget */ int mouse_x, /* Last mouse X */ @@ -248,29 +290,58 @@ int runme = FALSE, /* True if print should proceed */ printer_t printers[] = /* List of supported printer types */ { - { "PostScript Printer", "ps", 72, 72, 1, 1, 0, 1.000, 1.000, ps_print }, - { "PostScript Printer (Level 2)", "ps2", 72, 72, 1, 1, 1, 1.000, 1.000, ps_print }, - { "HP DeskJet 500, 520", "pcl-500", 300, 300, 0, 0, 500, 0.541, 0.548, pcl_print }, - { "HP DeskJet 500C, 540C", "pcl-501", 300, 300, 0, 1, 501, 0.541, 0.548, pcl_print }, - { "HP DeskJet 550C, 560C", "pcl-550", 300, 300, 0, 1, 550, 0.541, 0.548, pcl_print }, - { "HP DeskJet 600 series", "pcl-600", 600, 300, 0, 1, 600, 0.541, 0.548, pcl_print }, - { "HP DeskJet 800 series", "pcl-800", 600, 600, 0, 1, 800, 0.541, 0.548, pcl_print }, - { "HP DeskJet 1200C, 1600C", "pcl-1200", 300, 300, 0, 1, 1200, 0.541, 0.548, pcl_print }, - { "HP LaserJet II series", "pcl-2", 300, 300, 0, 0, 2, 0.563, 0.596, pcl_print }, - { "HP LaserJet III series", "pcl-3", 300, 300, 0, 0, 3, 0.563, 0.596, pcl_print }, - { "HP LaserJet 4 series", "pcl-4", 600, 600, 1, 0, 4, 0.599, 0.615, pcl_print }, - { "HP LaserJet 5 series", "pcl-5", 600, 600, 1, 0, 4, 0.599, 0.615, pcl_print }, - { "HP LaserJet 6 series", "pcl-6", 600, 600, 1, 0, 4, 0.599, 0.615, pcl_print }, - { "EPSON Stylus Color", "escp2", 720, 720, 0, 1, 0, 0.325, 0.478, escp2_print }, - { "EPSON Stylus Color Pro", "escp2-pro", 720, 720, 0, 1, 1, 0.325, 0.478, escp2_print }, - { "EPSON Stylus Color Pro XL","escp2-proxl", 720, 720, 1, 1, 1, 0.325, 0.478, escp2_print }, - { "EPSON Stylus Color 1500", "escp2-1500", 720, 720, 1, 1, 2, 0.325, 0.478, escp2_print }, - { "EPSON Stylus Color 400", "escp2-400", 720, 720, 0, 1, 1, 0.530, 0.482, escp2_print }, - { "EPSON Stylus Color 500", "escp2-500", 720, 720, 0, 1, 1, 0.530, 0.482, escp2_print }, - { "EPSON Stylus Color 600", "escp2-600", 720, 720, 0, 1, 3, 0.530, 0.482, escp2_print }, - { "EPSON Stylus Color 800", "escp2-800", 720, 720, 0, 1, 4, 0.530, 0.482, escp2_print }, - { "EPSON Stylus Color 1520", "escp2-1520", 720, 720, 1, 1, 4, 0.530, 0.482, escp2_print }, - { "EPSON Stylus Color 3000", "escp2-3000", 720, 720, 1, 1, 4, 0.530, 0.482, escp2_print } + { "PostScript Level 1", "ps", 1, 0, 1.000, 1.000, + ps_parameters, ps_media_size, ps_imageable_area, ps_print }, + { "PostScript Level 2", "ps2", 1, 1, 1.000, 1.000, + ps_parameters, ps_media_size, ps_imageable_area, ps_print }, + { "HP DeskJet 500, 520", "pcl-500", 0, 500, 0.541, 0.548, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP DeskJet 500C, 540C", "pcl-501", 1, 501, 0.541, 0.548, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP DeskJet 550C, 560C", "pcl-550", 1, 550, 0.541, 0.548, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP DeskJet 600 series", "pcl-600", 1, 600, 0.541, 0.548, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP DeskJet 800 series", "pcl-800", 1, 800, 0.541, 0.548, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP DeskJet 1100C, 1120C", "pcl-1100", 1, 1100, 0.541, 0.548, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP DeskJet 1200C, 1600C", "pcl-1200", 1, 1200, 0.541, 0.548, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP LaserJet II series", "pcl-2", 0, 2, 0.563, 0.596, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP LaserJet III series", "pcl-3", 0, 3, 0.563, 0.596, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP LaserJet 4 series", "pcl-4", 0, 4, 0.599, 0.615, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP LaserJet 4V, 4Si", "pcl-4v", 0, 5, 0.599, 0.615, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP LaserJet 5 series", "pcl-5", 0, 4, 0.599, 0.615, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP LaserJet 5Si", "pcl-5si", 0, 5, 0.599, 0.615, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "HP LaserJet 6 series", "pcl-6", 0, 4, 0.599, 0.615, + pcl_parameters, default_media_size, pcl_imageable_area, pcl_print }, + { "EPSON Stylus Color", "escp2", 1, 0, 0.325, 0.478, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color Pro", "escp2-pro", 1, 1, 0.325, 0.478, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color Pro XL","escp2-proxl", 1, 1, 0.325, 0.478, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color 1500", "escp2-1500", 1, 2, 0.325, 0.478, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color 400", "escp2-400", 1, 1, 0.530, 0.482, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color 500", "escp2-500", 1, 1, 0.530, 0.482, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color 600", "escp2-600", 1, 3, 0.530, 0.482, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color 800", "escp2-800", 1, 4, 0.530, 0.482, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color 1520", "escp2-1520", 1, 5, 0.530, 0.482, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print }, + { "EPSON Stylus Color 3000", "escp2-3000", 1, 5, 0.530, 0.482, + escp2_parameters, default_media_size, escp2_imageable_area, escp2_print } }; @@ -300,10 +371,14 @@ query(void) { PARAM_DRAWABLE, "drawable", "Input drawable" }, { PARAM_STRING, "output_to", "Print command or filename (| to pipe to command)" }, { PARAM_STRING, "driver", "Printer driver short name" }, - { PARAM_INT32, "media_size", "Media size (0 = A/letter, 1 = legal, 2 = B/tabloid, 3 = A4, 4 = A3)" }, + { PARAM_STRING, "ppd_file", "PPD file" }, { PARAM_INT32, "output_type", "Output type (0 = gray, 1 = color)" }, + { PARAM_STRING, "resolution", "Resolution (\"300\", \"720\", etc.)" }, + { PARAM_STRING, "media_size", "Media size (\"Letter\", \"A4\", etc.)" }, + { PARAM_STRING, "media_type", "Media type (\"Plain\", \"Glossy\", etc.)" }, + { PARAM_STRING, "media_source", "Media source (\"Tray1\", \"Manual\", etc.)" }, { PARAM_INT32, "brightness", "Brightness (0-200%)" }, - { PARAM_INT32, "scaling", "Output scaling (0-100%)" }, + { PARAM_FLOAT, "scaling", "Output scaling (0-100%, -PPI)" }, { PARAM_INT32, "orientation", "Output orientation (-1 = auto, 0 = portrait, 1 = landscape)" }, { PARAM_INT32, "left", "Left offset (10ths inches, -1 = centered)" }, { PARAM_INT32, "top", "Top offset (10ths inches, -1 = centered)" } @@ -318,7 +393,7 @@ query(void) "Michael Sweet ", "Copyright 1997-1998 by Michael Sweet", PLUG_IN_VERSION, - "/File/Print...", + "/File/Print", "RGB*,GRAY*,INDEXED*", PROC_PLUG_IN, nargs, @@ -395,7 +470,7 @@ run(char *name, /* I - Name of print program. */ * Get information from the dialog... */ - if (!print_dialog()) + if (!do_print_dialog()) return; break; @@ -404,40 +479,48 @@ run(char *name, /* I - Name of print program. */ * Make sure all the arguments are present... */ - if (nparams < 8) + if (nparams < 11) values[0].data.d_status = STATUS_CALLING_ERROR; else { strcpy(vars.output_to, param[3].data.d_string); strcpy(vars.short_name, param[4].data.d_string); - vars.media_size = param[5].data.d_int32; + strcpy(vars.ppd_file, param[5].data.d_string); vars.output_type = param[6].data.d_int32; - vars.brightness = param[7].data.d_int32; + strcpy(vars.resolution, param[7].data.d_string); + strcpy(vars.media_size, param[8].data.d_string); + strcpy(vars.media_type, param[9].data.d_string); + strcpy(vars.media_source, param[10].data.d_string); - if (nparams > 8) - vars.scaling = param[8].data.d_int32; + if (nparams > 11) + vars.brightness = param[11].data.d_int32; + else + vars.brightness = 100; + + if (nparams > 12) + vars.scaling = param[12].data.d_float; else - vars.scaling = 100; + vars.scaling = 100.0; - if (nparams > 9) - vars.orientation = param[9].data.d_int32; + if (nparams > 13) + vars.orientation = param[13].data.d_int32; else vars.orientation = -1; - if (nparams > 10) - vars.left = param[10].data.d_int32; + if (nparams > 14) + vars.left = param[14].data.d_int32; else vars.left = -1; - if (nparams > 11) - vars.top = param[11].data.d_int32; + if (nparams > 15) + vars.top = param[15].data.d_int32; else vars.top = -1; - - for (i = 0; i < (sizeof(printers) / sizeof(printers[0])); i ++) - if (strcmp(printers[i].short_name, vars.short_name) == 0) - current_printer = i; }; + + for (i = 0; i < (sizeof(printers) / sizeof(printers[0])); i ++) + if (strcmp(printers[i].short_name, vars.short_name) == 0) + current_printer = i; break; case RUN_WITH_LAST_VALS : @@ -461,17 +544,18 @@ run(char *name, /* I - Name of print program. */ * Print the image... */ - signal(SIGBUS, SIG_DFL); - signal(SIGSEGV, SIG_DFL); - if (values[0].data.d_status == STATUS_SUCCESS) { /* * Set the tile cache size... */ - gimp_tile_cache_ntiles((drawable->width + gimp_tile_width() - 1) / - gimp_tile_width()); + if (drawable->height > drawable->width) + gimp_tile_cache_ntiles((drawable->height + gimp_tile_width() - 1) / + gimp_tile_width() + 1); + else + gimp_tile_cache_ntiles((drawable->width + gimp_tile_width() - 1) / + gimp_tile_width() + 1); /* * Open the file/execute the print command... @@ -519,9 +603,10 @@ run(char *name, /* I - Name of print program. */ * close the output file/command... */ - (*printer->print)(prn, drawable, vars.media_size, printer->xdpi, printer->ydpi, - vars.output_type, printer->model, lut, cmap, - vars.orientation, vars.scaling, vars.left, vars.top); + (*printer->print)(printer->model, vars.ppd_file, vars.resolution, + vars.media_size, vars.media_type, vars.media_source, + vars.output_type, vars.orientation, vars.scaling, + vars.left, vars.top, 1, prn, drawable, lut, cmap); if (plist_current > 0) pclose(prn); @@ -548,32 +633,28 @@ run(char *name, /* I - Name of print program. */ /* - * 'print_dialog()' - Pop up the print dialog... + * 'do_print_dialog()' - Pop up the print dialog... */ -static int -print_dialog(void) +int +do_print_dialog(void) { int i; /* Looping var */ + char s[100]; /* Text string */ GtkWidget *dialog, /* Dialog window */ *table, /* Table "container" for controls */ *label, /* Label string */ *button, /* OK/Cancel buttons */ - *entry, /* Print file/command text entry */ + *scale, /* Scale widget */ + *entry, /* Text entry widget */ *menu, /* Menu of drivers/sizes */ *item, /* Menu item */ - *option; /* Option menu button */ + *option, /* Option menu button */ + *box; /* Box container */ + GtkObject *scale_data; /* Scale data (limits) */ GSList *group; /* Grouping for output type */ gint argc; /* Fake argc for GUI */ gchar **argv; /* Fake argv for GUI */ - static char *sizes[] = /* Size strings */ - { - "A/Letter (8.5x11\")", - "Legal (8.5x14\")", - "B/Tabloid (11x17\")", - "A4 (210x297mm)", - "A3 (297x420mm)" - }; static char *orients[] = /* Orientation strings */ { "Auto", @@ -594,6 +675,9 @@ print_dialog(void) gtk_rc_parse(gimp_gtkrc()); gdk_set_use_xshm(gimp_use_xshm()); + signal(SIGBUS, SIG_DFL); + signal(SIGSEGV, SIG_DFL); + /* * Get printrc options... */ @@ -601,24 +685,25 @@ print_dialog(void) printrc_load(); /* - * Dialog window... + * Print dialog window... */ - dialog = gtk_dialog_new(); + print_dialog = dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(dialog), "Print " PLUG_IN_VERSION); + gtk_window_set_wmclass(GTK_WINDOW(dialog), "print", "Gimp"); gtk_window_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); gtk_container_border_width(GTK_CONTAINER(dialog), 0); gtk_signal_connect(GTK_OBJECT(dialog), "destroy", - (GtkSignalFunc) close_callback, - NULL); + (GtkSignalFunc)close_callback, NULL); /* * Top-level table for dialog... */ - table = gtk_table_new(13, 3, FALSE); + table = gtk_table_new(9, 4, FALSE); gtk_container_border_width(GTK_CONTAINER(table), 6); - gtk_table_set_row_spacings(GTK_TABLE(table), 4); + gtk_table_set_col_spacings(GTK_TABLE(table), 4); + gtk_table_set_row_spacings(GTK_TABLE(table), 8); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0); gtk_widget_show(table); @@ -628,7 +713,8 @@ print_dialog(void) preview = (GtkDrawingArea *)gtk_drawing_area_new(); gtk_drawing_area_size(preview, PREVIEW_SIZE, PREVIEW_SIZE); - gtk_table_attach(GTK_TABLE(table), (GtkWidget *)preview, 0, 3, 0, 4, 0, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), (GtkWidget *)preview, 0, 2, 0, 7, + GTK_FILL, GTK_FILL, 0, 0); gtk_signal_connect(GTK_OBJECT((GtkWidget *)preview), "expose_event", (GtkSignalFunc)preview_update, NULL); @@ -647,13 +733,230 @@ print_dialog(void) GDK_EXPOSURE_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + /* + * Media size option menu... + */ + + label = gtk_label_new("Media Size:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + box = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + media_size = option = gtk_option_menu_new(); + gtk_box_pack_start(GTK_BOX(box), option, FALSE, FALSE, 0); + + /* + * Media type option menu... + */ + + label = gtk_label_new("Media Type:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 2, 3, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + box = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 2, 3, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + media_type = option = gtk_option_menu_new(); + gtk_box_pack_start(GTK_BOX(box), option, FALSE, FALSE, 0); + + /* + * Media source option menu... + */ + + label = gtk_label_new("Media Source:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 3, 4, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + box = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 3, 4, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + media_source = option = gtk_option_menu_new(); + gtk_box_pack_start(GTK_BOX(box), option, FALSE, FALSE, 0); + + /* + * Orientation option menu... + */ + + label = gtk_label_new("Orientation:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 4, 5, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + menu = gtk_menu_new(); + for (i = 0; i < (int)(sizeof(orients) / sizeof(orients[0])); i ++) + { + item = gtk_menu_item_new_with_label(orients[i]); + gtk_menu_append(GTK_MENU(menu), item); + gtk_signal_connect(GTK_OBJECT(item), "activate", + (GtkSignalFunc)orientation_callback, + (gpointer)(i - 1)); + gtk_widget_show(item); + }; + + box = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 4, 5, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + option = gtk_option_menu_new(); + gtk_box_pack_start(GTK_BOX(box), option, FALSE, FALSE, 0); + gtk_option_menu_set_menu(GTK_OPTION_MENU(option), menu); + gtk_option_menu_set_history(GTK_OPTION_MENU(option), vars.orientation + 1); + gtk_widget_show(option); + + /* + * Resolution option menu... + */ + + label = gtk_label_new("Resolution:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 5, 6, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + box = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 5, 6, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + resolution = option = gtk_option_menu_new(); + gtk_box_pack_start(GTK_BOX(box), option, FALSE, FALSE, 0); + + /* + * Output type toggles... + */ + + label = gtk_label_new("Output Type:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 6, 7, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 6, 7, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + output_gray = button = gtk_radio_button_new_with_label(NULL, "B&W"); + group = gtk_radio_button_group(GTK_RADIO_BUTTON(button)); + if (vars.output_type == 0) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE); + gtk_signal_connect(GTK_OBJECT(button), "toggled", + (GtkSignalFunc)output_type_callback, + (gpointer)OUTPUT_GRAY); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + output_color = button = gtk_radio_button_new_with_label(group, "Color"); + if (vars.output_type == 1) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE); + gtk_signal_connect(GTK_OBJECT(button), "toggled", + (GtkSignalFunc)output_type_callback, + (gpointer)OUTPUT_COLOR); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + /* + * Scaling... + */ + + label = gtk_label_new("Scaling:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 7, 8, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 7, 8, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + if (vars.scaling < 0.0) + scaling_adjustment = scale_data = + gtk_adjustment_new(-vars.scaling, 50.0, 1201.0, 1.0, 1.0, 1.0); + else + scaling_adjustment = scale_data = + gtk_adjustment_new(vars.scaling, 5.0, 101.0, 1.0, 1.0, 1.0); + + gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed", + (GtkSignalFunc)scaling_update, NULL); + + scaling_scale = scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data)); + gtk_box_pack_start(GTK_BOX(box), scale, FALSE, FALSE, 0); + gtk_widget_set_usize(scale, 200, 0); + gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE); + gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_CONTINUOUS); + gtk_widget_show(scale); + + scaling_entry = entry = gtk_entry_new(); + sprintf(s, "%.1f", fabs(vars.scaling)); + gtk_entry_set_text(GTK_ENTRY(entry), s); + gtk_signal_connect(GTK_OBJECT(entry), "changed", + (GtkSignalFunc)scaling_callback, NULL); + gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); + gtk_widget_set_usize(entry, 60, 0); + gtk_widget_show(entry); + + scaling_percent = button = gtk_radio_button_new_with_label(NULL, "Percent"); + group = gtk_radio_button_group(GTK_RADIO_BUTTON(button)); + if (vars.scaling > 0.0) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE); + gtk_signal_connect(GTK_OBJECT(button), "toggled", + (GtkSignalFunc)scaling_callback, NULL); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + scaling_ppi = button = gtk_radio_button_new_with_label(group, "PPI"); + if (vars.scaling < 0.0) + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE); + gtk_signal_connect(GTK_OBJECT(button), "toggled", + (GtkSignalFunc)scaling_callback, NULL); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + /* + * Brightness slider... + */ + + label = gtk_label_new("Brightness:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 8, 9, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 1, 4, 8, 9, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + brightness_adjustment = scale_data = + gtk_adjustment_new((float)vars.brightness, 50.0, 201.0, 1.0, 1.0, 1.0); + + gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed", + (GtkSignalFunc)brightness_update, NULL); + + brightness_scale = scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data)); + gtk_box_pack_start(GTK_BOX(box), scale, FALSE, FALSE, 0); + gtk_widget_set_usize(scale, 200, 0); + gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE); + gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_CONTINUOUS); + gtk_widget_show(scale); + + brightness_entry = entry = gtk_entry_new(); + sprintf(s, "%d", vars.brightness); + gtk_entry_set_text(GTK_ENTRY(entry), s); + gtk_signal_connect(GTK_OBJECT(entry), "changed", + (GtkSignalFunc)brightness_callback, NULL); + gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); + gtk_widget_set_usize(entry, 40, 0); + gtk_widget_show(entry); + /* * Printer option menu... */ label = gtk_label_new("Printer:"); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 4, 0); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); menu = gtk_menu_new(); @@ -667,20 +970,74 @@ print_dialog(void) gtk_widget_show(item); }; + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + option = gtk_option_menu_new(); - gtk_table_attach(GTK_TABLE(table), option, 1, 3, 4, 5, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_box_pack_start(GTK_BOX(box), option, FALSE, FALSE, 0); gtk_option_menu_set_menu(GTK_OPTION_MENU(option), menu); gtk_option_menu_set_history(GTK_OPTION_MENU(option), plist_current); gtk_widget_show(option); + button = gtk_button_new_with_label(" Setup "); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + gtk_signal_connect(GTK_OBJECT(button), "clicked", + (GtkSignalFunc)setup_open_callback, NULL); + gtk_widget_show(button); + + /* + * Print, cancel buttons... + */ + + gtk_box_set_homogeneous(GTK_BOX(GTK_DIALOG(dialog)->action_area), FALSE); + gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->action_area), 0); + + button = gtk_button_new_with_label(" Cancel "); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_signal_connect(GTK_OBJECT(button), "clicked", + (GtkSignalFunc)cancel_callback, NULL); + gtk_box_pack_end(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + button = gtk_button_new_with_label(" Print "); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_signal_connect(GTK_OBJECT(button), "clicked", + (GtkSignalFunc)print_callback, NULL); + gtk_widget_grab_default(button); + gtk_box_pack_end(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + /* + * Setup dialog window... + */ + + setup_dialog = dialog = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(dialog), "Setup"); + gtk_window_set_wmclass(GTK_WINDOW(dialog), "print", "Gimp"); + gtk_window_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); + gtk_container_border_width(GTK_CONTAINER(dialog), 0); + gtk_signal_connect(GTK_OBJECT(dialog), "destroy", + (GtkSignalFunc)setup_cancel_callback, NULL); + + /* + * Top-level table for dialog... + */ + + table = gtk_table_new(3, 2, FALSE); + gtk_container_border_width(GTK_CONTAINER(table), 6); + gtk_table_set_col_spacings(GTK_TABLE(table), 4); + gtk_table_set_row_spacings(GTK_TABLE(table), 8); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0); + gtk_widget_show(table); + /* * Printer driver option menu... */ label = gtk_label_new("Driver:"); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 4, 0); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); menu = gtk_menu_new(); @@ -695,152 +1052,96 @@ print_dialog(void) }; printer_driver = option = gtk_option_menu_new(); - gtk_table_attach(GTK_TABLE(table), option, 1, 3, 5, 6, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach(GTK_TABLE(table), option, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_option_menu_set_menu(GTK_OPTION_MENU(option), menu); - gtk_option_menu_set_history(GTK_OPTION_MENU(option), current_printer); gtk_widget_show(option); /* - * Output type toggles... + * PPD file... */ - label = gtk_label_new("Output Type:"); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 6, 7, GTK_FILL, GTK_FILL, 4, 0); + label = gtk_label_new("PPD File:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); - output_gray = button = gtk_radio_button_new_with_label(NULL, "B&W"); - group = gtk_radio_button_group(GTK_RADIO_BUTTON(button)); - gtk_signal_connect(GTK_OBJECT(button), "toggled", - (GtkSignalFunc)output_type_callback, - (gpointer)OUTPUT_GRAY); - gtk_table_attach(GTK_TABLE(table), button, 1, 2, 6, 7, GTK_FILL, GTK_FILL, 4, 0); + box = gtk_hbox_new(FALSE, 8); + gtk_table_attach(GTK_TABLE(table), box, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(box); + + ppd_file = entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); + gtk_widget_show(entry); + + ppd_button = button = gtk_button_new_with_label(" Browse "); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + gtk_signal_connect(GTK_OBJECT(button), "clicked", + (GtkSignalFunc)ppd_browse_callback, NULL); gtk_widget_show(button); - if (vars.output_type == 0) - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE); - - output_color = button = gtk_radio_button_new_with_label(group, "Color"); - gtk_signal_connect(GTK_OBJECT(button), "toggled", - (GtkSignalFunc)output_type_callback, - (gpointer)OUTPUT_COLOR); - gtk_table_attach(GTK_TABLE(table), button, 2, 3, 6, 7, GTK_FILL, GTK_FILL, 4, 0); - gtk_widget_show(button); - if (vars.output_type == 1) - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE); /* - * Media size option menu... + * Print command... */ - label = gtk_label_new("Media Size:"); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 7, 8, GTK_FILL, GTK_FILL, 4, 0); + label = gtk_label_new("Command:"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); - menu = gtk_menu_new(); - for (i = 0; i < (int)(sizeof(sizes) / sizeof(sizes[0])); i ++) - { - item = gtk_menu_item_new_with_label(sizes[i]); - gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", - (GtkSignalFunc)media_size_callback, - (gpointer)i); - gtk_widget_show(item); - }; - - option = gtk_option_menu_new(); - gtk_table_attach(GTK_TABLE(table), option, 1, 3, 7, 8, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_option_menu_set_menu(GTK_OPTION_MENU(option), menu); - gtk_option_menu_set_history(GTK_OPTION_MENU(option), vars.media_size); - gtk_widget_show(option); - - /* - * Orientation option menu... - */ - - label = gtk_label_new("Orientation:"); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 8, 9, GTK_FILL, GTK_FILL, 4, 0); - gtk_widget_show(label); - - menu = gtk_menu_new(); - for (i = 0; i < (int)(sizeof(orients) / sizeof(orients[0])); i ++) - { - item = gtk_menu_item_new_with_label(orients[i]); - gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", - (GtkSignalFunc)orientation_callback, - (gpointer)(i - 1)); - gtk_widget_show(item); - }; - - option = gtk_option_menu_new(); - gtk_table_attach(GTK_TABLE(table), option, 1, 3, 8, 9, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_option_menu_set_menu(GTK_OPTION_MENU(option), menu); - gtk_option_menu_set_history(GTK_OPTION_MENU(option), vars.orientation + 1); - gtk_widget_show(option); - - /* - * Scaling slider... - */ - - dialog_create_ivalue("Scaling:", GTK_TABLE(table), 9, &(vars.scaling), 1, 101); - - /* - * Brightness slider... - */ - - dialog_create_ivalue("Brightness:", GTK_TABLE(table), 10, &(vars.brightness), 50, 201); - - /* - * Print file/command... - */ - - label = gtk_label_new("File/Command:"); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 11, 12, GTK_FILL, GTK_FILL, 4, 0); - gtk_widget_show(label); - - output_to = entry = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(entry), vars.output_to); - gtk_signal_connect(GTK_OBJECT(entry), "changed", - (GtkSignalFunc)print_command_callback, NULL); - gtk_table_attach(GTK_TABLE(table), entry, 1, 3, 11, 12, GTK_FILL, GTK_FILL, 4, 0); + output_cmd = entry = gtk_entry_new(); + gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(entry); /* - * Print, cancel buttons... + * OK, cancel buttons... */ - gtk_container_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), 6); + gtk_box_set_homogeneous(GTK_BOX(GTK_DIALOG(dialog)->action_area), FALSE); + gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->action_area), 0); - button = gtk_button_new_with_label("Print"); + button = gtk_button_new_with_label(" Cancel "); GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); gtk_signal_connect(GTK_OBJECT(button), "clicked", - (GtkSignalFunc)print_callback, - dialog); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, TRUE, TRUE, 0); - gtk_widget_grab_default(button); + (GtkSignalFunc)setup_cancel_callback, NULL); + gtk_box_pack_end(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); gtk_widget_show(button); - button = gtk_button_new_with_label("Cancel"); + button = gtk_button_new_with_label(" OK "); GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); gtk_signal_connect(GTK_OBJECT(button), "clicked", - (GtkSignalFunc)cancel_callback, - dialog); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, TRUE, TRUE, 0); + (GtkSignalFunc)setup_ok_callback, NULL); + gtk_widget_grab_default(button); + gtk_box_pack_end(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); gtk_widget_show(button); /* - * Show it and wait for the user to do something... + * Output file selection dialog... + */ + + file_browser = gtk_file_selection_new("Print To File?"); + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(file_browser)->ok_button), + "clicked", (GtkSignalFunc)file_ok_callback, NULL); + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(file_browser)->cancel_button), + "clicked", (GtkSignalFunc)file_cancel_callback, NULL); + + /* + * PPD file selection dialog... + */ + + ppd_browser = gtk_file_selection_new("PPD File?"); + gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(ppd_browser)); + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ppd_browser)->ok_button), + "clicked", (GtkSignalFunc)ppd_ok_callback, NULL); + gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ppd_browser)->cancel_button), + "clicked", (GtkSignalFunc)ppd_cancel_callback, NULL); + + /* + * Show the main dialog and wait for the user to do something... */ plist_callback(NULL, plist_current); - gtk_widget_show(dialog); + gtk_widget_show(print_dialog); gtk_main(); gdk_flush(); @@ -860,127 +1161,198 @@ print_dialog(void) /* - * 'dialog_create_ivalue()' - Create an integer value control... + * 'brightness_update()' - Update the brightness field using the scale. */ static void -dialog_create_ivalue(char *title, /* I - Label for control */ - GtkTable *table, /* I - Table container to use */ - int row, /* I - Row # for container */ - gint *value, /* I - Value holder */ - int left, /* I - Minimum value for slider */ - int right) /* I - Maximum value for slider */ +brightness_update(GtkAdjustment *adjustment) /* I - New value */ { - GtkWidget *label, /* Control label */ - *scale, /* Scale widget */ - *entry; /* Text widget */ - GtkObject *scale_data; /* Scale data */ - char buf[256]; /* String buffer */ + char s[255]; /* Text buffer */ - /* - * Label... - */ - - label = gtk_label_new(title); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 1.0); - gtk_table_attach(table, label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 4, 0); - gtk_widget_show(label); - - /* - * Scale... - */ - - scale_data = gtk_adjustment_new(*value, left, right, 1.0, 1.0, 1.0); - - gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed", - (GtkSignalFunc) dialog_iscale_update, - value); - - scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data)); - gtk_widget_set_usize(scale, SCALE_WIDTH, 0); - gtk_table_attach(table, scale, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE); - gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_CONTINUOUS); - gtk_widget_show(scale); - - /* - * Text entry... - */ - - entry = gtk_entry_new(); - gtk_object_set_user_data(GTK_OBJECT(entry), scale_data); - gtk_object_set_user_data(scale_data, entry); - gtk_widget_set_usize(entry, ENTRY_WIDTH, 0); - sprintf(buf, "%d", *value); - gtk_entry_set_text(GTK_ENTRY(entry), buf); - gtk_signal_connect(GTK_OBJECT(entry), "changed", - (GtkSignalFunc) dialog_ientry_update, - value); - gtk_table_attach(GTK_TABLE(table), entry, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, 4, 0); - gtk_widget_show(entry); -} - - -/* - * 'dialog_iscale_update()' - Update the value field using the scale. - */ - -static void -dialog_iscale_update(GtkAdjustment *adjustment, /* I - New value */ - gint *value) /* I - Current value */ -{ - GtkWidget *entry; /* Text entry widget */ - char buf[256]; /* Text buffer */ - - - if (*value != adjustment->value) + if (vars.brightness != adjustment->value) { - *value = adjustment->value; + vars.brightness = adjustment->value; - entry = gtk_object_get_user_data(GTK_OBJECT(adjustment)); - sprintf(buf, "%d", *value); + sprintf(s, "%d", vars.brightness); - gtk_signal_handler_block_by_data(GTK_OBJECT(entry), value); - gtk_entry_set_text(GTK_ENTRY(entry), buf); - gtk_signal_handler_unblock_by_data(GTK_OBJECT(entry), value); + gtk_signal_handler_block_by_data(GTK_OBJECT(brightness_entry), NULL); + gtk_entry_set_text(GTK_ENTRY(brightness_entry), s); + gtk_signal_handler_unblock_by_data(GTK_OBJECT(brightness_entry), NULL); - if (value == &(vars.scaling)) - preview_update(); + preview_update(); }; } /* - * 'dialog_ientry_update()' - Update the value field using the text entry. + * 'brightness_callback()' - Update the brightness scale using the text entry. */ static void -dialog_ientry_update(GtkWidget *widget, /* I - Entry widget */ - gint *value) /* I - Current value */ +brightness_callback(GtkWidget *widget) /* I - Entry widget */ { - GtkAdjustment *adjustment; - gint new_value; + gint new_value; /* New scaling value */ new_value = atoi(gtk_entry_get_text(GTK_ENTRY(widget))); - if (*value != new_value) + if (vars.brightness != new_value) { - adjustment = gtk_object_get_user_data(GTK_OBJECT(widget)); - - if ((new_value >= adjustment->lower) && - (new_value <= adjustment->upper)) + if ((new_value >= GTK_ADJUSTMENT(brightness_adjustment)->lower) && + (new_value < GTK_ADJUSTMENT(brightness_adjustment)->upper)) { - *value = new_value; - adjustment->value = new_value; + GTK_ADJUSTMENT(brightness_adjustment)->value = new_value; - gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed"); + gtk_signal_emit_by_name(brightness_adjustment, "value_changed"); }; }; } +/* + * 'scaling_update()' - Update the scaling field using the scale. + */ + +static void +scaling_update(GtkAdjustment *adjustment) /* I - New value */ +{ + char s[255]; /* Text buffer */ + + + if (vars.scaling != adjustment->value) + { + if (GTK_TOGGLE_BUTTON(scaling_ppi)->active) + vars.scaling = -adjustment->value; + else + vars.scaling = adjustment->value; + + sprintf(s, "%.1f", adjustment->value); + + gtk_signal_handler_block_by_data(GTK_OBJECT(scaling_entry), NULL); + gtk_entry_set_text(GTK_ENTRY(scaling_entry), s); + gtk_signal_handler_unblock_by_data(GTK_OBJECT(scaling_entry), NULL); + + preview_update(); + }; +} + + +/* + * 'scaling_callback()' - Update the scaling scale using the text entry. + */ + +static void +scaling_callback(GtkWidget *widget) /* I - Entry widget */ +{ + gfloat new_value; /* New scaling value */ + + + if (widget == scaling_entry) + { + new_value = atof(gtk_entry_get_text(GTK_ENTRY(widget))); + + if (vars.scaling != new_value) + { + if ((new_value >= GTK_ADJUSTMENT(scaling_adjustment)->lower) && + (new_value < GTK_ADJUSTMENT(scaling_adjustment)->upper)) + { + GTK_ADJUSTMENT(scaling_adjustment)->value = new_value; + + gtk_signal_emit_by_name(scaling_adjustment, "value_changed"); + }; + }; + } + else if (widget == scaling_ppi) + { + GTK_ADJUSTMENT(scaling_adjustment)->lower = 50.0; + GTK_ADJUSTMENT(scaling_adjustment)->upper = 1201.0; + GTK_ADJUSTMENT(scaling_adjustment)->value = 72.0; + vars.scaling = 0.0; + gtk_signal_emit_by_name(scaling_adjustment, "value_changed"); + } + else if (widget == scaling_percent) + { + GTK_ADJUSTMENT(scaling_adjustment)->lower = 5.0; + GTK_ADJUSTMENT(scaling_adjustment)->upper = 101.0; + GTK_ADJUSTMENT(scaling_adjustment)->value = 100.0; + vars.scaling = 0.0; + gtk_signal_emit_by_name(scaling_adjustment, "value_changed"); + }; +} + + +/* + * 'plist_build_menu()' - Build an option menu for the given parameters... + */ + +static void +plist_build_menu(GtkWidget *option, /* I - Option button */ + GtkWidget **menu, /* IO - Current menu */ + int num_items, /* I - Number of items */ + char **items, /* I - Menu items */ + char *cur_item, /* I - Current item */ + void (*callback)(GtkWidget *, gint)) /* I - Callback */ +{ + int i; /* Looping var */ + GtkWidget *item, /* Menu item */ + *item0; /* First menu item */ + + + if (*menu != NULL) + { + gtk_widget_destroy(*menu); + *menu = NULL; + }; + + if (num_items == NULL) + { + gtk_widget_hide(option); + return; + }; + + *menu = gtk_menu_new(); + + for (i = 0; i < num_items; i ++) + { + item = gtk_menu_item_new_with_label(items[i]); + if (i == 0) + item0 = item; + gtk_menu_append(GTK_MENU(*menu), item); + gtk_signal_connect(GTK_OBJECT(item), "activate", + (GtkSignalFunc)callback, (gpointer)i); + gtk_widget_show(item); + }; + + gtk_option_menu_set_menu(GTK_OPTION_MENU(option), *menu); + +#ifdef DEBUG + printf("cur_item = \'%s\'\n", cur_item); +#endif /* DEBUG */ + + for (i = 0; i < num_items; i ++) + { +#ifdef DEBUG + printf("item[%d] = \'%s\'\n", i, items[i]); +#endif /* DEBUG */ + + if (strcmp(items[i], cur_item) == 0) + { + gtk_option_menu_set_history(GTK_OPTION_MENU(option), i); + break; + }; + }; + + if (i == num_items) + { + gtk_option_menu_set_history(GTK_OPTION_MENU(option), 0); + gtk_signal_emit_by_name(GTK_OBJECT(item0), "activate"); + }; + + gtk_widget_show(option); +} + + /* * 'plist_callback()' - Update the current system printer... */ @@ -989,14 +1361,17 @@ static void plist_callback(GtkWidget *widget, /* I - Driver option menu */ gint data) /* I - Data */ { - int i; + int i; /* Looping var */ + printer_t *printer; /* Printer driver entry */ + plist_t *p; plist_current = data; + p = plist + plist_current; - if (plist[plist_current].driver[0] != '\0') + if (p->driver[0] != '\0') { - strcpy(vars.short_name, plist[plist_current].driver); + strcpy(vars.short_name, p->driver); for (i = 0; i < (sizeof(printers) / sizeof(printers[0])); i ++) if (strcmp(printers[i].short_name, vars.short_name) == 0) @@ -1004,35 +1379,96 @@ plist_callback(GtkWidget *widget, /* I - Driver option menu */ current_printer = i; break; }; - - gtk_option_menu_set_history(GTK_OPTION_MENU(printer_driver), current_printer); }; - if (plist[plist_current].command[0] != '\0') - { - strcpy(vars.output_to, plist[plist_current].command); - gtk_entry_set_text(GTK_ENTRY(output_to), vars.output_to); - }; + if (p->ppd_file[0] != '\0') + strcpy(vars.ppd_file, p->ppd_file); - if (plist[plist_current].output_type == OUTPUT_GRAY) + if (p->media_size[0] != '\0') + strcpy(vars.media_size, p->media_size); + + if (p->media_type[0] != '\0') + strcpy(vars.media_type, p->media_type); + + if (p->media_source[0] != '\0') + strcpy(vars.media_source, p->media_source); + + if (p->resolution[0] != '\0') + strcpy(vars.resolution, p->resolution); + + if (p->command[0] != '\0') + strcpy(vars.output_to, p->command); + + if (p->output_type == OUTPUT_GRAY) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(output_gray), TRUE); else gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(output_color), TRUE); -} + /* + * Now get option parameters... + */ -/* - * 'print_driver_callback()' - Update the current printer driver... - */ + printer = printers + current_printer; -static void -print_driver_callback(GtkWidget *widget, /* I - Driver option menu */ - gint data) /* I - Data */ -{ - current_printer = data; + if (num_media_sizes > 0) + { + for (i = 0; i < num_media_sizes; i ++) + g_free(media_sizes[i]); + g_free(media_sizes); + }; - strcpy(vars.short_name, printers[current_printer].short_name); - strcpy(plist[plist_current].driver, printers[current_printer].short_name); + media_sizes = (*(printer->parameters))(printer->model, + p->ppd_file, + "PageSize", &num_media_sizes); + if (vars.media_size[0] == '\0') + strcpy(vars.media_size, media_sizes[0]); + plist_build_menu(media_size, &media_size_menu, num_media_sizes, media_sizes, + p->media_size, media_size_callback); + + if (num_media_types > 0) + { + for (i = 0; i < num_media_types; i ++) + g_free(media_types[i]); + g_free(media_types); + }; + + media_types = (*(printer->parameters))(printer->model, + p->ppd_file, + "MediaType", &num_media_types); + if (vars.media_type[0] == '\0' && media_types != NULL) + strcpy(vars.media_type, media_types[0]); + plist_build_menu(media_type, &media_type_menu, num_media_types, media_types, + p->media_type, media_type_callback); + + if (num_media_sources > 0) + { + for (i = 0; i < num_media_sources; i ++) + g_free(media_sources[i]); + g_free(media_sources); + }; + + media_sources = (*(printer->parameters))(printer->model, + p->ppd_file, + "InputSlot", &num_media_sources); + if (vars.media_source[0] == '\0' && media_sources != NULL) + strcpy(vars.media_source, media_sources[0]); + plist_build_menu(media_source, &media_source_menu, num_media_sources, media_sources, + p->media_source, media_source_callback); + + if (num_resolutions > 0) + { + for (i = 0; i < num_resolutions; i ++) + g_free(resolutions[i]); + g_free(resolutions); + }; + + resolutions = (*(printer->parameters))(printer->model, + p->ppd_file, + "Resolution", &num_resolutions); + if (vars.resolution[0] == '\0' && resolutions != NULL) + strcpy(vars.resolution, resolutions[0]); + plist_build_menu(resolution, &resolution_menu, num_resolutions, resolutions, + p->resolution, resolution_callback); } @@ -1044,7 +1480,8 @@ static void media_size_callback(GtkWidget *widget, /* I - Media size option menu */ gint data) /* I - Data */ { - vars.media_size = data; + strcpy(vars.media_size, media_sizes[data]); + strcpy(plist[plist_current].media_size, media_sizes[data]); vars.left = -1; vars.top = -1; @@ -1052,6 +1489,45 @@ media_size_callback(GtkWidget *widget, /* I - Media size option menu */ } +/* + * 'media_type_callback()' - Update the current media type... + */ + +static void +media_type_callback(GtkWidget *widget, /* I - Media type option menu */ + gint data) /* I - Data */ +{ + strcpy(vars.media_type, media_types[data]); + strcpy(plist[plist_current].media_type, media_types[data]); +} + + +/* + * 'media_source_callback()' - Update the current media source... + */ + +static void +media_source_callback(GtkWidget *widget, /* I - Media source option menu */ + gint data) /* I - Data */ +{ + strcpy(vars.media_source, media_sources[data]); + strcpy(plist[plist_current].media_source, media_sources[data]); +} + + +/* + * 'resolution_callback()' - Update the current resolution... + */ + +static void +resolution_callback(GtkWidget *widget, /* I - Media size option menu */ + gint data) /* I - Data */ +{ + strcpy(vars.resolution, resolutions[data]); + strcpy(plist[plist_current].resolution, resolutions[data]); +} + + /* * 'orientation_callback()' - Update the current media size... */ @@ -1068,19 +1544,6 @@ orientation_callback(GtkWidget *widget, /* I - Orientation option menu */ } -/* - * 'print_command_callback()' - Update the print command... - */ - -static void -print_command_callback(GtkWidget *widget, /* I - Command text field */ - gpointer data) /* I - Data */ -{ - strcpy(vars.output_to, gtk_entry_get_text(GTK_ENTRY(widget))); - strcpy(plist[plist_current].command, vars.output_to); -} - - /* * 'output_type_callback()' - Update the current output type... */ @@ -1102,11 +1565,16 @@ output_type_callback(GtkWidget *widget, /* I - Output type button */ */ static void -print_callback(GtkWidget *widget, /* I - OK button widget */ - gpointer data) /* I - Dialog window */ +print_callback(void) { - runme = TRUE; - gtk_widget_destroy(GTK_WIDGET(data)); + if (plist_current > 0) + { + runme = TRUE; + + gtk_widget_destroy(print_dialog); + } + else + gtk_widget_show(file_browser); } @@ -1115,10 +1583,9 @@ print_callback(GtkWidget *widget, /* I - OK button widget */ */ static void -cancel_callback(GtkWidget *widget, /* I - Cancel button widget */ - gpointer data) /* I - Dialog window */ +cancel_callback(void) { - gtk_widget_destroy(GTK_WIDGET(data)); + gtk_widget_destroy(print_dialog); } @@ -1127,32 +1594,184 @@ cancel_callback(GtkWidget *widget, /* I - Cancel button widget */ */ static void -close_callback(GtkWidget *widget, /* I - Dialog window */ - gpointer data) /* I - Dialog window */ +close_callback(void) { gtk_main_quit(); } +static void +setup_open_callback(void) +{ + int i; /* Looping var */ + + + for (i = 0; i < (int)(sizeof(printers) / sizeof(printers[0])); i ++) + if (strcmp(plist[plist_current].driver, printers[i].short_name) == 0) + { + current_printer = i; + break; + }; + + gtk_option_menu_set_history(GTK_OPTION_MENU(printer_driver), current_printer); + + gtk_entry_set_text(GTK_ENTRY(ppd_file), plist[plist_current].ppd_file); + + if (strncmp(plist[plist_current].driver, "ps", 2) == 0) + gtk_widget_show(ppd_file); + else + gtk_widget_show(ppd_file); + + gtk_entry_set_text(GTK_ENTRY(output_cmd), plist[plist_current].command); + + if (plist_current == 0) + gtk_widget_hide(output_cmd); + else + gtk_widget_show(output_cmd); + + gtk_widget_show(setup_dialog); +} + + +static void +setup_ok_callback(void) +{ + strcpy(vars.short_name, printers[current_printer].short_name); + strcpy(plist[plist_current].driver, printers[current_printer].short_name); + + strcpy(vars.output_to, gtk_entry_get_text(GTK_ENTRY(output_cmd))); + strcpy(plist[plist_current].command, vars.output_to); + + strcpy(vars.ppd_file, gtk_entry_get_text(GTK_ENTRY(ppd_file))); + strcpy(plist[plist_current].ppd_file, vars.ppd_file); + + plist_callback(NULL, plist_current); + + gtk_widget_hide(setup_dialog); +} + + +static void +setup_cancel_callback(void) +{ + gtk_widget_hide(setup_dialog); +} + + +/* + * 'print_driver_callback()' - Update the current printer driver... + */ + +static void +print_driver_callback(GtkWidget *widget, /* I - Driver option menu */ + gint data) /* I - Data */ +{ + current_printer = data; + + if (strncmp(printers[current_printer].short_name, "ps", 2) == 0) + { + gtk_widget_show(ppd_file); + gtk_widget_show(ppd_button); + } + else + { + gtk_widget_hide(ppd_file); + gtk_widget_hide(ppd_button); + }; +} + + +static void +ppd_browse_callback(void) +{ + gtk_file_selection_set_filename(GTK_FILE_SELECTION(ppd_browser), + gtk_entry_get_text(GTK_ENTRY(ppd_file))); + gtk_widget_show(ppd_browser); +} + + +static void +ppd_ok_callback(void) +{ + gtk_widget_hide(ppd_browser); + gtk_entry_set_text(GTK_ENTRY(ppd_file), + gtk_file_selection_get_filename(GTK_FILE_SELECTION(ppd_browser))); +} + + +static void +ppd_cancel_callback(void) +{ + gtk_widget_hide(ppd_browser); +} + + +static void +file_ok_callback(void) +{ + gtk_widget_hide(file_browser); + strcpy(vars.output_to, + gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_browser))); + + runme = TRUE; + + gtk_widget_destroy(print_dialog); +} + + +static void +file_cancel_callback(void) +{ + gtk_widget_hide(file_browser); + + gtk_widget_destroy(print_dialog); +} + + static void preview_update(void) { - int orient, /* True orientation of page */ + int temp, /* Swapping variable */ + orient, /* True orientation of page */ tw0, tw1, /* Temporary page_widths */ th0, th1, /* Temporary page_heights */ ta0, ta1; /* Temporary areas */ - static GdkGC *gc = NULL; + int left, right, /* Imageable area */ + top, bottom, + width, length; /* Physical width */ + static GdkGC *gc = NULL; /* Graphics context */ + printer_t *p; /* Current printer driver */ + if (preview->widget.window == NULL) + return; + gdk_window_clear(preview->widget.window); if (gc == NULL) gc = gdk_gc_new(preview->widget.window); - page_width = media_width(vars.media_size, 10); - page_height = media_height(vars.media_size, 10); + p = printers + current_printer; - if (vars.orientation == ORIENT_AUTO) + (*p->imageable_area)(p->model, vars.ppd_file, vars.media_size, &left, &right, + &bottom, &top); + + page_width = 10 * (right - left) / 72; + page_height = 10 * (top - bottom) / 72; + + (*p->media_size)(p->model, vars.ppd_file, vars.media_size, &width, &length); + + width = 10 * width / 72; + length = 10 * length / 72; + + if (vars.scaling < 0) + { + tw0 = -image_width * 10 / vars.scaling; + th0 = tw0 * image_height / image_width; + tw1 = tw0; + th1 = th0; + } + else { tw0 = page_width * vars.scaling / 100; th0 = tw0 * image_height / image_width; @@ -1171,36 +1790,54 @@ preview_update(void) tw1 = th1 * image_width / image_height; }; ta1 = tw1 * th1; + }; - if (ta0 >= ta1) - orient = ORIENT_PORTRAIT; + if (vars.orientation == ORIENT_AUTO) + { + if (vars.scaling < 0) + { + if ((th0 > page_height && tw0 <= page_height) || + (tw0 > page_width && th0 <= page_width)) + orient = ORIENT_LANDSCAPE; + else + orient = ORIENT_PORTRAIT; + } else - orient = ORIENT_LANDSCAPE; + { + if (ta0 >= ta1) + orient = ORIENT_PORTRAIT; + else + orient = ORIENT_LANDSCAPE; + }; } else orient = vars.orientation; if (orient == ORIENT_LANDSCAPE) { - page_width = media_height(vars.media_size, 10); - page_height = media_width(vars.media_size, 10); + temp = page_width; + page_width = page_height; + page_height = temp; + temp = width; + width = length; + length = temp; + print_width = tw1; + print_height = th1; + } + else + { + print_width = tw0; + print_height = th0; }; page_left = (PREVIEW_SIZE - page_width) / 2; page_top = (PREVIEW_SIZE - page_height) / 2; gdk_draw_rectangle(preview->widget.window, gc, 0, - (PREVIEW_SIZE - page_width - 5) / 2, - (PREVIEW_SIZE - page_height - 10) / 2, - page_width + 5, page_height + 10); + (PREVIEW_SIZE - width) / 2, + (PREVIEW_SIZE - length) / 2, + width, length); - print_width = page_width * vars.scaling / 100; - print_height = print_width * image_height / image_width; - if (print_height > page_height) - { - print_height = page_height; - print_width = print_height * image_width / image_height; - }; if (vars.left < 0 || vars.top < 0) gdk_draw_rectangle(preview->widget.window, gc, 1, @@ -1237,6 +1874,7 @@ static void preview_motion_callback(GtkWidget *w, GdkEventMotion *event) { +#if 0 if (vars.left < 0 || vars.top < 0) { vars.left = (page_width - print_width) / 2; @@ -1256,6 +1894,7 @@ preview_motion_callback(GtkWidget *w, mouse_x = event->x; mouse_y = event->y; +#endif /* 0 */ } @@ -1266,8 +1905,11 @@ preview_motion_callback(GtkWidget *w, static void printrc_load(void) { + int i; /* Looping var */ FILE *fp; /* Printrc file */ - char line[1024]; /* Line in printrc file */ + char line[1024], /* Line in printrc file */ + *lineptr, /* Pointer in line */ + *commaptr; /* Pointer to next comma */ plist_t *p, /* Current printer */ key; /* Search key */ @@ -1298,24 +1940,90 @@ printrc_load(void) if (line[0] == '#') continue; /* Comment */ - if (sscanf(line, "%s%s%d%*[ \t]%[^\n]", key.name, key.driver, - &(key.output_type), key.command) == 4) - { - /* - * Check to see if this is an old printrc file... - */ + /* + * Read the command-delimited printer definition data. Note that + * we can't use sscanf because %[^,] fails if the string is empty... + */ - if (key.command[0] == '|') - strcpy(key.command, key.command + 1); + if ((commaptr = strchr(line, ',')) == NULL) + continue; /* Skip old printer definitions */ - if ((p = bsearch(&key, plist + 1, plist_count - 1, sizeof(plist_t), - (int (*)(const void *, const void *))compare_printers)) != NULL) - memcpy(p, &key, sizeof(plist_t)); - }; + strncpy(key.name, line, commaptr - line); + key.name[commaptr - line] = '\0'; + lineptr = commaptr + 1; + + if ((commaptr = strchr(lineptr, ',')) == NULL) + continue; /* Skip bad printer definitions */ + + strncpy(key.command, lineptr, commaptr - lineptr); + key.command[commaptr - lineptr] = '\0'; + lineptr = commaptr + 1; + + if ((commaptr = strchr(lineptr, ',')) == NULL) + continue; /* Skip bad printer definitions */ + + strncpy(key.driver, lineptr, commaptr - lineptr); + key.driver[commaptr - lineptr] = '\0'; + lineptr = commaptr + 1; + + if ((commaptr = strchr(lineptr, ',')) == NULL) + continue; /* Skip bad printer definitions */ + + strncpy(key.ppd_file, lineptr, commaptr - lineptr); + key.ppd_file[commaptr - lineptr] = '\0'; + lineptr = commaptr + 1; + + if ((commaptr = strchr(lineptr, ',')) == NULL) + continue; /* Skip bad printer definitions */ + + key.output_type = atoi(lineptr); + lineptr = commaptr + 1; + + if ((commaptr = strchr(lineptr, ',')) == NULL) + continue; /* Skip bad printer definitions */ + + strncpy(key.resolution, lineptr, commaptr - lineptr); + key.resolution[commaptr - lineptr] = '\0'; + lineptr = commaptr + 1; + + if ((commaptr = strchr(lineptr, ',')) == NULL) + continue; /* Skip bad printer definitions */ + + strncpy(key.media_size, lineptr, commaptr - lineptr); + key.media_size[commaptr - lineptr] = '\0'; + lineptr = commaptr + 1; + + if ((commaptr = strchr(lineptr, ',')) == NULL) + continue; /* Skip bad printer definitions */ + + strncpy(key.media_type, lineptr, commaptr - lineptr); + key.media_type[commaptr - lineptr] = '\0'; + lineptr = commaptr + 1; + + strcpy(key.media_source, lineptr); + key.media_source[strlen(key.media_source) - 1] = '\0'; /* Drop NL */ + + if ((p = bsearch(&key, plist + 1, plist_count - 1, sizeof(plist_t), + (int (*)(const void *, const void *))compare_printers)) != NULL) + memcpy(p, &key, sizeof(plist_t)); }; fclose(fp); }; + + /* + * Select the current printer as necessary... + */ + + if (vars.output_to[0] != '\0') + { + for (i = 0; i < plist_count; i ++) + if (strcmp(vars.output_to, plist[i].command) == 0) + break; + + if (i < plist_count) + plist_current = i; + }; } @@ -1350,7 +2058,9 @@ printrc_save(void) fputs("#PRINTRC " PLUG_IN_VERSION "\n", fp); for (i = 1, p = plist + 1; i < plist_count; i ++, p ++) - fprintf(fp, "%s %s %d %s\n", p->name, p->driver, p->output_type, p->command); + fprintf(fp, "%s,%s,%s,%s,%d,%s,%s,%s,%s\n", + p->name, p->command, p->driver, p->ppd_file, p->output_type, + p->resolution, p->media_size, p->media_type, p->media_source); fclose(fp); }; @@ -1389,7 +2099,7 @@ get_printers(void) memset(plist, 0, sizeof(plist)); plist_count = 1; strcpy(plist[0].name, "File"); - strcpy(plist[0].command, "file.ps"); + sprintf(plist[0].command, "", line); strcpy(plist[0].driver, "ps2"); plist[0].output_type = OUTPUT_COLOR; @@ -1444,15 +2154,6 @@ get_printers(void) if (strcmp(defname, plist[i].name) == 0) break; - if (i < plist_count) - plist_current = i; - } - else if (vars.output_to[0] != '\0') - { - for (i = 0; i < plist_count; i ++) - if (strcmp(vars.output_to, plist[i].command) == 0) - break; - if (i < plist_count) plist_current = i; }; diff --git a/plug-ins/print/print.h b/plug-ins/print/print.h index 379cf8306d..752053ac97 100644 --- a/plug-ins/print/print.h +++ b/plug-ins/print/print.h @@ -22,21 +22,16 @@ * Revision History: * * $Log$ - * Revision 1.4 1998/04/13 05:43:17 yosh - * Have fun recompiling gimp everyone. It's the great FSF address change! - * - * -Yosh - * - * Revision 1.3 1998/04/01 22:14:49 neo - * Added checks for print spoolers to configure.in as suggested by Michael - * Sweet. The print plug-in still needs some changes to Makefile.am to make - * make use of this. - * - * Updated print and sgi plug-ins to version on the registry. + * Revision 1.5 1998/05/11 19:53:31 neo + * Updated print plug-in to version 2.0 * * * --Sven * + * Revision 1.11 1998/05/08 19:20:50 mike + * Updated for new driver interface. + * Added media size, imageable area, and parameter functions. + * * Revision 1.10 1998/03/01 17:20:48 mike * Updated version number & date. * @@ -96,7 +91,7 @@ * Constants... */ -#define PLUG_IN_VERSION "1.4 - 1 March 1998" +#define PLUG_IN_VERSION "2.0 - 8 May 1998" #define PLUG_IN_NAME "Print" #define MEDIA_LETTER 0 /* 8.5x11" a.k.a. "A" size */ @@ -126,21 +121,25 @@ typedef struct { char *long_name, /* Long name for UI */ *short_name; /* Short name for printrc file */ - int xdpi, /* X resolution */ - ydpi, /* Y resolution */ - large_sizes, /* TRUE if supports large sizes */ - color, /* TRUE if supports color */ + int color, /* TRUE if supports color */ model; /* Model number */ float gamma, /* Gamma correction */ density; /* Ink "density" or black level */ - void (*print)(FILE *prn, GDrawable *drawable, int media_size, - int xdpi, int ydpi, int output_type, int model, - guchar *lut, guchar *cmap, int orientation, - int scaling, int left, int top); - /* Print function */ + char **(*parameters)(int model, char *ppd_file, char *name, int *count); + /* Parameter names */ + void (*media_size)(int model, char *ppd_file, char *media_size, + int *width, int *length); + void (*imageable_area)(int model, char *ppd_file, char *media_size, + int *left, int *right, int *bottom, int *top); + void (*print)(int model, char *ppd_file, char *resolution, + char *media_size, char *media_type, char *media_source, + int output_type, int orientation, float scaling, int left, + int top, int copies, FILE *prn, GDrawable *drawable, + guchar *lut, guchar *cmap); /* Print function */ } printer_t; -typedef void (*convert_t)(guchar *in, guchar *out, int width, int bpp, guchar *lut, guchar *cmap); +typedef void (*convert_t)(guchar *in, guchar *out, int width, int bpp, + guchar *lut, guchar *cmap); /* @@ -153,14 +152,43 @@ extern void dither_cmyk(guchar *, int, int, int, unsigned char *, extern void gray_to_gray(guchar *, guchar *, int, int, guchar *, guchar *); extern void indexed_to_gray(guchar *, guchar *, int, int, guchar *, guchar *); extern void indexed_to_rgb(guchar *, guchar *, int, int, guchar *, guchar *); -extern int media_width(int, int); -extern int media_height(int, int); extern void rgb_to_gray(guchar *, guchar *, int, int, guchar *, guchar *); extern void rgb_to_rgb(guchar *, guchar *, int, int, guchar *, guchar *); -extern void escp2_print(FILE *, GDrawable *, int, int, int, int, int, guchar *, guchar *, int, int, int, int); -extern void pcl_print(FILE *, GDrawable *, int, int, int, int, int, guchar *, guchar *, int, int, int, int); -extern void ps_print(FILE *, GDrawable *, int, int, int, int, int, guchar *, guchar *, int, int, int, int); +extern void default_media_size(int model, char *ppd_file, char *media_size, + int *width, int *length); + +extern char **escp2_parameters(int model, char *ppd_file, char *name, + int *count); +extern void escp2_imageable_area(int model, char *ppd_file, char *media_size, + int *left, int *right, int *bottom, int *top); +extern void escp2_print(int model, char *ppd_file, char *resolution, + char *media_size, char *media_type, char *media_source, + int output_type, int orientation, float scaling, + int left, int top, int copies, FILE *prn, + GDrawable *drawable, guchar *lut, guchar *cmap); + +extern char **pcl_parameters(int model, char *ppd_file, char *name, + int *count); +extern void pcl_imageable_area(int model, char *ppd_file, char *media_size, + int *left, int *right, int *bottom, int *top); +extern void pcl_print(int model, char *ppd_file, char *resolution, + char *media_size, char *media_type, char *media_source, + int output_type, int orientation, float scaling, + int left, int top, int copies, FILE *prn, + GDrawable *drawable, guchar *lut, guchar *cmap); + +extern char **ps_parameters(int model, char *ppd_file, char *name, + int *count); +extern void ps_media_size(int model, char *ppd_file, char *media_size, + int *width, int *length); +extern void ps_imageable_area(int model, char *ppd_file, char *media_size, + int *left, int *right, int *bottom, int *top); +extern void ps_print(int model, char *ppd_file, char *resolution, + char *media_size, char *media_type, char *media_source, + int output_type, int orientation, float scaling, + int left, int top, int copies, FILE *prn, + GDrawable *drawable, guchar *lut, guchar *cmap); /*