home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / psroff / part05 / ps.c < prev   
Encoding:
C/C++ Source or Header  |  1989-10-17  |  18.6 KB  |  639 lines

  1. /*    Copyright 1985, 1986, 1987, 1988 Chris Lewis
  2.         All Rights Reserved
  3.  
  4.     Permission to copy and further distribute is freely given provided 
  5.     this copyright notice remains intact and that this software is not 
  6.     sold for profit.
  7.  
  8.     Project:    Generic Troff drivers
  9.     Module:        ps.c
  10.     Author:     Chris Lewis
  11.     Specs:        PostScript driver
  12.  */
  13.  
  14. #include "defs.h"
  15.  
  16. #ifdef    PS
  17. #include "ps.h"
  18.  
  19. #ifndef    SVR3
  20. #ifndef    lint
  21. static char SCCSid[] = "@(#)ps.c: 1.24 Copyright 89/08/28 17:11:47 Chris Lewis";
  22. #endif
  23. #else
  24. #ident  "@(#)ps.c: 1.24 Copyright 89/08/28 17:11:47 Chris Lewis" /*(SVR3)*/
  25. #endif
  26.  
  27. #define    METRICS
  28. static charCount;
  29.  
  30. #ifdef    FORM
  31. static char Overlay[100] = {""};
  32. #endif
  33.  
  34. #ifdef    BIN
  35. static char Bin = 'D';
  36. #endif
  37.  
  38. #define    MAXFONT    50
  39.  
  40. #define    USED    01
  41.  
  42. struct psFts {
  43.     char *troffName;
  44.     char *fontName;
  45.     int     flags;
  46. } psFts[MAXFONT+1];
  47.  
  48. struct psFts *t2psf[8];
  49.  
  50. struct troff2befont psStdFont[108] = {
  51.  
  52. /*          +-------------------------------- Troff character number
  53.         |
  54.             |    +--------------------------- U: standard fonts
  55.             |    |                            S: symbol font
  56.             |    |                            D: draw macro
  57.             |    |                            n: new font
  58.             |    |
  59.             |    |  +------------------------ X-shift (scaled by point)
  60.             |    |  |                         Note: positive is right.
  61.             |    |  |
  62.             |    |  |  +--------------------- Y-shift (scaled by point)
  63.             |    |  |  |                      Note: positive is up.
  64.             |    |  |  |
  65.             |    |  |  |  +------------------ Point scale factor
  66.             |    |  |  |  |
  67.             |    |  |  |  |   +-------------- Sequence
  68.             |    |  |  |  |   |
  69.             |    |  |  |  |   |               Printable sequence title
  70.             |    |  |  |  |   |                 |
  71.             |    |  |  |  |   |                 |
  72.             v    v  v  v  v   v                 v                    */
  73.     /*  1*/    {U, 0, 0, 1, "h",        "h"},
  74.     /*  2*/    {U, 0, 0, 1, "t",        "t"},
  75.     /*  3*/    {U, 0, 0, 1, "n",        "n"},
  76.     /*  4*/    {U, 0, 0, 1, "m",        "m"},
  77.     /*  5*/    {U, 0, 0, 1, "l",        "l"},
  78.     /*  6*/    {U, 0, 0, 1, "i",        "i"},
  79.     /*  7*/    {U, 0, 0, 1, "z",        "z"},
  80.     /*  8*/    {U, 0, 0, 1, "s",        "s"},
  81.     /*  9*/    {U, 0, 0, 1, "d",        "d"},
  82.     /* 10*/    {U, 0, 0, 1, "b",        "b"},
  83.     /* 11*/    {U, 0, 0, 1, "x",        "x"},
  84.     /* 12*/    {U, 0, 0, 1, "f",        "f"},
  85.     /* 13*/    {U, 0, 0, 1, "j",        "j"},
  86.     /* 14*/    {U, 0, 0, 1, "u",        "u"},
  87.     /* 15*/    {U, 0, 0, 1, "k",        "k"},
  88.     /* 16*/    {U, 0, 0, 1, NOCODE,        "unassigned"},
  89.     /* 17*/    {U, 0, 0, 1, "p",        "p"},
  90.     /* 18*/    {D, 0, 0, 1, "do34em",        "3/4 em"},
  91.     /* 19*/    {U, 0, 0, 1, ";",        ";"},
  92.     /* 20*/    {U, 0, 0, 1, NOCODE,        "unassigned"},
  93.     /* 21*/    {U, 0, 0, 1, "a",        "a"},
  94.     /* 22*/    {D, 0, 0, 1, "doru",        "horizontal rule"},
  95.     /* 23*/    {U, 0, 0, 1, "c",        "c"},
  96.     /* 24*/    {U, 0, 0, 1, "`",        "` open"},
  97.     /* 25*/    {U, 0, 0, 1, "e",        "e"},
  98.     /* 26*/    {U, 0, 0, 1, "'",        "' close"},
  99.     /* 27*/    {U, 0, 0, 1, "o",        "o"},
  100.     /* 28*/    {D, 0, 0, 1, "do14",        "1/4"},
  101.     /* 29*/    {U, 0, 0, 1, "r",        "r"},
  102.     /* 30*/    {D, 0, 0, 1, "do12",        "1/2"},
  103.     /* 31*/    {U, 0, 0, 1, "v",        "v"},
  104.     /* 32*/    {U, 0, 0, 1, "-",        "- hyphen"},
  105.     /* 33*/    {U, 0, 0, 1, "w",        "w"},
  106.     /* 34*/    {U, 0, 0, 1, "q",        "q"},
  107.     /* 35*/    {U, 0, 0, 1, "/",        "/"},
  108.     /* 36*/    {U, 0, 0, 1, ".",        "."},
  109.     /* 37*/    {U, 0, 0, 1, "g",        "g"},
  110.     /* 38*/    {D, 0, 0, 1, "do34",        "3/4"},
  111.     /* 39*/    {U, 0, 0, 1, ",",        ","},
  112.     /* 40*/    {U, 0, 0, 1, "&",        "&"},
  113.     /* 41*/    {U, 0, 0, 1, "y",        "y"},
  114.     /* 42*/    {U, 0, 0, 1, NOCODE,        "unassigned"},
  115.     /* 43*/    {U, 0, 0, 1, "\%",        "%"},
  116.     /* 44*/    {U, 0, 0, 1, NOCODE,        "unassigned"},
  117.     /* 45*/    {U, 0, 0, 1, "Q",        "Q"},
  118.     /* 46*/    {U, 0, 0, 1, "T",        "T"},
  119.     /* 47*/    {U, 0, 0, 1, "O",        "O"},
  120.     /* 48*/    {U, 0, 0, 1, "H",        "H"},
  121.     /* 49*/    {U, 0, 0, 1, "N",        "N"},
  122.     /* 50*/    {U, 0, 0, 1, "M",        "M"},
  123.     /* 51*/    {U, 0, 0, 1, "L",        "L"},
  124.     /* 52*/    {U, 0, 0, 1, "R",        "R"},
  125.     /* 53*/    {U, 0, 0, 1, "G",        "G"},
  126.     /* 54*/    {U, 0, 0, 1, "I",        "I"},
  127.     /* 55*/    {U, 0, 0, 1, "P",        "P"},
  128.     /* 56*/    {U, 0, 0, 1, "C",        "C"},
  129.     /* 57*/    {U, 0, 0, 1, "V",        "V"},
  130.     /* 58*/    {U, 0, 0, 1, "E",        "E"},
  131.     /* 59*/    {U, 0, 0, 1, "Z",        "Z"},
  132.     /* 60*/    {U, 0, 0, 1, "D",        "D"},
  133.     /* 61*/    {U, 0, 0, 1, "B",        "B"},
  134.     /* 62*/    {U, 0, 0, 1, "S",        "S"},
  135.     /* 63*/    {U, 0, 0, 1, "Y",        "Y"},
  136.     /*from here on are actually code 1-45, upper half of font */
  137.     /* 64*/    {U, 0, 0, 1, "F",        "F"},
  138.     /* 65*/    {U, 0, 0, 1, "X",        "X"},
  139.     /* 66*/    {U, 0, 0, 1, "A",        "A"},
  140.     /* 67*/    {U, 0, 0, 1, "W",        "W"},
  141.     /* 68*/    {U, 0, 0, 1, "J",        "J"},
  142.     /* 69*/    {U, 0, 0, 1, "U",        "U"},
  143.     /* 70*/    {U, 0, 0, 1, "K",        "K"},
  144.     /* 71*/    {U, 0, 0, 1, "0",        "0"},
  145.     /* 72*/    {U, 0, 0, 1, "1",        "1"},
  146.     /* 73*/    {U, 0, 0, 1, "2",        "2"},
  147.     /* 74*/    {U, 0, 0, 1, "3",        "3"},
  148.     /* 75*/    {U, 0, 0, 1, "4",        "4"},
  149.     /* 76*/    {U, 0, 0, 1, "5",        "5"},
  150.     /* 77*/    {U, 0, 0, 1, "6",        "6"},
  151.     /* 78*/    {U, 0, 0, 1, "7",        "7"},
  152.     /* 79*/    {U, 0, 0, 1, "8",        "8"},
  153.     /* 80*/    {U, 0, 0, 1, "9",        "9"},
  154.     /* 81*/    {U, 0, 0, 1, "*",        "*"},
  155.     /* 82*/    {S, 0, 0, 1, "\\055",        "minus"},
  156.     /* 83*/    {U, 0, 0, 1, "\\256",        "fi"},
  157.     /* 84*/    {U, 0, 0, 1, "\\257",        "fl"},
  158.     /* 85*/    {D, 0, 0, 1, "doff",        "ff"},
  159.     /* 86*/    {S, 0, 0, 1, "\\242",        "cent sign"},
  160.     /* 87*/    {D, 0, 0, 1, "doFl",        "ffl"},
  161.     /* 88*/    {D, 0, 0, 1, "doFi",        "ffi"},
  162.     /* 89*/    {U, 0, 0, 1, "\\(",        "("},
  163.     /* 90*/    {U, 0, 0, 1, "\\)",        ")"},
  164.     /* 91*/    {U, 0, 0, 1, "[",        "["},
  165.     /* 92*/    {U, 0, 0, 1, "]",        "]"},
  166.     /* 93*/    {S, 0, 0, 1, "\\260",        "degree"},
  167.     /* 94*/    {U, 0, 0, 1, "\\262",        "dagger"},
  168.     /* 95*/    {U, 0, 0, 1, "=",        "="},
  169.     /* 96*/    {S, 0, 0, 1, "\\322",        "registered"},
  170.     /* 97*/    {U, 0, 0, 1, ":",        ":"},
  171.     /* 98*/    {U, 0, 0, 1, "+",        "+"},
  172.     /* 99*/    {U, 0, 0, 1, NOCODE,        "unassigned"},
  173.     /*100*/    {U, 0, 0, 1, "!",        "!"},
  174.     /*101*/    {U, 0, -.1, 1.5, "\\267",    "bullet"},
  175.     /*102*/    {U, 0, 0, 1, "?",        "?"},
  176.     /*103*/    {S, 0, 0, 1, "\\242",        "foot mark (minute)"},
  177.     /*104*/    {U, -.1, 0, 1, "|",        "|"},
  178.     /*105*/    {U, 0, 0, 1, NOCODE,        "unassigned"},
  179.     /*106*/    {S, 0, 0, 1, "\\323",        "copyright"},
  180.     /*107*/    {D, 0, 0, 1, "dosq",        "square"},
  181.     /*108*/    {U, 0, 0, 1, "$",        "$"}
  182.     };
  183.  
  184.     struct troff2befont psSymFont[] = {
  185. /*          +-------------------------------- Troff character number
  186.         |
  187.             |    +--------------------------- U: standard fonts
  188.             |    |                            S: symbol font
  189.             |    |                            D: draw macro
  190.             |    |                            n: new font
  191.             |    |
  192.             |    |  +------------------------ X-shift (scaled by point)
  193.             |    |  |                         Note: positive is right.
  194.             |    |  |
  195.             |    |  |  +--------------------- Y-shift (scaled by point)
  196.             |    |  |  |                      Note: positive is up.
  197.             |    |  |  |
  198.             |    |  |  |  +------------------ Point scale factor
  199.             |    |  |  |  |
  200.             |    |  |  |  |   +-------------- Sequence
  201.             |    |  |  |  |   |
  202.             |    |  |  |  |   |               Printable sequence title
  203.             |    |  |  |  |   |                 |
  204.             |    |  |  |  |   |                 |
  205.             v    v  v  v  v   v                 v                    */
  206.     /*  1*/    {S, 0, 0, 1, "\\171",        "psi"},
  207.     /*  2*/    {S, 0, 0, 1, "\\161",        "theta"},
  208.     /*  3*/    {S, 0, 0, 1, "\\156",        "nu"},
  209.     /*  4*/    {S, 0, 0, 1, "\\155",        "mu"},
  210.     /*  5*/    {S, 0, 0, 1, "\\154",        "lambda"},
  211.     /*  6*/    {S, 0, 0, 1, "\\151",        "iota"},
  212.     /*  7*/    {S, 0, 0, 1, "\\172",        "zeta"},
  213.     /*  8*/    {S, 0, 0, 1, "\\163",        "sigma"},
  214.     /*  9*/    {S, 0, 0, 1, "\\144",        "delta"},
  215.     /* 10*/    {S, 0, 0, 1, "\\142",        "beta"},
  216.     /* 11*/    {S, 0, 0, 1, "\\170",        "xi"},
  217.     /* 12*/    {S, 0, 0, 1, "\\150",        "eta"},
  218.     /* 13*/    {S, 0, 0, 1, "\\146",        "phi"},
  219.     /* 14*/    {S, 0, 0, 1, "\\165",        "upsilon"},
  220.     /* 15*/    {S, 0, 0, 1, "\\153",        "kappa"},
  221.     /* 16*/    {S, 0, 0, 1, NOCODE,        "unassigned"},
  222.     /* 17*/    {S, 0, 0, 1, "\\160",        "pi"},
  223.     /* 18*/    {U, 0, 0, 1, "@",        "@"},
  224.     /* 19*/    {S, 0, 0, 1, "\\257",        "down arrow"},
  225.     /* 20*/    {S, 0, 0, 1, NOCODE,        "unassigned"},
  226.     /* 21*/    {S, 0, 0, 1, "\\141",        "alpha"},
  227.     /* 22*/    {S, 0, 0, 1, "\\174",        "or (was star)"},
  228.     /* 23*/    {S, 0, 0, 1, "\\143",        "chi"},
  229.     /* 24*/    {U, 0, 0, 1, "\\042",        "double quote"},
  230.     /* 25*/    {S, 0, 0, 1, "\\145",        "epsilon"},
  231.     /* 26*/    {S, 0, 0, 1, "\\075",        "equation equal"},
  232.     /* 27*/    {S, 0, 0, 1, "\\157",        "omicron"},
  233.     /* 28*/    {S, 0, 0, 1, "\\254",        "left arrow"},
  234.     /* 29*/    {S, 0, 0, 1, "\\162",        "rho"},
  235.     /* 30*/    {S, 0, 0, 1, "\\255",        "up arrow"},
  236.     /* 31*/    {S, 0, 0, 1, "\\164",        "tau"},
  237.     /* 32*/    {4, 0, 0, 1, "O",        "underline"},
  238.     /* 33*/    {U, 0, 0, 1, "\\134",        "\\\\"},
  239.     /* 34*/    {S, 0, 0, 1, "\\131",        "Psi"},
  240.     /* 35*/    {D, 0, 0, 1, "BellSymbol",    "bell system sign"},
  241.     /* 36*/    {S, 0, 0, 1, "\\245",        "infinity"},
  242.     /* 37*/    {S, 0, 0, 1, "\\147",        "gamma"},
  243.     /* 38*/    {S, 0, 0, 1, "\\312",        "improper superset"},
  244.     /* 39*/    {S, 0, 0, 1, "\\265",        "proportional to"},
  245.     /* 40*/    {S, 0, 0, 1, "\\336",        "right hand"},
  246.     /* 41*/    {S, 0, 0, 1, "\\167",        "omega"},
  247.     /* 42*/    {S, 0, 0, 1, NOCODE,        "unassigned"},
  248.     /* 43*/    {S, 0, 0, 1, "\\321",        "gradient"},
  249.     /* 44*/    {S, 0, 0, 1, NOCODE,        "unassigned"},
  250.     /* 45*/    {S, 0, 0, 1, "\\106",        "Phi"},
  251.     /* 46*/    {S, 0, 0, 1, "\\121",        "Theta"},
  252.     /* 47*/    {S, 0, 0, 1, "\\127",        "Omega"},
  253.     /* 48*/    {S, 0, 0, 1, "\\310",        "union"},
  254.     /* 49*/    {4, 0, 0, 1, "M",        "root en"},
  255.     /* 50*/    {S, 0, 0, 1, "\\123",        "terminal sigma (was root em)"},
  256.     /* 51*/    {S, 0, 0, 1, "\\114",        "Lambda"},
  257.     /* 52*/    {S, 0, 0, 1, "\\055",        "equation minus"},
  258.     /* 53*/    {S, 0, 0, 1, "\\107",        "Gamma"},
  259.     /* 54*/    {S, 0, 0, 1, "\\362",        "integral sign"},
  260.     /* 55*/    {S, 0, 0, 1, "\\120",        "Pi"},
  261.     /* 56*/    {S, 0, 0, 1, "\\314",        "subset of"},
  262.     /* 57*/    {S, 0, 0, 1, "\\311",        "superset of"},
  263.     /* 58*/    {U, 0, 0, 1, "\\176",        "approximates"},
  264.     /* 59*/    {S, 0, 0, 1, "\\266",        "partial derivative"},
  265.     /* 60*/    {S, 0, 0, 1, "\\104",        "Delta"},
  266.     /* 61*/    {S, .35, 0, 1, "\\326",        "square root"},
  267.     /* 62*/    {S, 0, 0, 1, "\\123",        "Sigma"},
  268.     /* 63*/    {S, 0, 0, 1, "\\273",        "approx ="},
  269.     /* 64*/    {S, 0, 0, 1, "\\076",        ">"},
  270.     /* 65*/    {S, 0, 0, 1, "\\130",        "Xi"},
  271.     /* 66*/    {S, 0, 0, 1, "\\074",        "<"},
  272.     /* 67*/    {S, 0, 0, 1, "\\244",        "long slash (longer)"},
  273.     /* 68*/    {S, 0, 0, 1, "\\307",        "intersect"},
  274.     /* 69*/    {S, 0, 0, 1, "\\125",        "Upsilon"},
  275.     /* 70*/    {S, 0, 0, 1, "\\330",        "logical not"},
  276.     /* 71*/    {4, 0, 0, 1, "J",        "right ceiling"},
  277.     /* 72*/    {4, 0, 0, 1, "B",        "left top brace"},
  278.     /* 73*/    {4, 0, 0, 1, "A",        "bold vertical"},
  279.     /* 74*/    {4, 0, 0, 1, "C",        "left ctr brace"},
  280.     /* 75*/    {4, 0, 0, 1, "D",        "left bot brace"},
  281.     /* 76*/    {4, 0, 0, 1, "E",        "right top brace"},
  282.     /* 77*/    {4, 0, 0, 1, "F",        "right ctr brace"},
  283.     /* 78*/    {4, 0, 0, 1, "G",        "right bot brace"},
  284.     /* 79*/    {4, 0, 0, 1, "K",        "right floor"},
  285.     /* 80*/    {4, 0, 0, 1, "I",        "left floor"},
  286.     /* 81*/    {4, 0, 0, 1, "H",        "left ceiling"},
  287.     /* 82*/    {S, 0, 0, 1, "\\264",        "multiply"},
  288.     /* 83*/    {S, 0, 0, 1, "\\270",        "divide"},
  289.     /* 84*/    {S, 0, 0, 1, "\\261",        "plus-minus"},
  290.     /* 85*/    {S, 0, 0, 1, "\\243",        "<="},
  291.     /* 86*/    {S, 0, 0, 1, "\\263",        ">="},
  292.     /* 87*/    {S, 0, 0, 1, "\\272",        "identically equal"},
  293.     /* 88*/    {S, 0, 0, 1, "\\271",        "not equal"},
  294.     /* 89*/    {S, 0, 0, 1, "\\173",        "{"},
  295.     /* 90*/    {S, 0, 0, 1, "\\175",        "}"},
  296.     /* 91*/    {U, 0, 0, 1, "\\302",        "acute accent"},
  297.     /* 92*/    {U, 0, 0, 1, "\\301",        "grave accent"},
  298.     /* 93*/    {U, 0, 0, 1, "\\303",        "^"},
  299.     /* 94*/    {U, 0, 0, 1, "\\043",        "#"},
  300.     /* 95*/    {S, 0, 0, 1, "\\334",        "left hand"},
  301.     /* 96*/    {S, 0, 0, 1, "\\316",        "member of"},
  302.     /* 97*/    {U, 0, 0, 1, "\\304",        "~"},
  303.     /* 98*/    {S, 0, 0, 1, "\\306",        "empty set"},
  304.     /* 99*/    {S, 0, 0, 1, NOCODE,        "unassigned"},
  305.     /*100*/    {U, 0, 0, 1, "\\263",        "dbl dagger"},
  306.     /*101*/    {4, 0, 0, 1, "L",        "box rule (was parallel sign)"},
  307.     /*102*/    {S, 0, 0, 1, "\\052",        "math * "},
  308.     /*103*/    {S, 0, 0, 1, "\\315",        "improper subset"},
  309.     /*104*/    {4, 0, 0, 1, "N",        "circle"},
  310.     /*105*/    {S, 0, 0, 1, NOCODE,        "unassigned"},
  311.     /*106*/    {S, 0, 0, 1, "\\053",        "equation plus"},
  312.     /*107*/    {S, 0, 0, 1, "\\256",        "right arrow"},
  313.     /*108*/    {U, 0, 0, 1, "\\247",        "section"}
  314. };
  315.  
  316. psPage() {
  317.     EMITPS("ShowPage\n");
  318.     EMITPS("PageSave restore\n");
  319.     pagePending = 1;
  320. }
  321.  
  322. static
  323. doPageStart(e) {
  324.     currentPage++;
  325.     EMITPS("%%%%Page: ? %d\n", currentPage);
  326. #ifdef    BIN
  327.     switch(Bin) {
  328.     case 'M':
  329.         EMITPS("/manualfeed true def\n");
  330.         break;
  331.     default:
  332.         fprintf(stderr, 
  333.         "%s: bad bin selection %c - set to default\n", progname, 
  334.         Bin);
  335.         Bin = 'D';
  336.     case 'D':
  337.         EMITPS("/manualfeed false def\n");
  338.         break;
  339.     }
  340. #endif
  341. #ifdef    FORM
  342.     EMITPS("/Form { %s } def\n", Overlay);
  343. #endif
  344.     EMITPS("/PageSave save def\n");
  345.     pagePending = 0;
  346.     EMITPS("StartPage\n");
  347. }
  348.  
  349. static int lastFont = (-1), lastPoints = (-1);
  350.  
  351. psSetFont(font, points)
  352. int font, points; {
  353.     if (lastPoints != points || font != lastFont) {
  354.         psFts[font].flags |= USED;
  355. #ifdef    FONTMACRO
  356.         EMITPS("/%s %d SetFont\n", psFts[font].fontName, points);
  357. #else
  358.         EMITPS("/%s dup /curFont exch def findfont\n", 
  359.         psFts[font].fontName);
  360.         EMITPS("%d dup /curPoints exch def scalefont setfont\n", points);
  361. #endif
  362.         lastPoints = points;
  363.         lastFont = font;
  364.     }
  365. }
  366.  
  367. psChar(x, y, font, points, troffChar) 
  368. int x, y, font, points, troffChar; {
  369.     static double lasty = (-1);
  370.     register double nx = TROFF2PSX(x), ny = TROFF2PSY(y);
  371.     register struct troff2befont *rp;
  372.     register char *sequence = "a";
  373.     if (pagePending) {
  374.         lasty = lastFont = lastPoints = (-1);
  375.         doPageStart();
  376.     }
  377.  
  378.     charCount++;
  379.  
  380.     DEBUGPRINTF("x,y=%d,%d; font=%d, points=%d, tc=%d\n",
  381.         x, y, font, points, troffChar);
  382.  
  383.     if (font == 3) {
  384.         rp = &be->besymfont[troffChar];
  385.     } else {
  386.         rp = &be->bestdfont[troffChar];
  387.     }
  388.  
  389.     switch(rp->t2b_font) {
  390.         /* Only fonts with "U" are subject to font translation */
  391.         case U: 
  392.         if (font == 3)
  393.             font = 0;    /* Special chars are Courier */
  394.         else {
  395.             DEBUGPRINTF("psSetChar %d->%s (%s)\n", font, 
  396.             t2psf[font]->troffName,
  397.             t2psf[font]->fontName);
  398.             font = t2psf[font] - psFts;
  399.         }
  400.         break;
  401.         case S: 
  402.         font = 3;
  403.         break;
  404.         case D:
  405.         break;
  406.         default:
  407.         /* Typically used when the main fonts don't have the
  408.            character desired.  Eg: right-hand is in the
  409.            ZapfDingbats font */
  410.         font = rp->t2b_font;
  411.         break;
  412.     }
  413.  
  414.     sequence = rp->t2b_charseq;
  415.  
  416.     if (!sequence) {
  417.         fprintf(stderr, "No coding for %d\n", troffChar);
  418.         return;
  419.     }
  420.  
  421.     /*    We're committed now */
  422.  
  423.     points *= rp->t2b_scale;
  424.     nx += points * rp->t2b_xc;
  425.     ny += points * rp->t2b_yc;
  426.     psSetFont(font, points);
  427.     if (rp->t2b_font == D)
  428.         EMITPS("%g %g %s\n", nx, ny, sequence);
  429.     else {
  430.         emitnum(nx);
  431.         if (lasty != ny) {
  432.         EMITPS(" ");
  433.         emitnum(ny);
  434.         EMITPS("(%s)Y\n", sequence);
  435.         lasty = ny;
  436.         } else
  437.         EMITPS("(%s)X\n",sequence);
  438.     }
  439. }
  440.  
  441. emitnum(val)
  442. double val; {
  443.     static char buffer[30];
  444.     register char *p;
  445.     sprintf(buffer, "%g", val);
  446.     p = strchr(buffer, '.');
  447.     if (p)
  448.     *(p+2) = '\0';
  449.     EMITPS(buffer);
  450. }
  451.  
  452.  
  453. static
  454. loadfontdefs(f)
  455. FILE *f; {
  456.     struct psFts *p = psFts;
  457.     extern char *malloc();
  458.     char rbuf[512], nbuf[512], psbuf[512];
  459.     while(fgets(rbuf, sizeof(rbuf), f)) {
  460.     switch(sscanf(rbuf, "%s%s", nbuf, psbuf)) {
  461.         default:
  462.         break;
  463.         case 2:
  464.         if (nbuf[0] == '#')
  465.             break;
  466.         if (p - psFts >= MAXFONT) {
  467.             fprintf(stderr, "Too many font definitions in %s\n",
  468.             PSFONTS);
  469.             exit(1);
  470.         }
  471.         p->troffName = malloc(strlen(nbuf) + 1);
  472.         strcpy(p->troffName, nbuf);
  473.         p->fontName = malloc(strlen(psbuf) + 1);
  474.         strcpy(p->fontName, psbuf);
  475.         p++;
  476.     }
  477.     }
  478. #ifdef    DEBUG
  479.     for (p = psFts; p->troffName; p++)
  480.     DEBUGPRINTF("%s -> %s\n", p->troffName, p->fontName);
  481. #endif
  482. }
  483.  
  484. extern char nodename[];
  485.  
  486. psProlog() {
  487.     extern char *getlogin(), *ctime();
  488.     extern char *strchr();
  489.     char buffer[512];
  490.     char *lognm;
  491.     FILE *library;
  492.     int c;
  493.     long curtime;
  494.  
  495.     currentPage = 0;
  496.     pagePending = 1;
  497.  
  498.     for (c = 0; c < 8; c++)
  499.     t2psf[c] = &psFts[c];
  500.     if ((library = fopen(PSFONTS, "r")) == NULL) {
  501.     sprintf(buffer, "%s/%s", LIBDIR, PSFONTS);
  502.     if ((library = fopen(buffer, "r")) == NULL) {
  503.         fprintf(stderr, "Cannot open PostScript font definitions %s\n",
  504.         buffer);
  505.         exit(1);
  506.     }
  507.     }
  508.  
  509.     loadfontdefs(library);
  510.     fclose(library);
  511.  
  512.     if ((library = fopen(PSLIB, "r")) == NULL) {
  513.     sprintf(buffer, "%s/%s", LIBDIR, PSLIB);
  514.     if ((library = fopen(buffer, "r")) == NULL) {
  515.         fprintf(stderr, "Cannot open %s\n", buffer);
  516.         exit(1);
  517.     }
  518.     }
  519.  
  520.     time(&curtime);
  521.     strcpy(buffer, ctime(&curtime));
  522.     *strchr(buffer, '\n') = '\0';
  523.     getnodename();
  524.  
  525.     lognm = getlogin();
  526.     if (!lognm || !*lognm)
  527.     lognm = "unknown";
  528.  
  529.     EMITPS("%%!PS-Adobe-1.0\n");
  530.     EMITPS("%%%%Title: (stdin)\n");
  531.     EMITPS("%%%%Creator: %s %s %s\n", lognm, progname, T2VERSION);
  532.     EMITPS("%%%%CreationDate: %s\n", buffer);
  533.     EMITPS("%%%%For: %s\n", lognm);
  534.     EMITPS("%%%%Pages: (atend)\n");
  535.     EMITPS("%%%%DocumentFonts: (atend)\n");
  536.     EMITPS("%%%%EndComments\n");
  537.     EMITPS("(%s@%s %s %s %s\n) print\n", lognm, nodename, buffer, 
  538.     progname, T2VERSION);
  539.     psXlate(library);
  540.     EMITPS("/GlobalSave save def\n");
  541.     EMITPS("%%%%EndProlog\n");
  542.     fclose(library);
  543. }
  544.  
  545. psEpilog() {
  546.     int i;
  547. #ifdef    METRICS
  548.     int curpos = 720;        /* ten inches from bottom of page */
  549. #define    XD    36
  550. #define    CH    16
  551.     if (metrics) {
  552.     psBin("");
  553.     psOverlay("");
  554.     doPageStart();
  555.     lastFont = -1;    /* force the font change nomatter what */
  556.     psSetFont(0, 16);
  557.     EMITPS("%d %d(%s Execution Summary:)Y\n", progname, XD, curpos);
  558.     curpos -= CH;
  559.     EMITPS("%d %d(Font cache hits: )Y Hits show\n",
  560.         XD + 18, curpos);
  561.     curpos -= CH;
  562.     EMITPS("%d %d(Font cache misses: )Y Misses show\n",
  563.         XD + 18, curpos);
  564.     curpos -= CH;
  565.     EMITPS("%d %d(Character Count: %d)Y\n",
  566.         charCount, XD + 18, curpos);
  567.     psPage();
  568.     }
  569. #endif
  570.     EMITPS("%%%%Trailer\n");
  571.     EMITPS("GlobalSave restore\n");
  572.     EMITPS("%%%%DocumentFonts:");
  573.     for (i = 0; i < MAXFONT; i++)
  574.     if (psFts[i].flags&USED)
  575.         EMITPS(" %s", psFts[i].fontName);
  576.     EMITPS("\n");
  577.     EMITPS("%%%%Pages: %d\n", currentPage);
  578.     putchar('\004');
  579. }
  580.  
  581. psFontSel(from, to)
  582. char from, *to; {
  583. #ifdef    DEBUG
  584.     register int i;
  585.     register struct psFts *p;
  586. #endif
  587.     DEBUGPRINTF("psFontSel: %c -> %s\n", from, to);
  588.     if (from < '1' || from > '8') {
  589.     fprintf(stderr, "Bad arguments to psFontSel: %c %s\n", from, to);
  590.     return;
  591.     }
  592.  
  593.     for (p = psFts; p->troffName; p++)
  594.     if (strcmp(p->troffName, to) == 0) {
  595.         t2psf[from - '1'] = p;
  596.         break;
  597.     }
  598.     if (!p->troffName) {
  599.     fprintf(stderr, "Could not translate font %c (%s)\n", from, to);
  600.     }
  601. #ifdef    DEBUG
  602.     for (i = 0; i < 8; i++)
  603.     DEBUGPRINTF("Font %d->%s\n", i+1, t2psf[i]->fontName);
  604. #endif
  605. }
  606.  
  607. /*struct troff2befont *
  608. psGetFontTables(which)
  609. int which; {
  610.     return(which? symbolFont: standardFont);
  611. }*/
  612.  
  613. psXlate(library)
  614. FILE *library; {
  615.     char buf[512];
  616.     while (fgets(buf, sizeof(buf), library))
  617.     if (0 == strncmp(buf, "%%%", 3))
  618.         interp(&buf[3], psXlate, ".ps");
  619.     else
  620.         fputs(buf, stdout);
  621. }
  622.  
  623. psOverlay(overlay)
  624. char *overlay; {
  625. #ifdef    FORM
  626.     strcpy(Overlay, overlay);
  627.     EMITPS("%%%%%%Form set: %s\n", Overlay);
  628. #endif
  629. }
  630.  
  631. psBin(bin)
  632. char *bin; {
  633. #ifdef    BIN
  634.     Bin = *bin;
  635. #endif
  636. }
  637.  
  638. #endif /* PS */
  639.