home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume27 / psf3 / part07 / psfbanner.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-20  |  12.4 KB  |  534 lines

  1. /* ta=4 */
  2. /****************************************************************************
  3. *                p s f b a n n e r . c                                        *
  4. *                                                                            *
  5. *    Print a banner page on a postscript printer                                *
  6. *                                                                            *
  7. *    The generated print stream is NOT minimally conforming as per Red Book.    *
  8. *                                                                            *
  9. *    Tony Field.       tony@ajfcal.cuc.ab.ca                                    *
  10. ****************************************************************************/
  11.  
  12. /*
  13.  * $Id: psfbanner.c,v 3.2 1992/01/19 05:50:33 ajf Exp ajf $
  14.  *
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include "ctp.h"
  20. #include "psf.h"
  21. #include "patchlevel.h"
  22.  
  23. /* modifiy the following font selections if language changes
  24.    are needed in psfprint.def. Also enable the language translation
  25.    code at line 257  (   if (need_xlate)  )
  26. */
  27.  
  28. #define FONT1 "/Helvetica-BoldOblique findfont %d scalefont setfont\n"
  29. #define FONT2 "/Helvetica-Bold findfont %d scalefont setfont\n"
  30. #define FONT3 "/Courier findfont %d scalefont setfont\n"
  31. #define FONT4 "/Helvetica-Bold findfont %d scalefont setfont\n"
  32.  
  33. /*    setup paper dimensions                                    */
  34.  
  35. typedef struct                     /*    measurement in point                    */
  36. {    char    paper_name[60];        /*    name of paper size (for command line)    */
  37.     char    paper_tray[200];    /*    postscript operator to select this tray    */
  38.     int        width;                /*    portrait point width of paper            */
  39.     int        height;                /*    portrait point height of paper            */
  40.     int        lx, ly, ux, uy;
  41. } measure;
  42.  
  43. measure    *p;        /*    working set of parameters  (points to something below)     */
  44.  
  45.                 /*    standard paper sizes in portrait layout.                 */
  46.  
  47. measure    page_types[NPAGE] =
  48. {            {     "letter",
  49.                 "statusdict begin lettertray end",
  50.                   612,   792,    18,    15,   593,   777
  51.             },
  52.             {     "legal",
  53.                 "statusdict begin legaltray end",
  54.                   612,  1008,    18,    15,   593,   993
  55.             },
  56.             {    "a4",
  57.                 "statusdict begin a4tray end",
  58.                   595,   842,    18,    15,   578,   827
  59.             },
  60.             {    "b5",
  61.                 "statusdict begin b5tray end",
  62.                   516,   729,    18,    15,   497,   712
  63.             },
  64.             {    "",            /* end of paper list */
  65.                 "",
  66.                  0, 0,  0,  0, 0, 0
  67.             }
  68. };
  69.  
  70. char    slots[NSLOTS][200] = 
  71. {            "statusdict begin 1 setpapertray end",
  72.             "statusdict begin 2 setpapertray end",
  73.             "", "", "", ""
  74. } ;
  75. int        nslots = 2;
  76.  
  77. int    X_INDENT    = 30;        /*    points                        */
  78. int Y_INDENT    = 30;
  79. int    BIG_POINT    = 60;        /* changes to point size automatically scale    */
  80. int MED_POINT    = 35;        /* the printout.                                */
  81. int    SMALL_POINT    = 15;
  82. int    UX, UY, DX, DY, MAX_X, MAX_Y;
  83.  
  84. /*    The following arguments are received in the command line
  85.     argv[9] and argv[10] may be page size and paper tray specifications.
  86.     these could be:
  87.     
  88.             -b n    = select paper bin n
  89.             -g size = selelct paper tray (letter, b5, etc)
  90. */
  91.  
  92. #define    Userid        argv[1]
  93. #define    Name        argv[2]
  94. #define    Requestid    argv[3]
  95. #define    Printer        argv[4]
  96. #define    Options        argv[5]
  97. #define    Date        argv[6]
  98. #define    Machineid    argv[7]
  99. #define    Title        argv[8]
  100.  
  101. char    *defref = NULL;
  102.  
  103. FILE    *outfp;
  104. unsigned char    xlate[256];            /*    translation vector     */
  105. int        need_xlate = 0;                /*    no default xlate    */
  106. FILE    *pdef;
  107. void trim();
  108.  
  109. main (argc, argv)
  110. int        argc;
  111. char    *argv[];
  112. {    int        x, y, c, i, set_paper_tray, set_paper_bin, number, j;
  113.     char    line[200];
  114.  
  115.     if (argc < 8)
  116.         usage ();
  117.  
  118.     for (i = 0;  i < 256;  i++)
  119.         xlate[i] = i;
  120.     
  121.     outfp = stdout;
  122.     pdef = NULL;
  123.  
  124.     /* get user specified def file with -u */
  125.  
  126.     for (i = 0;  i < argc;  i++)
  127.     {    if (strncmp (argv[i], "-u", 2) == 0)
  128.         {    if (strlen (argv[i]) > 2)
  129.                 defref = argv[i] + 2;
  130.             else
  131.                 defref = argv[i+1];
  132.             break;
  133.         }
  134.     }
  135.     if (i >= argc)
  136.         defref = PDEF;
  137.  
  138.     if ((pdef = fopen (defref, "r")) != NULL)
  139.     {    char    line_type[200];
  140.  
  141.         while (fgets (line, 200, pdef))
  142.         {    if (strncmp (line, "*printer", 8) == 0)
  143.                 break;
  144.         }
  145.         nslots = 0;
  146.         fgets (line, 200, pdef);        /*    skip printer name     */
  147.  
  148.         while (fgets (line, 200, pdef))
  149.         {    trim (line);
  150.             sscanf (line, "%s%d", line_type, &number);
  151.  
  152.             if (strcmp (line_type, "*paper") == 0)
  153.             {    for (i = j = 0;  i < number;  i++)
  154.                 {    if (i >= NPAGE - 1)
  155.                     {    fgets (line, 200, pdef);
  156.                         fgets (line, 200, pdef);
  157.                         fgets (line, 200, pdef);
  158.                         continue;
  159.                     }
  160.                     if (fgets (line, 200, pdef) == NULL)
  161.                         bad_file();
  162.                     line[59] = 0;
  163.                     trim (line);
  164.                     strcpy (page_types[i].paper_name, line);
  165.                     if (fgets (line, 99, pdef) == NULL)
  166.                         bad_file();
  167.                     line[99] = 0;
  168.                     trim (line);
  169.                     strcpy (page_types[i].paper_tray, line);
  170.                     if (fgets (line, 100, pdef) == NULL)
  171.                         bad_file();
  172.                     trim (line);
  173.                     sscanf (line, "%d%d%d%d%d%d",
  174.                         &page_types[i].width, &page_types[i].height,
  175.                         &page_types[i].lx,    &page_types[i].ly,
  176.                         &page_types[i].ux,    &page_types[i].uy);
  177.                     j = i;
  178.                 }
  179.                 page_types[j+1].paper_name[0] = '\0';
  180.             }
  181.  
  182.             else if (strcmp (line_type, "*slots") == 0)
  183.             {
  184.                 for (j = 0;  j < NSLOTS;  j++)
  185.                     slots[j][0] = 0;
  186.                 for (i = j = 0;  i < number;  i++)
  187.                 {    if (fgets (line, 200, pdef) == NULL)
  188.                         bad_file();
  189.                     if (i >= NSLOTS)
  190.                         continue;
  191.                     line[99] = 0;
  192.                     trim (line);
  193.                     strcpy (slots[i], line);
  194.                     j = i;
  195.                 }
  196.                 nslots = j + 1;
  197.             }
  198.  
  199.             else if (strcmp (line_type, "*eof") == 0)
  200.                 break;
  201.         }
  202.     }
  203.  
  204.     MAX_X = page_types[0].width;
  205.     MAX_Y = page_types[0].height;
  206.     set_paper_bin = 0;
  207.     set_paper_tray = -1;
  208.     
  209.     for (i = 9;  i < argc;  i++)
  210.     {    if (argv[i][0] != '-')
  211.             continue;
  212.         c = argv[i][1];
  213.         switch (c)
  214.         {
  215.         case 'b':
  216.             if ((set_paper_bin = atoi (argv[i+1])) > nslots)
  217.             {    fprintf (stderr, "paper bin greater than %d\n", nslots);
  218.                 exit (1);
  219.             }
  220.             i++;
  221.             break;
  222.  
  223.         case 'g':
  224.             for (set_paper_tray = 0;  page_types[set_paper_tray].paper_name[0];  set_paper_tray++)
  225.             {    if (compare (argv[i+1], page_types[set_paper_tray].paper_name) == 0)
  226.                 {    MAX_X = page_types[set_paper_tray].width;
  227.                     MAX_Y = page_types[set_paper_tray].height;
  228.                     break;
  229.                 }
  230.             }
  231.             if (page_types[set_paper_tray].paper_name[0] == '\0')
  232.             {    fprintf (stderr, "Invalid paper size\n");
  233.                 exit (1);
  234.             }
  235.             i++;
  236.             break;
  237.  
  238.         case 'u':            /* already processed */
  239.             break;
  240.  
  241.         default: ;
  242.         }
  243.     }
  244.  
  245.     UX    =    X_INDENT;
  246.     UY    =    (MAX_Y - Y_INDENT);
  247.     DX    =    (MAX_X - 2 * X_INDENT);
  248.     DY    =    (BIG_POINT * 3);
  249.  
  250.     /*    center text used for userid and job title print  */
  251.     
  252.     send ("%!\n");
  253.     send ("/ctext {     % center text:   string x y dx\n");
  254.     send ("   2 div\n");
  255.     send ("   /Dx exch def\n");
  256.     send ("   /Yv exch def\n");
  257.     send ("   /Xv exch def\n");
  258.     send ("   dup stringwidth pop\n");
  259.     send ("   2 div\n");
  260.     send ("   Dx exch sub\n");
  261.     send ("   Xv add\n");
  262.     send ("   Yv moveto\n");
  263.     send ("   show\n");
  264.     send ("} def\n");
  265.     replacement_fonts();                /*    get font translations */
  266.     send ("%%EndProlog\n");
  267.  
  268.     /*    Uncomment the following code if languange translation is
  269.         needed for the following parameters
  270.     */
  271. /*
  272.     if (need_xlate)
  273.     {    xlate_string (Userid);
  274.         xlate_string (Name);
  275.         xlate_string (Requestid);
  276.         xlate_string (Printer);
  277.         xlate_string (Options);
  278.         xlate_string (Date);
  279.         xlate_string (Machineid);
  280.         xlate_string (Title);
  281.     }
  282. */
  283.     send ("%%Page: ? 1\n");
  284.     if (set_paper_bin)
  285.         printf ("%s\n", slots[set_paper_bin-1]);
  286.  
  287.     if (set_paper_tray >= 0)
  288.         printf ("%s\n", page_types[set_paper_tray].paper_tray);
  289.         
  290.     send ("/pg save def\n");
  291.  
  292.     /*    draw a box for the userid */
  293.     
  294.     printf ("newpath\n");
  295.     printf ("%d %d moveto\n", UX,UY);
  296.     printf ("%d %d rlineto\n", DX, 0);
  297.     printf ("%d %d rlineto\n", 0, -DY);
  298.     printf ("%d %d rlineto\n", -DX, 0);
  299.     printf ("closepath\n");
  300.     printf ("4 setlinewidth\n");
  301.     printf ("stroke\n");
  302.  
  303.     /*    center the userid and the job title */
  304.     
  305.     y = UY - DY / 2 - BIG_POINT / 2;
  306.     printf (FONT1, BIG_POINT);
  307.     printf ("(%s) %d %d %d ctext\n", Userid, X_INDENT, y, DX);
  308.  
  309.     y = UY - (DY + MED_POINT * 3);
  310.     printf (FONT2, MED_POINT);
  311.     printf ("(%s) %d %d %d ctext\n", Title, X_INDENT, y, DX);
  312.  
  313.     /*    print other banner page parameters */
  314.     
  315.     x = X_INDENT;
  316.     y -= (MED_POINT * 2);
  317.     printf ("%d %d moveto\n", x,y);    
  318.     sendnormal ("User:       ");
  319.     sendbold (Name);
  320.  
  321.     y -= SMALL_POINT + (SMALL_POINT / 2);
  322.     printf ("%d %d moveto\n", x,y);    
  323.     sendnormal ("Request ID: ");
  324.     sendbold (Requestid);
  325.     
  326.     y -= SMALL_POINT + (SMALL_POINT / 2);
  327.     printf ("%d %d moveto\n", x,y);    
  328.     sendnormal ("Printer ID: ");
  329.     sendbold (Printer);
  330.     
  331.     y -= SMALL_POINT + (SMALL_POINT / 2);
  332.     printf ("%d %d moveto\n", x,y);    
  333.     sendnormal ("Options:    ");
  334.     sendbold (Options);
  335.     
  336.     y -= SMALL_POINT + (SMALL_POINT / 2);
  337.     printf ("%d %d moveto\n", x,y);    
  338.     sendnormal ("Date:       ");
  339.     sendbold (Date);
  340.     
  341.     y -= SMALL_POINT + (SMALL_POINT / 2);
  342.     printf ("%d %d moveto\n", x,y);    
  343.     sendnormal ("Machine:    ");
  344.     sendbold (Machineid);
  345.  
  346.     send ("showpage pg restore\n");
  347.     send ("%%Trailer\n");    
  348.     exit (0);
  349. }
  350.  
  351.  
  352. /****************************************************************************
  353. *    send font selection information and text.                                *
  354. ****************************************************************************/
  355.  
  356. send (s)
  357. char    *s;
  358. {
  359.     while (*s)
  360.         fputc (*s++, outfp);
  361. }
  362.  
  363. sendnormal (s)
  364. char     *s;
  365. {
  366.     printf (FONT3, SMALL_POINT);
  367.     send ("(");
  368.     send (s);
  369.     send (")show\n");
  370. }
  371.  
  372. sendbold (s)
  373. char     *s;
  374. {
  375.     printf (FONT4, SMALL_POINT);
  376.     send ("(");
  377.     send (s);
  378.     send (")show\n");
  379. }
  380.  
  381. /****************************************************************************
  382. *    trim ()                                                                    *
  383. *    trucate garbage                                                            *
  384. ****************************************************************************/
  385.  
  386. void trim (s)                    /*    trim trailing blanks  and \n */
  387. char    *s;
  388. {    int many;
  389.  
  390.     for (many = strlen (s) - 1;  many >= 0;  many--)
  391.     {    if (isgraph (s[many]))
  392.             break;
  393.         else
  394.             s[many] = '\0';
  395.     }
  396. }
  397.  
  398. /****************************************************************************
  399. *    bad_file()                                                                *
  400. ****************************************************************************/
  401.  
  402. bad_file()
  403. {
  404.     fprintf (stderr, "Bad %s file\n", defref);
  405.     exit (1);
  406. }
  407.  
  408. /****************************************************************************
  409. *    compare ()                                                                *
  410. *    partial compare of two strings.                                            *
  411. ****************************************************************************/
  412.  
  413. compare (a,b)
  414. char    *a, *b;
  415. {    int    aa, bb;
  416.  
  417.     while (*a  &&  *b)
  418.     {    aa = *a++;
  419.         bb = *b++;
  420.         if (UCCHAR (aa)  !=  UCCHAR (bb))
  421.             return (aa - bb);
  422.     }
  423.     return (0);
  424. }
  425.  
  426.  
  427. /****************************************************************************
  428. *    replacement_fonts()                                                        *
  429. *    read the text translation strings only.                                    *
  430. ****************************************************************************/
  431.  
  432. replacement_fonts ()
  433. {    int        found, xold, xnew;
  434.     char    line[201];
  435.     char    *x;
  436.  
  437.     if (pdef == NULL)
  438.         return;
  439.     found = 0;
  440.     while (fgets (line, 200, pdef))        /*    skip printer name     */
  441.     {    if (strncmp (line, "%%PsfStart", 10) == 0)
  442.         {    found = 1;
  443.             break;
  444.         }
  445.     }
  446.     if (found)
  447.     {    while (fgets (line, 200, pdef))            /*    read fonts, translate */
  448.         {    if (strncmp (line, "%%PsfEnd", 8) == 0)
  449.                 break;
  450.             if (strncmp (line, "%%translate",  11) == 0)
  451.             {    x = strtok (line + 11, " ");
  452.                 do
  453.                 {    xold = otoi (x) % 256;
  454.                     xnew = otoi (x+4) % 256;
  455.                     xlate[xold] = xnew;
  456.                 } while (x = strtok (NULL, " "));
  457.                 need_xlate = 1;
  458.             }
  459.         }
  460.         fclose (pdef);
  461.         pdef = NULL;
  462.     }
  463.     else
  464.     {    fclose (pdef);
  465.         pdef = NULL;
  466.     }
  467.     return;
  468. }
  469.  
  470. /****************************************************************************
  471. *    octal to integer                                                        *
  472. ****************************************************************************/
  473.  
  474. int    otoi (s)
  475. char    *s;
  476. {
  477.     int        v, p, quit;
  478.  
  479.     v = 0;
  480.     while (*s == ' ')
  481.         s++;
  482.     quit = 0;
  483.     while (*s)
  484.     {    switch (*s)
  485.         {
  486.         case '0':    p = 0;  break;
  487.         case '1':    p = 1;  break;
  488.         case '2':    p = 2;  break;
  489.         case '3':    p = 3;  break;
  490.         case '4':    p = 4;  break;
  491.         case '5':    p = 5;  break;
  492.         case '6':    p = 6;  break;
  493.         case '7':    p = 7;  break;
  494.         default:    quit = 1;
  495.         }
  496.         if (quit)
  497.             break;
  498.         v = (v << 3) + p;
  499.     }
  500.     return (v);
  501. }
  502.  
  503.  
  504. /****************************************************************************
  505. *    xlate_string ()                                                            *
  506. *    translate the string according to the language translation vector        *
  507. ****************************************************************************/
  508. xlate_string (s)
  509. unsigned char    *s;
  510. {
  511.     int    sold;
  512.     
  513.     while (*s)
  514.     {    sold = *s;
  515.         *s = xlate[sold];
  516.         s++;
  517.     }
  518. }
  519.  
  520.  
  521. /****************************************************************************
  522. *    usage()                                                                    *
  523. ****************************************************************************/
  524. usage ()
  525. {
  526.     fprintf (stderr, "Usage:  psfbanner Userid Name Requestid Printer Options Date\n");
  527.     fprintf (stderr, "                   Machineid Title [-b n] [-g size] [-u f.def]\n");
  528.     fprintf (stderr, "        where:   Userid, Name, etc are passed by lpsched\n");
  529.     fprintf (stderr, "                 -b n    = select paper bin n\n");
  530.     fprintf (stderr, "                 -g size = select paper size (letter, b5, etc)\n");
  531.     fprintf (stderr, "                -u f.def = use this printer definition file\n");    
  532.     exit (1);
  533. }        
  534.