1*219b2ee8SDavid du Colombier #include <u.h> 2*219b2ee8SDavid du Colombier #include <libc.h> 3*219b2ee8SDavid du Colombier #include <ctype.h> 4*219b2ee8SDavid du Colombier #include <bio.h> 5*219b2ee8SDavid du Colombier #include <comments.h> 6*219b2ee8SDavid du Colombier #include <path.h> 7*219b2ee8SDavid du Colombier 8*219b2ee8SDavid du Colombier #define UNKNOWNCHAR "/sys/lib/postscript/prologues/pjw.char.ps" 9*219b2ee8SDavid du Colombier 10*219b2ee8SDavid du Colombier char *optnames = "a:c:f:l:m:n:o:p:s:t:x:y:P:"; 11*219b2ee8SDavid du Colombier 12*219b2ee8SDavid du Colombier Biobuf *bstdin, *bstdout, *bstderr; 13*219b2ee8SDavid du Colombier Biobufhdr *Bstdin, *Bstdout, *Bstderr; 14*219b2ee8SDavid du Colombier int char_no = 0; /* character to be done on a line */ 15*219b2ee8SDavid du Colombier int line_no = 0; /* line number on a page */ 16*219b2ee8SDavid du Colombier int page_no = 0; /* page number in a document */ 17*219b2ee8SDavid du Colombier int in_string; /* Boolean, to know whether or not we are inside a Postscript string */ 18*219b2ee8SDavid du Colombier int spaces = 0; 19*219b2ee8SDavid du Colombier int tabs = 0; 20*219b2ee8SDavid du Colombier int pages_printed; 21*219b2ee8SDavid du Colombier double aspectratio = 1.0; 22*219b2ee8SDavid du Colombier int copies = 1; 23*219b2ee8SDavid du Colombier double magnification = 1.0; 24*219b2ee8SDavid du Colombier int landscape = 0; 25*219b2ee8SDavid du Colombier int formsperpage = 1; 26*219b2ee8SDavid du Colombier int linesperpage = 66; 27*219b2ee8SDavid du Colombier int pointsize = 10; 28*219b2ee8SDavid du Colombier double xoffset = .25; 29*219b2ee8SDavid du Colombier double yoffset = .25; 30*219b2ee8SDavid du Colombier char *passthrough = 0; 31*219b2ee8SDavid du Colombier double tabstop = .5; 32*219b2ee8SDavid du Colombier static int pplistmaxsize=0; 33*219b2ee8SDavid du Colombier 34*219b2ee8SDavid du Colombier unsigned char *pplist=0; /* bitmap list for storing pages to print */ 35*219b2ee8SDavid du Colombier 36*219b2ee8SDavid du Colombier struct strtab { 37*219b2ee8SDavid du Colombier int size; 38*219b2ee8SDavid du Colombier char *str; 39*219b2ee8SDavid du Colombier int used; 40*219b2ee8SDavid du Colombier }; 41*219b2ee8SDavid du Colombier 42*219b2ee8SDavid du Colombier struct strtab charcode[256] = { 43*219b2ee8SDavid du Colombier {4, "\\000"}, {4, "\\001"}, {4, "\\002"}, {4, "\\003"}, 44*219b2ee8SDavid du Colombier {4, "\\004"}, {4, "\\005"}, {4, "\\006"}, {4, "\\007"}, 45*219b2ee8SDavid du Colombier {4, "\\010"}, {4, "\\011"}, {4, "\\012"}, {4, "\\013"}, 46*219b2ee8SDavid du Colombier {4, "\\014"}, {4, "\\015"}, {4, "\\016"}, {4, "\\017"}, 47*219b2ee8SDavid du Colombier {4, "\\020"}, {4, "\\021"}, {4, "\\022"}, {4, "\\023"}, 48*219b2ee8SDavid du Colombier {4, "\\024"}, {4, "\\025"}, {4, "\\026"}, {4, "\\027"}, 49*219b2ee8SDavid du Colombier {4, "\\030"}, {4, "\\031"}, {4, "\\032"}, {4, "\\033"}, 50*219b2ee8SDavid du Colombier {4, "\\034"}, {4, "\\035"}, {4, "\\036"}, {4, "\\037"}, 51*219b2ee8SDavid du Colombier {1, " "}, {1, "!"}, {1, "\""}, {1, "#"}, 52*219b2ee8SDavid du Colombier {1, "$"}, {1, "%"}, {1, "&"}, {1, "'"}, 53*219b2ee8SDavid du Colombier {2, "\\("}, {2, "\\)"}, {1, "*"}, {1, "+"}, 54*219b2ee8SDavid du Colombier {1, ","}, {1, "-"}, {1, "."}, {1, "/"}, 55*219b2ee8SDavid du Colombier {1, "0"}, {1, "1"}, {1, "2"}, {1, "3"}, 56*219b2ee8SDavid du Colombier {1, "4"}, {1, "5"}, {1, "6"}, {1, "7"}, 57*219b2ee8SDavid du Colombier {1, "8"}, {1, "9"}, {1, ":"}, {1, ";"}, 58*219b2ee8SDavid du Colombier {1, "<"}, {1, "="}, {1, ">"}, {1, "?"}, 59*219b2ee8SDavid du Colombier {1, "@"}, {1, "A"}, {1, "B"}, {1, "C"}, 60*219b2ee8SDavid du Colombier {1, "D"}, {1, "E"}, {1, "F"}, {1, "G"}, 61*219b2ee8SDavid du Colombier {1, "H"}, {1, "I"}, {1, "J"}, {1, "K"}, 62*219b2ee8SDavid du Colombier {1, "L"}, {1, "M"}, {1, "N"}, {1, "O"}, 63*219b2ee8SDavid du Colombier {1, "P"}, {1, "Q"}, {1, "R"}, {1, "S"}, 64*219b2ee8SDavid du Colombier {1, "T"}, {1, "U"}, {1, "V"}, {1, "W"}, 65*219b2ee8SDavid du Colombier {1, "X"}, {1, "Y"}, {1, "Z"}, {1, "["}, 66*219b2ee8SDavid du Colombier {2, "\\\\"}, {1, "]"}, {1, "^"}, {1, "_"}, 67*219b2ee8SDavid du Colombier {1, "`"}, {1, "a"}, {1, "b"}, {1, "c"}, 68*219b2ee8SDavid du Colombier {1, "d"}, {1, "e"}, {1, "f"}, {1, "g"}, 69*219b2ee8SDavid du Colombier {1, "h"}, {1, "i"}, {1, "j"}, {1, "k"}, 70*219b2ee8SDavid du Colombier {1, "l"}, {1, "m"}, {1, "n"}, {1, "o"}, 71*219b2ee8SDavid du Colombier {1, "p"}, {1, "q"}, {1, "r"}, {1, "s"}, 72*219b2ee8SDavid du Colombier {1, "t"}, {1, "u"}, {1, "v"}, {1, "w"}, 73*219b2ee8SDavid du Colombier {1, "x"}, {1, "y"}, {1, "z"}, {1, "{"}, 74*219b2ee8SDavid du Colombier {1, "|"}, {1, "}"}, {1, "~"}, {4, "\\177"}, 75*219b2ee8SDavid du Colombier {4, "\\200"}, {4, "\\201"}, {4, "\\202"}, {4, "\\203"}, 76*219b2ee8SDavid du Colombier {4, "\\204"}, {4, "\\205"}, {4, "\\206"}, {4, "\\207"}, 77*219b2ee8SDavid du Colombier {4, "\\210"}, {4, "\\211"}, {4, "\\212"}, {4, "\\213"}, 78*219b2ee8SDavid du Colombier {4, "\\214"}, {4, "\\215"}, {4, "\\216"}, {4, "\\217"}, 79*219b2ee8SDavid du Colombier {4, "\\220"}, {4, "\\221"}, {4, "\\222"}, {4, "\\223"}, 80*219b2ee8SDavid du Colombier {4, "\\224"}, {4, "\\225"}, {4, "\\226"}, {4, "\\227"}, 81*219b2ee8SDavid du Colombier {4, "\\230"}, {4, "\\231"}, {4, "\\232"}, {4, "\\233"}, 82*219b2ee8SDavid du Colombier {4, "\\234"}, {4, "\\235"}, {4, "\\236"}, {4, "\\237"}, 83*219b2ee8SDavid du Colombier {4, "\\240"}, {4, "\\241"}, {4, "\\242"}, {4, "\\243"}, 84*219b2ee8SDavid du Colombier {4, "\\244"}, {4, "\\245"}, {4, "\\246"}, {4, "\\247"}, 85*219b2ee8SDavid du Colombier {4, "\\250"}, {4, "\\251"}, {4, "\\252"}, {4, "\\253"}, 86*219b2ee8SDavid du Colombier {4, "\\254"}, {4, "\\255"}, {4, "\\256"}, {4, "\\257"}, 87*219b2ee8SDavid du Colombier {4, "\\260"}, {4, "\\261"}, {4, "\\262"}, {4, "\\263"}, 88*219b2ee8SDavid du Colombier {4, "\\264"}, {4, "\\265"}, {4, "\\266"}, {4, "\\267"}, 89*219b2ee8SDavid du Colombier {4, "\\270"}, {4, "\\271"}, {4, "\\272"}, {4, "\\273"}, 90*219b2ee8SDavid du Colombier {4, "\\274"}, {4, "\\275"}, {4, "\\276"}, {4, "\\277"}, 91*219b2ee8SDavid du Colombier {4, "\\300"}, {4, "\\301"}, {4, "\\302"}, {4, "\\303"}, 92*219b2ee8SDavid du Colombier {4, "\\304"}, {4, "\\305"}, {4, "\\306"}, {4, "\\307"}, 93*219b2ee8SDavid du Colombier {4, "\\310"}, {4, "\\311"}, {4, "\\312"}, {4, "\\313"}, 94*219b2ee8SDavid du Colombier {4, "\\314"}, {4, "\\315"}, {4, "\\316"}, {4, "\\317"}, 95*219b2ee8SDavid du Colombier {4, "\\320"}, {4, "\\321"}, {4, "\\322"}, {4, "\\323"}, 96*219b2ee8SDavid du Colombier {4, "\\324"}, {4, "\\325"}, {4, "\\326"}, {4, "\\327"}, 97*219b2ee8SDavid du Colombier {4, "\\330"}, {4, "\\331"}, {4, "\\332"}, {4, "\\333"}, 98*219b2ee8SDavid du Colombier {4, "\\334"}, {4, "\\335"}, {4, "\\336"}, {4, "\\337"}, 99*219b2ee8SDavid du Colombier {4, "\\340"}, {4, "\\341"}, {4, "\\342"}, {4, "\\343"}, 100*219b2ee8SDavid du Colombier {4, "\\344"}, {4, "\\345"}, {4, "\\346"}, {4, "\\347"}, 101*219b2ee8SDavid du Colombier {4, "\\350"}, {4, "\\351"}, {4, "\\352"}, {4, "\\353"}, 102*219b2ee8SDavid du Colombier {4, "\\354"}, {4, "\\355"}, {4, "\\356"}, {4, "\\357"}, 103*219b2ee8SDavid du Colombier {4, "\\360"}, {4, "\\361"}, {4, "\\362"}, {4, "\\363"}, 104*219b2ee8SDavid du Colombier {4, "\\364"}, {4, "\\365"}, {4, "\\366"}, {4, "\\367"}, 105*219b2ee8SDavid du Colombier {4, "\\370"}, {4, "\\371"}, {4, "\\372"}, {4, "\\373"}, 106*219b2ee8SDavid du Colombier {4, "\\374"}, {4, "\\375"}, {4, "\\376"}, {4, "\\377"} 107*219b2ee8SDavid du Colombier }; 108*219b2ee8SDavid du Colombier 109*219b2ee8SDavid du Colombier #define FONTABSIZE 27 110*219b2ee8SDavid du Colombier 111*219b2ee8SDavid du Colombier struct strtab fontname[FONTABSIZE] = { 112*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode00", 0}, 113*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode01", 0}, 114*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode02", 0}, 115*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode03", 0}, 116*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode04", 0}, 117*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode05", 0}, 118*219b2ee8SDavid du Colombier {0, "", 0}, 119*219b2ee8SDavid du Colombier {0, "", 0}, 120*219b2ee8SDavid du Colombier {0, "", 0}, 121*219b2ee8SDavid du Colombier {0, "", 0}, 122*219b2ee8SDavid du Colombier {0, "", 0}, 123*219b2ee8SDavid du Colombier {0, "", 0}, 124*219b2ee8SDavid du Colombier {0, "", 0}, 125*219b2ee8SDavid du Colombier {0, "", 0}, 126*219b2ee8SDavid du Colombier {0, "", 0}, 127*219b2ee8SDavid du Colombier {0, "", 0}, 128*219b2ee8SDavid du Colombier {0, "", 0}, 129*219b2ee8SDavid du Colombier {0, "", 0}, 130*219b2ee8SDavid du Colombier {0, "", 0}, 131*219b2ee8SDavid du Colombier {0, "", 0}, 132*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode20", 0}, 133*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode21", 0}, 134*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode22", 0}, 135*219b2ee8SDavid du Colombier {0, "", 0}, 136*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode24", 0}, 137*219b2ee8SDavid du Colombier {19, "LucidaSansUnicode25", 0}, 138*219b2ee8SDavid du Colombier {7, "Courier", 0} 139*219b2ee8SDavid du Colombier }; 140*219b2ee8SDavid du Colombier 141*219b2ee8SDavid du Colombier /* This was taken from postprint */ 142*219b2ee8SDavid du Colombier 143*219b2ee8SDavid du Colombier int 144*219b2ee8SDavid du Colombier cat(char *filename) { 145*219b2ee8SDavid du Colombier Biobuf *bfile; 146*219b2ee8SDavid du Colombier Biobufhdr *Bfile; 147*219b2ee8SDavid du Colombier int n; 148*219b2ee8SDavid du Colombier static char buf[Bsize]; 149*219b2ee8SDavid du Colombier 150*219b2ee8SDavid du Colombier bstdin = Bopen(filename, 0); 151*219b2ee8SDavid du Colombier if (bstdin == 0) { 152*219b2ee8SDavid du Colombier return(1); 153*219b2ee8SDavid du Colombier } 154*219b2ee8SDavid du Colombier Bstdin = &(bstdin->Biobufhdr); 155*219b2ee8SDavid du Colombier if ((bfile = Bopen(filename, OREAD)) == 0) { 156*219b2ee8SDavid du Colombier return(1); 157*219b2ee8SDavid du Colombier } 158*219b2ee8SDavid du Colombier Bfile = &(bfile->Biobufhdr); 159*219b2ee8SDavid du Colombier while ((n=Bread(Bfile, buf, Bsize)) > 0) { 160*219b2ee8SDavid du Colombier if (Bwrite(Bstdout, buf, n) != n) { 161*219b2ee8SDavid du Colombier return(1); 162*219b2ee8SDavid du Colombier } 163*219b2ee8SDavid du Colombier } 164*219b2ee8SDavid du Colombier if (n != 0) { 165*219b2ee8SDavid du Colombier return(1); 166*219b2ee8SDavid du Colombier } 167*219b2ee8SDavid du Colombier return(0); 168*219b2ee8SDavid du Colombier } 169*219b2ee8SDavid du Colombier 170*219b2ee8SDavid du Colombier void 171*219b2ee8SDavid du Colombier prologues(void) { 172*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", CONFORMING); 173*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %s\n", VERSION, PROGRAMVERSION); 174*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %s\n", DOCUMENTFONTS, ATEND); 175*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %s\n", PAGES, ATEND); 176*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", ENDCOMMENTS); 177*219b2ee8SDavid du Colombier 178*219b2ee8SDavid du Colombier if (cat(POSTPRINT)) { 179*219b2ee8SDavid du Colombier Bprint(Bstderr, "can't read %s", POSTPRINT); 180*219b2ee8SDavid du Colombier exits("prologue"); 181*219b2ee8SDavid du Colombier } 182*219b2ee8SDavid du Colombier 183*219b2ee8SDavid du Colombier if (DOROUND) 184*219b2ee8SDavid du Colombier cat(ROUNDPAGE); 185*219b2ee8SDavid du Colombier 186*219b2ee8SDavid du Colombier Bprint(Bstdout, "/f {findfont pointsize scalefont setfont} bind def\n"); 187*219b2ee8SDavid du Colombier Bprint(Bstdout, "/tabstop %g def\n", tabstop); 188*219b2ee8SDavid du Colombier Bprint(Bstdout, "/tabwidth /Courier f (nnnnnnnn) stringwidth pop def\n"); 189*219b2ee8SDavid du Colombier Bprint(Bstdout, "/tab {tabwidth 0 ne {currentpoint 3 1 roll exch tabwidth mul add tabwidth\n"); 190*219b2ee8SDavid du Colombier Bprint(Bstdout, "\tdiv truncate tabwidth mul exch moveto} if} bind def\n"); 191*219b2ee8SDavid du Colombier Bprint(Bstdout, "/spacewidth /%s f ( ) stringwidth pop def\n", fontname[0].str); 192*219b2ee8SDavid du Colombier Bprint(Bstdout, "/sp {spacewidth mul 0 rmoveto} bind def\n"); 193*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", ENDPROLOG); 194*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", BEGINSETUP); 195*219b2ee8SDavid du Colombier Bprint(Bstdout, "mark\n"); 196*219b2ee8SDavid du Colombier 197*219b2ee8SDavid du Colombier if (formsperpage > 1) { 198*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d\n", FORMSPERPAGE, formsperpage); 199*219b2ee8SDavid du Colombier Bprint(Bstdout, "/formsperpage %d def\n", formsperpage); 200*219b2ee8SDavid du Colombier } 201*219b2ee8SDavid du Colombier if (aspectratio != 1) Bprint(Bstdout, "/aspectratio %g def\n", aspectratio); 202*219b2ee8SDavid du Colombier if (copies != 1) Bprint(Bstdout, "/#copies %d store\n", copies); 203*219b2ee8SDavid du Colombier if (landscape) Bprint(Bstdout, "/landscape true def\n"); 204*219b2ee8SDavid du Colombier if (magnification != 1) Bprint(Bstdout, "/magnification %s def\n", magnification); 205*219b2ee8SDavid du Colombier if (pointsize != 10) Bprint(Bstdout, "/pointsize %d def\n", pointsize); 206*219b2ee8SDavid du Colombier if (xoffset != .25) Bprint(Bstdout, "/xoffset %g def\n", xoffset); 207*219b2ee8SDavid du Colombier if (yoffset != .25) Bprint(Bstdout, "/yoffset %g def\n", yoffset); 208*219b2ee8SDavid du Colombier cat(ENCODINGDIR"/Latin1.enc"); 209*219b2ee8SDavid du Colombier if (passthrough != 0) Bprint(Bstdout, "%s\n", passthrough); 210*219b2ee8SDavid du Colombier Bprint(Bstdout, "setup\n"); 211*219b2ee8SDavid du Colombier if (formsperpage > 1) { 212*219b2ee8SDavid du Colombier cat(FORMFILE); 213*219b2ee8SDavid du Colombier Bprint(Bstdout, "%d setupforms \n", formsperpage); 214*219b2ee8SDavid du Colombier } 215*219b2ee8SDavid du Colombier if (cat(UNKNOWNCHAR)) 216*219b2ee8SDavid du Colombier Bprint(Bstderr, "cannot open %s\n", UNKNOWNCHAR); 217*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", ENDSETUP); 218*219b2ee8SDavid du Colombier } 219*219b2ee8SDavid du Colombier 220*219b2ee8SDavid du Colombier int 221*219b2ee8SDavid du Colombier pageon(void) { 222*219b2ee8SDavid du Colombier if (pplist == 0 && page_no != 0) return(1); /* no page list, print all pages */ 223*219b2ee8SDavid du Colombier if (page_no/8 < pplistmaxsize && (pplist[page_no/8] & 1<<(page_no%8))) 224*219b2ee8SDavid du Colombier return(1); 225*219b2ee8SDavid du Colombier else 226*219b2ee8SDavid du Colombier return(0); 227*219b2ee8SDavid du Colombier } 228*219b2ee8SDavid du Colombier 229*219b2ee8SDavid du Colombier void 230*219b2ee8SDavid du Colombier startpage(void) { 231*219b2ee8SDavid du Colombier ++char_no; 232*219b2ee8SDavid du Colombier ++line_no; 233*219b2ee8SDavid du Colombier ++page_no; 234*219b2ee8SDavid du Colombier if (pageon()) { 235*219b2ee8SDavid du Colombier ++pages_printed; 236*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d %d\n", PAGE, page_no, pages_printed); 237*219b2ee8SDavid du Colombier Bprint(Bstdout, "/saveobj save def\n"); 238*219b2ee8SDavid du Colombier Bprint(Bstdout, "mark\n"); 239*219b2ee8SDavid du Colombier Bprint(Bstdout, "%d pagesetup\n", pages_printed); 240*219b2ee8SDavid du Colombier } 241*219b2ee8SDavid du Colombier } 242*219b2ee8SDavid du Colombier 243*219b2ee8SDavid du Colombier void 244*219b2ee8SDavid du Colombier endpage(void) { 245*219b2ee8SDavid du Colombier line_no = 0; 246*219b2ee8SDavid du Colombier char_no = 0; 247*219b2ee8SDavid du Colombier if (pageon()) { 248*219b2ee8SDavid du Colombier Bprint(Bstdout, "cleartomark\n"); 249*219b2ee8SDavid du Colombier Bprint(Bstdout, "showpage\n"); 250*219b2ee8SDavid du Colombier Bprint(Bstdout, "saveobj restore\n"); 251*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d %d\n", ENDPAGE, page_no, pages_printed); 252*219b2ee8SDavid du Colombier } 253*219b2ee8SDavid du Colombier } 254*219b2ee8SDavid du Colombier 255*219b2ee8SDavid du Colombier void 256*219b2ee8SDavid du Colombier startstring(void) { 257*219b2ee8SDavid du Colombier if (!in_string) { 258*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "("); 259*219b2ee8SDavid du Colombier in_string = 1; 260*219b2ee8SDavid du Colombier } 261*219b2ee8SDavid du Colombier } 262*219b2ee8SDavid du Colombier 263*219b2ee8SDavid du Colombier void 264*219b2ee8SDavid du Colombier endstring(void) { 265*219b2ee8SDavid du Colombier if (in_string) { 266*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, ") show "); 267*219b2ee8SDavid du Colombier in_string = 0; 268*219b2ee8SDavid du Colombier } 269*219b2ee8SDavid du Colombier } 270*219b2ee8SDavid du Colombier 271*219b2ee8SDavid du Colombier void 272*219b2ee8SDavid du Colombier prspace(void) { 273*219b2ee8SDavid du Colombier if (spaces) { 274*219b2ee8SDavid du Colombier endstring(); 275*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "%d sp ", spaces); 276*219b2ee8SDavid du Colombier spaces = 0; 277*219b2ee8SDavid du Colombier } 278*219b2ee8SDavid du Colombier } 279*219b2ee8SDavid du Colombier 280*219b2ee8SDavid du Colombier void 281*219b2ee8SDavid du Colombier prtab(void) { 282*219b2ee8SDavid du Colombier if (tabs) { 283*219b2ee8SDavid du Colombier endstring(); 284*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "%d tab ", tabs); 285*219b2ee8SDavid du Colombier tabs = 0; 286*219b2ee8SDavid du Colombier } 287*219b2ee8SDavid du Colombier } 288*219b2ee8SDavid du Colombier 289*219b2ee8SDavid du Colombier void 290*219b2ee8SDavid du Colombier txt2post(void) { 291*219b2ee8SDavid du Colombier int lastfont = -1; 292*219b2ee8SDavid du Colombier int lastchar = -1; 293*219b2ee8SDavid du Colombier int thisfont, thischar; 294*219b2ee8SDavid du Colombier long r; 295*219b2ee8SDavid du Colombier 296*219b2ee8SDavid du Colombier in_string = 0; 297*219b2ee8SDavid du Colombier char_no = 0; 298*219b2ee8SDavid du Colombier line_no = 0; 299*219b2ee8SDavid du Colombier page_no = 0; 300*219b2ee8SDavid du Colombier spaces = 0; 301*219b2ee8SDavid du Colombier fontname[0].used++; 302*219b2ee8SDavid du Colombier while ((r=Bgetrune(Bstdin)) >= 0) { 303*219b2ee8SDavid du Colombier thischar = r & 0xff; 304*219b2ee8SDavid du Colombier thisfont = (r>>8) & 0xff; 305*219b2ee8SDavid du Colombier 306*219b2ee8SDavid du Colombier if (line_no == 0 && char_no == 0) 307*219b2ee8SDavid du Colombier startpage(); 308*219b2ee8SDavid du Colombier 309*219b2ee8SDavid du Colombier if (line_no == 1 && char_no == 1) { 310*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, " /%s f\n", fontname[thisfont].str); 311*219b2ee8SDavid du Colombier lastfont = thisfont; 312*219b2ee8SDavid du Colombier } 313*219b2ee8SDavid du Colombier 314*219b2ee8SDavid du Colombier switch (r) { 315*219b2ee8SDavid du Colombier case ' ': 316*219b2ee8SDavid du Colombier prtab(); 317*219b2ee8SDavid du Colombier if (lastfont > 0) { 318*219b2ee8SDavid du Colombier spaces++; 319*219b2ee8SDavid du Colombier continue; 320*219b2ee8SDavid du Colombier } 321*219b2ee8SDavid du Colombier break; 322*219b2ee8SDavid du Colombier case '\n': 323*219b2ee8SDavid du Colombier case '\f': 324*219b2ee8SDavid du Colombier startstring(); 325*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, ")l\n"); 326*219b2ee8SDavid du Colombier char_no = 1; 327*219b2ee8SDavid du Colombier in_string = 0; 328*219b2ee8SDavid du Colombier spaces = 0; 329*219b2ee8SDavid du Colombier tabs = 0; 330*219b2ee8SDavid du Colombier if (++line_no > linesperpage || r == '\f') { 331*219b2ee8SDavid du Colombier endpage(); 332*219b2ee8SDavid du Colombier } 333*219b2ee8SDavid du Colombier lastchar = -1; 334*219b2ee8SDavid du Colombier continue; 335*219b2ee8SDavid du Colombier case '\t': 336*219b2ee8SDavid du Colombier prspace(); 337*219b2ee8SDavid du Colombier tabs++; 338*219b2ee8SDavid du Colombier char_no++; 339*219b2ee8SDavid du Colombier lastchar = -1; 340*219b2ee8SDavid du Colombier continue; 341*219b2ee8SDavid du Colombier case '\b': 342*219b2ee8SDavid du Colombier /* just toss out backspaces for now */ 343*219b2ee8SDavid du Colombier if (lastchar != -1) { 344*219b2ee8SDavid du Colombier endstring(); 345*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "(%s) stringwidth pop neg 0 rmoveto ", charcode[lastchar].str); 346*219b2ee8SDavid du Colombier } 347*219b2ee8SDavid du Colombier char_no++; 348*219b2ee8SDavid du Colombier lastchar = -1; 349*219b2ee8SDavid du Colombier continue; 350*219b2ee8SDavid du Colombier } 351*219b2ee8SDavid du Colombier 352*219b2ee8SDavid du Colombier /* do something if font is out of table range */ 353*219b2ee8SDavid du Colombier if (thisfont>=FONTABSIZE || fontname[thisfont].size == 0) { 354*219b2ee8SDavid du Colombier prspace(); 355*219b2ee8SDavid du Colombier prtab(); 356*219b2ee8SDavid du Colombier endstring(); 357*219b2ee8SDavid du Colombier Bprint(Bstdout, "pw "); 358*219b2ee8SDavid du Colombier char_no++; 359*219b2ee8SDavid du Colombier lastchar = -1; 360*219b2ee8SDavid du Colombier continue; 361*219b2ee8SDavid du Colombier } 362*219b2ee8SDavid du Colombier 363*219b2ee8SDavid du Colombier if (thisfont != lastfont) { 364*219b2ee8SDavid du Colombier endstring(); 365*219b2ee8SDavid du Colombier if (pageon()) { 366*219b2ee8SDavid du Colombier Bprint(Bstdout, "/%s f\n", fontname[thisfont].str); 367*219b2ee8SDavid du Colombier } 368*219b2ee8SDavid du Colombier fontname[thisfont].used++; 369*219b2ee8SDavid du Colombier } 370*219b2ee8SDavid du Colombier prspace(); 371*219b2ee8SDavid du Colombier prtab(); 372*219b2ee8SDavid du Colombier startstring(); 373*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "%s", charcode[thischar].str); 374*219b2ee8SDavid du Colombier /* if (pageon()) Bprint(Bstdout, "%2.2x", thischar); /* try hex strings*/ 375*219b2ee8SDavid du Colombier char_no++; 376*219b2ee8SDavid du Colombier lastchar = thischar; 377*219b2ee8SDavid du Colombier lastfont = thisfont; 378*219b2ee8SDavid du Colombier } 379*219b2ee8SDavid du Colombier if (line_no != 0 || char_no != 0) { 380*219b2ee8SDavid du Colombier if (char_no != 1) { 381*219b2ee8SDavid du Colombier Bprint(Bstderr, "premature EOF: newline appended\n"); 382*219b2ee8SDavid du Colombier startstring(); 383*219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, ")l\n"); 384*219b2ee8SDavid du Colombier } 385*219b2ee8SDavid du Colombier endpage(); 386*219b2ee8SDavid du Colombier } 387*219b2ee8SDavid du Colombier } 388*219b2ee8SDavid du Colombier 389*219b2ee8SDavid du Colombier void 390*219b2ee8SDavid du Colombier pagelist(char *list) { 391*219b2ee8SDavid du Colombier char c; 392*219b2ee8SDavid du Colombier int n, m; 393*219b2ee8SDavid du Colombier int state, start, end; 394*219b2ee8SDavid du Colombier 395*219b2ee8SDavid du Colombier if (list == 0) return; 396*219b2ee8SDavid du Colombier state = 1; 397*219b2ee8SDavid du Colombier while ((c=*list) != '\0') { 398*219b2ee8SDavid du Colombier n = 0; 399*219b2ee8SDavid du Colombier while (isdigit(c)) { 400*219b2ee8SDavid du Colombier n = n * 10 + c - '0'; 401*219b2ee8SDavid du Colombier c = *++list; 402*219b2ee8SDavid du Colombier } 403*219b2ee8SDavid du Colombier switch (state) { 404*219b2ee8SDavid du Colombier case 1: 405*219b2ee8SDavid du Colombier start = n; 406*219b2ee8SDavid du Colombier case 2: 407*219b2ee8SDavid du Colombier if (n/8+1 > pplistmaxsize) { 408*219b2ee8SDavid du Colombier pplistmaxsize = n/8+1; 409*219b2ee8SDavid du Colombier if ((pplist = realloc(pplist, n/8+1)) == 0) { 410*219b2ee8SDavid du Colombier Bprint(Bstderr, "cannot allocate memory for page list\n"); 411*219b2ee8SDavid du Colombier exits("malloc"); 412*219b2ee8SDavid du Colombier } 413*219b2ee8SDavid du Colombier } 414*219b2ee8SDavid du Colombier for (m=start; m<=n; m++) 415*219b2ee8SDavid du Colombier pplist[m/8] |= 1<<(m%8); 416*219b2ee8SDavid du Colombier break; 417*219b2ee8SDavid du Colombier } 418*219b2ee8SDavid du Colombier switch (c) { 419*219b2ee8SDavid du Colombier case '-': 420*219b2ee8SDavid du Colombier state = 2; 421*219b2ee8SDavid du Colombier list++; 422*219b2ee8SDavid du Colombier break; 423*219b2ee8SDavid du Colombier case ',': 424*219b2ee8SDavid du Colombier state = 1; 425*219b2ee8SDavid du Colombier list++; 426*219b2ee8SDavid du Colombier break; 427*219b2ee8SDavid du Colombier case '\0': 428*219b2ee8SDavid du Colombier break; 429*219b2ee8SDavid du Colombier } 430*219b2ee8SDavid du Colombier } 431*219b2ee8SDavid du Colombier } 432*219b2ee8SDavid du Colombier 433*219b2ee8SDavid du Colombier void 434*219b2ee8SDavid du Colombier finish(void) { 435*219b2ee8SDavid du Colombier int i; 436*219b2ee8SDavid du Colombier 437*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", TRAILER); 438*219b2ee8SDavid du Colombier Bprint(Bstdout, "done\n"); 439*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", DOCUMENTFONTS); 440*219b2ee8SDavid du Colombier 441*219b2ee8SDavid du Colombier for (i=0; i<FONTABSIZE; i++) 442*219b2ee8SDavid du Colombier if (fontname[i].used) 443*219b2ee8SDavid du Colombier Bprint(Bstdout, " %s", fontname[i].str); 444*219b2ee8SDavid du Colombier Bprint(Bstdout, "\n"); 445*219b2ee8SDavid du Colombier 446*219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d\n", PAGES, pages_printed); 447*219b2ee8SDavid du Colombier 448*219b2ee8SDavid du Colombier } 449*219b2ee8SDavid du Colombier 450*219b2ee8SDavid du Colombier main(int argc, char *argv[]) { 451*219b2ee8SDavid du Colombier int i; 452*219b2ee8SDavid du Colombier char *t; 453*219b2ee8SDavid du Colombier Biobuf *input; 454*219b2ee8SDavid du Colombier 455*219b2ee8SDavid du Colombier if ((bstderr = (Biobuf *)malloc(sizeof(Biobuf))) < (Biobuf *)0) 456*219b2ee8SDavid du Colombier exits("malloc"); 457*219b2ee8SDavid du Colombier if (Binit(bstderr, 2, OWRITE) == Beof) 458*219b2ee8SDavid du Colombier exits("Binit"); 459*219b2ee8SDavid du Colombier Bstderr = &(bstderr->Biobufhdr); 460*219b2ee8SDavid du Colombier 461*219b2ee8SDavid du Colombier if ((bstdout = (Biobuf *)malloc(sizeof(Biobuf))) < (Biobuf *)0) 462*219b2ee8SDavid du Colombier exits("malloc"); 463*219b2ee8SDavid du Colombier if (Binit(bstdout, 1, OWRITE) == Beof) 464*219b2ee8SDavid du Colombier exits("Binit"); 465*219b2ee8SDavid du Colombier Bstdout = &(bstdout->Biobufhdr); 466*219b2ee8SDavid du Colombier 467*219b2ee8SDavid du Colombier ARGBEGIN{ 468*219b2ee8SDavid du Colombier case 'a': /* aspect ratio */ 469*219b2ee8SDavid du Colombier aspectratio = atof(ARGF()); 470*219b2ee8SDavid du Colombier break; 471*219b2ee8SDavid du Colombier case 'c': /* copies */ 472*219b2ee8SDavid du Colombier copies = atoi(ARGF()); 473*219b2ee8SDavid du Colombier break; 474*219b2ee8SDavid du Colombier case 'f': /* primary font, for now */ 475*219b2ee8SDavid du Colombier t = ARGF(); 476*219b2ee8SDavid du Colombier fontname[0].str = malloc(strlen(t)+1); 477*219b2ee8SDavid du Colombier strcpy(fontname[0].str, t); 478*219b2ee8SDavid du Colombier break; 479*219b2ee8SDavid du Colombier case 'l': /* lines per page */ 480*219b2ee8SDavid du Colombier linesperpage = atoi(ARGF()); 481*219b2ee8SDavid du Colombier break; 482*219b2ee8SDavid du Colombier case 'm': /* magnification */ 483*219b2ee8SDavid du Colombier magnification = atof(ARGF()); 484*219b2ee8SDavid du Colombier break; 485*219b2ee8SDavid du Colombier case 'n': /* forms per page */ 486*219b2ee8SDavid du Colombier formsperpage = atoi(ARGF()); 487*219b2ee8SDavid du Colombier break; 488*219b2ee8SDavid du Colombier case 'o': /* output page list */ 489*219b2ee8SDavid du Colombier pagelist(ARGF()); 490*219b2ee8SDavid du Colombier break; 491*219b2ee8SDavid du Colombier case 'p': /* landscape or portrait mode */ 492*219b2ee8SDavid du Colombier if ( ARGF()[0] == 'l' ) 493*219b2ee8SDavid du Colombier landscape = 1; 494*219b2ee8SDavid du Colombier else 495*219b2ee8SDavid du Colombier landscape = 0; 496*219b2ee8SDavid du Colombier break; 497*219b2ee8SDavid du Colombier case 's': /* point size */ 498*219b2ee8SDavid du Colombier pointsize = atoi(ARGF()); 499*219b2ee8SDavid du Colombier break; 500*219b2ee8SDavid du Colombier case 't': /* tabstop */ 501*219b2ee8SDavid du Colombier tabstop = atof(ARGF()); 502*219b2ee8SDavid du Colombier break; 503*219b2ee8SDavid du Colombier case 'x': /* shift things horizontally */ 504*219b2ee8SDavid du Colombier xoffset = atof(ARGF()); 505*219b2ee8SDavid du Colombier break; 506*219b2ee8SDavid du Colombier 507*219b2ee8SDavid du Colombier case 'y': /* and vertically on the page */ 508*219b2ee8SDavid du Colombier yoffset = atof(ARGF()); 509*219b2ee8SDavid du Colombier break; 510*219b2ee8SDavid du Colombier case 'P': /* PostScript pass through */ 511*219b2ee8SDavid du Colombier t = ARGF(); 512*219b2ee8SDavid du Colombier i = strlen(t) + 1; 513*219b2ee8SDavid du Colombier passthrough = malloc(i); 514*219b2ee8SDavid du Colombier if (passthrough == 0) { 515*219b2ee8SDavid du Colombier Bprint(Bstderr, "cannot allocate memory for argument string\n"); 516*219b2ee8SDavid du Colombier exits("malloc"); 517*219b2ee8SDavid du Colombier } 518*219b2ee8SDavid du Colombier strncpy(passthrough, t, i); 519*219b2ee8SDavid du Colombier break; 520*219b2ee8SDavid du Colombier default: /* don't know what to do for ch */ 521*219b2ee8SDavid du Colombier Bprint(Bstderr, "unknown option %C\n", ARGC()); 522*219b2ee8SDavid du Colombier break; 523*219b2ee8SDavid du Colombier }ARGEND; 524*219b2ee8SDavid du Colombier prologues(); 525*219b2ee8SDavid du Colombier if (argc <= 0) { 526*219b2ee8SDavid du Colombier if ((bstdin = (Biobuf *)malloc(sizeof(Biobuf))) < (Biobuf *)0) 527*219b2ee8SDavid du Colombier exits("malloc"); 528*219b2ee8SDavid du Colombier if (Binit(bstdin, 0, OREAD) == Beof) { 529*219b2ee8SDavid du Colombier fprint(2, "cannot Binit stdin\n"); 530*219b2ee8SDavid du Colombier exits("Binit"); 531*219b2ee8SDavid du Colombier } 532*219b2ee8SDavid du Colombier Bstdin = &(bstdin->Biobufhdr); 533*219b2ee8SDavid du Colombier txt2post(); 534*219b2ee8SDavid du Colombier } 535*219b2ee8SDavid du Colombier for (i=0; i<argc; i++) { 536*219b2ee8SDavid du Colombier bstdin = Bopen(argv[i], 0); 537*219b2ee8SDavid du Colombier if (bstdin == 0) { 538*219b2ee8SDavid du Colombier fprint(2, "cannot open file %s\n", argv[i]); 539*219b2ee8SDavid du Colombier continue; 540*219b2ee8SDavid du Colombier } 541*219b2ee8SDavid du Colombier Bstdin = &(bstdin->Biobufhdr); 542*219b2ee8SDavid du Colombier txt2post(); 543*219b2ee8SDavid du Colombier } 544*219b2ee8SDavid du Colombier finish(); 545*219b2ee8SDavid du Colombier exits(""); 546*219b2ee8SDavid du Colombier } 547