home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3938 / hpp.c
Encoding:
C/C++ Source or Header  |  1991-08-30  |  25.0 KB  |  1,184 lines

  1. /*
  2.     Copyright 1989, 1990, 1991 Chris Lewis
  3.     All Rights Reserved
  4.  
  5.     Permission to copy and further distribute is freely given provided
  6.     this copyright notice remains intact, that this software is not
  7.     sold for profit, that credit is given, and that sources will be made
  8.     available on request.
  9.  
  10.     This software is a subset of Psroff 3.0.  See the LICENSE file
  11.     in Psroff 3.0 for more details, or contact:
  12.  
  13.     Chris Lewis
  14.     Box 124
  15.     Dunrobin, Ontario
  16.     Canada K0A 1T0
  17.     (613) 832-0541
  18.  
  19.     Function: interprets HPLJ sequences.
  20.  */
  21.  
  22. #ifndef    lint
  23. static char SCCSID[] =
  24.     "@(#)hpp.c %I% Copyright %E% %U%";
  25. #endif
  26.  
  27. #include "hptopbm.h"
  28.  
  29. #define    XSIZE        (RITE_MARGIN+8)*30
  30. #define    YSIZE        (PAGE_LEN*50)+50
  31.  
  32. #define    dbprintf(x)    if (verbose) printf x
  33. #define    ESCAPE    0x1b
  34.  
  35. #define    TRANSFER    1
  36. #define    TRANSPARENT    2
  37. #define    FONTHEADER    3
  38. #define    DOWNLOAD    4
  39.  
  40. #define    ABSOLUTE    0
  41. #define    RELATIVE    1
  42.  
  43. #define    MAC_BUFSIZE    4096
  44.  
  45. #ifdef    FAXPAK
  46. struct    FAXCONFIG fc;
  47. int    blah = 0;
  48. #endif
  49.  
  50. union    t {
  51.     char a[2];
  52.     short b;
  53. };
  54. int    smallend;
  55.  
  56. typedef int(*FUNC)();
  57.  
  58. int    firstchar = 0;
  59. int    lastchar = 0xff;
  60. int    lastschar;
  61. int    lastfontid = -1;
  62. int    verbose = 0;
  63. int    plotch = 0;
  64. int    rast = 0, rast_org = 0;
  65. int    characteristic = 1;
  66. int    ps_symset = 0;
  67. int    dotted = 0;
  68. int    pbmpage = 0;
  69. int    movetype = 0;
  70. int    mac_ctr = 0;
  71. int    need_mac_end_call = 0;
  72. int    have_auto_macro = -1;
  73. int    builtin = -1;
  74.  
  75. int    ps_pointsize = 10;
  76. int    ps_style = 1;
  77. int    ps_stroke = 0;
  78. int    ps_tface = 5;
  79. int    ps_spacing = 0;
  80. int    genps = 0;
  81.  
  82. FILE    *out = (FILE *) NULL;
  83. FILE    *txtout = (FILE *) NULL;
  84. FILE    *infp = (FILE *) NULL;
  85. char    *PGM;
  86. extern    int errno;
  87.  
  88. char pbmname[256], pbmtname[256];
  89. uchar McBuffer[MAC_BUFSIZE], *CurMc, *CurMc_Ptr, *CurMc_End, *rs_get_macro();
  90.  
  91. double    curX = 0, curY = 0;
  92.  
  93. short    pts[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 4, 4};
  94.  
  95. void    exit();
  96.  
  97. int    (*getchar_func)();
  98. int    getc_only(),        /* get input from file */
  99.     getc_copy(),        /* get it from file AND copy to macro */
  100.     mgetc(),        /* get it from stashed away macro */
  101.     auto_getc();        /* same, but exec on every page */
  102.  
  103. char    *fchcont[] = {
  104.     "Delete all fonts",
  105.     "Delete all temporary fonts",
  106.     "Delete last font ID specified",
  107.     "Delete last font ID and char code",
  108.     "Make Temp font",
  109.     "Make Perm font",
  110.     "Copy/Assign",
  111.     NULL
  112. };
  113.  
  114. char *spcont[] = {
  115.     "Fixed",
  116.     "Proportional",
  117.     NULL
  118. };
  119.  
  120. char *stcont[] = {
  121.     "Upright",
  122.     "Italic",
  123.     NULL
  124. };
  125.  
  126. char *tfcont[] = {
  127.     "Line Printer",
  128.     "Pica",
  129.     "Elite",
  130.     "Courier",
  131.     "Helvetica",
  132.     "Times Roman",
  133.     "Gothic",
  134.     "Script",
  135.     "Prestige Elite",
  136.     "Caslon",
  137.     "Orator",
  138.     NULL
  139. };
  140.  
  141. char *sgcont[] = {
  142.     "Left-most position",
  143.     "Current Cursor",
  144.     NULL
  145. };
  146.  
  147. char *pscont[] = {
  148.     "Disable",
  149.     "Enable",
  150.     NULL
  151. };
  152.  
  153.  
  154. int    movex(),movey(), papinctrl(), movedx(), movedy();
  155. int    spset(), psset(), styset(), strset(), tfset();
  156. int    macro_id(), macro_ctl();
  157. int    rs_lpi(), rs_plen(), rs_mtop(),
  158.     create_fnthdr(), rs_dpi(), rs_graphxy(),
  159.     rs_pitch(), rs_tlen(), rs_mleft(), rs_mright(),
  160.     rs_vmi(), rs_row(), rs_col(), rs_ul(), rs_thru(),
  161.     rs_hmi(), rs_lterm(), rs_setpitch(),
  162.     rs_fc_ctl(), rs_stack(), rs_hsize(), rs_hdsize(),
  163.     rs_vsize(), rs_vdsize(), rs_pid(), rs_prnpat();
  164.  
  165. struct intlist {
  166.     char *code;
  167.     char *name;
  168.     char **parmnames;
  169.     FUNC exec;
  170.     FUNC rastfunc;
  171. } intlist[] = {
  172.  
  173. /*    code    name            parnam    exec    rastfunc   */
  174.  
  175.     {"&lO",    "Orientation"    /* don't want to go into landscaping */ },
  176.     {"(sP",    "Primary Spacing",    spcont, spset },
  177.     {"(sH",    "Primary Pitch",    NULL,    NULL,    rs_pitch },
  178.     {"(sV",    "Primary Point Size",    NULL,    psset },
  179.     {"(sS",    "Primary Style",    stcont,    styset },
  180.     {"(sB",    "Primary Stroke",    NULL,    strset },
  181.     {"(sT",    "Primary Typeface",    tfcont,    tfset },
  182.     {")sP",    "Secondary Spacing",    spcont,    spset },
  183.     {")sH",    "Secondary Pitch" },
  184.     {")sV",    "Secondary Point Size" },
  185.     {")sS",    "Secondary Style",    stcont },
  186.     {")sB",    "Secondary Stroke" },
  187.     {")sT",    "Secondary Typeface" },
  188.     {"&lP",    "Page Length",        NULL,    NULL,    rs_plen },
  189.     {"&lE",    "Top Margin",        NULL,    NULL,    rs_mtop },
  190.     {"&lF",    "Text Length",        NULL,    NULL,    rs_tlen },
  191.     {"&aL",    "Left Margin",        NULL,    NULL,    rs_mleft },
  192.     {"&aM",    "Right Margin",        NULL,    NULL,    rs_mright },
  193.     {"&lC",    "Motion Index",        NULL,    NULL,    rs_vmi },
  194.     {"&lD",    "Lines/Inch",        NULL,    NULL,    rs_lpi },
  195.     {"*tR",    "Resolution",        NULL,    NULL,    rs_dpi },
  196.     {"*rA",    "Start Graphics",    sgcont,    NULL,    rs_graphxy },
  197.     {"*bW",    "Transfer" },
  198.     {"*rB",    "End Graphics" },
  199.     {"&aR",    "Move to Row",        NULL,    NULL,    rs_row },
  200.     {"&aC",    "Move to Column",    NULL,    NULL,    rs_col },
  201.     {"&aH",    "Move to Column (Decipoints)",NULL,movedx },
  202.     {"&aV",    "Move to Row (Decipoints)",NULL,movedy },
  203.     {"&dD",    "Underline on",        NULL,    NULL,    rs_ul },
  204.     {"&d@",    "Underline off",    NULL,    NULL,    rs_ul },
  205.     {"&pX",    "Transparent Print",    NULL,    NULL,    rs_thru },
  206.     {"&lL",    "Perf Skip",         pscont },
  207.     {"&kH",    "HMI",            NULL,    NULL,    rs_hmi },
  208.     {"&kS",    "Font Pitch",        NULL,    NULL,    rs_setpitch },
  209.     {"&kG",    "Line Termination",    NULL,    NULL,    rs_lterm },
  210.     {"&sC",    "Line Wrap" },
  211.     {"&lX",    "Number of Copies" },
  212.     {"&lH",    "Paper Input Control",    NULL,    papinctrl },
  213.     {"*pX",    "Horizontal cursor (dots)",NULL,movex },
  214.     {"*pY",    "Vertical cursor (dots)",NULL,    movey },
  215.     {"*cD",    "Font ID" },
  216.     {"*cE",    "Character Code" },
  217.     {"*cF",    "Font/Char control",    fchcont,NULL,    rs_fc_ctl },
  218.     {")sW",    "Create Font Header" },
  219.     {"(sW",    "Download Character" },
  220.     {"&fY",    "Macro ID",        NULL,    NULL,    macro_id },
  221.     {"&fX",    "Macro control",    NULL,    NULL,    macro_ctl },
  222.     {"&fS",    "Push/Pop",        NULL,    NULL,    rs_stack },
  223.     {"*cA",    "Horizontal Rule/Pattern Size",NULL,NULL, rs_hsize },
  224.     {"*cH",    "Horizontal Rule/Pattern Size",NULL,NULL, rs_hdsize },
  225.     {"*cB",    "Vertical Rule/Pattern Size",NULL,NULL,    rs_vsize },
  226.     {"*cV",    "Vertical Rule/Pattern Size",NULL,NULL,    rs_vdsize },
  227.     {"*cP",    "Print Rule/Pattern"    ,NULL,    NULL,    rs_prnpat },
  228.     {"*cG",    "Grey scale/pattern id",NULL,    NULL,    rs_pid },
  229.     {"&lT",    "Job offset control" },
  230.     {NULL,NULL}
  231. };
  232.  
  233. union {
  234.     struct fontdesc b_fd;
  235.     struct download b_dl;
  236.     char b_buffer[2048];
  237. } buffer;
  238.  
  239. #ifndef    lint
  240. die(va_alist)
  241. va_dcl {
  242.     va_list args;
  243.     char *fmt;
  244.     int e;
  245.  
  246.     e = errno;    /* save him just in case */
  247.     va_start(args);
  248.     fmt = va_arg(args, char *);
  249. #ifndef    LOG
  250.     if (e)
  251.     fprintf(stderr,"%s: {%02d} ", PGM, errno);
  252.     else fprintf(stderr,"%s: ",PGM);
  253.     vfprintf(stderr, fmt, args);
  254. #else
  255.     if (e)
  256.     printf("%s: {%02d} ", PGM, errno);
  257.     else printf("%s: ",PGM);
  258.     vprintf(fmt, args);
  259. #endif
  260.     va_end(args);
  261.     exit(e);
  262. }
  263. #else
  264. /*VARARGS*/
  265. die(){}
  266. #endif
  267.  
  268. getc_only() {
  269.     return(getc(infp));
  270. }
  271.  
  272. getc_copy() {
  273.     int c;
  274.  
  275.     if ((c = getc(infp)) != EOF) {
  276.     McBuffer[mac_ctr++] = c;
  277.     if (mac_ctr == MAC_BUFSIZE) {
  278.         mac_download(MAC_BUFSIZE, McBuffer);
  279.         mac_ctr = 0;
  280.     }
  281.     }
  282.     return(c);
  283. }
  284.  
  285. mgetc() {
  286.     int c;
  287.  
  288.     c = *CurMc_Ptr++;
  289.     if (CurMc_Ptr == CurMc_End) {
  290.     getchar_func = getc_only;
  291.     if (need_mac_end_call) {
  292.         rs_call_macro(RESTORE);
  293.         need_mac_end_call = FALSE;
  294.     }
  295.     }
  296.     return(c);
  297. }
  298.  
  299. auto_getc() {
  300.     if (CurMc_Ptr == CurMc_End)
  301.     return(EOF);
  302.     return(*CurMc_Ptr++);
  303. }
  304.  
  305. readhex(len)
  306. int len; {
  307.     while(len--)
  308.     (void)(*getchar_func)();
  309. }
  310.  
  311. interp(prefix, anchor, number, suffix)
  312. char prefix, anchor, suffix;
  313. double number; {
  314.     int multi;
  315.     register int i;
  316.     char lookup[4];
  317.  
  318.     dbprintf(("ESC%c%c%g%c\n", prefix, anchor, number, suffix));
  319.  
  320.     if (islower(suffix))
  321.     suffix = toupper(suffix);
  322.  
  323.     sprintf(lookup, "%c%c%c", prefix, anchor, suffix);
  324.     for (i = 0; intlist[i].code; i++) {
  325.     if (0 == strcmp(intlist[i].code, lookup)) {
  326.         dbprintf(("%s:", intlist[i].name));
  327.         if (intlist[i].parmnames) {
  328.         int j, ii;
  329.         ii = (int)number;
  330.         for (j = 0; j < ii; j++)
  331.             if (!intlist[i].parmnames[j])
  332.             break;
  333.  
  334.         if (intlist[i].parmnames[j])
  335.             dbprintf((" %s\n", intlist[i].parmnames[j]));
  336.         else
  337.             dbprintf((" %d\n", (int) number));
  338.         }
  339.         else
  340.         dbprintf ((" %g\n", number));
  341.  
  342.         if (intlist[i].exec)
  343.         (*intlist[i].exec)(number);
  344.         if (rast && intlist[i].rastfunc)
  345.         (*intlist[i].rastfunc)(number);
  346.         break;
  347.     }
  348.     }
  349.  
  350.     multi = 0;
  351.     /* For parsing variable length ones */
  352.     switch(prefix) {
  353.     case '*':
  354.         if (anchor == 'b' && suffix == 'W')
  355.         multi = TRANSFER;
  356.         break;
  357.     case '&':
  358.         if (anchor == 'p' && suffix == 'X')
  359.         multi = TRANSPARENT;
  360.         break;
  361.     case ')':
  362.         if (anchor == 's' && suffix == 'W')
  363.         multi = FONTHEADER;
  364.         break;
  365.     case '(':
  366.         if (anchor == 's' && suffix == 'W')
  367.         multi = DOWNLOAD;
  368.         break;
  369.     }
  370.  
  371.     if (prefix == '*' && anchor == 'c' && suffix == 'E')
  372.     lastschar = number;
  373.  
  374.     if (prefix == '*' && anchor == 'c' && suffix == 'D')
  375.     lastfontid = number;
  376.     if (multi)
  377.     readdesc(multi, (int) number);
  378. }
  379.  
  380. short canon(v)
  381. short v; {
  382.     if (smallend)
  383.     return(((v & 0xff) << 8) | ((v&0xff00) >> 8));
  384.     return(v);
  385. }
  386.  
  387. readdesc(type, bytecount)
  388. int type; int bytecount; {
  389.     int points;
  390.     char *typeface;
  391.     char *style;
  392.     char filename[1000];
  393.  
  394.     switch(type) {
  395.  
  396.     default:
  397.         readhex(bytecount);
  398.         break;
  399.     case DOWNLOAD:
  400.         if (fread((char *) &buffer, 1, bytecount, infp) != bytecount)
  401.         die("fread error in readdesc\n");
  402.  
  403.         if ((!rast) && (builtin < 0)) {
  404.         sprintf(filename, BINFILE, lastfontid);
  405.         if (out)
  406.             fclose(out);
  407.         if ((out = fopen(filename, "a")) == NULL)
  408.             die("can't open %s\n", filename);
  409.  
  410.         sprintf(filename, DESCFILE, lastfontid);
  411.         if (txtout)
  412.             fclose(txtout);
  413.         if ((txtout = fopen(filename, "a")) == NULL)
  414.             die("can't open %s\n", filename);
  415.         }
  416.  
  417.         if (lastschar >= firstchar && lastschar <= lastchar) {
  418.         if (txtout) {
  419.             fprintf(txtout, "Character: %c\n", lastschar);
  420.             fprintf(txtout, "  orientation: %d\n",
  421.             buffer.b_dl.dl_orientation);
  422.             fprintf(txtout, "  leftoffset: %d\n",
  423.             canon(buffer.b_dl.dl_leftoffset));
  424.             fprintf(txtout, "  topoffset: %d\n",
  425.             canon(buffer.b_dl.dl_topoffset));
  426.             fprintf(txtout, "  charwidth: %d\n",
  427.             canon(buffer.b_dl.dl_charwidth));
  428.             fprintf(txtout, "  charheight: %d\n",
  429.             canon(buffer.b_dl.dl_charheight));
  430.             fprintf(txtout, "  deltax: %d\n",
  431.             canon(buffer.b_dl.dl_deltax));
  432. #ifdef    PLOT
  433.             if (plotch)
  434.             plotchars(txtout, &buffer.b_dl);
  435. #endif
  436.         }
  437.         }
  438.  
  439.         if ((!rast) && out) {
  440.         fprintf(out, "\033*c%dE", lastschar);
  441.         fprintf(out, "\033(s%dW", bytecount);
  442.         if (fwrite((char *) &buffer, 1, bytecount, out) != bytecount)
  443.             die("fwrite error in readdesc\n");
  444.         }
  445.         if (rast)
  446.         char_download(lastschar,lastfontid,
  447.             (int)canon(buffer.b_dl.dl_leftoffset),
  448.             (int)canon(buffer.b_dl.dl_topoffset),
  449.             (int)canon(buffer.b_dl.dl_charwidth),
  450.             (int)canon(buffer.b_dl.dl_charheight),
  451.             (int)canon(buffer.b_dl.dl_deltax),
  452.             (uchar*)&buffer);
  453.         break;
  454.  
  455.     case FONTHEADER:
  456.         if (txtout)
  457.         fclose(txtout);
  458.         if (out)
  459.         fclose(out);
  460.  
  461.         if (fread((char *) &buffer, 1, bytecount, infp) != bytecount)
  462.         die("fread error in readdesc");
  463.  
  464.         points = (double) canon(buffer.b_fd.fd_height) * 72 / 4 / 300 + .5;
  465.  
  466.         switch(buffer.b_fd.fd_typeface) {
  467.  
  468.         case 0: typeface = "Line Printer"; break;
  469.         case 1: typeface = "Pica"; break;
  470.         case 2: typeface = "Elite"; break;
  471.         case 3: typeface = "Courier"; break;
  472.         case 4: typeface = "Helvetica"; break;
  473.         case 5: typeface = "Times-Roman"; break;
  474.         case 6: typeface = "Gothic"; break;
  475.         case 7: typeface = "Script"; break;
  476.         case 8: typeface = "Prestige"; break;
  477.         case 9: typeface = "Caslon"; break;
  478.         case 10: typeface = "Orator"; break;
  479.         default: typeface = "               ";
  480.             sprintf(typeface, "T%d", buffer.b_fd.fd_typeface);
  481.             break;
  482.         }
  483.         switch(buffer.b_fd.fd_style) {
  484.  
  485.         case 0:    style = "Upright";    break;
  486.         case 1: style = "Italic";    break;
  487.  
  488.         }
  489.  
  490.         if ((!rast) && (builtin < 0)) {
  491.  
  492.         sprintf(filename, BINFILE, lastfontid);
  493.         if ((out = fopen(filename, "w")) == NULL)
  494.             die("can't open %s\n", filename);
  495.  
  496.         sprintf(filename, DESCFILE, lastfontid);
  497.         if ((txtout = fopen(filename, "w")) == NULL)
  498.             die("can't open %s\n", filename);
  499.  
  500.         fprintf(out, "\033)s%dW", bytecount);
  501.         if (fwrite((char *) &buffer, 1, bytecount, out) != bytecount)
  502.             die("fwrite error in readdesc\n");
  503.  
  504.         if (txtout) {
  505.             fprintf(txtout, "Height: %d\n", canon(buffer.b_fd.fd_height));
  506.             fprintf(txtout, "  Points (rounded): %d\n", points);
  507.             fprintf(txtout, "  Points (floating): %.2f\n",
  508.             (double) canon(buffer.b_fd.fd_height) * 72 / 4 / 300);
  509.             fprintf(txtout, "Pitch: %d\n", canon(buffer.b_fd.fd_pitch));
  510.             fprintf(txtout, "  Pitch (chars/inch): %d\n",
  511.             4 * 300 / canon(buffer.b_fd.fd_pitch));
  512.             if (buffer.b_fd.fd_fixedprop)
  513.             fprintf(txtout, "Proportional width font\n");
  514.             else fprintf(txtout, "Fixed width font\n");
  515.             fprintf(txtout, "Stroke weight: %d\n", buffer.b_fd.fd_weight);
  516.             fprintf(txtout, "Style: %d; (%s)\n", buffer.b_fd.fd_style,
  517.             style);
  518.             fprintf(txtout, "Typeface: %d; (%s)\n", buffer.b_fd.fd_typeface,
  519.             typeface);
  520.             fprintf(txtout, "Symset: %04x; (%d%c)\n",
  521.             canon(buffer.b_fd.fd_symset),
  522.             canon(buffer.b_fd.fd_symset) >> 5,
  523.             (canon(buffer.b_fd.fd_symset) & 0x1f) + 'A' - 1);
  524.  
  525.             fprintf(txtout, "Type: %x\n", buffer.b_fd.fd_type);
  526.             fprintf(txtout, "Base: %d\n", canon(buffer.b_fd.fd_base));
  527.             fprintf(txtout, "Cellwidth: %d\n", canon(buffer.b_fd.fd_cellwidth));
  528.             fprintf(txtout, "Cellheight: %d\n", canon(buffer.b_fd.fd_cellheight));
  529.             fprintf(txtout, "Orientation: %d\n", buffer.b_fd.fd_orientation);
  530.             fprintf(txtout, "Height: %d\n", canon(buffer.b_fd.fd_height));
  531.         }
  532.         } else { /* convert to dots moved per char */
  533.         create_fnthdr(
  534.             (int)buffer.b_fd.fd_orientation,
  535.             (int)canon(buffer.b_fd.fd_symset),
  536.             (int)buffer.b_fd.fd_fixedprop,
  537.             (int)canon(buffer.b_fd.fd_pitch),
  538.             (int)buffer.b_fd.fd_style,
  539.             (int)buffer.b_fd.fd_weight,
  540.             (int)buffer.b_fd.fd_typeface,
  541.             ((double) canon(buffer.b_fd.fd_height) * 72 / 4 / 300));
  542.         }
  543.         break;
  544.     case TRANSFER:
  545.         if (fread((char *) &buffer, 1, bytecount, infp) != bytecount)
  546.         die("fread error in readdesc\n");
  547.         if (rast)
  548.         rs_pix((uchar*)&buffer, bytecount);
  549.     }
  550. }
  551.  
  552. /*    We've got ESC<prefix><anchor>
  553.  *    read number/suffix pairs
  554.  */
  555. multisequence(prefix, anchor)
  556. char prefix, anchor;
  557. {
  558.     int c, neg, seendot;
  559.     double v;
  560.  
  561.     for (;;) {
  562.     v = 0;
  563.     seendot = 0;
  564.     neg = 1;
  565.     movetype = ABSOLUTE;
  566.     while (isdigit(c = (*getchar_func)()) ||
  567.         (c == '.') || (c == '-') || (c == '+')) {
  568.  
  569.         if (c == '+') {
  570.         movetype = RELATIVE;
  571.         continue;
  572.         }
  573.  
  574.         if (c == '.') {
  575.         seendot = 10;
  576.         continue;
  577.         }
  578.  
  579.         if (c == '-') {
  580.         neg *= -1;
  581.         movetype = RELATIVE;
  582.         continue;
  583.         }
  584.  
  585.         if (seendot) {
  586.         v += (double) (c - '0') / seendot;
  587.         seendot *= 10;
  588.         }
  589.         else
  590.         v = v * 10 + c - '0';
  591.  
  592.     }
  593.     v *= neg;
  594.     interp(prefix, anchor, v, c);
  595.     if (!islower(c))
  596.         break;
  597.     }
  598.     movetype = ABSOLUTE;
  599. }
  600.  
  601. readescape() {
  602.     int c, v;
  603.  
  604.     c = (*getchar_func)();
  605.     switch(c) {
  606.     case '9':
  607.         dbprintf(("Clear Margins\n"));
  608.         if (rast)
  609.         lr_default();
  610.         return;
  611.     case '=':
  612.         dbprintf(("Half linefeed\n"));
  613.         if (rast)
  614.         half_linefeed();
  615.         return;
  616.     case 'E':
  617.         dbprintf(("Reset\n"));
  618.         if (rast_org) {
  619.         if (pbmpage)
  620.             pbmeject(TRUE);
  621.         else pbmnewpage(TRUE);
  622.         clearfonts(TEMPORARY);
  623.         rs_del_macros(TEMPORARY,0);
  624.         getchar_func = getc_only;
  625.         }
  626.         return;
  627.     case 'z':
  628.         dbprintf(("Self test\n"));
  629.         return;
  630.     case 'Y':
  631.         dbprintf(("Display functions on\n"));
  632.         return;
  633.     case 'Z':
  634.         dbprintf(("Display functions off\n"));
  635.         return;
  636.     case ')':
  637.         c = (*getchar_func)();
  638.         if (isdigit(c)) {
  639.         v = 0;
  640.         while(isdigit(c)) {
  641.             v = v * 10 + c - '0';
  642.             c = (*getchar_func)();
  643.         }
  644.         switch(c) {
  645.         case 'X':
  646.             dbprintf(("Secondary font %d\n", v));
  647.             if (rast)
  648.             rs_font(v,SECONDARY);
  649.             break;
  650.         case '@':
  651.             dbprintf(("Secondary font value %d\n", v));
  652.             break;
  653.         default:
  654.             dbprintf(("HUH ESC)%d%c\n", v, c));
  655.         }
  656.         return;
  657.         }
  658.         multisequence(')', c);
  659.         return;
  660.     case '(':
  661.         c = (*getchar_func)();
  662.         if (isdigit(c) || (c == 'X' || c == '@')) {
  663.         v = 0;
  664.         while(isdigit(c)) {
  665.             v = v * 10 + c - '0';
  666.             c = (*getchar_func)();
  667.         }
  668.         switch(c) {
  669.             case 'X':
  670.             dbprintf(("Primary font %d\n", v));
  671.             if (rast)
  672.                 rs_font(v,PRIMARY);
  673.             if (genps)
  674.                 ps_font(v, pts[v&0xf]);
  675.             break;
  676.             case '@':
  677.             dbprintf(("Primary font value %d\n", v));
  678.             break;
  679.             default:
  680.             dbprintf(("Symbol set: %d%c\n", v, c));
  681.             if (rast)
  682.                 rs_symset(v*32+c-64);
  683.             ps_symset = c;
  684.         }
  685.         return;
  686.         }
  687.         multisequence('(', c);
  688.         return;
  689.     case '&':
  690.         c = (*getchar_func)();
  691.         multisequence('&', c);
  692.         return;
  693.     case '*':
  694.         c = (*getchar_func)();
  695.         multisequence('*', c);
  696.         return;
  697.     default:
  698.         dbprintf(("Huh? %02x\n", c));
  699.         return;
  700.     }
  701. }
  702.  
  703. main(argc, argv)
  704. int argc; char **argv; {
  705.     int c;
  706.  
  707.     int resdone = 0;
  708.  
  709.     extern char *optarg;
  710.     extern int optind;
  711.  
  712. #if    !defined(BIGEND) && !defined(SMALLEND)
  713.     union t ta;
  714.     ta.a[0] = 0x01;
  715.     ta.a[1] = 0x02;
  716.     smallend = ((ta.b&0xff) == 0x01);
  717. #endif
  718.  
  719.     errno = 0;
  720.     if ((PGM = strrchr(argv[0], '/')) != NULL)
  721.     ++PGM;
  722.     else PGM = argv[0];
  723.  
  724. #ifdef    FAXPAK
  725.     if (read_defaults(&fc) || read_config(&fc))
  726.     exit(1);
  727. #endif
  728.  
  729.     getchar_func = getc_only;
  730.     infp = stdin;
  731.  
  732.     pbmname[0] = '\0';
  733.     while((c = getopt(argc, argv, "r:d:pvcV")) != EOF)
  734.     switch(c) {
  735. #ifdef    PS
  736.         case 'p':
  737.         genps++;
  738.         break;
  739. #endif
  740.         case 'v':
  741.         verbose++;
  742.         break;
  743.         case 'V':
  744.         printf("%s\n", VERSION);
  745.         exit(0);
  746.         case 'c':
  747.         plotch++;
  748.         break;
  749.         case 'd': {
  750.         double x, y;
  751.  
  752.         switch (sscanf(optarg, "%f,%f", &x, &y)) {
  753.             case 0:
  754.             fprintf(stderr, "%s: bad -d option %s\n", PGM, optarg);
  755.             exit(1);
  756.             case 1:
  757.             y = x;
  758.             case 2:
  759.             rs_rastsize(x, x);
  760.             break;
  761.         }
  762.  
  763.         resdone++;
  764.         
  765.         break;
  766.         }
  767.         case 'r':
  768.         rast_org = ++rast;
  769.         strcpy(pbmname, optarg);
  770.         break;
  771.         case '?':
  772.         fprintf(stderr, "usage: hpinterp [-dx[,y]][-p][-v][-c][-rpbm]< file\n");
  773.         exit(1);
  774.     }
  775.     
  776.     if (!resdone) {
  777.  
  778.     if (!strcmp(PGM,    "hp2hifax"))
  779.         rs_rastsize(    204.15, 195.58);
  780.     else if (!strcmp(PGM,    "hp2lofax"))
  781.         rs_rastsize(    204.15, 97.79);
  782.     else if (!strcmp(PGM,    "hp2sun"))
  783.         rs_rastsize(     84.0,  84.0);
  784.     else if (!strcmp(PGM,    "hp2e24"))
  785.         rs_rastsize(     180.0, 180.0);
  786.     else
  787.         rs_rastsize(         300.0, 300.0);    /* be prepared just in case */
  788.     }
  789.  
  790.     if (rast) {
  791.     if (pbmname[0] == '\0')
  792.         die("need an output file name\n");
  793.     make_bitmap(XSIZE,YSIZE);
  794.     }
  795.  
  796.     if (genps)
  797.     ps_init();
  798.     hptoany();    /* to allow recursion */
  799.  
  800.     if (out)
  801.     fclose(out);
  802.     if (txtout)
  803.     fclose(txtout);
  804.     if (rast && dotted)
  805.     pbmeject(FALSE);
  806.     if (genps)
  807.     ps_endemit();
  808.     exit(0);
  809. /*NOTREACHED*/
  810. }
  811.  
  812. hptoany() {
  813.     int c;
  814.  
  815.     while ((c = (*getchar_func)()) != EOF) {
  816.     if (c == ESCAPE)
  817.         readescape();
  818.     else {
  819.  
  820.         if (isprint(c)) {
  821.         dbprintf(("Char: %c\n", c));
  822.         } else {
  823.         dbprintf(("Char: 0x%02x\n", c));
  824.         }
  825.  
  826.         if (rast) {
  827.         if (c == '\n')
  828.             movetype = RELATIVE;
  829.  
  830.         if (c == '\f')
  831.             pbmeject(TRUE);
  832.         else prt_hpchr(c);
  833.         movetype = ABSOLUTE;
  834.         }
  835.         if (genps)
  836.         ps_emitchar(c);
  837.     }
  838.     }
  839. }
  840.  
  841. movex(num)
  842. double num; {
  843.     curX = num;
  844.     if (rast)
  845.     rs_X(curX);
  846.     if (genps)
  847.     ps_endemit();
  848. }
  849.  
  850. movey(num)
  851. double num; {
  852.     curY = num;
  853.     if (rast)
  854.     rs_Y(curY,FALSE);
  855.     if (genps)
  856.     ps_endemit();
  857. }
  858.  
  859. movedx(num)
  860. double num; {
  861.     curX = num * 300.0 / 720.0;
  862.     if (rast)
  863.     rs_X(curX);
  864.     if (genps)
  865.     ps_endemit();
  866. }
  867.  
  868. movedy(num)
  869. double num; {
  870.     curY = num * 300.0 / 720.0;
  871.     if (rast)
  872.     rs_Y(curY,TRUE);
  873.     if (genps)
  874.     ps_endemit();
  875. }
  876.  
  877. papinctrl(num)
  878. double num; {
  879.     if (num == 0) {
  880.     if (rast)
  881.         pbmeject(TRUE);
  882.     if (genps) {
  883.         ps_endemit();
  884.         printf("showpage\n");
  885.     }
  886.     }
  887. }
  888.  
  889. spset(num)
  890. double num; {
  891.     ps_spacing = num;
  892.     characteristic = 1;
  893.     if (rast)
  894.     rs_spacing((int)num);
  895.     if (genps)
  896.     ps_endemit();
  897. }
  898.  
  899. psset(num)
  900. double num; {
  901.     characteristic = 1;
  902.     ps_pointsize = num;
  903.     if (rast)
  904.     rs_points(num);
  905.     if (genps)
  906.     ps_endemit();
  907. }
  908.  
  909. styset(num)
  910. double num; {
  911.     characteristic = 1;
  912.     ps_style = num;
  913.     if (rast)
  914.     rs_style((int)num);
  915.     if (genps)
  916.     ps_endemit();
  917. }
  918.  
  919. strset(num)
  920. double num;
  921. {
  922.     characteristic = 1;
  923.     ps_stroke = num;
  924.     if (rast)
  925.     rs_stroke((int)num);
  926.     if (genps)
  927.     ps_endemit();
  928. }
  929.  
  930. tfset(num)
  931. double num; {
  932.     characteristic = 1;
  933.     ps_tface = num;
  934.     if (rast)
  935.     rs_typeface((int)num);
  936.     if (genps)
  937.     ps_endemit();
  938. }
  939.  
  940. macro_id(n)
  941. double n; {
  942.     if (rast)
  943.     rs_macro_id(n);
  944. }
  945.  
  946. macro_ctl(n)
  947. double n; {
  948.     int len;
  949.  
  950.     if (!rast_org)
  951.     return;
  952.  
  953.     switch((int)n) {
  954.     case 0:    rast = 0;
  955.         getchar_func = getc_copy;
  956.         mac_ctr = 0;
  957.         rs_mac_startdef();
  958.         break;
  959.     case 1:    rast = rast_org;
  960.         getchar_func = getc_only;
  961.         if (mac_ctr)
  962.         mac_download(mac_ctr, McBuffer);
  963.         rs_mac_enddef();
  964.         break;
  965.     case 2:    CurMc = CurMc_Ptr = rs_get_macro(&len);
  966.         if (len > 0)
  967.         {
  968.         getchar_func = mgetc;
  969.         CurMc_End = CurMc + len;
  970.         }
  971.         break;
  972.     case 3:    CurMc = CurMc_Ptr = rs_get_macro(&len);
  973.         if (len > 0) {
  974.         getchar_func = mgetc;
  975.         CurMc_End = CurMc + len;
  976.         rs_call_macro(SAVE);
  977.         need_mac_end_call = TRUE;
  978.         }
  979.         break;
  980.     case 4:    have_auto_macro = rs_auto_enable(TRUE);    break;
  981.     case 5:    have_auto_macro = rs_auto_enable(FALSE);break;
  982.     case 6: rs_del_macros(TEMPORARY,PERMANENT);    break;
  983.     case 7:    rs_del_macros(TEMPORARY,FALSE);        break;
  984.     case 8: rs_del_macro();                break;
  985.     case 9:    rs_makemtype(TEMPORARY);        break;
  986.     case 10:rs_makemtype(PERMANENT);        break;
  987.     }
  988. }
  989.  
  990. pbmeject(newpage)
  991. int newpage; {
  992.     int olddot;
  993.  
  994.     olddot = dotted;
  995.     if (dotted) {
  996.     if (!pbmpage)
  997.         pbmnewpage(TRUE);
  998.     end_bitmap(pbmtname);
  999.     }
  1000.     if (newpage)
  1001.     pbmnewpage(olddot);
  1002. }
  1003.  
  1004. pbmnewpage(inc)
  1005. int inc; {
  1006.     int (*old_func)();
  1007.  
  1008.     sprintf(pbmtname,"%s.%d",pbmname,pbmpage);
  1009.     pbmpage += inc;
  1010.     if (have_auto_macro > -1) {
  1011.     old_func = getchar_func;
  1012.     getchar_func = auto_getc;
  1013.     rs_auto();
  1014.     getchar_func = old_func;
  1015.     }
  1016. }
  1017.  
  1018. loadbuiltin(fontname)
  1019. char *fontname; {
  1020.     char fname[256];
  1021.     static FILE *fload, *old_infp;
  1022.     static int (*old_func)();
  1023.  
  1024. #ifdef    FAXPAK
  1025.     sprintf(fname, "%s/hplib/%s", fc.faxlib, fontname);
  1026. #else
  1027.     sprintf(fname, BUILTINDIR, LIBDIR, fontname);
  1028. #endif
  1029.     if ((fload = fopen(fname, "r")) == NULL)
  1030.     die("have some difficulty opening %s\n",fname);
  1031.     old_infp = infp;
  1032.     old_func = getchar_func;
  1033.     getchar_func = getc_only;
  1034.     infp = fload;
  1035.     hptoany();            /* load the font */
  1036.     fclose(fload);
  1037.     infp = old_infp;
  1038.     getchar_func = old_func;
  1039. }
  1040.  
  1041. #ifdef    PLOT
  1042. plotchars(f, dl)
  1043. struct download *dl;
  1044. FILE *f; {
  1045.     short x, y, bx, by, bytes, byteindex, bitindex, bit;
  1046.     uchar *data;
  1047.  
  1048.     data = (uchar *)dl;
  1049.     data += sizeof(struct download);
  1050.     bytes = (canon(dl->dl_charwidth) + 7) / 8;
  1051.     for (y = 0; y < canon(dl->dl_charheight); y++) {
  1052.     fprintf(f, "        ");
  1053.     for (x = 0; x < (canon(dl->dl_charwidth) + canon(dl->dl_leftoffset));
  1054.     x++) {
  1055.         bx = x - canon(dl->dl_leftoffset);
  1056.         by = y;
  1057.         if (bx >= 0) {
  1058.     byteindex = bytes * by + bx / 8;
  1059.     bitindex = (7 - (bx % 8));
  1060.     if (data[byteindex] & (1 << bitindex))
  1061.         bit = 'X';
  1062.     else
  1063.         bit = ' ';
  1064.         } else
  1065.     bit = ' ';
  1066.         if (x == 0 && y == canon(dl->dl_topoffset))
  1067.     bit = '+';
  1068.         if (bit == ' ' && y == canon(dl->dl_topoffset))
  1069.     bit = '=';
  1070.         fputc(bit, f);
  1071.     }
  1072.     fputc('\n',f);
  1073.     }
  1074. }
  1075. #endif
  1076.  
  1077. /*    Postscript driver */
  1078.  
  1079. ps_font(v, p)
  1080. int v, p; {
  1081.     ps_endemit();
  1082.     characteristic = 0;
  1083.     printf("/f%d findfont %d scalefont setfont\n", v, p);
  1084. }
  1085.  
  1086. ps_init() {
  1087.     printf("/M { moveto } def\n");
  1088.     printf("/S { show } def\n");
  1089. }
  1090.  
  1091. int    emitting = 0;
  1092.  
  1093. #define    TMS    "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic"
  1094. #define COUR    "Courier", "Courier-Oblique", "Courier-Bold",\
  1095.     "Courier-BoldOblique"
  1096. #define HELV    "Helvetica", "Helvetica-Oblique", "Helvetica-Bold",\
  1097.     "Helvetica-BoldOblique"
  1098.  
  1099. #define    LAST    7
  1100.  
  1101. char    *fonts[LAST][4] = {{COUR}, {COUR}, {COUR}, {COUR},
  1102.           {HELV}, {TMS}, {COUR}};
  1103.  
  1104. selchar() {
  1105.     int idx = 0;
  1106.     char *p;
  1107.  
  1108. #ifdef    NEVER
  1109.     printf("ps_pointsize: %d\n", ps_pointsize);
  1110.     printf("ps_style: %d\n", ps_style);
  1111.     printf("ps_stroke: %d\n", ps_stroke);
  1112.     printf("ps_symset: %d\n", ps_symset);
  1113.     printf("ps_tface: %d\n", ps_tface);
  1114.     printf("ps_spacing: %d\n", ps_spacing);
  1115. #endif
  1116.     if (ps_tface == 4101)    /* CG Roman on LJ III */
  1117.     ps_tface = 5;
  1118.     if (ps_tface == 4148)    /* CG Univers (Helvetica like) Roman on LJ III */
  1119.     ps_tface = 4;
  1120.     if (ps_tface >= LAST || ps_tface < 0)
  1121.     ps_tface = 3;
  1122.     idx = 0;
  1123.     if (ps_stroke > 0)
  1124.     idx = 2;
  1125.     if (ps_style != 0)
  1126.     idx++;
  1127.     if (ps_symset == 'M')
  1128.     p = "Symbol";
  1129.     else p = fonts[ps_tface][idx];
  1130.     printf("/%s findfont %d scalefont setfont\n", p, ps_pointsize);
  1131.     characteristic = 0;
  1132. }
  1133.  
  1134. ps_emitchar(c)
  1135. int c; {
  1136.     if (!genps)
  1137.     return;
  1138.  
  1139.     if (characteristic)
  1140.     selchar();
  1141.  
  1142.     if (!emitting)
  1143.     printf("%g %g M(", curX * 72 / 300, (72 * 11) - (curY * 72 / 300));
  1144.  
  1145.     emitting = 1;
  1146.  
  1147.     switch(c) {
  1148.     case '(':
  1149.     case ')':
  1150.     case '\\':
  1151.         printf("\\%c", c);
  1152.         break;
  1153.     default:
  1154.         if (c > ' ' && c < 0x7e)
  1155.         printf("%c", c);
  1156.         else printf("\\%03o", c&0xff);
  1157.         break;
  1158.     }
  1159. }
  1160.  
  1161. ps_endemit() {
  1162.     if (emitting)
  1163.     printf(")S\n");
  1164.     emitting = 0;
  1165. }
  1166.  
  1167. #ifdef    SELDOM    /* not used */
  1168. printhex(buf, n)
  1169. char *buf; int n; {
  1170.     int i;
  1171.  
  1172.     dbprintf(("SEQ:"));
  1173.     for (i = 0; i < n; i++) {
  1174.     if (isprint(buf[i]))
  1175.         putchar(buf[i]);
  1176.     else {
  1177.         dbprintf(("\\%02x", buf[i]));
  1178.     }
  1179.     }
  1180.     dbprintf(("\n"));
  1181. }
  1182. #endif
  1183.  
  1184.