home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 125.img / PRO-C4.ZIP / BENCH1.ZIP / PRINT / FLUSH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-28  |  26.4 KB  |  895 lines

  1. /***( flush.c )*****************************************************************
  2. *                                                                              *
  3. *  Written: Brent Faulkner - June 19, 1989                                     *
  4. *  Updated: Brent Faulkner - June 19, 1989                                     *
  5. *                                                                              *
  6. ********************************************************************************
  7. *                                                                              *
  8. * Contents:    flushprt() - flush the buffers to the printer                   *
  9. *                outlen() - return output length of line                       *
  10. *                                                                              *
  11. *******************************************************************************/
  12. #include <stdio.h>
  13. #include <bench.h>
  14. #include "prt.h"
  15.  
  16. #ifdef ANSI
  17. static int do_attr(int, int);
  18. static int outlen(char *, int);
  19. static void flush1(void);
  20. static void flush2(void);
  21. static void ps_attr(int, int);
  22. static void ps_comment(char *, ...);
  23. static void ps_line(char *, ...);
  24. #else
  25. static int do_attr();
  26. static int outlen();
  27. static void flush1();
  28. static void flush2();
  29. static void ps_attr();
  30. static void ps_comment();
  31. static void ps_line();
  32. #endif
  33.  
  34. #define ps_skip()    fputs("\015\012", devfp)
  35.  
  36. /*
  37.  * Flush the page buffers to the printer device
  38. */
  39. void flushprt()
  40. {
  41.     if (prtdef[POSTSCRIPT] == NULL)
  42.         flush1();  /* standard (non-postscript) printer */
  43.     else
  44.         flush2();  /* postscript printer */
  45. }
  46.  
  47. static void flush1()
  48. {
  49.     int i;
  50.     register int j;
  51.     int oldattr = P_DUMMY;
  52.  
  53.     /* for each line */
  54.     for(i = 0; i < (unsigned char)*prtdef[NUM_LINES]; i++)
  55.     {
  56.         /* for each column */
  57.         for(j = 0; j < outlen(pagebuff[i], (unsigned char)*prtdef[NUM_COLS]); j++)
  58.         {
  59.             /* change attribute if required */
  60.             oldattr = do_attr(oldattr, attrbuff[i][j]);
  61.             /* do underline if it isn't defined but BS is */
  62.             if((attrbuff[i][j] & P_UNDER) && prtdef[UNDER_ON] == NULL)
  63.             {
  64.                 if (prtdef[BS] != NULL)
  65.                 {
  66.                     fputc('_', devfp);
  67.                     emit_seq(BS);
  68.                 }
  69.             }
  70.             /* overstrike for BOLD if it isn't defined but BS is */
  71.             if((attrbuff[i][j] & P_BOLD) && prtdef[BOLD_ON] == NULL)
  72.             {
  73.                 if (prtdef[BS] != NULL && pagebuff[i][j] != '\0')    
  74.                 {
  75.                     fputc(pagebuff[i][j], devfp);
  76.                     emit_seq(BS);
  77.                 }
  78.             }
  79.             /* overstrike for LQ if it isn't defined but BS is */
  80.             if((attrbuff[i][j] & P_LQ) && prtdef[LQ_ON] == NULL)
  81.             {
  82.                 if(pagebuff[i][j] != '\0')
  83.                 {
  84.                     fputc(pagebuff[i][j], devfp);
  85.                     emit_seq(BS);
  86.                 }
  87.             }
  88.                 
  89.             /* output character */
  90.             if(pagebuff[i][j] == '\0')
  91.                 fputc(' ', devfp);
  92.             else
  93.                 fputc(pagebuff[i][j], devfp);
  94.         }
  95.         if (prtdef[ATTR_REFRESH] != NULL)
  96.         {
  97.             do_attr(oldattr, P_DUMMY);
  98.             oldattr = P_DUMMY;
  99.         }
  100.         emit_seq(LINEFEED);     /* do the line feed */
  101.     }
  102.     if (prtdef[ATTR_REFRESH] == NULL)
  103.         do_attr(oldattr, P_DUMMY);
  104. }
  105.  
  106. /*
  107.  * Return the output length of a line
  108.  * ie. the number of characters on a line not counting trailing spaces
  109.  *     or \0's
  110. */
  111. static int outlen(outstr, outsiz)
  112. char *outstr;
  113. int outsiz;
  114. {
  115.     register int i;
  116.  
  117.     for(i = outsiz; i > 0; i--)
  118.         if(outstr[i - 1] != '\0' && outstr[i - 1] != ' ')
  119.             break;
  120.  
  121.     return(i);
  122. }
  123.  
  124. /*
  125.  * Output any sequences for a change in attributes
  126. */
  127. static int do_attr(oatt, natt)
  128. int oatt;
  129. int natt;
  130. {
  131.     int i;
  132.     register int tbit;
  133.     int tatt;
  134.  
  135.     tatt = natt ^ oatt;     /* find any changed attributes */
  136.     /* for each changed attribute turn off if on and on if off */
  137.     for(i = 0; i < 16; i++)
  138.     {
  139.         tbit = 1 << i;
  140.         if(tatt & tbit)
  141.         {
  142.             switch(tbit)
  143.             {
  144.                 case P_ITALIC:             /* 0x0001 */
  145.                     if (natt & P_ITALIC)
  146.                         emit_seq(ITALIC_ON);
  147.                     else
  148.                         emit_seq(ITALIC_OFF);
  149.                     break;
  150.                 case P_BOLD:               /* 0x0002 */
  151.                     if (natt & P_BOLD)
  152.                         emit_seq(BOLD_ON);
  153.                     else
  154.                         emit_seq(BOLD_OFF);
  155.                     break;
  156.                 case P_UNDER:              /* 0x0004 */
  157.                     if (natt & P_UNDER)
  158.                         emit_seq(UNDER_ON);
  159.                     else
  160.                         emit_seq(UNDER_OFF);
  161.                     break;
  162.                 case P_LQ:                 /* 0x0008 */
  163.                     if (natt & P_LQ)
  164.                         emit_seq(LQ_ON);
  165.                     else
  166.                         emit_seq(LQ_OFF);
  167.                     break;
  168.                 case P_PS:                 /* 0x0010 */
  169.                     if (natt & P_PS)
  170.                         emit_seq(PS_ON);
  171.                     else
  172.                         emit_seq(PS_OFF);
  173.                     break;
  174.                 case P_SUBSCRIPT:          /* 0x0020 */
  175.                     if (natt & P_SUBSCRIPT)
  176.                         emit_seq(SUBSCRIPT_ON);
  177.                     else
  178.                         emit_seq(SUBSCRIPT_OFF);
  179.                     break;
  180.                 case P_SUPERSCRIPT:        /* 0x0040 */
  181.                     if (natt & P_SUPERSCRIPT)
  182.                         emit_seq(SUPERSCRIPT_ON);
  183.                     else
  184.                         emit_seq(SUPERSCRIPT_OFF);
  185.                     break;
  186.                 case P_DBL_WIDE:           /* 0x0080 */
  187.                     if (natt & P_DBL_WIDE)
  188.                         emit_seq(DBL_WIDE_ON);
  189.                     else
  190.                         emit_seq(DBL_WIDE_OFF);
  191.                     break;
  192.                 case P_DBL_HIGH:           /* 0x0100 */
  193.                     if (natt & P_DBL_HIGH)
  194.                         emit_seq(DBL_HIGH_ON);
  195.                     else
  196.                         emit_seq(DBL_HIGH_OFF);
  197.                     break;
  198.                 case P_CONDENSED:          /* 0x0200 */
  199.                     if (natt & P_CONDENSED)
  200.                         emit_seq(CONDENSED_ON);
  201.                     else
  202.                         emit_seq(CONDENSED_OFF);
  203.                     break;
  204.                 case P_CPI5:               /* 0x0400 */
  205.                     if (natt & P_CPI5)
  206.                         emit_seq(CPI5);
  207.                     else
  208.                         emit_seq(CPI10);
  209.                     break;
  210.                 case P_CPI10:              /* 0x0800 */
  211.                     if (natt & P_CPI10)
  212.                         emit_seq(CPI10);
  213.                     else
  214.                         emit_seq(CPI10);
  215.                     break;
  216.                 case P_CPI12:              /* 0x1000 */
  217.                     if (natt & P_CPI12)
  218.                         emit_seq(CPI12);
  219.                     else
  220.                         emit_seq(CPI10);
  221.                     break;
  222.                 case P_CPI16:              /* 0x2000 */
  223.                     if (natt & P_CPI16)
  224.                         emit_seq(CPI16);
  225.                     else
  226.                         emit_seq(CPI10);
  227.                     break;
  228.                 case P_BOX:                /* 0x4000 */
  229.                     if (natt & P_BOX)
  230.                         emit_seq(BOX_ON);
  231.                     else
  232.                         emit_seq(BOX_OFF);
  233.                     break;
  234.             }
  235.         }      
  236.     }
  237.     return(natt);
  238. }
  239.  
  240. static void flush2()
  241. {
  242.     int i;
  243.     int j, J;
  244.     register int k;
  245.     unsigned int oldattr = P_DUMMY;
  246.     char LBUFF[512];
  247.     int aflag = 0;      /* flag for attribute change */
  248.  
  249.     ps_comment("Beginning of Page");    /* page prefix */
  250.     ps_line("/pg save def");
  251.  
  252.     /* for each line */
  253.     for(i = 0; i < (unsigned char)*prtdef[NUM_LINES]; i++)
  254.     {
  255.         /* calculate line length */
  256.         J = outlen(pagebuff[i], (unsigned char)*prtdef[NUM_COLS]);
  257.         if (J > 0)                 /* if line has non-zero length do moveto */
  258.             ps_line("18 %d moveto", 756 - i * 12);
  259.         for(j = 0; j < J;)         /* for each column */
  260.         {
  261.             memset(LBUFF, '\0', 512); /* zero out line buffer */
  262.             for(k = 0; j < J; j++, k++)  /* gather chars with same attribute */
  263.             {
  264.                 if (attrbuff[i][j] != oldattr)
  265.                 {
  266.                     aflag = 1;        /* if the attribute changes set the */
  267.                     break;            /* flag and break out of the loop */
  268.                 }
  269.                                          /* add the char to the line buffer */
  270.                 if (pagebuff[i][j] == '\0')
  271.                     LBUFF[k] = ' ';
  272.                 else
  273.                 {                     /* convert non-printable chars to octal */
  274.                     if(pagebuff[i][j] < 0x20 || pagebuff[i][j] > 0x7e)
  275.                     {
  276.                         int n = pagebuff[i][j];
  277.                    
  278.                         LBUFF[k] = '\\';
  279.                         k++;
  280.                         LBUFF[k] = (char)(0x30 + n / 64);
  281.                         k++;
  282.                         n %= 64;
  283.                         LBUFF[k] = (char)(0x30 + n / 8);
  284.                         k++;
  285.                         n %= 8;
  286.                         LBUFF[k] = (char)(0x30 + n);
  287.                     }
  288.                     else
  289.                     {
  290.                         if (pagebuff[i][j] == '%')
  291.                         {
  292.                             LBUFF[k] = '%';  /* do two percents for a percent */
  293.                             k++;
  294.                             LBUFF[k] = '%';
  295.                         }
  296.                         else
  297.                             LBUFF[k] = pagebuff[i][j];
  298.                     }
  299.                 }
  300.             }
  301.             if (strlen(LBUFF) > 0)
  302.             {
  303.                 if (oldattr & P_DBL_WIDE)    /* call any modifying postscript */
  304.                     ps_line("dbl-width");    /* functions */
  305.                 if (oldattr & P_DBL_HIGH)
  306.                     ps_line("dbl-height");
  307.                 if (oldattr & P_CONDENSED)
  308.                     ps_line("condense");
  309.  
  310.                 if (oldattr & P_UNDER)       /* output the text using show */
  311.                     ps_line("12 (%s) undershow", LBUFF); /* underlined */
  312.                 else
  313.                     ps_line("(%s) show", LBUFF);
  314.  
  315.                 if (oldattr & P_DBL_WIDE)    /* call the complimenting */
  316.                     ps_line("half-width");   /* postscript function for */
  317.                 if (oldattr & P_DBL_HIGH)    /* any modifiers */
  318.                     ps_line("half-height");
  319.                 if (oldattr & P_CONDENSED)
  320.                     ps_line("expand");
  321.             }
  322.             if (aflag)                       /* if an attribute change is */
  323.             {                                /* do any font changes */
  324.                 ps_attr(attrbuff[i][j], oldattr);
  325.                 oldattr = attrbuff[i][j];
  326.                 aflag = 0;
  327.             }
  328.         }
  329.     }
  330.  
  331.     ps_line("showpage pg restore");          /* end of the page */
  332. }
  333.  
  334. static char vpsbuff[512];                    /* buffer for varargs functions */
  335.  
  336. /*
  337.  * Output a postscript comment
  338. */
  339. #ifdef ANSI
  340. static void ps_comment(char *va_alist, ...)
  341. #else
  342. static void ps_comment(va_alist)
  343. va_dcl
  344. #endif
  345. {
  346.     va_list ap;
  347.     register char *fmt;
  348.  
  349. #ifdef ANSI
  350.     va_start(ap, va_alist);
  351.     fmt = va_alist;
  352. #else
  353.     va_start(ap);
  354.     fmt = va_arg(ap, char *);
  355. #endif
  356.  
  357.     vsprintf(vpsbuff, fmt, ap);
  358.     va_end(ap);
  359.  
  360.     fprintf(devfp, "%% %s\015\012", vpsbuff);
  361. }
  362.  
  363. /*
  364.  * Output a line of postscript (other than a comment or a blank line)
  365. */
  366. #ifdef ANSI
  367. static void ps_line(char *va_alist, ...)
  368. #else
  369. static void ps_line(va_alist)
  370. va_dcl
  371. #endif
  372. {
  373.     va_list ap;
  374.     register char *fmt;
  375.  
  376. #ifdef ANSI
  377.     va_start(ap, va_alist);
  378.     fmt = va_alist;
  379. #else
  380.     va_start(ap);
  381.     fmt = va_arg(ap, char *);
  382. #endif
  383.  
  384.     vsprintf(vpsbuff, fmt, ap);
  385.     va_end(ap);
  386.  
  387.     fprintf(devfp, "%s\015\012", vpsbuff);
  388. }
  389.  
  390. /*
  391.  * Output any postscript required for a font change
  392. */
  393. static void ps_attr(nattr, oattr)
  394. int nattr;
  395. int oattr;
  396. {
  397.     char fontname[40];
  398.     static char lastfont[40];
  399.     int fontsize;
  400.     static int lastsize = 0;
  401.     
  402.     if (nattr & P_BOX)                 /* get the initial name for a font */
  403.         strcpy(fontname, "LineChars");
  404.     else if (nattr & P_PS)
  405.         strcpy(fontname, "Helvetica");
  406.     else
  407.         strcpy(fontname, "Courier");
  408.  
  409.     if (nattr & P_BOLD)                /* modify the font name for BOLD */
  410.         strcat(fontname, "-Bold");     /* or ITALIC */
  411.  
  412.     if (nattr & P_ITALIC && !(nattr & P_BOX))
  413.     {
  414.         if (!(nattr & P_BOLD))    
  415.             strcat(fontname, "-");
  416.         strcat(fontname, "Oblique");
  417.     }
  418.  
  419.     if (nattr & P_CPI5)                 /* set the font size required */
  420.         fontsize = 24;
  421.     else if (nattr & P_CPI12)
  422.         fontsize = 10;
  423.     else if (nattr & P_CPI16)
  424.         fontsize = 8;
  425.     else
  426.         fontsize = 12;
  427.  
  428. /* only output the change if really required
  429.  * ie. the attribute may change but the font may not
  430.  *     such as for condensed, etc.
  431. */
  432.     if (lastsize != fontsize || strcmp(lastfont, fontname) != 0)
  433.         ps_line("/%s findfont %d scalefont setfont", fontname, fontsize);
  434.     lastsize = fontsize;
  435.     strcpy(lastfont, fontname);
  436.  
  437. /* do any relative moves required for super/sub scripting */
  438.     if ( ((oattr & P_SUBSCRIPT) && !(nattr & P_SUBSCRIPT)) ||
  439.         (!(oattr & P_SUPERSCRIPT) && (nattr & P_SUPERSCRIPT)) )
  440.         ps_line("0 3 rmoveto");
  441.  
  442.     if ( (!(oattr & P_SUBSCRIPT) && (nattr & P_SUBSCRIPT)) ||
  443.         ((oattr & P_SUPERSCRIPT) && !(nattr & P_SUPERSCRIPT)) )
  444.         ps_line("0 -3 rmoveto");
  445. }
  446.  
  447. /*
  448.  * Output the postscript required by all print jobs
  449.  * ie. define the functions for underline, etc. and define the LineChars
  450.  *     and LineChars-Bold fonts
  451. */
  452. void ps_init()
  453. {
  454.     ps_comment("!PS-Adobe");
  455.     ps_skip();
  456.     ps_line("/undershow {              %% show with underline");
  457.     ps_line("    dup stringwidth pop");
  458.     ps_line("    3 -1 roll");
  459.     ps_line("    uline");
  460.     ps_line("    show");
  461.     ps_line("    } def");
  462.     ps_skip();
  463.     ps_line("/uline {                  %% do the underlining");
  464.     ps_line("    /ps exch def");
  465.     ps_line("    gsave");
  466.     ps_line("    currentfont /FontInfo get dup");
  467.     ps_line("    /UnderlinePosition get ps mul 1000 div 0 exch rmoveto exch 0 rlineto");
  468.     ps_line("    /UnderlineThickness get ps mul 1000 div setlinewidth stroke");
  469.     ps_line("    grestore");
  470.     ps_line("    } def");
  471.     ps_skip();
  472.     ps_line("/dbl-height {             %% double the y-scale");
  473.     ps_line("    1 2 scale");
  474.     ps_line("    } def");
  475.     ps_skip();
  476.     ps_line("/half-height {            %% half the y-scale");
  477.     ps_line("    1 .5 scale");
  478.     ps_line("    } def");
  479.     ps_skip();
  480.     ps_line("/dbl-width {              %% double the x-scale");
  481.     ps_line("    2 1 scale");
  482.     ps_line("    } def");
  483.     ps_skip();
  484.     ps_line("/half-width {             %% half the x-scale");
  485.     ps_line("    .5 1 scale");
  486.     ps_line("    } def");
  487.     ps_skip();
  488.     ps_line("/condense {               %% 2/3 the x-scale");
  489.     ps_line("    2 3 div 1 scale");
  490.     ps_line("    } def");    
  491.     ps_skip();
  492.     ps_line("/expand {                 %% 3/2 the x-scale");
  493.     ps_line("    1.5 1 scale");
  494.     ps_line("    } def");
  495.     ps_skip();
  496.     ps_comment("Define the PC line drawing character set (LineChars),");
  497.     ps_comment("and the bold equivalent (LineChars-Bold).");
  498.     ps_comment("");
  499.     ps_comment("The characters are drawn on a 1000 by 1000 square then the x is");
  500.     ps_comment("scaled by .0006 to make it line up with the courier character set.");
  501.     ps_skip();
  502.     ps_line("10 dict dup begin");
  503.     ps_skip();
  504.     ps_line("/FontType 3 def");
  505.     ps_line("/FontMatrix [.0006 0 0 .001 0 0] def");
  506.     ps_line("/FontBBox [0 0 1000 1000] def");
  507.     ps_line("/Encoding 256 array def");
  508.     ps_line("0 1 255 { Encoding exch /.notdef put } for");
  509.     ps_line("Encoding 16#b0 /shade_block put");
  510.     ps_line("Encoding 16#b3 /vertical put");
  511.     ps_line("Encoding 16#b4 /right_tee put");
  512.     ps_line("Encoding 16#b6 /dsright_tee put");
  513.     ps_line("Encoding 16#b5 /sdright_tee put");
  514.     ps_line("Encoding 16#b7 /sdtop_right put");
  515.     ps_line("Encoding 16#b8 /dstop_right put");
  516.     ps_line("Encoding 16#b9 /dright_tee put");
  517.     ps_line("Encoding 16#ba /dvertical put");
  518.     ps_line("Encoding 16#bb /dtop_right put");
  519.     ps_line("Encoding 16#bc /dbot_right put");
  520.     ps_line("Encoding 16#bd /sdbot_right put");
  521.     ps_line("Encoding 16#be /dsbot_right put");
  522.     ps_line("Encoding 16#bf /top_right put");
  523.     ps_line("Encoding 16#c0 /bot_left put");
  524.     ps_line("Encoding 16#c1 /up_tee put");
  525.     ps_line("Encoding 16#c2 /down_tee put");
  526.     ps_line("Encoding 16#c3 /left_tee put");
  527.     ps_line("Encoding 16#c4 /horizontal put");
  528.     ps_line("Encoding 16#c5 /cross put");
  529.     ps_line("Encoding 16#c6 /sdleft_tee put");
  530.     ps_line("Encoding 16#c7 /dsleft_tee put");
  531.     ps_line("Encoding 16#c8 /dbot_left put");
  532.     ps_line("Encoding 16#c9 /dtop_left put");
  533.     ps_line("Encoding 16#ca /dup_tee put");
  534.     ps_line("Encoding 16#cb /ddown_tee put");
  535.     ps_line("Encoding 16#cc /dleft_tee put");
  536.     ps_line("Encoding 16#cd /dhorizontal put");
  537.     ps_line("Encoding 16#ce /dcross put");
  538.     ps_line("Encoding 16#cf /dsup_tee put");
  539.     ps_line("Encoding 16#d0 /sdup_tee put");
  540.     ps_line("Encoding 16#d1 /dsdown_tee put");
  541.     ps_line("Encoding 16#d2 /sddown_tee put");
  542.     ps_line("Encoding 16#d3 /sdbot_left put");
  543.     ps_line("Encoding 16#d4 /dsbot_left put");
  544.     ps_line("Encoding 16#d5 /dstop_left put");
  545.     ps_line("Encoding 16#d6 /sdtop_left put");
  546.     ps_line("Encoding 16#d7 /sdcross put");
  547.     ps_line("Encoding 16#d8 /dscross put");
  548.     ps_line("Encoding 16#d9 /bot_right put");
  549.     ps_line("Encoding 16#da /top_left put");
  550.     ps_line("Encoding 16#db /solid_block put");
  551.     ps_line("Encoding 16#dc /bot_block put");
  552.     ps_line("Encoding 16#df /top_block put");
  553.     ps_skip();
  554.     ps_line("/CharProcs 45 dict def");
  555.     ps_line("CharProcs begin           %% The functions for each character");
  556.     ps_line("/.notdef {} def");
  557.     ps_line("/solid_block {");
  558.     ps_line("    newpath");
  559.     ps_line("    0 0 moveto 1000 0 lineto 1000 1000 lineto 0 1000 lineto");
  560.     ps_line("    closepath");
  561.     ps_line("    fill");
  562.     ps_line("    } def");
  563.     ps_line("/shade_block {");
  564.     ps_line("    newpath");
  565.     ps_line("    125 0 moveto 250 0 lineto 625 0 moveto 750 0 lineto");
  566.     ps_line("    375 62 moveto 500 62 lineto 875 62 moveto 1000 62 lineto");
  567.     ps_line("    125 124 moveto 250 124 lineto 625 124 moveto 750 124 lineto");
  568.     ps_line("    375 186 moveto 500 186 lineto 875 186 moveto 1000 186 lineto");
  569.     ps_line("    125 248 moveto 250 248 lineto 625 248 moveto 750 248 lineto");
  570.     ps_line("    375 310 moveto 500 310 lineto 875 310 moveto 1000 310 lineto");
  571.     ps_line("    125 372 moveto 250 372 lineto 625 372 moveto 750 372 lineto");
  572.     ps_line("    375 434 moveto 500 434 lineto 875 434 moveto 1000 434 lineto");
  573.     ps_line("    125 496 moveto 250 496 lineto 625 496 moveto 750 496 lineto");
  574.     ps_line("    375 558 moveto 500 558 lineto 875 558 moveto 1000 558 lineto");
  575.     ps_line("    125 620 moveto 250 620 lineto 625 620 moveto 750 620 lineto");
  576.     ps_line("    375 682 moveto 500 682 lineto 875 682 moveto 1000 682 lineto");
  577.     ps_line("    125 744 moveto 250 744 lineto 625 744 moveto 750 744 lineto");
  578.     ps_line("    375 806 moveto 500 806 lineto 875 806 moveto 1000 806 lineto");
  579.     ps_line("    125 868 moveto 250 868 lineto 625 868 moveto 750 868 lineto");
  580.     ps_line("    375 930 moveto 500 930 lineto 875 930 moveto 1000 930 lineto");
  581.     ps_line("    stroke");
  582.     ps_line("    } def");
  583.     ps_line("/horizontal {");
  584.     ps_line("    newpath");
  585.     ps_line("    0 500 moveto 1000 500 lineto");
  586.     ps_line("    stroke");
  587.     ps_line("    } def");
  588.     ps_line("/dhorizontal {");
  589.     ps_line("    newpath");
  590.     ps_line("    0 500 moveto 1000 500 lineto");
  591.     ps_line("    0 700 moveto 1000 700 lineto");
  592.     ps_line("    stroke");
  593.     ps_line("    } def");
  594.     ps_line("/vertical {");
  595.     ps_line("    newpath");
  596.     ps_line("    500 0 moveto 500 1000 lineto");
  597.     ps_line("    stroke");
  598.     ps_line("    } def");
  599.     ps_line("/dvertical {");
  600.     ps_line("    newpath");
  601.     ps_line("    400 0 moveto 400 1000 lineto");
  602.     ps_line("    600 0 moveto 600 1000 lineto");
  603.     ps_line("    stroke");
  604.     ps_line("    } def");
  605.     ps_line("/cross {");
  606.     ps_line("    newpath");
  607.     ps_line("    0 500 moveto 1000 500 lineto");
  608.     ps_line("    500 0 moveto 500 1000 lineto");
  609.     ps_line("    stroke");
  610.     ps_line("    } def");
  611.     ps_line("/dcross {");
  612.     ps_line("    newpath");
  613.     ps_line("    0 500 moveto 400 500 lineto 400 0 lineto");
  614.     ps_line("    0 700 moveto 400 700 lineto 400 1000 lineto");
  615.     ps_line("    600 0 moveto 600 500 lineto 1000 500 lineto");
  616.     ps_line("    600 1000 moveto 600 700 lineto 1000 700 lineto");
  617.     ps_line("    stroke");
  618.     ps_line("    } def");
  619.     ps_line("/dscross {");
  620.     ps_line("    newpath");
  621.     ps_line("    0 500 moveto 1000 500 lineto");
  622.     ps_line("    0 700 moveto 1000 700 lineto");
  623.     ps_line("    500 0 moveto 500 1000 lineto");
  624.     ps_line("    stroke");
  625.     ps_line("    } def");
  626.     ps_line("/top_left {");
  627.     ps_line("    newpath");
  628.     ps_line("    500 0 moveto 500 500 lineto 1000 500 lineto");
  629.     ps_line("    stroke");
  630.     ps_line("    } def");
  631.     ps_line("/dtop_left {");
  632.     ps_line("    newpath");
  633.     ps_line("    400 0 moveto 400 700 lineto 1000 700 lineto");
  634.     ps_line("    600 0 moveto 600 500 lineto 1000 500 lineto");
  635.     ps_line("    stroke");
  636.     ps_line("    } def");
  637.     ps_line("/dstop_left {");
  638.     ps_line("    newpath");
  639.     ps_line("    500 0 moveto 500 700 lineto 1000 700 lineto");
  640.     ps_line("    500 500 moveto 1000 500 lineto");
  641.     ps_line("    stroke");
  642.     ps_line("    } def");
  643.     ps_line("/sdtop_left {");
  644.     ps_line("    newpath");
  645.     ps_line("    400 0 moveto 400 500 lineto 1000 500 lineto");
  646.     ps_line("    600 0 moveto 600 500 lineto");
  647.     ps_line("    stroke");
  648.     ps_line("    } def");
  649.     ps_line("/top_right {");
  650.     ps_line("    newpath");
  651.     ps_line("    0 500 moveto 500 500 lineto 500 0 lineto");
  652.     ps_line("    stroke");
  653.     ps_line("    } def");
  654.     ps_line("/sdtop_right {");
  655.     ps_line("    newpath");
  656.     ps_line("    400 500 moveto 400 0 lineto");
  657.     ps_line("    0 500 moveto 600 500 lineto 600 0 lineto");
  658.     ps_line("    stroke");
  659.     ps_line("    } def");
  660.     ps_line("/dtop_right {");
  661.     ps_line("    newpath");
  662.     ps_line("    0 700 moveto 600 700 lineto 600 0 lineto");
  663.     ps_line("    0 500 moveto 400 500 lineto 400 0 lineto");
  664.     ps_line("    stroke");
  665.     ps_line("    } def");
  666.     ps_line("/bot_right {");
  667.     ps_line("    newpath");
  668.     ps_line("    0 500 moveto 500 500 lineto 500 1000 lineto");
  669.     ps_line("    stroke");
  670.     ps_line("    } def");
  671.     ps_line("/dbot_right {");
  672.     ps_line("    newpath");
  673.     ps_line("    0 700 moveto 400 700 lineto 400 1000 lineto");
  674.     ps_line("    0 500 moveto 600 500 lineto 600 1000 lineto");
  675.     ps_line("    stroke");
  676.     ps_line("    } def");
  677.     ps_line("/sdbot_right {");
  678.     ps_line("    newpath");
  679.     ps_line("    400 500 moveto 400 1000 lineto");
  680.     ps_line("    0 500 moveto 600 500 lineto 600 1000 lineto");
  681.     ps_line("    stroke");
  682.     ps_line("    } def");
  683.     ps_line("/bot_left {");
  684.     ps_line("    newpath");
  685.     ps_line("    500 1000 moveto 500 500 lineto 1000 500 lineto");
  686.     ps_line("    stroke");
  687.     ps_line("    } def");
  688.     ps_line("/dbot_left {");
  689.     ps_line("    newpath");
  690.     ps_line("    600 1000 moveto 600 700 lineto 1000 700 lineto");
  691.     ps_line("    400 1000 moveto 400 500 lineto 1000 500 lineto");
  692.     ps_line("    stroke");
  693.     ps_line("    } def");
  694.     ps_line("/dsbot_left {");
  695.     ps_line("    newpath");
  696.     ps_line("    500 700 moveto 1000 700 lineto");
  697.     ps_line("    500 1000 moveto 500 500 lineto 1000 500 lineto");
  698.     ps_line("    stroke");
  699.     ps_line("    } def");
  700.     ps_line("/dsbot_right {");
  701.     ps_line("    newpath");
  702.     ps_line("    500 700 moveto 0 700 lineto");
  703.     ps_line("    500 1000 moveto 500 500 lineto 0 500 lineto");
  704.     ps_line("    stroke");
  705.     ps_line("    } def");
  706.     ps_line("/dstop_right {");
  707.     ps_line("    newpath");
  708.     ps_line("    0 700 moveto 500 700 lineto 500 0 lineto");
  709.     ps_line("    500 500 lineto 0 500 lineto");
  710.     ps_line("    stroke");
  711.     ps_line("    } def");
  712.     ps_line("/sdbot_left {");
  713.     ps_line("    newpath");
  714.     ps_line("    400 1000 moveto 400 500 lineto 1000 500 lineto");
  715.     ps_line("    600 1000 moveto 600 500 lineto");
  716.     ps_line("    stroke");
  717.     ps_line("    } def");
  718.     ps_line("/left_tee {");
  719.     ps_line("    newpath");
  720.     ps_line("    500 0 moveto 500 1000 lineto 500 500 moveto 1000 500 lineto");
  721.     ps_line("    stroke");
  722.     ps_line("    } def");
  723.     ps_line("/dleft_tee {");
  724.     ps_line("    newpath");
  725.     ps_line("    400 0 moveto 400 1000 lineto");
  726.     ps_line("    600 0 moveto 600 500 lineto 1000 500 lineto");
  727.     ps_line("    1000 700 moveto 600 700 lineto 600 1000 lineto");
  728.     ps_line("    stroke");
  729.     ps_line("    } def");
  730.     ps_line("/sdleft_tee {");
  731.     ps_line("    newpath");
  732.     ps_line("    500 0 moveto 500 1000 lineto");
  733.     ps_line("    500 500 moveto 1000 500 lineto");
  734.     ps_line("    500 700 moveto 1000 700 lineto");
  735.     ps_line("    stroke");
  736.     ps_line("    } def");
  737.     ps_line("/sdright_tee {");
  738.     ps_line("    newpath");
  739.     ps_line("    0 500 moveto 500 500 lineto");
  740.     ps_line("    0 700 moveto 500 700 lineto");
  741.     ps_line("    500 0 moveto 500 1000 lineto");
  742.     ps_line("    stroke");
  743.     ps_line("    } def");
  744.     ps_line("/dsleft_tee {");
  745.     ps_line("    newpath");
  746.     ps_line("    400 0 moveto 400 1000 lineto 600 0 moveto 600 1000 lineto 600 500 moveto 1000 500 lineto");
  747.     ps_line("    stroke");
  748.     ps_line("    } def");
  749.     ps_line("/sdcross {");
  750.     ps_line("    newpath");
  751.     ps_line("    400 0 moveto 400 1000 lineto 600 0 moveto 600 1000 lineto 0 500 moveto 1000 500 lineto");
  752.     ps_line("    stroke");
  753.     ps_line("    } def");
  754.     ps_line("/right_tee {");
  755.     ps_line("    newpath");
  756.     ps_line("    500 0 moveto 500 1000 lineto 500 500 moveto 0 500 lineto");
  757.     ps_line("    stroke");
  758.     ps_line("    } def");
  759.     ps_line("/dright_tee {");
  760.     ps_line("    newpath");
  761.     ps_line("    600 1000 moveto 600 0 lineto");
  762.     ps_line("    400 1000 moveto 400 700 lineto 0 700 lineto");
  763.     ps_line("    0 500 moveto 400 500 lineto 400 0 lineto");
  764.     ps_line("    stroke");
  765.     ps_line("    } def");
  766.     ps_line("/dsright_tee {");
  767.     ps_line("    newpath");
  768.     ps_line("    600 0 moveto 600 1000 lineto 400 0 moveto 400 1000 lineto 400 500 moveto 0 500 lineto");
  769.     ps_line("    stroke");
  770.     ps_line("    } def");
  771.     ps_line("/up_tee {");
  772.     ps_line("    newpath");
  773.     ps_line("    0 500 moveto 1000 500 lineto 500 500 moveto 500 1000 lineto");
  774.     ps_line("    stroke");
  775.     ps_line("    } def");
  776.     ps_line("/dup_tee {");
  777.     ps_line("    newpath");
  778.     ps_line("    0 700 moveto 400 700 lineto 400 1000 lineto");
  779.     ps_line("    600 1000 moveto 600 700 lineto 1000 700 lineto");
  780.     ps_line("    0 500 moveto 1000 500 lineto");
  781.     ps_line("    stroke");
  782.     ps_line("    } def");
  783.     ps_line("/dsup_tee {");
  784.     ps_line("    newpath");
  785.     ps_line("    0 700 moveto 1000 700 lineto");
  786.     ps_line("    0 500 moveto 1000 500 lineto");
  787.     ps_line("    500 700 moveto 500 1000 lineto");
  788.     ps_line("    stroke");
  789.     ps_line("    } def");
  790.     ps_line("/sdup_tee {");
  791.     ps_line("    newpath");
  792.     ps_line("    0 500 moveto 1000 500 lineto");
  793.     ps_line("    400 500 moveto 400 1000 lineto");
  794.     ps_line("    600 500 moveto 600 1000 lineto");
  795.     ps_line("    stroke");
  796.     ps_line("    } def");
  797.     ps_line("/down_tee {");
  798.     ps_line("    newpath");
  799.     ps_line("    0 500 moveto 1000 500 lineto 500 500 moveto 500 0 lineto");
  800.     ps_line("    stroke");
  801.     ps_line("    } def");
  802.     ps_line("/ddown_tee {");
  803.     ps_line("    newpath");
  804.     ps_line("    0 700 moveto 1000 700 lineto");
  805.     ps_line("    0 500 moveto 400 500 lineto 400 0 lineto");
  806.     ps_line("    600 0 moveto 600 500 lineto 1000 500 lineto");
  807.     ps_line("    stroke");
  808.     ps_line("    } def");
  809.     ps_line("/dsdown_tee {");
  810.     ps_line("    newpath");
  811.     ps_line("    0 500 moveto 1000 500 lineto 500 500 moveto 500 0 lineto");
  812.     ps_line("    0 700 moveto 1000 700 lineto");
  813.     ps_line("    stroke");
  814.     ps_line("    } def");
  815.     ps_line("/sddown_tee {");
  816.     ps_line("    newpath");
  817.     ps_line("    0 500 moveto 1000 500 lineto");
  818.     ps_line("    400 500 moveto 400 0 lineto");
  819.     ps_line("    600 500 moveto 600 0 lineto");
  820.     ps_line("    stroke");
  821.     ps_line("    } def");
  822.     ps_line("/top_block {");
  823.     ps_line("    newpath");
  824.     ps_line("    0 500 moveto 1000 500 lineto 1000 1000 lineto 0 1000 lineto");
  825.     ps_line("    closepath");
  826.     ps_line("    fill");
  827.     ps_line("    } def");
  828.     ps_line("/bot_block {");
  829.     ps_line("    newpath");
  830.     ps_line("    0 500 moveto 1000 500 lineto 1000 0 lineto 0 0 lineto");
  831.     ps_line("    closepath");
  832.     ps_line("    fill");
  833.     ps_line("    } def");
  834.     ps_line("end");
  835.     ps_skip();
  836.     ps_line("/BuildChar {");
  837.     ps_line("    40 setlinewidth");
  838.     ps_line("    1000 0");
  839.     ps_line("    0 0 1000 1000");
  840.     ps_line("    setcachedevice");
  841.     ps_line("    exch");
  842.     ps_line("    begin");
  843.     ps_line("        Encoding exch get");
  844.     ps_line("        CharProcs exch get");
  845.     ps_line("    end");
  846.     ps_line("    exec");
  847.     ps_line("    } def");
  848.     ps_skip();
  849.     ps_line("end");
  850.     ps_skip();
  851.     ps_line("/LineChars exch definefont pop");
  852.     ps_skip();
  853.     ps_comment("Now copy the LineChars font and modify the line width for -Bold");
  854.     ps_line("/makelinecharsbolddict 7 dict def");
  855.     ps_line("/MakeLineChars-BoldFont");
  856.     ps_line("{ makelinecharsbolddict begin");
  857.     ps_skip();
  858.     ps_line("    /linecharsdict /LineChars findfont def");
  859.     ps_skip();
  860.     ps_line("    /numentries linecharsdict maxlength def");
  861.     ps_skip();
  862.     ps_line("    /linecharsbolddict numentries dict def");
  863.     ps_skip();
  864.     ps_line("    linecharsdict");
  865.     ps_line("    { exch dup /FID ne");
  866.     ps_line("        { exch linecharsbolddict 3 1 roll put }    ");
  867.     ps_line("        { pop pop }");
  868.     ps_line("        ifelse");
  869.     ps_line("    } forall");
  870.     ps_skip();
  871.     ps_line("    linecharsbolddict begin");
  872.     ps_line("    /BuildChar {");
  873.     ps_line("        80 setlinewidth");
  874.     ps_line("        1000 0");
  875.     ps_line("        0 0 1000 1000");
  876.     ps_line("        setcachedevice");
  877.     ps_line("        exch");
  878.     ps_line("        begin");
  879.     ps_line("            Encoding exch get");
  880.     ps_line("            CharProcs exch get");
  881.     ps_line("        end");
  882.     ps_line("        exec");
  883.     ps_line("        } def");
  884.     ps_line("    end");
  885.     ps_skip();
  886.     ps_line("    /LineChars-Bold linecharsbolddict definefont pop");
  887.     ps_line("    end");
  888.     ps_line("} def");
  889.     ps_skip();
  890.     ps_line("MakeLineChars-BoldFont");
  891.     ps_skip();
  892.     ps_comment("End of Prolog");
  893.     ps_skip();
  894. }
  895.