/*
- * "$Id: pstops.c 5326 2006-03-23 19:33:35Z mike $"
+ * "$Id: pstops.c 6320 2007-03-08 13:36:56Z mike $"
*
* PostScript filter for the Common UNIX Printing System (CUPS).
*
- * Copyright 1993-2006 by Easy Software Products.
+ * Copyright 1993-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* property of Easy Software Products and are protected by Federal
* set_pstops_options() - Set pstops options...
* skip_page() - Skip past a page that won't be printed...
* start_nup() - Start processing for N-up printing...
+ * write_labels() - Write the actual page labels.
*/
/*
*/
#include "common.h"
+#include <limits.h>
#include <math.h>
#include <cups/file.h>
#include <cups/array.h>
static void copy_bytes(cups_file_t *fp, off_t offset,
size_t length);
static size_t copy_comments(cups_file_t *fp, pstops_doc_t *doc,
- char *line, size_t linelen,
- size_t linesize);
+ ppd_file_t *ppd, char *line,
+ size_t linelen, size_t linesize);
static void copy_dsc(cups_file_t *fp, pstops_doc_t *doc,
ppd_file_t *ppd, char *line, size_t linelen,
size_t linesize);
size_t linelen, size_t linesize);
static void do_prolog(pstops_doc_t *doc, ppd_file_t *ppd);
static void do_setup(pstops_doc_t *doc, ppd_file_t *ppd);
-static void doc_printf(pstops_doc_t *doc, const char *format, ...);
+static void doc_printf(pstops_doc_t *doc, const char *format, ...)
+#ifdef __GNUC__
+__attribute__ ((__format__ (__printf__, 2, 3)))
+#endif /* __GNUC__ */
+;
static void doc_puts(pstops_doc_t *doc, const char *s);
static void doc_write(pstops_doc_t *doc, const char *s, size_t len);
static void end_nup(pstops_doc_t *doc, int number);
size_t linesize);
static void start_nup(pstops_doc_t *doc, int number,
int show_border, const int *bounding_box);
+static void write_label_prolog(pstops_doc_t *doc, const char *label,
+ float bottom, float top,
+ float width);
+static void write_labels(pstops_doc_t *doc, int orient);
/*
fputs("DEBUG: Skipping PJL header...\n", stderr);
- while (strstr(line, "ENTER LANGUAGE") == NULL)
+ while (strstr(line, "ENTER LANGUAGE") == NULL && strncmp(line, "%!", 2))
if ((len = cupsFileGetLine(fp, line, sizeof(line))) == 0)
break;
+ if (!strncmp(line, "%!", 2))
+ break;
+
if ((len = cupsFileGetLine(fp, line, sizeof(line))) == 0)
break;
}
* See if we only print even or odd pages...
*/
- if (!strcasecmp(doc->page_set, "even") &&
- ((page - 1) % (doc->number_up << 1)) < doc->number_up)
+ if (!strcasecmp(doc->page_set, "even") && (page & 1))
return (0);
- if (!strcasecmp(doc->page_set, "odd") &&
- ((page - 1) % (doc->number_up << 1)) >= doc->number_up)
+ if (!strcasecmp(doc->page_set, "odd") && !(page & 1))
return (0);
}
static size_t /* O - Length of next line */
copy_comments(cups_file_t *fp, /* I - File to read from */
pstops_doc_t *doc, /* I - Document info */
+ ppd_file_t *ppd, /* I - PPD file */
char *line, /* I - Line buffer */
size_t linelen, /* I - Length of initial line */
size_t linesize) /* I - Size of line buffer */
if (!strncmp(line, "%%Pages:", 8))
{
+ int pages; /* Number of pages */
+
+
if (saw_pages)
fputs("ERROR: Duplicate %%Pages: comment seen!\n", stderr);
saw_pages = 1;
+
+ if (Duplex && (pages = atoi(line + 8)) > 0 && pages <= doc->number_up)
+ {
+ /*
+ * Since we will only be printing on a single page, disable duplexing.
+ */
+
+ Duplex = 0;
+ doc->slow_duplex = 0;
+
+ if (cupsGetOption("sides", doc->num_options, doc->options))
+ doc->num_options = cupsAddOption("sides", "one-sided",
+ doc->num_options, &(doc->options));
+
+ if (cupsGetOption("Duplex", doc->num_options, doc->options))
+ doc->num_options = cupsAddOption("Duplex", "None",
+ doc->num_options, &(doc->options));
+
+ if (cupsGetOption("EFDuplex", doc->num_options, doc->options))
+ doc->num_options = cupsAddOption("EFDuplex", "None",
+ doc->num_options, &(doc->options));
+
+ if (cupsGetOption("EFDuplexing", doc->num_options, doc->options))
+ doc->num_options = cupsAddOption("EFDuplexing", "False",
+ doc->num_options, &(doc->options));
+
+ if (cupsGetOption("KD03Duplex", doc->num_options, doc->options))
+ doc->num_options = cupsAddOption("KD03Duplex", "None",
+ doc->num_options, &(doc->options));
+
+ if (cupsGetOption("JCLDuplex", doc->num_options, doc->options))
+ doc->num_options = cupsAddOption("JCLDuplex", "None",
+ doc->num_options, &(doc->options));
+
+ ppdMarkOption(ppd, "Duplex", "None");
+ ppdMarkOption(ppd, "EFDuplex", "None");
+ ppdMarkOption(ppd, "EFDuplexing", "False");
+ ppdMarkOption(ppd, "KD03Duplex", "None");
+ ppdMarkOption(ppd, "JCLDuplex", "None");
+ }
}
else if (!strncmp(line, "%%BoundingBox:", 14))
{
if (saw_bounding_box)
fputs("ERROR: Duplicate %%BoundingBox: comment seen!\n", stderr);
+ else if (strstr(line + 14, "(atend)"))
+ {
+ /*
+ * Do nothing for now but use the default imageable area...
+ */
+ }
else if (sscanf(line + 14, "%d%d%d%d", doc->bounding_box + 0,
doc->bounding_box + 1, doc->bounding_box + 2,
doc->bounding_box + 3) != 4)
else if (!strncmp(line, "%%For:", 6))
{
saw_for = 1;
- printf("%s\n", line);
+ doc_printf(doc, "%s\n", line);
}
else if (!strncmp(line, "%%Title:", 8))
{
saw_title = 1;
- printf("%s\n", line);
+ doc_printf(doc, "%s\n", line);
}
else if (!strncmp(line, "%cupsRotation:", 14))
{
break;
}
else if (strncmp(line, "%!", 2) && strncmp(line, "%cups", 5))
- printf("%s\n", line);
+ doc_printf(doc, "%s\n", line);
if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0)
break;
fputs("ERROR: No %%Pages: comment in header!\n", stderr);
if (!saw_for)
- printf("%%%%For: %s\n", doc->user);
+ WriteTextComment("For", doc->user);
if (!saw_title)
- printf("%%%%Title: %s\n", doc->title);
+ WriteTextComment("Title", doc->title);
if (doc->copies != 1 && (!doc->collate || !doc->slow_collate))
{
* that are required...
*/
- printf("%%%%Requirements: numcopies(%d)%s%s\n", doc->copies,
- doc->collate ? " collate" : "",
- Duplex ? " duplex" : "");
+ doc_printf(doc, "%%%%Requirements: numcopies(%d)%s%s\n", doc->copies,
+ doc->collate ? " collate" : "",
+ Duplex ? " duplex" : "");
/*
* Apple uses RBI comments for various non-PPD options...
*/
- printf("%%RBINumCopies: %d\n", doc->copies);
+ doc_printf(doc, "%%RBINumCopies: %d\n", doc->copies);
}
else
{
*/
if (Duplex)
- puts("%%Requirements: duplex");
+ doc_puts(doc, "%%Requirements: duplex\n");
/*
* Apple uses RBI comments for various non-PPD options...
*/
- puts("%RBINumCopies: 1");
+ doc_puts(doc, "%RBINumCopies: 1\n");
}
- puts("%%Pages: (atend)");
- puts("%%BoundingBox: (atend)");
- puts("%%EndComments");
+ doc_puts(doc, "%%Pages: (atend)\n");
+ doc_puts(doc, "%%BoundingBox: (atend)\n");
+ doc_puts(doc, "%%EndComments\n");
return (linelen);
}
*/
fprintf(stderr, "DEBUG: Before copy_comments - %s", line);
- linelen = copy_comments(fp, doc, line, linelen, linesize);
+ linelen = copy_comments(fp, doc, ppd, line, linelen, linesize);
/*
* Now find the prolog section, if any...
*/
fprintf(stderr, "DEBUG: Before copy_prolog - %s", line);
- copy_prolog(fp, doc, ppd, line, linelen, linesize);
+ linelen = copy_prolog(fp, doc, ppd, line, linelen, linesize);
/*
* Then the document setup section...
*/
fprintf(stderr, "DEBUG: Before copy_setup - %s", line);
- copy_setup(fp, doc, ppd, line, linelen, linesize);
+ linelen = copy_setup(fp, doc, ppd, line, linelen, linesize);
+
+ /*
+ * Copy until we see %%Page:...
+ */
+
+ while (strncmp(line, "%%Page:", 7) && strncmp(line, "%%Trailer", 9))
+ {
+ doc_write(doc, line, linelen);
+
+ if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0)
+ break;
+ }
/*
* Then process pages until we have no more...
* Finish up the last page(s)...
*/
- if (number && is_not_last_page(number))
+ if (number && is_not_last_page(number) && cupsArrayLast(doc->pages))
{
pageinfo = (pstops_page_t *)cupsArrayLast(doc->pages);
- start_nup(doc, doc->number_up - 1, 0, doc->bounding_box);
+ start_nup(doc, doc->number_up, 0, doc->bounding_box);
doc_puts(doc, "showpage\n");
- end_nup(doc, doc->number_up - 1);
+ end_nup(doc, doc->number_up);
pageinfo->length = cupsFileTell(doc->temp) - pageinfo->offset;
}
printf("%%%%Page: (filler) %d\n", doc->page);
}
- start_nup(doc, doc->number_up - 1, 0, doc->bounding_box);
+ start_nup(doc, doc->number_up, 0, doc->bounding_box);
doc_puts(doc, "showpage\n");
- end_nup(doc, doc->number_up - 1);
+ end_nup(doc, doc->number_up);
pageinfo->length = cupsFileTell(doc->temp) - pageinfo->offset;
}
for (copy = !doc->slow_order; copy < doc->copies; copy ++)
{
+ /*
+ * Send end-of-job stuff followed by any start-of-job stuff required
+ * for the JCL options...
+ */
+
+ if (number && doc->emit_jcl && ppd && ppd->jcl_end)
+ {
+ /*
+ * Send the trailer...
+ */
+
+ puts("%%Trailer");
+ printf("%%%%Pages: %d\n", cupsArrayCount(doc->pages));
+ if (doc->number_up > 1 || doc->fitplot)
+ printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n",
+ PageLeft, PageBottom, PageRight, PageTop);
+ else
+ printf("%%%%BoundingBox: %d %d %d %d\n",
+ doc->new_bounding_box[0], doc->new_bounding_box[1],
+ doc->new_bounding_box[2], doc->new_bounding_box[3]);
+ puts("%%EOF");
+
+ /*
+ * Start a new document...
+ */
+
+ ppdEmitJCLEnd(ppd, stdout);
+ ppdEmitJCL(ppd, stdout, doc->job_id, doc->user, doc->title);
+
+ puts("%!PS-Adobe-3.0");
+
+ number = 0;
+ }
+
+ /*
+ * Copy the prolog as needed...
+ */
+
+ if (!number)
+ {
+ pageinfo = (pstops_page_t *)cupsArrayFirst(doc->pages);
+ copy_bytes(doc->temp, 0, pageinfo->offset);
+ }
+
+ /*
+ * Then copy all of the pages...
+ */
+
pageinfo = doc->slow_order ? (pstops_page_t *)cupsArrayLast(doc->pages) :
(pstops_page_t *)cupsArrayFirst(doc->pages);
}
else
{
- printf("%%%%Page: %s %d\n", pageinfo->label, number);
+ printf("%%%%Page: %s %d\n", pageinfo->label, number);
printf("%%%%PageBoundingBox: %d %d %d %d\n",
pageinfo->bounding_box[0], pageinfo->bounding_box[1],
pageinfo->bounding_box[2], pageinfo->bounding_box[3]);
}
}
+ /*
+ * Restore the old showpage operator as needed...
+ */
+
+ if (doc->use_ESPshowpage)
+ puts("userdict/showpage/ESPshowpage load put\n");
+
/*
* Write/copy the trailer...
*/
else
puts("%%Pages: 1");
- printf("%%%%For: %s\n", doc->user);
- printf("%%%%Title: %s\n", doc->title);
+ WriteTextComment("For", doc->user);
+ WriteTextComment("Title", doc->title);
if (doc->copies != 1 && (!doc->collate || !doc->slow_collate))
{
}
}
}
+
+ /*
+ * Restore the old showpage operator as needed...
+ */
+
+ if (doc->use_ESPshowpage)
+ puts("userdict/showpage/ESPshowpage load put\n");
}
memcpy(bounding_box, doc->bounding_box,
sizeof(bounding_box));
}
+ else if (doc->number_up == 1 && !doc->fitplot && Orientation)
+ {
+ int temp_bbox[4]; /* Temporary bounding box */
+
+
+ memcpy(temp_bbox, bounding_box, sizeof(temp_bbox));
+
+ fprintf(stderr, "DEBUG: Orientation = %d\n", Orientation);
+ fprintf(stderr, "DEBUG: original bounding_box = [ %d %d %d %d ]\n",
+ bounding_box[0], bounding_box[1],
+ bounding_box[2], bounding_box[3]);
+ fprintf(stderr, "DEBUG: PageWidth = %.1f, PageLength = %.1f\n",
+ PageWidth, PageLength);
+
+ switch (Orientation)
+ {
+ case 1 : /* Landscape */
+ bounding_box[0] = PageLength - temp_bbox[3];
+ bounding_box[1] = temp_bbox[0];
+ bounding_box[2] = PageLength - temp_bbox[1];
+ bounding_box[3] = temp_bbox[2];
+ break;
+
+ case 2 : /* Reverse Portrait */
+ bounding_box[0] = PageWidth - temp_bbox[2];
+ bounding_box[1] = PageLength - temp_bbox[3];
+ bounding_box[2] = PageWidth - temp_bbox[0];
+ bounding_box[3] = PageLength - temp_bbox[1];
+ break;
+
+ case 3 : /* Reverse Landscape */
+ bounding_box[0] = temp_bbox[1];
+ bounding_box[1] = PageWidth - temp_bbox[2];
+ bounding_box[2] = temp_bbox[3];
+ bounding_box[3] = PageWidth - temp_bbox[0];
+ break;
+ }
+
+ fprintf(stderr, "DEBUG: updated bounding_box = [ %d %d %d %d ]\n",
+ bounding_box[0], bounding_box[1],
+ bounding_box[2], bounding_box[3]);
+ }
}
#if 0
else if (!strncmp(line, "%%PageCustomColors:", 19) ||
* Copy any page setup commands...
*/
- if (!strncmp(line, "%%BeginPageSetup", 16))
+ if (first_page)
{
- /*
- * Copy page setup commands...
- */
+ char *page_setup; /* PageSetup commands to send */
- doc_write(doc, line, linelen);
- while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0)
+ doc_puts(doc, "%%BeginPageSetup\n");
+
+ if (pageinfo->num_options > 0)
{
- if (!strncmp(line, "%%EndPageSetup", 14))
- break;
- else if (!strncmp(line, "%%Include", 9))
- continue;
+ int i; /* Looping var */
+ ppd_option_t *option; /* PPD option */
+ int min_order; /* Minimum OrderDependency value */
+ char *doc_setup, /* DocumentSetup commands to send */
+ *any_setup; /* AnySetup commands to send */
- if (doc->number_up == 1 && !doc->fitplot)
- doc_write(doc, line, linelen);
- }
- /*
- * Skip %%EndPageSetup...
- */
+ /*
+ * Yes, figure out the minimum OrderDependency value...
+ */
- if (linelen > 0)
- linelen = cupsFileGetLine(fp, line, linesize);
+ if ((option = ppdFindOption(ppd, "PageRegion")) != NULL)
+ min_order = option->order;
+ else
+ min_order = 999.0f;
- if (pageinfo->num_options == 0)
- doc_puts(doc, "%%EndPageSetup\n");
- }
- else if (first_page && pageinfo->num_options > 0)
- doc_puts(doc, "%%BeginPageSetup\n");
+ for (i = 0; i < pageinfo->num_options; i ++)
+ if ((option = ppdFindOption(ppd, pageinfo->options[i].name)) != NULL &&
+ option->order < min_order)
+ min_order = option->order;
- if (first_page && pageinfo->num_options > 0)
- {
- int i; /* Looping var */
- ppd_option_t *option; /* PPD option */
- int min_order; /* Minimum OrderDependency value */
- char *doc_setup, /* DocumentSetup commands to send */
- *any_setup; /* AnySetup commands to send */
+ /*
+ * Mark and extract them...
+ */
+ cupsMarkOptions(ppd, pageinfo->num_options, pageinfo->options);
- /*
- * Yes, figure out the minimum OrderDependency value...
- */
+ doc_setup = ppdEmitString(ppd, PPD_ORDER_DOCUMENT, min_order);
+ any_setup = ppdEmitString(ppd, PPD_ORDER_ANY, min_order);
- if ((option = ppdFindOption(ppd, "PageRegion")) != NULL)
- min_order = option->order;
- else
- min_order = 999.0f;
+ /*
+ * Then send them out...
+ */
+
+ if (doc_setup)
+ {
+ doc_puts(doc, doc_setup);
+ free(doc_setup);
+ }
- for (i = 0; i < pageinfo->num_options; i ++)
- if ((option = ppdFindOption(ppd, pageinfo->options[i].name)) != NULL &&
- option->order < min_order)
- min_order = option->order;
+ if (any_setup)
+ {
+ doc_puts(doc, any_setup);
+ free(any_setup);
+ }
+ }
/*
- * Mark and extract them...
+ * Output commands for the current page...
*/
- cupsMarkOptions(ppd, pageinfo->num_options, pageinfo->options);
+ page_setup = ppdEmitString(ppd, PPD_ORDER_PAGE, 0);
+
+ if (page_setup)
+ {
+ doc_puts(doc, page_setup);
+ free(page_setup);
+ }
+ }
- doc_setup = ppdEmitString(ppd, PPD_ORDER_DOCUMENT, min_order);
- any_setup = ppdEmitString(ppd, PPD_ORDER_ANY, min_order);
+ /*
+ * Prep for the start of the page description...
+ */
- /*
- * Then send them out...
- */
+ start_nup(doc, number, 1, bounding_box);
- if (doc_setup)
- doc_puts(doc, doc_setup);
+ /*
+ * Copy page setup commands as needed...
+ */
+
+ if (!strncmp(line, "%%BeginPageSetup", 16))
+ {
+ int feature = 0; /* In a Begin/EndFeature block? */
- if (any_setup)
- doc_puts(doc, any_setup);
- /*
- * Free the command strings...
- */
+ while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0)
+ {
+ if (!strncmp(line, "%%EndPageSetup", 14))
+ break;
+ else if (!strncmp(line, "%%BeginFeature:", 15))
+ {
+ feature = 1;
+
+ if (doc->number_up > 1 || doc->fitplot)
+ continue;
+ }
+ else if (!strncmp(line, "%%EndFeature:", 13))
+ {
+ feature = 0;
+
+ if (doc->number_up > 1 || doc->fitplot)
+ continue;
+ }
+ else if (!strncmp(line, "%%Include", 9))
+ continue;
- if (doc_setup)
- free(doc_setup);
+ if (!feature || (doc->number_up == 1 && !doc->fitplot))
+ doc_write(doc, line, linelen);
+ }
- if (any_setup)
- free(any_setup);
+ /*
+ * Skip %%EndPageSetup...
+ */
- doc_puts(doc, "%%EndPageSetup\n");
+ if (linelen > 0)
+ linelen = cupsFileGetLine(fp, line, linesize);
}
/*
- * Prep for the start of the page description...
+ * Finish the PageSetup section as needed...
*/
- start_nup(doc, number, 1, bounding_box);
+ if (first_page)
+ doc_puts(doc, "%%EndPageSetup\n");
/*
* Read the rest of the page description...
{
if (level == 0 &&
(!strncmp(line, "%%Page:", 7) ||
- !strncmp(line, "%%Trailer:", 10) ||
+ !strncmp(line, "%%Trailer", 9) ||
!strncmp(line, "%%EOF", 5)))
break;
else if (!strncmp(line, "%%BeginDocument", 15) ||
if (!strncmp(line, "%%BeginSetup", 12) || !strncmp(line, "%%Page:", 7))
break;
- fwrite(line, 1, linelen, stdout);
+ doc_write(doc, line, linelen);
if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0)
break;
}
- puts("%%BeginProlog");
+ doc_puts(doc, "%%BeginProlog\n");
do_prolog(doc, ppd);
!strncmp(line, "%%Page:", 7))
break;
- fwrite(line, 1, linelen, stdout);
+ doc_write(doc, line, linelen);
}
if (!strncmp(line, "%%EndProlog", 11))
fputs("ERROR: Missing %%EndProlog!\n", stderr);
}
- puts("%%EndProlog");
+ doc_puts(doc, "%%EndProlog\n");
return (linelen);
}
if (!strncmp(line, "%%Page:", 7))
break;
- fwrite(line, 1, linelen, stdout);
+ doc_write(doc, line, linelen);
if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0)
break;
}
+ doc_puts(doc, "%%BeginSetup\n");
+
+ do_setup(doc, ppd);
+
if (!strncmp(line, "%%BeginSetup", 12))
{
while (strncmp(line, "%%EndSetup", 10))
doc->num_options = include_feature(ppd, line, doc->num_options,
&(doc->options));
}
- else
- fwrite(line, 1, linelen, stdout);
+ else if (strncmp(line, "%%BeginSetup", 12))
+ doc_write(doc, line, linelen);
if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0)
break;
else
fputs("ERROR: Missing %%EndSetup!\n", stderr);
}
- else
- puts("%%BeginSetup");
-
- do_setup(doc, ppd);
- puts("%%EndSetup");
+ doc_puts(doc, "%%EndSetup\n");
return (linelen);
}
do_prolog(pstops_doc_t *doc, /* I - Document information */
ppd_file_t *ppd) /* I - PPD file */
{
+ char *ps; /* PS commands */
+
+
/*
* Send the document prolog commands...
*/
if (ppd && ppd->patches)
{
- puts("%%BeginFeature: *JobPatchFile 1");
- puts(ppd->patches);
- puts("%%EndFeature");
+ doc_puts(doc, "%%BeginFeature: *JobPatchFile 1\n");
+ doc_puts(doc, ppd->patches);
+ doc_puts(doc, "\n%%EndFeature\n");
}
- ppdEmit(ppd, stdout, PPD_ORDER_PROLOG);
+ if ((ps = ppdEmitString(ppd, PPD_ORDER_PROLOG, 0.0)) != NULL)
+ {
+ doc_puts(doc, ps);
+ free(ps);
+ }
/*
* Define ESPshowpage here so that applications that define their
*/
if (doc->use_ESPshowpage)
- puts("userdict/ESPshowpage/showpage load put\n"
- "userdict/showpage{}put");
-
+ doc_puts(doc, "userdict/ESPshowpage/showpage load put\n"
+ "userdict/showpage{}put\n");
}
do_setup(pstops_doc_t *doc, /* I - Document information */
ppd_file_t *ppd) /* I - PPD file */
{
+ char *ps; /* PS commands */
+
+
+ /*
+ * Disable CTRL-D so that embedded files don't cause printing
+ * errors...
+ */
+
+ doc_puts(doc, "% Disable CTRL-D as an end-of-file marker...\n");
+ doc_puts(doc, "userdict dup(\\004)cvn{}put (\\004\\004)cvn{}put\n");
+
/*
* Mark any options from %%IncludeFeature: comments...
*/
* Send all the printer-specific setup commands...
*/
- ppdEmit(ppd, stdout, PPD_ORDER_DOCUMENT);
- ppdEmit(ppd, stdout, PPD_ORDER_ANY);
+ if ((ps = ppdEmitString(ppd, PPD_ORDER_DOCUMENT, 0.0)) != NULL)
+ {
+ doc_puts(doc, ps);
+ free(ps);
+ }
+
+ if ((ps = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL)
+ {
+ doc_puts(doc, ps);
+ free(ps);
+ }
/*
* Set the number of copies for the job...
if (doc->copies != 1 && (!doc->collate || !doc->slow_collate))
{
- printf("%%RBIBeginNonPPDFeature: *NumCopies %d\n", doc->copies);
- printf("%d/languagelevel where{pop languagelevel 2 ge}{false}ifelse\n"
- "{1 dict begin/NumCopies exch def currentdict end setpagedevice}\n"
- "{userdict/#copies 3 -1 roll put}ifelse\n", doc->copies);
- puts("%RBIEndNonPPDFeature");
+ doc_printf(doc, "%%RBIBeginNonPPDFeature: *NumCopies %d\n", doc->copies);
+ doc_printf(doc,
+ "%d/languagelevel where{pop languagelevel 2 ge}{false}ifelse\n"
+ "{1 dict begin/NumCopies exch def currentdict end "
+ "setpagedevice}\n"
+ "{userdict/#copies 3 -1 roll put}ifelse\n", doc->copies);
+ doc_puts(doc, "%RBIEndNonPPDFeature\n");
}
/*
*/
if (doc->number_up > 1)
- puts("userdict/setpagedevice{pop}bind put");
+ doc_puts(doc, "userdict/setpagedevice{pop}bind put\n");
/*
* Changes to the transfer function must be made AFTER any
*/
if (doc->gamma != 1.0f || doc->brightness != 1.0f)
- printf("{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } "
- "ifelse %.3f mul } bind settransfer\n", doc->gamma,
- doc->brightness);
+ doc_printf(doc, "{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } "
+ "ifelse %.3f mul } bind settransfer\n",
+ doc->gamma, doc->brightness);
/*
* Make sure we have rectclip and rectstroke procedures of some sort...
*/
- WriteCommon();
+ doc_puts(doc,
+ "% x y w h ESPrc - Clip to a rectangle.\n"
+ "userdict/ESPrc/rectclip where{pop/rectclip load}\n"
+ "{{newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath clip newpath}bind}ifelse put\n");
+
+ doc_puts(doc,
+ "% x y w h ESPrf - Fill a rectangle.\n"
+ "userdict/ESPrf/rectfill where{pop/rectfill load}\n"
+ "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath fill grestore}bind}ifelse put\n");
+
+ doc_puts(doc,
+ "% x y w h ESPrs - Stroke a rectangle.\n"
+ "userdict/ESPrs/rectstroke where{pop/rectstroke load}\n"
+ "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath stroke grestore}bind}ifelse put\n");
/*
* Write the page and label prologs...
*/
if (Orientation & 1)
- WriteLabelProlog(doc->page_label, PageBottom,
- PageWidth - PageLength + PageTop, PageLength);
+ write_label_prolog(doc, doc->page_label, PageBottom,
+ PageWidth - PageLength + PageTop, PageLength);
else
- WriteLabelProlog(doc->page_label, PageLeft, PageRight, PageLength);
+ write_label_prolog(doc, doc->page_label, PageLeft, PageRight,
+ PageLength);
}
else
- WriteLabelProlog(doc->page_label, PageBottom, PageTop, PageWidth);
+ write_label_prolog(doc, doc->page_label, PageBottom, PageTop, PageWidth);
}
end_nup(pstops_doc_t *doc, /* I - Document information */
int number) /* I - Page number */
{
- if (doc->mirror || Orientation || doc->number_up > 1)
- puts("userdict /ESPsave get restore");
+ if (doc->number_up > 1)
+ doc_puts(doc, "userdict/ESPsave get restore\n");
switch (doc->number_up)
{
case 1 :
if (doc->use_ESPshowpage)
{
- WriteLabels(Orientation);
- puts("ESPshowpage");
+ write_labels(doc, Orientation);
+ doc_puts(doc, "ESPshowpage\n");
}
break;
* Rotate the labels back to portrait...
*/
- WriteLabels(Orientation - 1);
+ write_labels(doc, Orientation - 1);
}
else if (Orientation == 0)
{
* Rotate the labels to landscape...
*/
- WriteLabels(doc->normal_landscape ? 1 : 3);
+ write_labels(doc, doc->normal_landscape ? 1 : 3);
}
else
{
* Rotate the labels to landscape...
*/
- WriteLabels(doc->normal_landscape ? 3 : 1);
+ write_labels(doc, doc->normal_landscape ? 3 : 1);
}
- puts("ESPshowpage");
+ doc_puts(doc, "ESPshowpage\n");
}
break;
default :
if (is_last_page(number) && doc->use_ESPshowpage)
{
- WriteLabels(Orientation);
- puts("ESPshowpage");
+ write_labels(doc, Orientation);
+ doc_puts(doc, "ESPshowpage\n");
}
break;
}
* turn the hardware collate option off...
*/
- if ((option = ppdFindOption(ppd, "Option")) != NULL &&
+ if ((option = ppdFindOption(ppd, "Collate")) != NULL &&
!option->conflicted)
doc->slow_collate = 0;
else
else
doc->slow_order = 0;
- if ((doc->slow_collate || doc->slow_order) && Duplex)
+ if (Duplex &&
+ (doc->slow_collate || doc->slow_order ||
+ ((attr = ppdFindAttr(ppd, "cupsEvenDuplex", NULL)) != NULL &&
+ attr->value && !strcasecmp(attr->value, "true"))))
doc->slow_duplex = 1;
else
doc->slow_duplex = 0;
while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0)
{
if (level == 0 &&
- (!strncmp(line, "%%Page:", 7) || !strncmp(line, "%%Trailer:", 10)))
+ (!strncmp(line, "%%Page:", 7) || !strncmp(line, "%%Trailer", 9)))
break;
else if (!strncmp(line, "%%BeginDocument", 15) ||
!strncmp(line, "%ADO_BeginApplication", 21))
bboxl; /* BoundingBox height */
- if (doc->mirror || Orientation || doc->number_up > 1)
+ if (doc->number_up > 1)
doc_puts(doc, "userdict/ESPsave save put\n");
if (doc->mirror)
ty = 0.5 * (pagew - 3 * l);
if (doc->normal_landscape)
- doc_printf(doc, "0.0 %.1f translate -90 rotate\n", pagel);
+ doc_printf(doc, "0 %.1f translate -90 rotate\n", pagel);
else
- doc_printf(doc, "%.1f 0.0 translate 90 rotate\n", pagew);
+ doc_printf(doc, "%.1f 0 translate 90 rotate\n", pagew);
doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n",
- tx + x * y * pagel * 0.5, ty + pagew * 0.333,
- w / bboxw, l / bboxl);
+ tx + x * w, ty + y * l, l / bboxl, w / bboxw);
}
else
{
l = w * bboxl / bboxw;
}
- tx = 0.5 * (pagel - 3 * w);
- ty = 0.5 * (pagew - 2 * l);
+ tx = 0.5 * (pagel - 3 * w);
+ ty = 0.5 * (pagew - 2 * l);
if (doc->normal_landscape)
- doc_printf(doc, "%.1f 0.0 translate 90 rotate\n", pagew);
+ doc_printf(doc, "%.1f 0 translate 90 rotate\n", pagew);
else
- doc_printf(doc, "0.0 %.1f translate -90 rotate\n", pagel);
+ doc_printf(doc, "0 %.1f translate -90 rotate\n", pagel);
doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n",
- tx + x * pagel * 0.333, ty + y * pagew * 0.5,
- w / bboxw, l / bboxl);
+ tx + w * x, ty + l * y, w / bboxw, l / bboxl);
+
}
break;
/*
- * End of "$Id: pstops.c 5326 2006-03-23 19:33:35Z mike $".
+ * 'write_label_prolog()' - Write the prolog with the classification
+ * and page label.
+ */
+
+static void
+write_label_prolog(pstops_doc_t *doc, /* I - Document info */
+ const char *label, /* I - Page label */
+ float bottom, /* I - Bottom position in points */
+ float top, /* I - Top position in points */
+ float width) /* I - Width in points */
+{
+ const char *classification; /* CLASSIFICATION environment variable */
+ const char *ptr; /* Temporary string pointer */
+
+
+ /*
+ * First get the current classification...
+ */
+
+ if ((classification = getenv("CLASSIFICATION")) == NULL)
+ classification = "";
+ if (strcmp(classification, "none") == 0)
+ classification = "";
+
+ /*
+ * If there is nothing to show, bind an empty 'write labels' procedure
+ * and return...
+ */
+
+ if (!classification[0] && (label == NULL || !label[0]))
+ {
+ doc_puts(doc, "userdict/ESPwl{}bind put\n");
+ return;
+ }
+
+ /*
+ * Set the classification + page label string...
+ */
+
+ doc_puts(doc, "userdict");
+ if (!strcmp(classification, "confidential"))
+ doc_puts(doc, "/ESPpl(CONFIDENTIAL");
+ else if (!strcmp(classification, "classified"))
+ doc_puts(doc, "/ESPpl(CLASSIFIED");
+ else if (!strcmp(classification, "secret"))
+ doc_puts(doc, "/ESPpl(SECRET");
+ else if (!strcmp(classification, "topsecret"))
+ doc_puts(doc, "/ESPpl(TOP SECRET");
+ else if (!strcmp(classification, "unclassified"))
+ doc_puts(doc, "/ESPpl(UNCLASSIFIED");
+ else
+ {
+ doc_puts(doc, "/ESPpl(");
+
+ for (ptr = classification; *ptr; ptr ++)
+ {
+ if (*ptr < 32 || *ptr > 126)
+ doc_printf(doc, "\\%03o", *ptr);
+ else if (*ptr == '_')
+ doc_puts(doc, " ");
+ else if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
+ doc_printf(doc, "\\%c", *ptr);
+ else
+ doc_printf(doc, "%c", *ptr);
+ }
+ }
+
+ if (label)
+ {
+ if (classification[0])
+ doc_puts(doc, " - ");
+
+ /*
+ * Quote the label string as needed...
+ */
+
+ for (ptr = label; *ptr; ptr ++)
+ {
+ if (*ptr < 32 || *ptr > 126)
+ doc_printf(doc, "\\%03o", *ptr);
+ else if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
+ doc_printf(doc, "\\%c", *ptr);
+ else
+ doc_printf(doc, "%c", *ptr);
+ }
+ }
+
+ doc_puts(doc, ")put\n");
+
+ /*
+ * Then get a 14 point Helvetica-Bold font...
+ */
+
+ doc_puts(doc, "userdict/ESPpf /Helvetica-Bold findfont 14 scalefont put\n");
+
+ /*
+ * Finally, the procedure to write the labels on the page...
+ */
+
+ doc_puts(doc, "userdict/ESPwl{\n");
+ doc_puts(doc, " ESPpf setfont\n");
+ doc_printf(doc, " ESPpl stringwidth pop dup 12 add exch -0.5 mul %.0f add\n",
+ width * 0.5f);
+ doc_puts(doc, " 1 setgray\n");
+ doc_printf(doc, " dup 6 sub %.0f 3 index 20 ESPrf\n", bottom - 2.0);
+ doc_printf(doc, " dup 6 sub %.0f 3 index 20 ESPrf\n", top - 18.0);
+ doc_puts(doc, " 0 setgray\n");
+ doc_printf(doc, " dup 6 sub %.0f 3 index 20 ESPrs\n", bottom - 2.0);
+ doc_printf(doc, " dup 6 sub %.0f 3 index 20 ESPrs\n", top - 18.0);
+ doc_printf(doc, " dup %.0f moveto ESPpl show\n", bottom + 2.0);
+ doc_printf(doc, " %.0f moveto ESPpl show\n", top - 14.0);
+ doc_puts(doc, "pop\n");
+ doc_puts(doc, "}bind put\n");
+}
+
+
+/*
+ * 'write_labels()' - Write the actual page labels.
+ *
+ * This function is a copy of the one in common.c since we need to
+ * use doc_puts/doc_printf instead of puts/printf...
+ */
+
+static void
+write_labels(pstops_doc_t *doc, /* I - Document information */
+ int orient) /* I - Orientation of the page */
+{
+ float width, /* Width of page */
+ length; /* Length of page */
+
+
+ doc_puts(doc, "gsave\n");
+
+ if ((orient ^ Orientation) & 1)
+ {
+ width = PageLength;
+ length = PageWidth;
+ }
+ else
+ {
+ width = PageWidth;
+ length = PageLength;
+ }
+
+ switch (orient & 3)
+ {
+ case 1 : /* Landscape */
+ doc_printf(doc, "%.1f 0.0 translate 90 rotate\n", length);
+ break;
+ case 2 : /* Reverse Portrait */
+ doc_printf(doc, "%.1f %.1f translate 180 rotate\n", width, length);
+ break;
+ case 3 : /* Reverse Landscape */
+ doc_printf(doc, "0.0 %.1f translate -90 rotate\n", width);
+ break;
+ }
+
+ doc_puts(doc, "ESPwl\n");
+ doc_puts(doc, "grestore\n");
+}
+
+
+/*
+ * End of "$Id: pstops.c 6320 2007-03-08 13:36:56Z mike $".
*/