1997-11-25 06:05:25 +08:00
|
|
|
/*
|
|
|
|
* "$Id$"
|
|
|
|
*
|
|
|
|
* Print plug-in Adobe PostScript driver for the GIMP.
|
|
|
|
*
|
2000-01-27 00:00:48 +08:00
|
|
|
* Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
|
1999-12-17 03:44:02 +08:00
|
|
|
* Robert Krawitz (rlk@alum.mit.edu)
|
1997-11-25 06:05:25 +08:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
2000-10-04 09:47:59 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file must include only standard C header files. The core code must
|
|
|
|
* compile on generic platforms that don't support glib, gimp, gtk, etc.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "print.h"
|
|
|
|
#include <time.h>
|
2000-08-15 08:43:48 +08:00
|
|
|
#include <string.h>
|
|
|
|
#include <limits.h>
|
1999-05-30 00:35:47 +08:00
|
|
|
|
1998-05-12 03:53:31 +08:00
|
|
|
/*#define DEBUG*/
|
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
|
1998-05-12 03:53:31 +08:00
|
|
|
/*
|
|
|
|
* Local variables...
|
|
|
|
*/
|
|
|
|
|
|
|
|
static FILE *ps_ppd = NULL;
|
2000-10-04 09:47:59 +08:00
|
|
|
static const char *ps_ppd_file = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local functions...
|
|
|
|
*/
|
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
static void ps_hex(FILE *, unsigned short *, int);
|
|
|
|
static void ps_ascii85(FILE *, unsigned short *, int, int);
|
2000-08-15 08:43:48 +08:00
|
|
|
static char *ppd_find(const char *, const char *, const char *, int *);
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 'ps_parameters()' - Return the parameter values for the given parameter.
|
|
|
|
*/
|
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
char ** /* O - Parameter values */
|
|
|
|
ps_parameters(const printer_t *printer, /* I - Printer model */
|
|
|
|
char *ppd_file, /* I - PPD file (not used) */
|
|
|
|
char *name, /* I - Name of parameter */
|
|
|
|
int *count) /* O - Number of values */
|
1998-05-12 03:53:31 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
char line[1024],
|
|
|
|
lname[255],
|
|
|
|
loption[255];
|
|
|
|
char **valptrs;
|
|
|
|
|
|
|
|
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;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
if (ps_ppd == NULL)
|
|
|
|
{
|
2000-08-15 08:43:48 +08:00
|
|
|
if (strcmp(name, "PageSize") == 0)
|
1999-12-17 03:44:02 +08:00
|
|
|
{
|
2000-08-15 08:43:48 +08:00
|
|
|
const papersize_t *papersizes = get_papersizes();
|
|
|
|
valptrs = malloc(sizeof(char *) * known_papersizes());
|
|
|
|
*count = 0;
|
|
|
|
for (i = 0; i < known_papersizes(); i++)
|
|
|
|
{
|
|
|
|
if (strlen(papersizes[i].name) > 0)
|
|
|
|
{
|
|
|
|
valptrs[*count] = malloc(strlen(papersizes[i].name) + 1);
|
|
|
|
strcpy(valptrs[*count], papersizes[i].name);
|
|
|
|
(*count)++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (valptrs);
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
2000-08-15 08:43:48 +08:00
|
|
|
else
|
|
|
|
return (NULL);
|
1998-05-12 03:53:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
rewind(ps_ppd);
|
|
|
|
*count = 0;
|
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
valptrs = malloc(100 * sizeof(char *));
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
while (fgets(line, sizeof(line), ps_ppd) != NULL)
|
|
|
|
{
|
|
|
|
if (line[0] != '*')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (sscanf(line, "*%s %[^/:]", lname, loption) != 2)
|
|
|
|
continue;
|
|
|
|
|
2000-10-04 09:47:59 +08:00
|
|
|
if (strcasecmp(lname, name) == 0)
|
1998-05-12 03:53:31 +08:00
|
|
|
{
|
2000-01-27 00:00:48 +08:00
|
|
|
valptrs[(*count)] = malloc(strlen(loption) + 1);
|
|
|
|
strcpy(valptrs[(*count)], loption);
|
1998-05-12 03:53:31 +08:00
|
|
|
(*count) ++;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
if (*count == 0)
|
|
|
|
{
|
1999-12-17 03:44:02 +08:00
|
|
|
free(valptrs);
|
1998-05-12 03:53:31 +08:00
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return (valptrs);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 'ps_media_size()' - Return the size of the page.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2000-08-15 08:43:48 +08:00
|
|
|
ps_media_size(const printer_t *printer, /* I - Printer model */
|
|
|
|
const vars_t *v, /* I */
|
1998-05-12 03:53:31 +08:00
|
|
|
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 */
|
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
if ((dimensions = ppd_find(v->ppd_file, "PaperDimension", v->media_size,
|
|
|
|
NULL))
|
|
|
|
!= NULL)
|
1998-05-12 03:53:31 +08:00
|
|
|
sscanf(dimensions, "%d%d", width, length);
|
|
|
|
else
|
2000-08-15 08:43:48 +08:00
|
|
|
default_media_size(printer, v, width, length);
|
1998-05-12 03:53:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 'ps_imageable_area()' - Return the imageable area of the page.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2000-08-15 08:43:48 +08:00
|
|
|
ps_imageable_area(const printer_t *printer, /* I - Printer model */
|
|
|
|
const vars_t *v, /* I */
|
1998-05-12 03:53:31 +08:00
|
|
|
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;
|
|
|
|
|
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
if ((area = ppd_find(v->ppd_file, "ImageableArea", v->media_size, NULL))
|
|
|
|
!= NULL)
|
1998-05-12 03:53:31 +08:00
|
|
|
{
|
|
|
|
#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
|
1998-05-17 15:16:50 +08:00
|
|
|
{
|
2000-08-15 08:43:48 +08:00
|
|
|
default_media_size(printer, v, right, top);
|
1998-05-17 15:16:50 +08:00
|
|
|
*left = 18;
|
|
|
|
*right -= 18;
|
|
|
|
*top -= 36;
|
|
|
|
*bottom = 36;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
void
|
|
|
|
ps_limit(const printer_t *printer, /* I - Printer model */
|
|
|
|
const vars_t *v, /* I */
|
|
|
|
int *width, /* O - Left position in points */
|
|
|
|
int *length) /* O - Top position in points */
|
|
|
|
{
|
|
|
|
*width = INT_MAX;
|
|
|
|
*length = INT_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
ps_default_resolution(const printer_t *printer)
|
|
|
|
{
|
|
|
|
return "default";
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 'ps_print()' - Print an image to a PostScript printer.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2000-08-15 08:43:48 +08:00
|
|
|
ps_print(const printer_t *printer, /* I - Model (Level 1 or 2) */
|
1998-05-12 03:53:31 +08:00
|
|
|
int copies, /* I - Number of copies */
|
|
|
|
FILE *prn, /* I - File to print to */
|
1999-12-17 03:44:02 +08:00
|
|
|
Image image, /* I - Image to print */
|
2000-08-15 08:43:48 +08:00
|
|
|
const vars_t *v)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-08-15 08:43:48 +08:00
|
|
|
unsigned char *cmap = v->cmap;
|
|
|
|
int model = printer->model;
|
2000-10-04 09:47:59 +08:00
|
|
|
const char *ppd_file = v->ppd_file;
|
|
|
|
const char *resolution = v->resolution;
|
|
|
|
const char *media_size = v->media_size;
|
|
|
|
const char *media_type = v->media_type;
|
|
|
|
const char *media_source = v->media_source;
|
1999-12-17 03:44:02 +08:00
|
|
|
int output_type = v->output_type;
|
|
|
|
int orientation = v->orientation;
|
2000-10-04 09:47:59 +08:00
|
|
|
double scaling = v->scaling;
|
1999-12-17 03:44:02 +08:00
|
|
|
int top = v->top;
|
|
|
|
int left = v->left;
|
1998-05-12 03:53:31 +08:00
|
|
|
int i, j; /* Looping vars */
|
2000-08-15 08:43:48 +08:00
|
|
|
int y; /* Looping vars */
|
1999-12-17 03:44:02 +08:00
|
|
|
unsigned char *in; /* Input pixels from image */
|
|
|
|
unsigned short *out; /* Output pixels for printer */
|
1998-05-12 03:53:31 +08:00
|
|
|
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 */
|
1997-11-25 06:05:25 +08:00
|
|
|
page_height, /* Height of page */
|
|
|
|
out_width, /* Width of image on page */
|
|
|
|
out_height, /* Height of image on page */
|
|
|
|
out_bpp, /* Output bytes per pixel */
|
1998-01-25 17:29:29 +08:00
|
|
|
out_length, /* Output length (Level 2 output) */
|
2000-08-15 08:43:48 +08:00
|
|
|
out_offset; /* Output offset (Level 2 output) */
|
1997-11-25 06:05:25 +08:00
|
|
|
time_t curtime; /* Current time of day */
|
|
|
|
convert_t colorfunc; /* Color conversion function... */
|
1998-05-12 03:53:31 +08:00
|
|
|
char *command; /* PostScript command */
|
|
|
|
int order, /* Order of command */
|
|
|
|
num_commands; /* Number of commands */
|
|
|
|
struct /* PostScript commands... */
|
|
|
|
{
|
|
|
|
char *command;
|
|
|
|
int order;
|
|
|
|
} commands[4];
|
1999-12-17 03:44:02 +08:00
|
|
|
int image_height,
|
|
|
|
image_width,
|
|
|
|
image_bpp;
|
2000-08-15 08:43:48 +08:00
|
|
|
vars_t nv;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
memcpy(&nv, v, sizeof(vars_t));
|
1997-11-25 06:05:25 +08:00
|
|
|
/*
|
|
|
|
* Setup a read-only pixel region for the entire image...
|
|
|
|
*/
|
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
Image_init(image);
|
|
|
|
image_height = Image_height(image);
|
|
|
|
image_width = Image_width(image);
|
|
|
|
image_bpp = Image_bpp(image);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Choose the correct color conversion function...
|
|
|
|
*/
|
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
colorfunc = choose_colorfunc(output_type, image_bpp, cmap, &out_bpp, &nv);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Compute the output size...
|
|
|
|
*/
|
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
ps_imageable_area(printer, &nv, &page_left, &page_right,
|
1998-05-12 03:53:31 +08:00
|
|
|
&page_bottom, &page_top);
|
2000-08-15 08:43:48 +08:00
|
|
|
compute_page_parameters(page_right, page_left, page_top, page_bottom,
|
|
|
|
scaling, image_width, image_height, image,
|
|
|
|
&orientation, &page_width, &page_height,
|
|
|
|
&out_width, &out_height, &left, &top);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Recompute the image height and width. If the image has been
|
|
|
|
* rotated, these will change from previously.
|
|
|
|
*/
|
|
|
|
image_height = Image_height(image);
|
|
|
|
image_width = Image_width(image);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Let the user know what we're doing...
|
|
|
|
*/
|
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
Image_progress_init(image);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Output a standard PostScript header with DSC comments...
|
|
|
|
*/
|
|
|
|
|
|
|
|
curtime = time(NULL);
|
|
|
|
|
1998-05-17 15:16:50 +08:00
|
|
|
if (left < 0)
|
1998-05-12 03:53:31 +08:00
|
|
|
left = (page_width - out_width) / 2 + page_left;
|
2000-08-15 08:43:48 +08:00
|
|
|
else
|
|
|
|
left += page_left;
|
1998-05-17 15:16:50 +08:00
|
|
|
|
|
|
|
if (top < 0)
|
1998-05-12 03:53:31 +08:00
|
|
|
top = (page_height + out_height) / 2 + page_bottom;
|
1998-05-17 15:16:50 +08:00
|
|
|
else
|
|
|
|
top = page_height - top + page_bottom;
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
#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 */
|
|
|
|
|
1999-05-02 01:54:43 +08:00
|
|
|
#ifdef __EMX__
|
|
|
|
_fsetmode(prn, "t");
|
|
|
|
#endif
|
1997-11-25 06:05:25 +08:00
|
|
|
fputs("%!PS-Adobe-3.0\n", prn);
|
2000-08-15 08:43:48 +08:00
|
|
|
fprintf(prn, "%%%%Creator: %s\n", Image_get_appname(image));
|
1997-11-25 06:05:25 +08:00
|
|
|
fprintf(prn, "%%%%CreationDate: %s", ctime(&curtime));
|
2000-08-15 08:43:48 +08:00
|
|
|
fputs("%%Copyright: 1997-2000 by Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu)\n", prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
fprintf(prn, "%%%%BoundingBox: %d %d %d %d\n",
|
1998-05-12 03:53:31 +08:00
|
|
|
left, top - out_height, left + out_width, top);
|
1997-11-25 06:05:25 +08:00
|
|
|
fputs("%%DocumentData: Clean7Bit\n", prn);
|
1998-01-25 17:29:29 +08:00
|
|
|
fprintf(prn, "%%%%LanguageLevel: %d\n", model + 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
fputs("%%Pages: 1\n", prn);
|
|
|
|
fputs("%%Orientation: Portrait\n", prn);
|
|
|
|
fputs("%%EndComments\n", prn);
|
|
|
|
|
1998-05-12 03:53:31 +08:00
|
|
|
/*
|
|
|
|
* Find any printer-specific commands...
|
|
|
|
*/
|
|
|
|
|
|
|
|
num_commands = 0;
|
|
|
|
|
|
|
|
if ((command = ppd_find(ppd_file, "PageSize", media_size, &order)) != NULL)
|
|
|
|
{
|
1999-12-17 03:44:02 +08:00
|
|
|
commands[num_commands].command = malloc(strlen(command) + 1);
|
|
|
|
strcpy(commands[num_commands].command, command);
|
1998-05-12 03:53:31 +08:00
|
|
|
commands[num_commands].order = order;
|
|
|
|
num_commands ++;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
if ((command = ppd_find(ppd_file, "InputSlot", media_source, &order)) != NULL)
|
|
|
|
{
|
1999-12-17 03:44:02 +08:00
|
|
|
commands[num_commands].command = malloc(strlen(command) + 1);
|
|
|
|
strcpy(commands[num_commands].command, command);
|
1998-05-12 03:53:31 +08:00
|
|
|
commands[num_commands].order = order;
|
|
|
|
num_commands ++;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
if ((command = ppd_find(ppd_file, "MediaType", media_type, &order)) != NULL)
|
|
|
|
{
|
1999-12-17 03:44:02 +08:00
|
|
|
commands[num_commands].command = malloc(strlen(command) + 1);
|
|
|
|
strcpy(commands[num_commands].command, command);
|
1998-05-12 03:53:31 +08:00
|
|
|
commands[num_commands].order = order;
|
|
|
|
num_commands ++;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
if ((command = ppd_find(ppd_file, "Resolution", resolution, &order)) != NULL)
|
|
|
|
{
|
1999-12-17 03:44:02 +08:00
|
|
|
commands[num_commands].command = malloc(strlen(command) + 1);
|
|
|
|
strcpy(commands[num_commands].command, command);
|
1998-05-12 03:53:31 +08:00
|
|
|
commands[num_commands].order = order;
|
|
|
|
num_commands ++;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Send the commands...
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (num_commands > 0)
|
|
|
|
{
|
|
|
|
fputs("%%BeginProlog\n", prn);
|
|
|
|
|
|
|
|
for (i = 0; i < num_commands; i ++)
|
|
|
|
{
|
|
|
|
fputs(commands[i].command, prn);
|
2000-02-28 08:45:58 +08:00
|
|
|
fputs("\n", prn);
|
1999-12-17 03:44:02 +08:00
|
|
|
free(commands[i].command);
|
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
fputs("%%EndProlog\n", prn);
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/*
|
2000-08-15 08:43:48 +08:00
|
|
|
* Output the page...
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
fputs("%%Page: 1\n", prn);
|
|
|
|
fputs("gsave\n", prn);
|
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
fprintf(prn, "%d %d translate\n", left, top);
|
|
|
|
fprintf(prn, "%.3f %.3f scale\n",
|
2000-10-04 09:47:59 +08:00
|
|
|
(double)out_width / ((double)image_width),
|
|
|
|
(double)out_height / ((double)image_height));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
in = malloc(image_width * image_bpp);
|
|
|
|
out = malloc((image_width * out_bpp + 3) * 2);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
compute_lut(256, &nv);
|
|
|
|
|
1998-05-12 03:53:31 +08:00
|
|
|
if (model == 0)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-12-17 03:44:02 +08:00
|
|
|
fprintf(prn, "/picture %d string def\n", image_width * out_bpp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
fprintf(prn, "%d %d 8\n", image_width, image_height);
|
1998-05-12 03:53:31 +08:00
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
fputs("[ 1 0 0 -1 0 1 ]\n", prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (output_type == OUTPUT_GRAY)
|
1998-05-12 03:53:31 +08:00
|
|
|
fputs("{currentfile picture readhexstring pop} image\n", prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
1998-05-12 03:53:31 +08:00
|
|
|
fputs("{currentfile picture readhexstring pop} false 3 colorimage\n", prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
for (y = 0; y < image_height; y ++)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-05-12 03:53:31 +08:00
|
|
|
if ((y & 15) == 0)
|
1999-12-17 03:44:02 +08:00
|
|
|
Image_note_progress(image, y, image_height);
|
1998-01-25 17:29:29 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
Image_get_row(image, in, y);
|
2000-08-15 08:43:48 +08:00
|
|
|
(*colorfunc)(in, out, image_width, image_bpp, cmap, &nv);
|
1998-01-25 17:29:29 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
ps_hex(prn, out, image_width * out_bpp);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1998-05-12 03:53:31 +08:00
|
|
|
if (output_type == OUTPUT_GRAY)
|
|
|
|
fputs("/DeviceGray setcolorspace\n", prn);
|
|
|
|
else
|
|
|
|
fputs("/DeviceRGB setcolorspace\n", prn);
|
|
|
|
|
|
|
|
fputs("<<\n", prn);
|
|
|
|
fputs("\t/ImageType 1\n", prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
fprintf(prn, "\t/Width %d\n", image_width);
|
|
|
|
fprintf(prn, "\t/Height %d\n", image_height);
|
1998-05-12 03:53:31 +08:00
|
|
|
fputs("\t/BitsPerComponent 8\n", prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (output_type == OUTPUT_GRAY)
|
1998-05-12 03:53:31 +08:00
|
|
|
fputs("\t/Decode [ 0 1 ]\n", prn);
|
|
|
|
else
|
|
|
|
fputs("\t/Decode [ 0 1 0 1 0 1 ]\n", prn);
|
|
|
|
|
|
|
|
fputs("\t/DataSource currentfile /ASCII85Decode filter\n", prn);
|
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
if ((image_width * 72 / out_width) < 100)
|
1998-05-12 03:53:31 +08:00
|
|
|
fputs("\t/Interpolate true\n", prn);
|
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
fputs("\t/ImageMatrix [ 1 0 0 -1 0 1 ]\n", prn);
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
fputs(">>\n", prn);
|
|
|
|
fputs("image\n", prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
for (y = 0, out_offset = 0; y < image_height; y ++)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
if ((y & 15) == 0)
|
1999-12-17 03:44:02 +08:00
|
|
|
Image_note_progress(image, y, image_height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
Image_get_row(image, in, y);
|
2000-08-15 08:43:48 +08:00
|
|
|
(*colorfunc)(in, out + out_offset, image_width, image_bpp, cmap, &nv);
|
1998-01-25 17:29:29 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
out_length = out_offset + image_width * out_bpp;
|
1998-01-25 17:29:29 +08:00
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
if (y < (image_height - 1))
|
1998-05-12 03:53:31 +08:00
|
|
|
{
|
|
|
|
ps_ascii85(prn, out, out_length & ~3, 0);
|
|
|
|
out_offset = out_length & 3;
|
1998-01-25 17:29:29 +08:00
|
|
|
}
|
|
|
|
else
|
1998-05-12 03:53:31 +08:00
|
|
|
{
|
|
|
|
ps_ascii85(prn, out, out_length, 1);
|
|
|
|
out_offset = 0;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
if (out_offset > 0)
|
|
|
|
memcpy(out, out + out_length - out_offset, out_offset);
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
2000-08-15 08:43:48 +08:00
|
|
|
Image_progress_conclude(image);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-08-15 08:43:48 +08:00
|
|
|
free_lut(&nv);
|
1999-12-17 03:44:02 +08:00
|
|
|
free(in);
|
|
|
|
free(out);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
fputs("grestore\n", prn);
|
|
|
|
fputs("showpage\n", prn);
|
|
|
|
fputs("%%EndPage\n", prn);
|
|
|
|
fputs("%%EOF\n", prn);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 'ps_hex()' - Print binary data as a series of hexadecimal numbers.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
ps_hex(FILE *prn, /* I - File to print to */
|
1999-12-17 03:44:02 +08:00
|
|
|
unsigned short *data, /* I - Data to print */
|
1997-11-25 06:05:25 +08:00
|
|
|
int length) /* I - Number of bytes to print */
|
|
|
|
{
|
1998-05-12 03:53:31 +08:00
|
|
|
int col; /* Current column */
|
1997-11-25 06:05:25 +08:00
|
|
|
static char *hex = "0123456789ABCDEF";
|
|
|
|
|
|
|
|
|
1998-05-12 03:53:31 +08:00
|
|
|
col = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
while (length > 0)
|
|
|
|
{
|
1999-12-17 03:44:02 +08:00
|
|
|
unsigned char pixel = (*data & 0xff00) >> 8;
|
1997-11-25 06:05:25 +08:00
|
|
|
/*
|
|
|
|
* Put the hex chars out to the file; note that we don't use fprintf()
|
|
|
|
* for speed reasons...
|
|
|
|
*/
|
|
|
|
|
1999-12-17 03:44:02 +08:00
|
|
|
putc(hex[pixel >> 4], prn);
|
|
|
|
putc(hex[pixel & 15], prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
data ++;
|
|
|
|
length --;
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
col = (col + 1) & 31;
|
|
|
|
if (col == 0)
|
|
|
|
putc('\n', prn);
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-05-12 03:53:31 +08:00
|
|
|
if (col > 0)
|
|
|
|
putc('\n', prn);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-01-25 17:29:29 +08:00
|
|
|
/*
|
|
|
|
* 'ps_ascii85()' - Print binary data as a series of base-85 numbers.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
ps_ascii85(FILE *prn, /* I - File to print to */
|
1999-12-17 03:44:02 +08:00
|
|
|
unsigned short *data, /* I - Data to print */
|
1998-01-25 17:29:29 +08:00
|
|
|
int length, /* I - Number of bytes to print */
|
|
|
|
int last_line) /* I - Last line of raster data? */
|
|
|
|
{
|
1998-05-12 03:53:31 +08:00
|
|
|
int i; /* Looping var */
|
1998-01-25 17:29:29 +08:00
|
|
|
unsigned b; /* Binary data word */
|
|
|
|
unsigned char c[5]; /* ASCII85 encoded chars */
|
|
|
|
|
|
|
|
|
|
|
|
while (length > 3)
|
|
|
|
{
|
1999-12-17 03:44:02 +08:00
|
|
|
unsigned char d0 = (data[0] & 0xff00) >> 8;
|
|
|
|
unsigned char d1 = (data[1] & 0xff00) >> 8;
|
|
|
|
unsigned char d2 = (data[2] & 0xff00) >> 8;
|
|
|
|
unsigned char d3 = (data[3] & 0xff00) >> 8;
|
|
|
|
b = (((((d0 << 8) | d1) << 8) | d2) << 8) | d3;
|
1998-01-25 17:29:29 +08:00
|
|
|
|
|
|
|
if (b == 0)
|
|
|
|
putc('z', prn);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
c[4] = (b % 85) + '!';
|
|
|
|
b /= 85;
|
|
|
|
c[3] = (b % 85) + '!';
|
|
|
|
b /= 85;
|
|
|
|
c[2] = (b % 85) + '!';
|
|
|
|
b /= 85;
|
|
|
|
c[1] = (b % 85) + '!';
|
|
|
|
b /= 85;
|
|
|
|
c[0] = b + '!';
|
|
|
|
|
|
|
|
fwrite(c, 5, 1, prn);
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-01-25 17:29:29 +08:00
|
|
|
|
|
|
|
data += 4;
|
|
|
|
length -= 4;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-01-25 17:29:29 +08:00
|
|
|
|
|
|
|
if (last_line)
|
|
|
|
{
|
|
|
|
if (length > 0)
|
|
|
|
{
|
1998-05-12 03:53:31 +08:00
|
|
|
for (b = 0, i = length; i > 0; b = (b << 8) | data[0], data ++, i --);
|
1998-01-25 17:29:29 +08:00
|
|
|
|
|
|
|
c[4] = (b % 85) + '!';
|
|
|
|
b /= 85;
|
|
|
|
c[3] = (b % 85) + '!';
|
|
|
|
b /= 85;
|
|
|
|
c[2] = (b % 85) + '!';
|
|
|
|
b /= 85;
|
|
|
|
c[1] = (b % 85) + '!';
|
|
|
|
b /= 85;
|
|
|
|
c[0] = b + '!';
|
|
|
|
|
|
|
|
fwrite(c, length + 1, 1, prn);
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-01-25 17:29:29 +08:00
|
|
|
|
|
|
|
fputs("~>\n", prn);
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 'ppd_find()' - Find a control string with the specified name & parameters.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static char * /* O - Control string */
|
2000-08-15 08:43:48 +08:00
|
|
|
ppd_find(const char *ppd_file, /* I - Name of PPD file */
|
|
|
|
const char *name, /* I - Name of parameter */
|
|
|
|
const char *option, /* I - Value of parameter */
|
1998-05-12 03:53:31 +08:00
|
|
|
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 */
|
2000-08-15 08:43:48 +08:00
|
|
|
static char *value = NULL; /* Current control string value */
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
|
|
|
|
if (ppd_file == NULL || name == NULL || option == NULL)
|
|
|
|
return (NULL);
|
2000-08-15 08:43:48 +08:00
|
|
|
if (!value)
|
|
|
|
value = malloc(32768);
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
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;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2000-10-04 09:47:59 +08:00
|
|
|
if (strncasecmp(line, "*OrderDependency:", 17) == 0 && order != NULL)
|
1998-05-12 03:53:31 +08:00
|
|
|
{
|
|
|
|
sscanf(line, "%*s%d", order);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (sscanf(line, "*%s %[^/:]", lname, loption) != 2)
|
|
|
|
continue;
|
|
|
|
|
2000-10-04 09:47:59 +08:00
|
|
|
if (strcasecmp(lname, name) == 0 &&
|
|
|
|
strcasecmp(loption, option) == 0)
|
1998-05-12 03:53:31 +08:00
|
|
|
{
|
|
|
|
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;
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
*opt = '\0';
|
|
|
|
|
|
|
|
return (value);
|
1999-12-17 03:44:02 +08:00
|
|
|
}
|
|
|
|
}
|
1998-05-12 03:53:31 +08:00
|
|
|
|
|
|
|
return (NULL);
|
1998-01-25 17:29:29 +08:00
|
|
|
}
|