home *** CD-ROM | disk | FTP | other *** search
- /* ta=4 set tabstop=4 */
- /****************************************************************************
- * p s f . c v3 *
- * *
- * Print text files to postscript printer. *
- * *
- * Tony Field: tony@ajfcal.cuc.ab.ca *
- ****************************************************************************/
- /*
- * $Id: psf.c,v 3.2 1992/01/19 05:50:33 ajf Exp ajf $
- */
- /* Three versions of psf can be compiled:
-
- psf: postscript filter for command line use.
-
- psffilter: used with lp/lpsched. accepts command line argument.
- Input on stdin. compile with -DPSFFILTER.
-
- psflpd: used with lpr/lpd. does not accept command line
- arguments. compile with -DPSFFILTER -DFORLPD
- */
-
- #include <stdio.h>
- #include <malloc.h>
- #include <string.h>
- #include <setjmp.h>
- #include <math.h>
- #include <time.h>
- #include <signal.h>
- #include "ctp.h"
- #include "patchlevel.h"
- #include "psf.h"
- #include "psfproto.h"
-
- #if defined(MSDOS) || defined (__MSDOS__)
- #ifndef BINDIR
- #define BINDIR "c:/bin"
- #endif
- #ifndef PDEF
- #define PDEF "c:/lib/psfprint.def"
- #endif
- #endif
-
- #ifndef PAPERTYPE
- #define PAPERTYPE "letter"
- #endif
- #ifndef PSFDOUB
- #define PSFDOUB "psfdoub"
- #endif
-
- /* set up the mechanism for underline display */
-
- #define SHOWU(fp,ps) fprintf (fp, ") %d showuline\n", ps)
-
- #define NOMINAL_CWIDE 7.2001 /* point width for Courier 12-point */
- #define NOMINAL_POINTS 12 /* standard 12-point for printing */
-
- #define NORMAL 0x00 /* bitset for print_attributes */
- #define ITALICS 0x01
- #define BOLD 0x02
- #define UNDERLINE 0x04 /* must be 0x04. underline is not a font */
-
- #define CTLD_EOJ 0x04 /* ctl/d is end of postscript job. */
-
- /* Paper physical dimensions.
- The default paper sizes is for a NEC LC890 and is overridden in
- "psfprint.def".
- */
-
- typedef struct /* measurement in point */
- { char paper_name[60]; /* name of paper size (for command line) */
- char paper_tray[100]; /* postscript operator to select this tray */
- int width; /* portrait point width of paper */
- int height; /* portrait point height of paper */
- int lx, ly, ux, uy;
- int left_marg; /* margin widths (unprintable area) */
- int bot_marg; /* " */
- int right_marg; /* " */
- int top_marg; /* " */
- int x_size; /* generated by psf. */
- int y_size; /* size after correction for line count */
- } measure;
-
- measure *p; /* working set of parameters (points to something below) */
- measure page_types[NPAGE] =
- { { "letter",
- "statusdict begin lettertray end",
- 612, 792, 18, 15, 593, 777
- },
- { "legal",
- "statusdict begin legaltray end",
- 612, 1008, 18, 15, 593, 993
- },
- { "a4",
- "statusdict begin a4tray end",
- 595, 842, 18, 15, 578, 827
- },
- { "b5",
- "statusdict begin b5tray end",
- 516, 729, 18, 15, 497, 712
- },
- { "", /* end of paper list */
- "",
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }
- };
-
- char order_default[20] = "Normal";
- char order_normal[100] = "\0";
- char order_reverse[100] = "\0";
- char *order_command = NULL;
-
- char slots[NSLOTS][200] =
- { "statusdict begin 1 setpapertray end",
- "statusdict begin 2 setpapertray end",
- "", "", "", ""
- } ;
- int nslots = 2;
-
- int y_top_offset; /* offsets for each frame */
- int x_left_offset;
- int dx_home[4]; /* page frame home (0,0) translations */
- int dy_home[4];
-
- int x,y; /* current x,y coordinate */
- double scale_x, scale_y; /* scale factors for 2-up, 4-up printing */
- int real_width;
-
- long *pg_loc; /* double side print byte ptr to %%Page: */
- int npg_loc; /* number of elements in pg_loc[] */
-
- int book = 0; /* book format: double sided */
- int bookwork = 0; /* book format, 2-up print */
- int lines_on_page = 60; /* user print lines on page */
- int lines_total = 0; /* total number of lines for scale purposes */
- int chars_on_line = 80; /* default number of chars on line */
- int landscape = 0; /* 1 = landscape, 0 = portrait layout */
- int header = 0; /* 1 = print header at top of each page */
- int cross = 0; /* 1 = print cross on 4-up pages */
- int line_number = 0; /* current logical line number on page */
- int tab_size = 8; /* space translation for tabs. */
- int font_number = 0; /* one of the valid fonts in the printer */
- int point_size = 12; /* can be changed with the -p option */
- int x_user_offset = 0; /* offsets specified buy user */
- int y_user_offset = 0; /* points from physical page edge. */
- int set_paper_tray = 0; /* user has set paper tray selection */
- int set_line_count = 0; /* print line count on page */
- int set_total_count = 0; /* total line count on page */
- int set_point_size = 0; /* point size */
- int set_char_count = 0; /* characters on a line */
- int set_paper_bin = 0; /* paper bin (not page size) */
- char header_text[100]; /* header line text */
-
- int print_attribute = 0; /* such as BOLD, UNDERLINE, ITALICS */
- int default_font_number; /* set with -f option, or 0 */
- int default_point_size; /* assumes value due to -p option */
- int y_coord = 0; /* current logical page y-coordinate, points*/
- int x_coord = 0; /* current logical page x-coordinate, points*/
- int page_number; /* current page number for this file */
- int physical_page = 0; /* postscript physical page for multi-up */
- int print_postscript = 0; /* force print of postscript */
- int remove_beginning = 0; /* remove lines at beginning of job */
- int remove_between = 0; /* remove lines between printed pages */
- int is_a_formfeed = 0; /* skip to top of page caused by formfeed */
- int end_of_file = 0; /* end of printing file */
- int save_point_size ; /* save original point size for headers */
- int n_chars; /* number of characters on a line */
- int reverse_order = 0; /* print in reverse_order */
- int reverse_requested = 0; /* user option for reverse order */
- char fname[100];
- char now[50]; /* time of day for page headers */
-
- #ifdef HOPPER
- int hopper_available = 1;
- #else
- int hopper_available = 0;
- #endif
-
- /* to select a font, use 4 * font_number + print_attribute as index.
-
- Helvetica-Bold = fonts[4 * 1 + 2]
- = fonts [4 * 1 + ITALICS | BOLD]
-
- If one of the following fonts is found in "psfprint.def", then it is
- flagged as "available" (fonts_have[i] = 1), if not, it is
- "unavailable". This font list should include all known adobe fonts.
- */
-
- #define NFONTS 144 /* 4 variations * 36 font families */
-
- int font_count = 48; /* 4 * 12 default fonts for fonts below */
- char *fonts[NFONTS] =
- {
- /* base font italics font bold font bold-italics */
-
- "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique",
- "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique",
- "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic",
- "AvantGarde-Book", "AvantGarde-BookOblique", "AvantGarde-Demi", "AvantGarde-DemiOblique",
- "Bookman-Light", "Bookman-LightItalic", "Bookman-Demi", "Bookman-DemiItalic",
- "NewCenturySchlbk-Roman", "NewCenturySchlbk-Italic", "NewCenturySchlbk-Bold", "NewCenturySchlbk-BoldItalic",
- "Palatino-Roman", "Palatino-Italic", "Palatino-Bold", "Palatino-BoldItalic",
- "Helvetica-Narrow", "Helvetica-Narrow-Oblique", "Helvetica-Narrow-Bold", "Helvetica-Narrow-BoldOblique",
- "Garamond-Light", "Garamond-LightItalic", "Garamond-Bold", "Garamond-BoldItalic",
- "Korinna-Regular", "Korinna-KursivRegular", "Korinna-Bold", "Korinna-KursivBold",
- "Helvetica-Condensed", "Helvetica-Condensed-Oblique", "Helvetica-Condensed-Bold", "Helvetica-Condensed-BoldObl",
- "ZapfChancery-MediumItalic","ZapfChancery-MediumItalic","ZapfChancery-MediumItalic","ZapfChancery-MediumItalic"
- } ;
-
- int fonts_used[NFONTS];
- int fonts_have[NFONTS];
- unsigned char xlate[256]; /* translation vector */
- int need_xlate = 0; /* no default xlate */
- char copyfile[150]; /* copy file name from psfprint.def */
-
- int max_frame = 1; /* max number of frames in use */
- int frame = -1; /* current frame in use */
-
- FILE *input_fp, *output_fp;
-
- /* input line and input line pointer */
- char *c;
- char line[LONG_STR + 1];
-
- char *pgmname;
-
- void catch();
- jmp_buf eof_env;
-
- char *defref = NULL;
- FILE *pdef = NULL; /* psfprint.def file */
-
- char *ascii_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
- extern int atoi(), getpid();
-
- /****************************************************************************
- * main () *
- ****************************************************************************/
-
- main (argc, argv)
- int argc;
- char *argv[];
- { int c, i, j, number;
- extern char *optarg;
- extern int optind, getopt();
- char bookfile[100];
- char *env_fname; /* environment specified output file */
- char *getenv();
- int narrow2x;
- char alt_cmd[200];
-
- if ((pgmname = strrchr (argv[0], '/'))
- || (pgmname = strrchr (argv[0], '\\'))
- || (pgmname = strrchr (argv[0], ':')))
- pgmname++;
- else
- pgmname = argv[0];
-
- copyfile[0] = 0;
- for (i = 0; i < 256; i++) /* initial xlate = no translation */
- xlate[i] = i;
- for (i = font_count; i < NFONTS; i++)
- fonts[i] = "N/A";
-
- for (i = 0; i < argc; i++) /* if user sets -u alt.def */
- { if (strncmp (argv[i], "-u", 2) == 0)
- { if (strlen (argv[i]) > 2)
- defref = argv[i] + 2;
- else
- defref = argv[i+1];
- break;
- }
- }
- if (i >= argc)
- { if ((defref = getenv ("PSFDEF")) == NULL)
- defref = PDEF;
- }
-
- /* Read the .def file if it exists */
-
- alt_cmd[0] = '\0';
- if ((pdef = fopen (defref, "r")) != NULL)
- { char line_type[50];
- #if defined(FORLPD)
- char *quote, *word;
- int modified_argv = 0;
-
- /* read lpd options from psfprint.def. Format is:
- *psflpd argv0name opt1 opt2 opt3...
- */
- while (fgets (alt_cmd, 200, pdef))
- { if (*alt_cmd == '#')
- continue;
- alt_cmd[199] = '\0';
- trim (alt_cmd);
- word = strtok (alt_cmd, " \t");
- if (strcmp (word, "*psflpd") == 0)
- { word = strtok (NULL, " \t");
- if (strcmp (word, pgmname) == 0)
- { argv = (char **) malloc (sizeof (char *) * 50);
- argv[0] = word;
- modified_argv = 1;
- for (argc = 1; word = strtok (NULL, " \t"); argc++)
- { if (*word == '#') /* quite on comments */
- break;
- argv[argc] = word;
- }
- argv[argc] = NULL;
- break;
- }
- }
- else if (strcmp (word, "*printer") == 0)
- break;
- }
- if (modified_argv == 0)
- { argc = 1;
- argv[1] = NULL;
- }
-
- #endif /* FORLPD */
-
- /* skip to printer definition */
- if (strncmp (alt_cmd, "*printer", 8))
- { while (fgets (line, 200, pdef))
- { if (strncmp (line, "*printer", 8) == 0)
- break;
- }
- }
- nslots = 0;
- fgets (line, 200, pdef); /* skip printer name */
- while (fgets (line, 200, pdef))
- { trim (line);
- sscanf (line, "%s%d", line_type, &number);
-
- if (strcmp (line_type, "*paper") == 0)
- { for (i = j = 0; i < number; i++)
- { if (i >= NPAGE - 1)
- { fgets (line, 200, pdef);
- fgets (line, 200, pdef);
- fgets (line, 200, pdef);
- continue;
- }
- if (fgets (line, 200, pdef) == NULL)
- bad_file();
- line[59] = 0;
- trim (line);
- strcpy (page_types[i].paper_name, line);
- if (fgets (line, 99, pdef) == NULL)
- bad_file();
- line[99] = 0;
- trim (line);
- strcpy (page_types[i].paper_tray, line);
- if (fgets (line, 100, pdef) == NULL)
- bad_file();
- trim (line);
- sscanf (line, "%d%d%d%d%d%d",
- &page_types[i].width, &page_types[i].height,
- &page_types[i].lx, &page_types[i].ly,
- &page_types[i].ux, &page_types[i].uy);
- j = i;
- }
- page_types[j+1].paper_name[0] = '\0';
- }
-
- else if (strcmp (line_type, "*order") == 0)
- { fgets (line, 200, pdef);
- line[19] = 0;
- trim (line);
- strcpy (order_default, line);
- if (number > 1)
- { if (fgets (line, 200, pdef) == NULL)
- bad_file();
- trim (line);
- line[99] = 0;
- strcpy (order_normal, line);
- if (fgets (line, 200, pdef) == NULL)
- bad_file();
- trim (line);
- line[99] = 0;
- strcpy (order_reverse, line);
- }
- }
-
- else if (strcmp (line_type, "*fonts") == 0)
- { for (i = 0; i < NFONTS; i++)
- fonts_have[i] = 0;
- for (i = 0; i < number; i++)
- { if (fgets (line, 200, pdef) == NULL)
- bad_file();
- trim (line);
- for (j = 0; j < font_count; j++)
- { if (compare (fonts[j], line) == 0)
- { fonts_have[j] = 1;
- break;
- }
- }
- }
- }
-
- else if (strcmp (line_type, "*slots") == 0)
- { for (j = 0; j < NSLOTS; j++)
- slots[j][0] = 0;
- for (i = j = 0; i < number; i++)
- { if (fgets (line, 200, pdef) == NULL)
- bad_file();
- if (i >= NSLOTS)
- continue;
- line[99] = 0;
- trim (line);
- strcpy (slots[i], line);
- j = i;
- }
- nslots = j + 1;
- }
-
- else if (strcmp (line_type, "*eof") == 0)
- break;
- else
- bad_file();
- }
- replacement_fonts ();
- }
- else /* if no .def, assume all fonts exist */
- { for (i = 0; i < font_count; i++)
- fonts_have[i] = 1;
- }
-
- for (i = 0; page_types[i].paper_name[0]; i++)
- { page_types[i].left_marg = page_types[i].lx;
- page_types[i].bot_marg = page_types[i].ly;
- page_types[i].top_marg = (page_types[i].height - 1) - page_types[i].uy;
- page_types[i].right_marg = (page_types[i].width - 1) - page_types[i].ux;
-
- page_types[i].x_size = page_types[i].ux - page_types[i].lx + 1;
- page_types[i].y_size = page_types[i].uy - page_types[i].ly + 1;
- }
-
- #ifdef PAPERTYPE
- for (i = 0; page_types[i].paper_name[0]; i++)
- { if (strcmp (page_types[i].paper_name, PAPERTYPE) == 0)
- { p = &page_types[i];
- break;
- }
- }
- if (page_types[i].paper_name[0] == '\0')
- p = &page_types[0];
- #else
- p = &page_types[0]; /* default to letter size paper */
- #endif /* PAPERTYPE */
-
- *header_text = '\0';
- if (argc > 1 && (strcmp (argv[1], "-") == 0 || strcmp (argv[1], "--") == 0))
- usage();
-
- narrow2x = 0;
- while ((c = getopt(argc, argv, "124xhnwdvzsi:m:b:c:g:H:l:L:f:t:p:r:R:u:-?")) != -1)
- { switch (c)
- {
- case '1':
- max_frame = 1;
- break;
-
- case '2':
- if (narrow2x == 0)
- landscape = 1;
- max_frame = 2;
- break;
-
- case '4':
- max_frame = 4;
- break;
-
- case 'b':
- if ((set_paper_bin = atoi (optarg)) > nslots)
- { if (nslots = 0)
- fprintf (stderr, "%s: no alternate bins permitted\n", nslots);
- else
- fprintf (stderr, "%s: paper bin greater than %d\n", pgmname, nslots);
- exit (1);
- }
- break;
-
- case 'c':
- chars_on_line = atoi (optarg);
- set_char_count = 1;
- break;
-
- case 'd':
- book = 1;
- break;
-
- case 'f':
- if (*optarg > '9' && optarg[1]) /* at least 2 chars */
- { /* character string name of font */
- for (i = 0; i < font_count; i += 4)
- { if (partial_compare (optarg, fonts[i]) == 0)
- { font_number = i / 4;
- break;
- }
- }
- if (i >= font_count)
- font_number = 0;
- }
- else
- { /* single digit hex */
- font_number = xtoi ((int) *optarg);
- if (font_number > (font_count / 4))
- font_number = 0;
- }
- break;
-
- case 'g':
- p = NULL;
- for (i = 0; page_types[i].paper_name[0]; i++)
- { if (compare (optarg, page_types[i].paper_name) == 0)
- { p = &page_types[i];
- break;
- }
- }
- if (p == NULL)
- usage ();
- set_paper_tray = 1;
- break;
-
- case 'h':
- header = 1;
- break;
-
- case 'H':
- header = 2;
- strcpy (header_text, optarg);
- break;
-
- case 'i':
- x_user_offset = atoi (optarg);
- break;
-
- case 'l':
- lines_on_page = atoi (optarg);
- set_line_count = 1;
- break;
-
- case 'L':
- lines_total = atoi (optarg);
- set_total_count = 1;
- break;
-
- case 'm':
- y_user_offset = atoi (optarg);
- break;
-
- case 'n':
- landscape = 0;
- narrow2x = 1;
- break;
-
- case 'p':
- point_size = atoi (optarg);
- set_point_size = 1;
- break;
-
- case 'r':
- remove_between = atoi (optarg);
- break;
-
- case 'R':
- remove_beginning = atoi (optarg);
- break;
-
- case 's':
- size_display();
- exit (1);
-
- case 't':
- tab_size = atoi (optarg);
- break;
-
- case 'u': /* already processed */
- break;
-
- case 'v':
- reverse_requested = 1;
- break;
-
- case 'w':
- landscape = 1;
- break;
-
- case 'x':
- cross = 1;
- break;
-
- case 'z':
- print_postscript = 1;
- break;
-
- default: usage ();
- break;
- }
- }
-
- if (strncmp (order_default, "Reverse", 7) == 0) /* stacking sequence */
- reverse_order = 1; /* "Reverse" */
- else
- reverse_order = 0; /* "Normal" */
- if (reverse_requested) /* User wants reverse ? */
- reverse_order = !reverse_order; /* yes */
- if (reverse_order && order_reverse[0]) /* Reverse tray command */
- { order_command = order_reverse; /* yes */
- reverse_order = 0; /* order_command does the work*/
- }
- else if (reverse_order == 0 && order_normal[0]) /* Force normal order tray?*/
- order_command = order_normal; /* yes */
- else
- order_command = NULL; /* use default action */
-
- if (reverse_requested && book)
- { fprintf (stderr, "Double sided or book in reverse ordered not supported\n");
- exit (1);
- }
-
-
- if (nslots <= 1)
- hopper_available = 0;
- if (reverse_order || (book && hopper_available))
- sprintf (bookfile, "%s%d.bok", TEMPFILE, getpid());
- else
- strcpy (bookfile, BOOKFILE);
-
- if (max_frame == 2 && landscape == 0)
- set_point_size = 1;
- if (optind >= argc && header == 1) /* no file name header on stdin */
- header = 0;
- save_point_size = point_size;
-
- (void) signal (SIGINT, catch); /* for lpd quit */
-
-
- #ifdef PSFFILTER
-
- output_fp = stdout;
- input_fp = stdin;
- if (header == 1)
- strcpy (fname, argv[optind]);
- else
- *fname = 0;
-
- if (fgets (line, LONG_STR, input_fp) == NULL)
- exit (0);
- if (tscan (line, "%!") >= 0 && print_postscript == 0)
- { /* already postscript copy to output */
- if (fputs (line, output_fp) == EOF)
- output_trouble (2);
- while ((i = fgetc (input_fp)) != EOF)
- { if (fputc (i, output_fp) == EOF)
- output_trouble (2);
- }
- }
- else
- { /* standard postscript conversion for file on stdin */
- bannerdone:
- if (font_number * 4 > font_count)
- { fprintf (stderr,"Font number invalid....\n");
- usage ();
- }
-
- if (book || reverse_order)
- { if ((output_fp = fopen (bookfile, "w")) == NULL)
- { fprintf (stderr, "%s: cannot create work file\n", pgmname);
- exit (1);
- }
- if ((pg_loc = (long *) malloc (sizeof (long) * MAX_PAGES)) == NULL)
- { fprintf (stderr, "%s: cannot allocate enough memory\n", pgmname);
- exit (1);
- }
- npg_loc = 0;
- }
-
- for (i = 0; i < NFONTS; i++)
- fonts_used[i] = 0;
-
- page_number = -1;
- line_number = 32000;
- default_point_size = point_size;
- default_font_number = font_number;
- bookwork = book && landscape && (max_frame == 2);
-
- input_fp = stdin;
- get_time (now);
- scale_factors ();
- prologue ();
- start_file ();
- process_file ();
- terminate_printer ();
- output_book (bookfile);
- }
-
- #else /* not PSFFILTER */
-
- /* begin normal "psf" code */
-
- if (font_number * 4 > font_count)
- { fprintf (stderr,"Font number invalid....\n");
- usage ();
- }
-
- if (book || reverse_order)
- { if ((output_fp = fopen (bookfile, "w")) == NULL)
- { fprintf (stderr, "%s: cannot create work file\n", pgmname);
- exit (1);
- }
- if ((pg_loc = (long *) malloc (sizeof (long) * MAX_PAGES)) == NULL)
- { fprintf (stderr, "%s: cannot allocate enough memory\n", pgmname);
- exit (1);
- }
- npg_loc = 0;
- }
- else
- { if (env_fname = getenv ("PSFLP"))
- #if defined(MSDOS) || defined (__MSDOS__)
- { if ((output_fp = fopen (env_fname, "wt")) == NULL)
- #else
- { if ((output_fp = fopen (env_fname, "w")) == NULL)
- #endif
- { fprintf (stderr, "Cannot open output file %s\n", env_fname);
- exit (1);
- }
- }
- else
- { output_fp = stdout;
- }
- }
-
-
- for (i = 0; i < NFONTS; i++)
- fonts_used[i] = 0;
-
- page_number = -1;
- line_number = 32000;
- default_point_size = point_size;
- default_font_number = font_number;
- bookwork = book && landscape && (max_frame == 2);
- *fname = 0;
-
- get_time (now);
- scale_factors ();
- prologue ();
- if (optind >= argc) /* process on stdin */
- { input_fp = stdin;
- start_file ();
- process_file ();
- }
- else
- { for ( ; optind < argc; optind++) /* files from cmd line */
- { strcpy (fname, argv[optind]);
- if ((input_fp = fopen (argv[optind], "r")) == NULL)
- { fprintf (stderr, "Unknown file: %s\n", argv[optind]);
- continue;
- }
- start_file ();
- process_file ();
- fclose (input_fp);
- }
- }
- terminate_printer ();
-
- output_book (bookfile);
- /* end normal psf code */
-
- #endif /* PSFFILTER */
-
- exit (0);
- }
-
-
- /****************************************************************************
- * scale_factors () *
- * Compute the x and y scale factors. *
- ****************************************************************************/
-
- /* total paper size - unprintable size
- scale factor = --------------------------------------
- print size
- */
-
- void scale_factors ()
- { int wide; /* width needed for char count */
- int high; /* points needed for line count */
- int n_lines; /* number of lines on a page */
- int i;
- double char_width, scale;
- double char_sf, line_sf;
- int nominal_high, nominal_wide;
- int on_portrait;
-
- /* use either the "portrait" or landscape width/height for basic scaling
- */
- switch (max_frame)
- {
- case 1: on_portrait = 0;
- break;
- case 2: if (landscape)
- on_portrait = 1;
- else
- on_portrait = 0;
- break;
- case 4: if (landscape)
- on_portrait = 0;
- else
- on_portrait = 1;
- }
-
- real_width = p->width; /* for initial axis translate only */
-
- /* if 4up in portrait or 2up, we want to shrink the image as
- though it were a proper 8.5x11 page. thus do all calculations
- of line and column count as though it were a normal portrait page.
- */
- if (on_portrait)
- { nominal_high = p->y_size;
- nominal_wide = p->x_size;
- }
- if (landscape)
- {
- i = p->height; p->height = p->width; p->width = i;
- i = p->left_marg; p->left_marg = p->bot_marg; p->bot_marg = i;
- i = p->top_marg; p->top_marg = p->right_marg; p->right_marg = i;
- i = p->lx; p->lx = p->ly; p->ly = i;
- i = p->ux; p->ux = p->uy; p->uy = i;
- i = p->x_size; p->x_size = p->y_size; p->y_size = i;
- }
- if (on_portrait == 0)
- { nominal_high = p->y_size;
- nominal_wide = p->x_size;
- }
-
- if (set_point_size)
- { /* if point size specified, ignore changes to rows and columns
- with -L, -l & -c. They destroy character shape.
- */
- char_width = point_size / 12.0 * NOMINAL_CWIDE;
- n_chars = ceil ((double) nominal_wide / (double) char_width);
- n_lines = (double) nominal_high / (double) point_size;
- char_sf = 1.0;
- line_sf = 1.0;
-
- if (set_total_count == 0 || lines_total > n_lines)
- lines_total = n_lines;
- if (set_line_count == 0 || lines_on_page > n_lines)
- lines_on_page = n_lines;
- if (lines_total < lines_on_page)
- lines_on_page = lines_total;
- if (header) /* compress scale to allow headers */
- { lines_on_page += 2;
- lines_total += 2;
- line_sf = (double) n_lines / (double) lines_total;
- }
- }
- else
- { /* determine independent scale factors to lines and columns
- based on user line and column count. This changes
- the character aspect ration - squashing it vertically
- and/or horizontally.
- */
- char_width = NOMINAL_CWIDE;
- n_chars = ceil ((double) nominal_wide / (double) char_width);
-
- if (set_char_count)
- char_sf = (double) n_chars / (double) chars_on_line;
- else
- { char_sf = 1.0; /* no change to char count */
- chars_on_line = n_chars;
- }
-
- n_lines = (double) nominal_high / (double) point_size;
-
- if (set_total_count == 0)
- lines_total = n_lines;
- if (set_line_count == 0)
- lines_on_page = n_lines;
- if (lines_total < lines_on_page)
- { if (set_total_count)
- lines_on_page = lines_total;
- else
- lines_total = lines_on_page;
- }
- if (header) /* compress scale to allow headers */
- { lines_on_page += 2;
- lines_total += 2;
- }
- line_sf = (double) n_lines / (double) lines_total;
- }
-
- /* theoretical points high and wide that we would "like" to
- have for our page - before scaling - including a 1/2 line
- for descenders for the last line.
- */
- high = ceil ((double) point_size * ((double) n_lines + 0.51));
- wide = ceil (n_chars * char_width);
-
- x_user_offset = max (0, x_user_offset - p->left_marg);
- y_user_offset = max (0, y_user_offset - p->top_marg );
-
- switch (max_frame)
- {
- case 1:
- scale_x = (double) (p->x_size) / (double) wide * char_sf;
- scale_y = (double) (p->y_size) / (double) high * line_sf;
- x_left_offset = (int) ceil ((double) (p->left_marg + x_user_offset) / scale_x);
- y_top_offset = (int) ceil ((double) (p->top_marg + y_user_offset) / scale_y);
- dx_home[0] = 0;
- dy_home[0] = 0;
- p->height = ceil ((double) p->height / scale_y);
- p->width = ceil ((double) p->width / scale_x);
- p->bot_marg = ceil ((double) p->bot_marg / scale_y);
- break;
-
- case 2:
- scale_x = (double) (p->width - 2 * p->left_marg - 2 * p->right_marg)
- / (double) (2 * wide) * char_sf;
- scale_y = (double) (p->y_size) / (double) high * line_sf;
-
- if (landscape == 0)
- { scale_y /= 2.0;
- lines_total *= 2.0;
- lines_on_page *= 2.0;
- }
-
- /* point offsets for margins account for physical "forbidden" area */
-
- x_left_offset = (int) ceil ((double) p->left_marg / scale_x);
- y_top_offset = (int) ceil ((double) p->top_marg / scale_y);
-
- /* page origin translation vectors */
-
- p->height = ceil ((double) p->height / scale_y);
- p->width = ceil ((double) p->width / (scale_x * 2.0));
- p->bot_marg = ceil ((double) p->bot_marg / scale_y);
- dx_home[0] = 0;
- dy_home[0] = 0;
- dx_home[1] = p->width;
- dy_home[1] = 0;
- break;
-
- case 4:
- scale_x = (double) (p->width - 2 * p->left_marg - 2 * p->right_marg)
- / (double) (2 * wide) * char_sf;
- scale_y = (double) (p->height - 2 * p->top_marg - 2 * p->bot_marg)
- / (double) (2 * high) * line_sf;
-
- /* point offsets for margins account for physical "forbidden" area */
-
- x_left_offset = (int) ceil ((double) p->left_marg / scale_x);
- y_top_offset = (int) ceil ((double) p->top_marg / scale_y);
-
- /* page origin tranlsation vectors */
-
- p->height = ceil ((double) p->height / (scale_y * 2.0));
- p->width = ceil ((double) p->width / (scale_x * 2.0));
- p->bot_marg = ceil ((double) p->bot_marg / scale_y);
- dx_home[0] = 0;
- dy_home[0] = p->height;
- dx_home[1] = p->width;
- dy_home[1] = 0;
- dx_home[2] = -p->width;
- dy_home[2] = -p->height;
- dx_home[3] = p->width;
- dy_home[3] = 0;
- break;
-
- default: ;
- }
-
- if (max_frame > 1)
- { x_left_offset += x_user_offset;
- y_top_offset += y_user_offset;
- }
- }
-
-
- /****************************************************************************
- * prologue () *
- * generate the require postscript-conformant prologue *
- ****************************************************************************/
-
- void prologue ()
- { char *getlogin(), *me;
- int c;
- FILE *fp;
-
- if (book || reverse_order)
- fprintf (output_fp, "%%Book file: psf-to-psfdoub\n");
- else
- fprintf (output_fp, "%%!PS-Adobe-\n");
- #if !defined(MSDOS) && !defined(__MSDOS__)
- me = getlogin();
- if (me == NULL) /* AT&T Unix 3.2 getlogin() is broken */
- #endif
- me = "psf"; /* could use cuserid() instead */
- fprintf (output_fp, "%%%%Creator: %s\n", me);
- fprintf (output_fp, "%%%%CreationDate: %s\n", now);
- fprintf (output_fp, "%%%%DocumentFonts: (atend)\n");
- fprintf (output_fp, "%%%%Pages: (atend)\n");
- fprintf (output_fp, "%%%%EndComments\n");
-
- /* usage: (text to underline) <pointsize> showuline
- where: <pointsize> is current text point size.
-
- eg: (text to underline) 12 showuline
- */
- fprintf (output_fp, "%s%s%s%s%s%s%s%s%s%s%s",
- "/showuline {\n",
- " /CurPointSize exch def\n",
- " dup stringwidth pop\n",
- " gsave\n",
- " currentfont /FontInfo get dup\n",
- " /UnderlinePosition get CurPointSize mul 1000 div 0 exch rmoveto exch 0 rlineto\n",
- " /UnderlineThickness get CurPointSize mul 1000 div setlinewidth stroke\n",
- " grestore\n",
- " show\n",
- "} def\n",
- "/mv {moveto} def\n");
-
- /* add additional startup prologue code from psfprint.def
- probably for non-English language support.
- */
- if (pdef)
- { while (fgets (line, LONG_STR, pdef))
- { if (fputs (line, output_fp) == EOF)
- output_trouble (2);
- }
- fclose (pdef);
- pdef = NULL;
- }
-
- /* copy a copyfile requested from psfprint.def */
-
- if (copyfile[0])
- { if (fp = fopen (copyfile, "r"))
- { while (1)
- { c = fgetc (fp);
- if (feof (fp) || ferror (fp))
- break;
- if (fputc (c, fp) == EOF)
- output_trouble (2);
- }
- fclose (fp);
- }
- }
-
- fprintf (output_fp, "%%%%EndProlog\n");
-
- if (set_paper_tray)
- fprintf (output_fp, "%s\n", p->paper_tray);
-
- if (order_command)
- fprintf (output_fp, "%s\n", order_command);
- else if (set_paper_bin)
- fprintf (output_fp, "%s\n", slots[set_paper_bin - 1]);
- }
-
- /****************************************************************************
- * showpage () *
- * Generate a real "showpage" if we have really finished generating a *
- * physical page. If we are processing 2 or 4 up, then generate *
- * coordinate "translates" if we really haven't finished all possible *
- * page frames of the page. *
- ****************************************************************************/
-
- void showpage (end_of_file)
- int end_of_file;
- { int skipping;
-
- line_number = 0;
-
- if (max_frame > 1)
- fprintf (output_fp, "grestore\n");
-
- if (is_a_formfeed) /* don't skip if caused by form feed */
- is_a_formfeed = 0; /* needed for lpr of= processing */
- else if (page_number > 0 && end_of_file == 0)
- { skipping = remove_between;
- while (skipping-- && fgets (line, LONG_STR, input_fp))
- ;
- if (skipping >= 0)
- { end_of_file = 1;
- if (bookwork == 0) /* psfdoub will re-insert this */
- fprintf (output_fp, "showpage pg restore\n");
- frame = 0;
- longjmp (eof_env, 1);
- }
- }
-
- if (++frame >= max_frame || end_of_file)
- { if (bookwork == 0) /* psfdoub will re-insert this */
- fprintf (output_fp, "showpage pg restore\n");
- frame = 0;
- }
- if (!end_of_file)
- set_frame ();
-
- }
-
- /****************************************************************************
- * set_frame () *
- * Select the next logical frame in two-up or four-up mode. If it is *
- * the first frame of a physical page, the generate the %%Page *
- ****************************************************************************/
-
- void set_frame ()
- {
- if (frame == 0 || bookwork)
- { if (book || reverse_order) /* mark byte position of %%Page: for psfdoub */
- { pg_loc[npg_loc++] = ftell (output_fp);
- }
- fprintf (output_fp, "%%%%Page: ? %d\n", ++physical_page);
- if (bookwork == 0) /* psfdoub will re-insert these */
- { fprintf (output_fp, "/pg save def\n");
- if (landscape)
- fprintf (output_fp, "90 rotate 0 %d translate\n", -real_width);
- fprintf (output_fp, "%.5f %.5f scale\n", scale_x, scale_y);
- }
- findfont();
- }
-
- set_y_coord ();
-
- if (max_frame > 1 && bookwork == 0)
- fprintf (output_fp, "%d %d translate\n", dx_home[frame], dy_home[frame]);
-
- if (frame == 0 && cross)
- draw_cross();
-
- if (max_frame > 1)
- { fprintf (output_fp, "gsave\n");
- set_clip_path (0, 0, p->width, p->height);
- }
- }
-
-
- /****************************************************************************
- * set_y_coord *
- * position next line to the top of a logical page. *
- *****************************************************************************/
-
- void set_y_coord ()
- {
- y_coord = p->height - y_top_offset - point_size;
- }
-
- /****************************************************************************
- * put_top *
- * put a header line at the top of the page *
- *****************************************************************************/
-
- void put_top ()
- { int save_attr, save_point, nc;
- char fmt[50], *hd;
-
- save_attr = print_attribute;
- save_point = point_size;
- print_attribute = BOLD;
- point_size = save_point_size;
-
- hd = (header == 1) ? fname : header_text;
- nc = n_chars - 33;
- if (nc < strlen (hd))
- nc = strlen (hd) + 3;
- sprintf (fmt, "(%%-%ds%%3d %%s)show\n", nc);
-
- findfont();
- moveto (0, y_coord, 1);
- fprintf (output_fp, fmt, hd, page_number + 1, now);
- y_coord -= point_size * 2;
- x_coord = 0;
- print_attribute = save_attr;
- point_size = save_point;
- findfont();
- }
-
- /****************************************************************************
- * process_file() *
- * Read the file, look for escape sequences, put text in postscript form *
- ****************************************************************************/
-
- void process_file ()
- { int char_type, char_count, i, set_page, esc_type;
- char *strchr ();
- int previous_attribute;
- int lcount = 0;
- unsigned char *xln;
-
- set_page = 0;
- i = remove_beginning;
- while (i-- && fgets (line, LONG_STR, input_fp))
- ;
- if (i >= 0)
- { showpage (1);
- return;
- }
-
- if (setjmp (eof_env))
- { return;
- }
-
- #ifdef PSFFILTER
- /* psffilter already has a first line, psf does not */
- do
- #else
- while (fgets (line, LONG_STR, input_fp) != NULL)
- #endif
- {
- if (*line == CTLD_EOJ) /* printing postscript code: ^D at end */
- break; /* assume it is end of file also */
-
- if (lcount++ == 0)
- { if ((i = tscan (line, "ta=")) >= 0)
- { tab_size = atoi (line + i + 3);
- }
- }
-
- if (need_xlate) /* translate character set? */
- { xln = (unsigned char *) line;
- while (*xln)
- { i = *xln;
- *xln++ = xlate[i];
- }
- }
-
- if ((c = strchr (line, '\f')) != NULL)
- { if (c == line)
- { line_number = 32000;
- c = line + 1;
- }
- else
- { *c = 0;
- set_page = 1;
- c = line;
- }
- is_a_formfeed = 1;
- }
- else
- c = line;
-
- if (line_number >= lines_on_page * 10)
- { page_number++;
- showpage (0);
- line_number = 10;
- if (header)
- { put_top();
- line_number += 20;
- }
- }
- else
- line_number += 10;
-
- char_type = char_count = 0;
-
- /* for empty lines, don't generate a real moveto - but to call
- to ensure that check for page overflow is done.
- */
- if (*c == '\n')
- moveto (x_coord, y_coord, 0); /* don't gen moveto */
- else
- moveto (x_coord, y_coord, 1); /* do gen moveto */
-
- while (*c && *c != '\n')
- { if (char_type == 0)
- { if (fputc ('(', output_fp) == EOF)
- output_trouble (2);
- }
- switch ((int) *c)
- {
- case ESCAPE:
- previous_attribute = print_attribute;
- esc_type = *(++c);
- if (escape_sequence (esc_type) == 0)
- { switch (esc_type)
- {
- case 'u':
- SHOWU (output_fp, point_size);
- break;
-
- default:
- if (char_type && (previous_attribute & UNDERLINE))
- SHOWU (output_fp, point_size);
- else
- { if (fputs (")show\n", output_fp) == EOF)
- output_trouble (2);
- }
- if (esc_type == '+' || esc_type == '-')
- { /* check for +/- 1/2 line feed */
- if (esc_type == '+')
- y_coord -= point_size / 2;
- else
- y_coord += point_size / 2;
- moveto (x_coord, y_coord, 1);
- char_type = -1;
- c++;
- if (*c != '\n')
- { if (fputc ('(', output_fp) == EOF)
- output_trouble (2);
- }
- continue;
- }
- else
- findfont ();
- }
- char_type = 0;
- }
- break;
-
- default:
- if (*c == '\t')
- { fputc (' ', output_fp);
- while (++char_count % tab_size)
- { if (fputc (' ', output_fp) == EOF)
- output_trouble (2);
- }
- }
- else
- { if (strchr ("\r\b\\()", *c) != NULL)
- if (fputc ('\\', output_fp) == EOF)
- output_trouble (2);
- if (fputc (*c, output_fp) == EOF)
- output_trouble (2);
- char_count++;
- }
- char_type = 1;
- break;
- }
- c++;
- }
- if (char_type == 1)
- { if (print_attribute & UNDERLINE)
- SHOWU (output_fp, point_size);
- else
- { if (fputs (")show\n", output_fp) == EOF)
- output_trouble (2);
- }
- }
-
- y_coord -= point_size;
- x_coord = 0;
- if (set_page)
- { line_number = 32000;
- set_page = 0;
- }
- #ifdef PSFFILTER
- } while (fgets (line, LONG_STR, input_fp) != NULL);
- #else
- }
- #endif
- if (end_of_file == 0)
- showpage (1);
- }
-
- /****************************************************************************
- * escape_sequence () *
- * If an escape sequence (esc,char) is found, mark which type of font *
- ****************************************************************************/
-
- int escape_sequence (which)
- int which;
- { char s[10];
-
- switch (which)
- {
- case 'I':
- print_attribute |= ITALICS;
- break;
-
- case 'i':
- print_attribute &= ~ITALICS;
- break;
-
- case 'B':
- print_attribute |= BOLD;
- break;
-
- case 'b':
- print_attribute &= ~BOLD;
- break;
-
- case 'U':
- print_attribute |= UNDERLINE;
- break;
-
- case 'u':
- print_attribute &= ~UNDERLINE;
- break;
-
- case 'F':
- s[0] = *(++c);
- s[1] = '\0';
- font_number = xtoi ((int) *s);
- if (font_number > (font_count / 4))
- font_number = (font_count / 4) - 1;
- break;
-
- case 'f':
- font_number = default_font_number;
- break;
-
- case 'P':
- s[0] = *(++c);
- s[1] = *(++c);
- s[2] = '\0';
- point_size = atoi (s);
- break;
-
- case 'p':
- point_size = default_point_size;
- break;
-
- case '+':
- case '-':
- break;
-
- default:
- return (-1);
- ;
- }
- return (0);
- }
-
- /****************************************************************************
- * moveto () *
- * Generate a postscript x y moveto statememt *
- ****************************************************************************/
-
- void moveto (x, y, do_move)
- int x;
- int y;
- int do_move; /* 1 = gen moveto 0 = dont gen moveto */
- {
- /* ensure that the current line can fit on the page - including the
- 1/4 line needed for the decenders
- */
-
- if (line_number > lines_on_page * 10 || y < (p->bot_marg + point_size / 3))
- { if (line_number < lines_on_page * 10)
- page_number++;
- showpage (0);
- if (header)
- { put_top();
- line_number += 20;
- }
- y = y_coord;
- x = x_coord;
- }
-
- if (do_move)
- fprintf (output_fp, "%d %d mv ", x + x_left_offset, y);
- }
-
- /****************************************************************************
- * findfont () *
- * generate a findfont statement *
- ****************************************************************************/
-
- void findfont ()
- { int this;
-
- /* remove reference to UNDERLINE. Underline is not a font. */
-
- this = (font_number * 4) + (print_attribute & 0x03);
- fonts_used[this] = 1;
- fprintf (output_fp, "/%s findfont %d scalefont setfont\n", fonts[this], point_size);
- }
-
- /****************************************************************************
- * start_file () *
- * Generate things that are appropriate for beginning of file processing *
- ****************************************************************************/
-
- void start_file ()
- {
- end_of_file = 0;
- line_number = 0;
- print_attribute = 0;
- page_number = 0;
- frame = 0;
- set_frame ();
- if (header)
- { put_top();
- line_number += 20;
- }
- }
-
-
- /****************************************************************************
- * terminate_printer () *
- * Generate things that are appropriate wrap-up after all files printed *
- * For double sided printing (book == 1), generate byte offset info. *
- ****************************************************************************/
-
- void terminate_printer ()
- { int i, used;
- long psfptr;
-
- if (book || reverse_order)
- { pg_loc[npg_loc++] = ftell (output_fp);
- }
- fprintf (output_fp, "%%%%Trailer\n");
- for (used = i = 0; i < font_count; i++)
- { if (fonts_used[i])
- { used = 1;
- break;
- }
- }
- if (used)
- { fprintf (output_fp, "%%%%DocumentFonts:");
- for (i = 0; i < font_count; i ++)
- { if (fonts_used[i])
- fprintf (output_fp, " %s", fonts[i]);
- }
- fprintf (output_fp, "\n");
- }
-
- fprintf (output_fp, "%%%%Pages: %d\n", physical_page);
-
- if (book || reverse_order) /* print statistics for psfdoub */
- { psfptr = ftell (output_fp);
- fprintf (output_fp, "%%PsfScale: %.5f %.5f scale\n", scale_x, scale_y);
- fprintf (output_fp, "%%PsfMargin: %d %d %d %d %d\n",
- max_frame, landscape, real_width, p->height, p->width);
- for (i = 0; i < 4; i++)
- fprintf (output_fp, "%%PsfHome: %d %d %d\n", i, dx_home[i], dy_home[i]);
- for (i = 0; i < npg_loc-1; i++)
- fprintf (output_fp, "%%PsfPg: %d %d\n", i, pg_loc[i]);
- fprintf (output_fp, "%%PsfPg: 9999 %d\n", pg_loc[npg_loc-1]);
- fprintf (output_fp, "%%PsfPtr: %d\n", psfptr);
- }
- fprintf (output_fp, "%c", CTLD_EOJ); /* CTL/D = end job */
- }
-
- /****************************************************************************
- * draw_cross () *
- * Draw horizontal and vertical separation lines between pages 2/4-up *
- ****************************************************************************/
-
- void draw_cross ()
- { int p_w, p_h;
-
- if (max_frame > 1)
- { p_w = p->width;
- p_h = p->height;
- if (max_frame == 4)
- { set_clip_path (0, -p_h, p_w * 2, p_h);
- fprintf (output_fp,"gsave %d %d moveto\n", p_w, p_h);
- fprintf (output_fp,"%d %d lineto\n", p_w, -p_h);
- fprintf (output_fp,"%d %d moveto\n", 0, 0);
- fprintf (output_fp,"%d %d lineto\n", p_w * 2, 0);
- fprintf (output_fp,"%s\n", "stroke grestore");
- }
- else
- { set_clip_path (0, 0, p_w * 2+ 1, p_h + 1);
- fprintf (output_fp,"gsave %d %d moveto\n", p_w, p_h);
- fprintf (output_fp,"%d %d lineto\n", p_w, 0);
- fprintf (output_fp,"%s\n", "stroke grestore");
- }
- }
- }
-
- /****************************************************************************
- * set_clip_path *
- ****************************************************************************/
-
- void set_clip_path (x1, y1, x2, y2)
- int x1, y1, x2, y2;
- {
- x1--; y1--; x2++; y2++;
-
- fprintf (output_fp, "newpath\n");
- fprintf (output_fp,"%d %d moveto\n", x1, y1);
- fprintf (output_fp,"%d %d lineto\n", x1, y2);
- fprintf (output_fp,"%d %d lineto\n", x2, y2);
- fprintf (output_fp,"%d %d lineto\n", x2, y1);
- fprintf (output_fp,"%s\n", "closepath clip");
- }
-
- /****************************************************************************
- * output_book () *
- * Send file "double sided print" mode. Used to make a "book". *
- ****************************************************************************/
-
- void output_book (bookfile)
- char *bookfile;
- { char opts[50];
-
- if (book == 0 && reverse_order == 0)
- return;
-
- #ifdef HOPPER
-
- if (nslots > 1 || reverse_order)
- { if (output_fp != stdout)
- { fflush (output_fp);
- fclose (output_fp);
-
- sprintf (opts, "%s %s", reverse_requested ? "-v" : "",
- book ? "-3" : "");
-
- #if defined(MSDOS) || defined(__MSDOS__)
- sprintf (line, "%s %s -u %s %s", PSFDOUB, opts, defref, bookfile);
- #else
- sprintf (line, "%s/%s %s -u %s %s", BINDIR, PSFDOUB, opts, defref, bookfile);
- #endif
- system (line);
- unlink (bookfile);
- }
- }
-
-
- #else /* not HOPPER */
- if (reverse_order)
- { if (output_fp != stdout)
- { fflush (output_fp);
- fclose (output_fp);
-
- sprintf (opts, "%s", reverse_requested ? "-v" : "");
-
- #if defined(MSDOS) || defined(__MSDOS__)
- sprintf (line, "%s %s -u %s %s", PSFDOUB, opts, defref, bookfile);
- #else
- sprintf (line, "%s/%s %s -u %s %s", BINDIR, PSFDOUB, opts, defref, bookfile);
- #endif
- system (line);
- unlink (bookfile);
- }
- }
-
-
- #endif /* HOPPER */
- }
-
-
- /************************************************************************
- * tscan (s,t) *
- * look for string t in s. return -1 if t does not exits in s else *
- * return array position of first character match *
- ************************************************************************/
-
- int tscan (s, t)
- char s[], t[];
- {
- int i, j, k;
- for (i = 0; s[i] != '\0'; i++)
- { for (j = i, k=0; t[k] != '\0' && s[j] == t[k]; j++, k++)
- ;
- if (t[k] == '\0')
- return (i);
- }
- return (-1);
- }
-
- void get_time (t) /* get current time of */
- char *t;
- {
- long n_time, time ();
- char *x_time, *cc, *strchr();
-
- n_time = time (0); /* get time */
- x_time = ctime (&n_time); /* convert ascii */
- if ((cc = strchr (x_time, '\n')) != NULL)
- *cc = '\0';
- strcpy (t, x_time);
- }
-
- int compare (a,b) /* case insensitive compare */
- char *a, *b;
- { int aa, bb;
-
- while (*a)
- { aa = *a++;
- bb = *b++;
- if (UCCHAR (aa) != UCCHAR (bb))
- return (UCCHAR(aa) - UCCHAR(bb));
- }
- return (UCCHAR (*a) - UCCHAR (*b));
- }
-
- int partial_compare (a,b) /* case insensitive compare */
- char *a, *b; /* if all parts of 'a' are successful */
- { int aa, bb;
-
- while (*a)
- { aa = *a++;
- bb = *b++;
- if (UCCHAR (aa) != UCCHAR (bb))
- return (UCCHAR(aa) - UCCHAR(bb));
- }
- return (0);
- }
-
- int comparen (a,b, n) /* case insensitive compare with count limit */
- char *a, *b;
- int n;
- { int aa, bb;
-
- while (*a && n--)
- { aa = *a++;
- bb = *b++;
- if (UCCHAR (aa) != UCCHAR (bb))
- return (UCCHAR(aa) - UCCHAR(bb));
- }
- if (n <= 0)
- return (0);
- return (UCCHAR (*a) - UCCHAR (*b));
- }
-
- int endcompare (a,b) /* compare end of a with b */
- char *a, *b;
- {
- int na, nb;
-
- na = strlen (a);
- nb = strlen (b);
- if (na > nb)
- a += na - nb;
- return (strcmp (a,b));
- }
-
-
- void trim (s) /* trim trailing blanks and \n */
- char *s;
- { int many;
-
- for (many = strlen (s) - 1; many >= 0; many--)
- { if (isgraph (s[many]))
- break;
- else
- s[many] = '\0';
- }
- }
-
- void bad_file()
- {
- fprintf (stderr, "Bad %s file\n", defref);
- exit (1);
- }
-
- int xtoi (c) /* hex character to integer */
- int c; /* any letter is a 'hex' digit */
- {
- char xc[2];
- int rv;
-
- if (isupper (c))
- xc[0] = tolower (c);
- else
- xc[0] = c;
- xc[1] = '\0';
-
- rv = tscan (ascii_hex, xc);
- if (rv >= 0)
- return (rv);
- return (0);
- }
-
-
- /********************************************************
- * catch () *
- * Catch SIGINT from lpd *
- ********************************************************/
-
- void catch (signo)
- int signo;
- {
- fprintf (output_fp, "%c", CTLD_EOJ);
- exit (0);
- }
-
- void output_trouble (rc)
- int rc;
- {
- #ifndef PSFFILTER
- fprintf (stderr, "Cannot write to output file\n");
- #endif
- exit (rc);
- }
- /************************************************************************
- * replacement_fonts() *
- * get language-specific fonts and translation vectors. *
- * Reads only the %%PsfStart -to- %%PsfEnd code. The file is is left *
- * positioned at the first postscript code that prologue() will copy *
- * to the output. *
- ************************************************************************/
-
- void replacement_fonts ()
- { int found, i, fn, xold, xnew;
- char line[201];
- char *ln, *x, *fname;
-
- if (pdef == NULL)
- return;
- found = 0;
- while (fgets (line, 200, pdef)) /* skip printer name */
- { if (strncmp (line, "%%PsfStart", 10) == 0)
- { found = 1;
- break;
- }
- }
- if (found)
- { while (fgets (line, 200, pdef)) /* read fonts, translate */
- { if (strncmp (line, "%%PsfEnd", 8) == 0)
- break;
- if (strncmp (line, "%%font", 6) == 0)
- { fn = xtoi (line[6]) * 4;
- if (fn >= font_count)
- font_count = fn + 4;
- trim (line);
- ln = malloc (strlen (line) - 6);
- strcpy (ln, line + 7);
- fonts_have[fn] = 1;
- fonts[fn++] = strtok (ln, " \t");
- for (i = 1; i < 4; i++)
- { fonts_have[fn] = 1;
- fonts[fn++] = strtok (NULL, " \t");
- }
- }
- else if (strncmp (line, "%%translate", 11) == 0)
- { x = strtok (line + 11, " \t");
- do
- { xold = otoi (x) % 256;
- xnew = otoi (x+4) % 256;
- xlate[xold] = xnew;
- } while (x = strtok (NULL, " \t"));
- need_xlate = 1;
- }
- else if (strncmp (line, "%%copy", 6) == 0)
- { fname = strtok (line + 6, " \t");
- if (fname)
- strcpy (copyfile, fname);
- }
- }
- }
- else
- { fclose (pdef);
- pdef = NULL;
- }
- return;
- }
-
- /****************************************************************************
- * octal to integer *
- ****************************************************************************/
- int otoi (s)
- char *s;
- {
- int v, p, quit;
-
- v = 0;
- while (*s == ' ')
- s++;
- quit = 0;
- while (*s)
- { switch (*s)
- {
- case '0': p = 0; break;
- case '1': p = 1; break;
- case '2': p = 2; break;
- case '3': p = 3; break;
- case '4': p = 4; break;
- case '5': p = 5; break;
- case '6': p = 6; break;
- case '7': p = 7; break;
- default: quit = 1;
- }
- if (quit)
- break;
- v = (v << 3) + p;
- s++;
- }
- return (v);
- }
-
- /****************************************************************************
- * usage () *
- ****************************************************************************/
-
- #ifdef PSFFILTER
-
- void usage ()
- { exit (1);
- }
- void size_display ()
- { exit (1);
- }
-
- #else /* not PSFFILTER */
-
- static char *usage_text[] =
- {
- "Usage: %s [-1|2|4] [-b n] [-c n] [-d] [-f n] [-g type ] [-h]\n",
- " [-H text] [-i n] [-l n] [-m n] [-n] [-p n] [-R n]",
- " [-r n] [-s] [-t n] [-u fil] [-w] [-x] file ...",
- "where:",
- " -1|2|4 print 1,2,4 up (default=1)",
- " -b n paper bin n",
- " -c n print columns",
- " -d double sided",
- " -f n font number (def=0:Courier)",
- " -g type letter legal a4 b5",
- " -h file name header",
- " -H text text header",
- " -i n indent left margin points",
- " -l n print lines per page",
- " -L n lines per page",
- " -m n top margin points",
- " -n portrait (narrow) format",
- " -p n point size n",
- " -R n remove lines from beginning",
- " -r n remove lines between pages",
- " -s show page stats",
- " -t n tabs to n (default=8)",
- " -u fil use this file as psfprint.def",
- " -v reverse page order",
- " -w landscape (wide) format",
- " -x draw cross (2/4-up page)",
- " file.. name of files (or stdin)",
- " output: stdout",
- ""
- } ;
-
- #define TOPCOUNT 4
-
- void usage ()
- { int i, many, n, ff;
-
- fprintf (stderr, usage_text[0], pgmname);
- for (i = 1; i < TOPCOUNT; i++)
- fprintf (stderr, "%s\n", usage_text[i]);
-
- many = sizeof (usage_text)/sizeof (char *) - TOPCOUNT;
-
- for (i = 0; i < many/2; i++)
- fprintf (stderr, "%-38s %-38s\n", usage_text[i+TOPCOUNT], usage_text[i+many/2+TOPCOUNT]);
-
- fprintf (stderr,"Fonts selection with -f n (number or name)\n");
- many = ff = 0;
- for (i = 0; i < font_count/4; i++)
- { if (fonts_have[i*4])
- { fprintf (stderr, " %c %-22s", ascii_hex[i], fonts[i*4]);
- many++;
- if ((ff = many % 3) == 0)
- fprintf (stderr, "\n");
- }
- }
- if (ff)
- fprintf (stderr, "\n");
-
- fprintf (stderr, "Paper type/size selection with -g type\n");
- many = 0;
- for (i = 0; page_types[i].paper_name[0] != '\0'; i++)
- { n = strlen (page_types[i].paper_name);
- if (many + n > 75)
- { many = 0;
- fprintf (stderr,"\n");
- ff = 0;
- }
- else ff = 1;
- many += n + 3;
- fprintf (stderr," %s", page_types[i].paper_name);
- }
- if (ff)
- fprintf (stderr, "\n");
- exit (1);
- }
-
- /************************************************************************
- * size_display () *
- * print a table of point size, page size, line count, column count *
- ************************************************************************/
-
- void size_display ()
- {
- int point_size, ps, nominal_high, nominal_wide, i;
- int n_chars, n_lines;
- double char_width;
- char *which;
-
- fprintf (stderr, "%22s", "point size: ");
- for (point_size = 6; point_size < 17; point_size += 2)
- fprintf (stderr, " %5d ", point_size);
- fprintf (stderr, "\n%-22s", " ");
- for (point_size = 6; point_size < 17; point_size += 2)
- fprintf (stderr, " lin col");
- fprintf (stderr, "\n%-22s", "---- Page Layout ----");
- for (point_size = 6; point_size < 17; point_size += 2)
- fprintf (stderr, " --- ---");
- fprintf (stderr, "\n");
- for (ps = 0; page_types[ps].paper_name[0]; ps++)
- { for (i = 0; i < 2; i++)
- { if (i == 0)
- { nominal_high = page_types[ps].y_size;
- nominal_wide = page_types[ps].x_size;
- which = "portrait";
- }
- else
- { nominal_high = page_types[ps].x_size;
- nominal_wide = page_types[ps].y_size;
- which = "landscape";
- }
- fprintf (stderr, "%10.10s %9s: ", page_types[ps].paper_name, which);
- for (point_size = 6; point_size < 17; point_size += 2)
- { char_width = point_size / 12.0 * NOMINAL_CWIDE;
- n_chars = ceil ((double) nominal_wide / (double) char_width);
- n_lines = (double) nominal_high / (double) point_size;
- fprintf (stderr, " %4d%4d", n_lines, n_chars);
- }
- fprintf (stderr, "\n");
- }
- }
- exit (1);
- }
- #endif /* PSFFILTER */
-