1219b2ee8SDavid du Colombier #include <u.h> 2219b2ee8SDavid du Colombier #include <libc.h> 3219b2ee8SDavid du Colombier #include <ctype.h> 4219b2ee8SDavid du Colombier #include <bio.h> 5219b2ee8SDavid du Colombier #include <comments.h> 6219b2ee8SDavid du Colombier #include <path.h> 7219b2ee8SDavid du Colombier 8219b2ee8SDavid du Colombier #define UNKNOWNCHAR "/sys/lib/postscript/prologues/pjw.char.ps" 9219b2ee8SDavid du Colombier 10219b2ee8SDavid du Colombier char *optnames = "a:c:f:l:m:n:o:p:s:t:x:y:P:"; 11219b2ee8SDavid du Colombier 12219b2ee8SDavid du Colombier Biobuf *bstdin, *bstdout, *bstderr; 13219b2ee8SDavid du Colombier Biobufhdr *Bstdin, *Bstdout, *Bstderr; 14219b2ee8SDavid du Colombier int char_no = 0; /* character to be done on a line */ 15219b2ee8SDavid du Colombier int line_no = 0; /* line number on a page */ 16219b2ee8SDavid du Colombier int page_no = 0; /* page number in a document */ 17219b2ee8SDavid du Colombier int in_string; /* Boolean, to know whether or not we are inside a Postscript string */ 18219b2ee8SDavid du Colombier int spaces = 0; 19219b2ee8SDavid du Colombier int tabs = 0; 20219b2ee8SDavid du Colombier int pages_printed; 21219b2ee8SDavid du Colombier double aspectratio = 1.0; 22219b2ee8SDavid du Colombier int copies = 1; 23219b2ee8SDavid du Colombier double magnification = 1.0; 24219b2ee8SDavid du Colombier int landscape = 0; 25219b2ee8SDavid du Colombier int formsperpage = 1; 26219b2ee8SDavid du Colombier int linesperpage = 66; 27219b2ee8SDavid du Colombier int pointsize = 10; 28219b2ee8SDavid du Colombier double xoffset = .25; 29219b2ee8SDavid du Colombier double yoffset = .25; 30219b2ee8SDavid du Colombier char *passthrough = 0; 31219b2ee8SDavid du Colombier static int pplistmaxsize=0; 32219b2ee8SDavid du Colombier 33219b2ee8SDavid du Colombier unsigned char *pplist=0; /* bitmap list for storing pages to print */ 34219b2ee8SDavid du Colombier 35219b2ee8SDavid du Colombier struct strtab { 36219b2ee8SDavid du Colombier int size; 37219b2ee8SDavid du Colombier char *str; 38219b2ee8SDavid du Colombier int used; 39219b2ee8SDavid du Colombier }; 40219b2ee8SDavid du Colombier 41219b2ee8SDavid du Colombier struct strtab charcode[256] = { 42219b2ee8SDavid du Colombier {4, "\\000"}, {4, "\\001"}, {4, "\\002"}, {4, "\\003"}, 43219b2ee8SDavid du Colombier {4, "\\004"}, {4, "\\005"}, {4, "\\006"}, {4, "\\007"}, 44219b2ee8SDavid du Colombier {4, "\\010"}, {4, "\\011"}, {4, "\\012"}, {4, "\\013"}, 45219b2ee8SDavid du Colombier {4, "\\014"}, {4, "\\015"}, {4, "\\016"}, {4, "\\017"}, 46219b2ee8SDavid du Colombier {4, "\\020"}, {4, "\\021"}, {4, "\\022"}, {4, "\\023"}, 47219b2ee8SDavid du Colombier {4, "\\024"}, {4, "\\025"}, {4, "\\026"}, {4, "\\027"}, 48219b2ee8SDavid du Colombier {4, "\\030"}, {4, "\\031"}, {4, "\\032"}, {4, "\\033"}, 49219b2ee8SDavid du Colombier {4, "\\034"}, {4, "\\035"}, {4, "\\036"}, {4, "\\037"}, 50219b2ee8SDavid du Colombier {1, " "}, {1, "!"}, {1, "\""}, {1, "#"}, 51219b2ee8SDavid du Colombier {1, "$"}, {1, "%"}, {1, "&"}, {1, "'"}, 52219b2ee8SDavid du Colombier {2, "\\("}, {2, "\\)"}, {1, "*"}, {1, "+"}, 53219b2ee8SDavid du Colombier {1, ","}, {1, "-"}, {1, "."}, {1, "/"}, 54219b2ee8SDavid du Colombier {1, "0"}, {1, "1"}, {1, "2"}, {1, "3"}, 55219b2ee8SDavid du Colombier {1, "4"}, {1, "5"}, {1, "6"}, {1, "7"}, 56219b2ee8SDavid du Colombier {1, "8"}, {1, "9"}, {1, ":"}, {1, ";"}, 57219b2ee8SDavid du Colombier {1, "<"}, {1, "="}, {1, ">"}, {1, "?"}, 58219b2ee8SDavid du Colombier {1, "@"}, {1, "A"}, {1, "B"}, {1, "C"}, 59219b2ee8SDavid du Colombier {1, "D"}, {1, "E"}, {1, "F"}, {1, "G"}, 60219b2ee8SDavid du Colombier {1, "H"}, {1, "I"}, {1, "J"}, {1, "K"}, 61219b2ee8SDavid du Colombier {1, "L"}, {1, "M"}, {1, "N"}, {1, "O"}, 62219b2ee8SDavid du Colombier {1, "P"}, {1, "Q"}, {1, "R"}, {1, "S"}, 63219b2ee8SDavid du Colombier {1, "T"}, {1, "U"}, {1, "V"}, {1, "W"}, 64219b2ee8SDavid du Colombier {1, "X"}, {1, "Y"}, {1, "Z"}, {1, "["}, 65219b2ee8SDavid du Colombier {2, "\\\\"}, {1, "]"}, {1, "^"}, {1, "_"}, 66219b2ee8SDavid du Colombier {1, "`"}, {1, "a"}, {1, "b"}, {1, "c"}, 67219b2ee8SDavid du Colombier {1, "d"}, {1, "e"}, {1, "f"}, {1, "g"}, 68219b2ee8SDavid du Colombier {1, "h"}, {1, "i"}, {1, "j"}, {1, "k"}, 69219b2ee8SDavid du Colombier {1, "l"}, {1, "m"}, {1, "n"}, {1, "o"}, 70219b2ee8SDavid du Colombier {1, "p"}, {1, "q"}, {1, "r"}, {1, "s"}, 71219b2ee8SDavid du Colombier {1, "t"}, {1, "u"}, {1, "v"}, {1, "w"}, 72219b2ee8SDavid du Colombier {1, "x"}, {1, "y"}, {1, "z"}, {1, "{"}, 73219b2ee8SDavid du Colombier {1, "|"}, {1, "}"}, {1, "~"}, {4, "\\177"}, 74219b2ee8SDavid du Colombier {4, "\\200"}, {4, "\\201"}, {4, "\\202"}, {4, "\\203"}, 75219b2ee8SDavid du Colombier {4, "\\204"}, {4, "\\205"}, {4, "\\206"}, {4, "\\207"}, 76219b2ee8SDavid du Colombier {4, "\\210"}, {4, "\\211"}, {4, "\\212"}, {4, "\\213"}, 77219b2ee8SDavid du Colombier {4, "\\214"}, {4, "\\215"}, {4, "\\216"}, {4, "\\217"}, 78219b2ee8SDavid du Colombier {4, "\\220"}, {4, "\\221"}, {4, "\\222"}, {4, "\\223"}, 79219b2ee8SDavid du Colombier {4, "\\224"}, {4, "\\225"}, {4, "\\226"}, {4, "\\227"}, 80219b2ee8SDavid du Colombier {4, "\\230"}, {4, "\\231"}, {4, "\\232"}, {4, "\\233"}, 81219b2ee8SDavid du Colombier {4, "\\234"}, {4, "\\235"}, {4, "\\236"}, {4, "\\237"}, 82219b2ee8SDavid du Colombier {4, "\\240"}, {4, "\\241"}, {4, "\\242"}, {4, "\\243"}, 83219b2ee8SDavid du Colombier {4, "\\244"}, {4, "\\245"}, {4, "\\246"}, {4, "\\247"}, 84219b2ee8SDavid du Colombier {4, "\\250"}, {4, "\\251"}, {4, "\\252"}, {4, "\\253"}, 85219b2ee8SDavid du Colombier {4, "\\254"}, {4, "\\255"}, {4, "\\256"}, {4, "\\257"}, 86219b2ee8SDavid du Colombier {4, "\\260"}, {4, "\\261"}, {4, "\\262"}, {4, "\\263"}, 87219b2ee8SDavid du Colombier {4, "\\264"}, {4, "\\265"}, {4, "\\266"}, {4, "\\267"}, 88219b2ee8SDavid du Colombier {4, "\\270"}, {4, "\\271"}, {4, "\\272"}, {4, "\\273"}, 89219b2ee8SDavid du Colombier {4, "\\274"}, {4, "\\275"}, {4, "\\276"}, {4, "\\277"}, 90219b2ee8SDavid du Colombier {4, "\\300"}, {4, "\\301"}, {4, "\\302"}, {4, "\\303"}, 91219b2ee8SDavid du Colombier {4, "\\304"}, {4, "\\305"}, {4, "\\306"}, {4, "\\307"}, 92219b2ee8SDavid du Colombier {4, "\\310"}, {4, "\\311"}, {4, "\\312"}, {4, "\\313"}, 93219b2ee8SDavid du Colombier {4, "\\314"}, {4, "\\315"}, {4, "\\316"}, {4, "\\317"}, 94219b2ee8SDavid du Colombier {4, "\\320"}, {4, "\\321"}, {4, "\\322"}, {4, "\\323"}, 95219b2ee8SDavid du Colombier {4, "\\324"}, {4, "\\325"}, {4, "\\326"}, {4, "\\327"}, 96219b2ee8SDavid du Colombier {4, "\\330"}, {4, "\\331"}, {4, "\\332"}, {4, "\\333"}, 97219b2ee8SDavid du Colombier {4, "\\334"}, {4, "\\335"}, {4, "\\336"}, {4, "\\337"}, 98219b2ee8SDavid du Colombier {4, "\\340"}, {4, "\\341"}, {4, "\\342"}, {4, "\\343"}, 99219b2ee8SDavid du Colombier {4, "\\344"}, {4, "\\345"}, {4, "\\346"}, {4, "\\347"}, 100219b2ee8SDavid du Colombier {4, "\\350"}, {4, "\\351"}, {4, "\\352"}, {4, "\\353"}, 101219b2ee8SDavid du Colombier {4, "\\354"}, {4, "\\355"}, {4, "\\356"}, {4, "\\357"}, 102219b2ee8SDavid du Colombier {4, "\\360"}, {4, "\\361"}, {4, "\\362"}, {4, "\\363"}, 103219b2ee8SDavid du Colombier {4, "\\364"}, {4, "\\365"}, {4, "\\366"}, {4, "\\367"}, 104219b2ee8SDavid du Colombier {4, "\\370"}, {4, "\\371"}, {4, "\\372"}, {4, "\\373"}, 105219b2ee8SDavid du Colombier {4, "\\374"}, {4, "\\375"}, {4, "\\376"}, {4, "\\377"} 106219b2ee8SDavid du Colombier }; 107219b2ee8SDavid du Colombier 108*7dd7cddfSDavid du Colombier #define FONTABSIZE 0x27 109219b2ee8SDavid du Colombier 110219b2ee8SDavid du Colombier struct strtab fontname[FONTABSIZE] = { 111219b2ee8SDavid du Colombier {19, "LucidaSansUnicode00", 0}, 112219b2ee8SDavid du Colombier {19, "LucidaSansUnicode01", 0}, 113219b2ee8SDavid du Colombier {19, "LucidaSansUnicode02", 0}, 114219b2ee8SDavid du Colombier {19, "LucidaSansUnicode03", 0}, 115219b2ee8SDavid du Colombier {19, "LucidaSansUnicode04", 0}, 116219b2ee8SDavid du Colombier {19, "LucidaSansUnicode05", 0}, 117219b2ee8SDavid du Colombier {0, "", 0}, 118219b2ee8SDavid du Colombier {0, "", 0}, 119219b2ee8SDavid du Colombier {0, "", 0}, 120219b2ee8SDavid du Colombier {0, "", 0}, 121219b2ee8SDavid du Colombier {0, "", 0}, 122219b2ee8SDavid du Colombier {0, "", 0}, 123219b2ee8SDavid du Colombier {0, "", 0}, 124219b2ee8SDavid du Colombier {0, "", 0}, 125219b2ee8SDavid du Colombier {0, "", 0}, 126219b2ee8SDavid du Colombier {0, "", 0}, 127219b2ee8SDavid du Colombier {0, "", 0}, 128219b2ee8SDavid du Colombier {0, "", 0}, 129219b2ee8SDavid du Colombier {0, "", 0}, 130219b2ee8SDavid du Colombier {0, "", 0}, 131*7dd7cddfSDavid du Colombier {0, "", 0}, 132*7dd7cddfSDavid du Colombier {0, "", 0}, 133*7dd7cddfSDavid du Colombier {0, "", 0}, 134*7dd7cddfSDavid du Colombier {0, "", 0}, 135*7dd7cddfSDavid du Colombier {0, "", 0}, 136*7dd7cddfSDavid du Colombier {0, "", 0}, 137*7dd7cddfSDavid du Colombier {0, "", 0}, 138*7dd7cddfSDavid du Colombier {0, "", 0}, 139*7dd7cddfSDavid du Colombier {0, "", 0}, 140*7dd7cddfSDavid du Colombier {0, "", 0}, 141*7dd7cddfSDavid du Colombier {0, "", 0}, 142*7dd7cddfSDavid du Colombier {0, "", 0}, 143219b2ee8SDavid du Colombier {19, "LucidaSansUnicode20", 0}, 144219b2ee8SDavid du Colombier {19, "LucidaSansUnicode21", 0}, 145219b2ee8SDavid du Colombier {19, "LucidaSansUnicode22", 0}, 146219b2ee8SDavid du Colombier {0, "", 0}, 147219b2ee8SDavid du Colombier {19, "LucidaSansUnicode24", 0}, 148219b2ee8SDavid du Colombier {19, "LucidaSansUnicode25", 0}, 149219b2ee8SDavid du Colombier {7, "Courier", 0} 150219b2ee8SDavid du Colombier }; 151219b2ee8SDavid du Colombier 152219b2ee8SDavid du Colombier /* This was taken from postprint */ 153219b2ee8SDavid du Colombier 154219b2ee8SDavid du Colombier int 155219b2ee8SDavid du Colombier cat(char *filename) { 156219b2ee8SDavid du Colombier Biobuf *bfile; 157219b2ee8SDavid du Colombier Biobufhdr *Bfile; 158219b2ee8SDavid du Colombier int n; 159219b2ee8SDavid du Colombier static char buf[Bsize]; 160219b2ee8SDavid du Colombier 161219b2ee8SDavid du Colombier bstdin = Bopen(filename, 0); 162219b2ee8SDavid du Colombier if (bstdin == 0) { 163219b2ee8SDavid du Colombier return(1); 164219b2ee8SDavid du Colombier } 165219b2ee8SDavid du Colombier Bstdin = &(bstdin->Biobufhdr); 166219b2ee8SDavid du Colombier if ((bfile = Bopen(filename, OREAD)) == 0) { 167219b2ee8SDavid du Colombier return(1); 168219b2ee8SDavid du Colombier } 169219b2ee8SDavid du Colombier Bfile = &(bfile->Biobufhdr); 170219b2ee8SDavid du Colombier while ((n=Bread(Bfile, buf, Bsize)) > 0) { 171219b2ee8SDavid du Colombier if (Bwrite(Bstdout, buf, n) != n) { 172219b2ee8SDavid du Colombier return(1); 173219b2ee8SDavid du Colombier } 174219b2ee8SDavid du Colombier } 175219b2ee8SDavid du Colombier if (n != 0) { 176219b2ee8SDavid du Colombier return(1); 177219b2ee8SDavid du Colombier } 178219b2ee8SDavid du Colombier return(0); 179219b2ee8SDavid du Colombier } 180219b2ee8SDavid du Colombier 181219b2ee8SDavid du Colombier void 182219b2ee8SDavid du Colombier prologues(void) { 183*7dd7cddfSDavid du Colombier char *ts; 184*7dd7cddfSDavid du Colombier int tabstop; 185*7dd7cddfSDavid du Colombier 186219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", CONFORMING); 187219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %s\n", VERSION, PROGRAMVERSION); 188219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %s\n", DOCUMENTFONTS, ATEND); 189219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %s\n", PAGES, ATEND); 190219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", ENDCOMMENTS); 191219b2ee8SDavid du Colombier 192219b2ee8SDavid du Colombier if (cat(POSTPRINT)) { 193219b2ee8SDavid du Colombier Bprint(Bstderr, "can't read %s", POSTPRINT); 194219b2ee8SDavid du Colombier exits("prologue"); 195219b2ee8SDavid du Colombier } 196219b2ee8SDavid du Colombier 197219b2ee8SDavid du Colombier if (DOROUND) 198219b2ee8SDavid du Colombier cat(ROUNDPAGE); 199219b2ee8SDavid du Colombier 200*7dd7cddfSDavid du Colombier tabstop = 0; 201*7dd7cddfSDavid du Colombier ts = getenv("tabstop"); 202*7dd7cddfSDavid du Colombier if(ts != nil) 203*7dd7cddfSDavid du Colombier tabstop = strtol(ts, nil, 0); 204*7dd7cddfSDavid du Colombier if(tabstop == 0) 205*7dd7cddfSDavid du Colombier tabstop = 8; 206219b2ee8SDavid du Colombier Bprint(Bstdout, "/f {findfont pointsize scalefont setfont} bind def\n"); 207*7dd7cddfSDavid du Colombier Bprint(Bstdout, "/tabwidth /Courier f ("); 208*7dd7cddfSDavid du Colombier while(tabstop--) 209*7dd7cddfSDavid du Colombier Bputc(Bstdout, 'n'); 210*7dd7cddfSDavid du Colombier Bprint(Bstdout, ") stringwidth pop def\n"); 211219b2ee8SDavid du Colombier Bprint(Bstdout, "/tab {tabwidth 0 ne {currentpoint 3 1 roll exch tabwidth mul add tabwidth\n"); 212219b2ee8SDavid du Colombier Bprint(Bstdout, "\tdiv truncate tabwidth mul exch moveto} if} bind def\n"); 213219b2ee8SDavid du Colombier Bprint(Bstdout, "/spacewidth /%s f ( ) stringwidth pop def\n", fontname[0].str); 214219b2ee8SDavid du Colombier Bprint(Bstdout, "/sp {spacewidth mul 0 rmoveto} bind def\n"); 215219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", ENDPROLOG); 216219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", BEGINSETUP); 217219b2ee8SDavid du Colombier Bprint(Bstdout, "mark\n"); 218219b2ee8SDavid du Colombier 219219b2ee8SDavid du Colombier if (formsperpage > 1) { 220219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d\n", FORMSPERPAGE, formsperpage); 221219b2ee8SDavid du Colombier Bprint(Bstdout, "/formsperpage %d def\n", formsperpage); 222219b2ee8SDavid du Colombier } 223219b2ee8SDavid du Colombier if (aspectratio != 1) Bprint(Bstdout, "/aspectratio %g def\n", aspectratio); 224219b2ee8SDavid du Colombier if (copies != 1) Bprint(Bstdout, "/#copies %d store\n", copies); 225219b2ee8SDavid du Colombier if (landscape) Bprint(Bstdout, "/landscape true def\n"); 226219b2ee8SDavid du Colombier if (magnification != 1) Bprint(Bstdout, "/magnification %s def\n", magnification); 227219b2ee8SDavid du Colombier if (pointsize != 10) Bprint(Bstdout, "/pointsize %d def\n", pointsize); 228219b2ee8SDavid du Colombier if (xoffset != .25) Bprint(Bstdout, "/xoffset %g def\n", xoffset); 229219b2ee8SDavid du Colombier if (yoffset != .25) Bprint(Bstdout, "/yoffset %g def\n", yoffset); 230219b2ee8SDavid du Colombier cat(ENCODINGDIR"/Latin1.enc"); 231219b2ee8SDavid du Colombier if (passthrough != 0) Bprint(Bstdout, "%s\n", passthrough); 232219b2ee8SDavid du Colombier Bprint(Bstdout, "setup\n"); 233219b2ee8SDavid du Colombier if (formsperpage > 1) { 234219b2ee8SDavid du Colombier cat(FORMFILE); 235219b2ee8SDavid du Colombier Bprint(Bstdout, "%d setupforms \n", formsperpage); 236219b2ee8SDavid du Colombier } 237219b2ee8SDavid du Colombier if (cat(UNKNOWNCHAR)) 238219b2ee8SDavid du Colombier Bprint(Bstderr, "cannot open %s\n", UNKNOWNCHAR); 239219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", ENDSETUP); 240219b2ee8SDavid du Colombier } 241219b2ee8SDavid du Colombier 242219b2ee8SDavid du Colombier int 243219b2ee8SDavid du Colombier pageon(void) { 244219b2ee8SDavid du Colombier if (pplist == 0 && page_no != 0) return(1); /* no page list, print all pages */ 245219b2ee8SDavid du Colombier if (page_no/8 < pplistmaxsize && (pplist[page_no/8] & 1<<(page_no%8))) 246219b2ee8SDavid du Colombier return(1); 247219b2ee8SDavid du Colombier else 248219b2ee8SDavid du Colombier return(0); 249219b2ee8SDavid du Colombier } 250219b2ee8SDavid du Colombier 251219b2ee8SDavid du Colombier void 252219b2ee8SDavid du Colombier startpage(void) { 253219b2ee8SDavid du Colombier ++char_no; 254219b2ee8SDavid du Colombier ++line_no; 255219b2ee8SDavid du Colombier ++page_no; 256219b2ee8SDavid du Colombier if (pageon()) { 257219b2ee8SDavid du Colombier ++pages_printed; 258219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d %d\n", PAGE, page_no, pages_printed); 259219b2ee8SDavid du Colombier Bprint(Bstdout, "/saveobj save def\n"); 260219b2ee8SDavid du Colombier Bprint(Bstdout, "mark\n"); 261219b2ee8SDavid du Colombier Bprint(Bstdout, "%d pagesetup\n", pages_printed); 262219b2ee8SDavid du Colombier } 263219b2ee8SDavid du Colombier } 264219b2ee8SDavid du Colombier 265219b2ee8SDavid du Colombier void 266219b2ee8SDavid du Colombier endpage(void) { 267219b2ee8SDavid du Colombier line_no = 0; 268219b2ee8SDavid du Colombier char_no = 0; 269219b2ee8SDavid du Colombier if (pageon()) { 270219b2ee8SDavid du Colombier Bprint(Bstdout, "cleartomark\n"); 271219b2ee8SDavid du Colombier Bprint(Bstdout, "showpage\n"); 272219b2ee8SDavid du Colombier Bprint(Bstdout, "saveobj restore\n"); 273219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d %d\n", ENDPAGE, page_no, pages_printed); 274219b2ee8SDavid du Colombier } 275219b2ee8SDavid du Colombier } 276219b2ee8SDavid du Colombier 277219b2ee8SDavid du Colombier void 278219b2ee8SDavid du Colombier startstring(void) { 279219b2ee8SDavid du Colombier if (!in_string) { 280219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "("); 281219b2ee8SDavid du Colombier in_string = 1; 282219b2ee8SDavid du Colombier } 283219b2ee8SDavid du Colombier } 284219b2ee8SDavid du Colombier 285219b2ee8SDavid du Colombier void 286219b2ee8SDavid du Colombier endstring(void) { 287219b2ee8SDavid du Colombier if (in_string) { 288219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, ") show "); 289219b2ee8SDavid du Colombier in_string = 0; 290219b2ee8SDavid du Colombier } 291219b2ee8SDavid du Colombier } 292219b2ee8SDavid du Colombier 293219b2ee8SDavid du Colombier void 294219b2ee8SDavid du Colombier prspace(void) { 295219b2ee8SDavid du Colombier if (spaces) { 296219b2ee8SDavid du Colombier endstring(); 297219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "%d sp ", spaces); 298219b2ee8SDavid du Colombier spaces = 0; 299219b2ee8SDavid du Colombier } 300219b2ee8SDavid du Colombier } 301219b2ee8SDavid du Colombier 302219b2ee8SDavid du Colombier void 303219b2ee8SDavid du Colombier prtab(void) { 304219b2ee8SDavid du Colombier if (tabs) { 305219b2ee8SDavid du Colombier endstring(); 306219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "%d tab ", tabs); 307219b2ee8SDavid du Colombier tabs = 0; 308219b2ee8SDavid du Colombier } 309219b2ee8SDavid du Colombier } 310219b2ee8SDavid du Colombier 311219b2ee8SDavid du Colombier void 312219b2ee8SDavid du Colombier txt2post(void) { 313219b2ee8SDavid du Colombier int lastfont = -1; 314219b2ee8SDavid du Colombier int lastchar = -1; 315219b2ee8SDavid du Colombier int thisfont, thischar; 316219b2ee8SDavid du Colombier long r; 317219b2ee8SDavid du Colombier 318219b2ee8SDavid du Colombier in_string = 0; 319219b2ee8SDavid du Colombier char_no = 0; 320219b2ee8SDavid du Colombier line_no = 0; 321219b2ee8SDavid du Colombier page_no = 0; 322219b2ee8SDavid du Colombier spaces = 0; 323219b2ee8SDavid du Colombier fontname[0].used++; 324219b2ee8SDavid du Colombier while ((r=Bgetrune(Bstdin)) >= 0) { 325219b2ee8SDavid du Colombier thischar = r & 0xff; 326219b2ee8SDavid du Colombier thisfont = (r>>8) & 0xff; 327219b2ee8SDavid du Colombier 328219b2ee8SDavid du Colombier if (line_no == 0 && char_no == 0) 329219b2ee8SDavid du Colombier startpage(); 330219b2ee8SDavid du Colombier 331219b2ee8SDavid du Colombier if (line_no == 1 && char_no == 1) { 332219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, " /%s f\n", fontname[thisfont].str); 333219b2ee8SDavid du Colombier lastfont = thisfont; 334219b2ee8SDavid du Colombier } 335219b2ee8SDavid du Colombier 336219b2ee8SDavid du Colombier switch (r) { 337219b2ee8SDavid du Colombier case ' ': 338219b2ee8SDavid du Colombier prtab(); 339219b2ee8SDavid du Colombier if (lastfont > 0) { 340219b2ee8SDavid du Colombier spaces++; 341219b2ee8SDavid du Colombier continue; 342219b2ee8SDavid du Colombier } 343219b2ee8SDavid du Colombier break; 344219b2ee8SDavid du Colombier case '\n': 345219b2ee8SDavid du Colombier case '\f': 346219b2ee8SDavid du Colombier startstring(); 347219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, ")l\n"); 348219b2ee8SDavid du Colombier char_no = 1; 349219b2ee8SDavid du Colombier in_string = 0; 350219b2ee8SDavid du Colombier spaces = 0; 351219b2ee8SDavid du Colombier tabs = 0; 352219b2ee8SDavid du Colombier if (++line_no > linesperpage || r == '\f') { 353219b2ee8SDavid du Colombier endpage(); 354219b2ee8SDavid du Colombier } 355219b2ee8SDavid du Colombier lastchar = -1; 356219b2ee8SDavid du Colombier continue; 357219b2ee8SDavid du Colombier case '\t': 358219b2ee8SDavid du Colombier prspace(); 359219b2ee8SDavid du Colombier tabs++; 360219b2ee8SDavid du Colombier char_no++; 361219b2ee8SDavid du Colombier lastchar = -1; 362219b2ee8SDavid du Colombier continue; 363219b2ee8SDavid du Colombier case '\b': 364219b2ee8SDavid du Colombier /* just toss out backspaces for now */ 365219b2ee8SDavid du Colombier if (lastchar != -1) { 366219b2ee8SDavid du Colombier endstring(); 367219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "(%s) stringwidth pop neg 0 rmoveto ", charcode[lastchar].str); 368219b2ee8SDavid du Colombier } 369219b2ee8SDavid du Colombier char_no++; 370219b2ee8SDavid du Colombier lastchar = -1; 371219b2ee8SDavid du Colombier continue; 372219b2ee8SDavid du Colombier } 373219b2ee8SDavid du Colombier 374219b2ee8SDavid du Colombier /* do something if font is out of table range */ 375219b2ee8SDavid du Colombier if (thisfont>=FONTABSIZE || fontname[thisfont].size == 0) { 376219b2ee8SDavid du Colombier prspace(); 377219b2ee8SDavid du Colombier prtab(); 378219b2ee8SDavid du Colombier endstring(); 379219b2ee8SDavid du Colombier Bprint(Bstdout, "pw "); 380219b2ee8SDavid du Colombier char_no++; 381219b2ee8SDavid du Colombier lastchar = -1; 382219b2ee8SDavid du Colombier continue; 383219b2ee8SDavid du Colombier } 384219b2ee8SDavid du Colombier 385219b2ee8SDavid du Colombier if (thisfont != lastfont) { 386219b2ee8SDavid du Colombier endstring(); 387219b2ee8SDavid du Colombier if (pageon()) { 388219b2ee8SDavid du Colombier Bprint(Bstdout, "/%s f\n", fontname[thisfont].str); 389219b2ee8SDavid du Colombier } 390219b2ee8SDavid du Colombier fontname[thisfont].used++; 391219b2ee8SDavid du Colombier } 392219b2ee8SDavid du Colombier prspace(); 393219b2ee8SDavid du Colombier prtab(); 394219b2ee8SDavid du Colombier startstring(); 395219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, "%s", charcode[thischar].str); 396219b2ee8SDavid du Colombier /* if (pageon()) Bprint(Bstdout, "%2.2x", thischar); /* try hex strings*/ 397219b2ee8SDavid du Colombier char_no++; 398219b2ee8SDavid du Colombier lastchar = thischar; 399219b2ee8SDavid du Colombier lastfont = thisfont; 400219b2ee8SDavid du Colombier } 401219b2ee8SDavid du Colombier if (line_no != 0 || char_no != 0) { 402219b2ee8SDavid du Colombier if (char_no != 1) { 403219b2ee8SDavid du Colombier Bprint(Bstderr, "premature EOF: newline appended\n"); 404219b2ee8SDavid du Colombier startstring(); 405219b2ee8SDavid du Colombier if (pageon()) Bprint(Bstdout, ")l\n"); 406219b2ee8SDavid du Colombier } 407219b2ee8SDavid du Colombier endpage(); 408219b2ee8SDavid du Colombier } 409219b2ee8SDavid du Colombier } 410219b2ee8SDavid du Colombier 411219b2ee8SDavid du Colombier void 412219b2ee8SDavid du Colombier pagelist(char *list) { 413219b2ee8SDavid du Colombier char c; 414219b2ee8SDavid du Colombier int n, m; 415219b2ee8SDavid du Colombier int state, start, end; 416219b2ee8SDavid du Colombier 417219b2ee8SDavid du Colombier if (list == 0) return; 418219b2ee8SDavid du Colombier state = 1; 419219b2ee8SDavid du Colombier while ((c=*list) != '\0') { 420219b2ee8SDavid du Colombier n = 0; 421219b2ee8SDavid du Colombier while (isdigit(c)) { 422219b2ee8SDavid du Colombier n = n * 10 + c - '0'; 423219b2ee8SDavid du Colombier c = *++list; 424219b2ee8SDavid du Colombier } 425219b2ee8SDavid du Colombier switch (state) { 426219b2ee8SDavid du Colombier case 1: 427219b2ee8SDavid du Colombier start = n; 428219b2ee8SDavid du Colombier case 2: 429219b2ee8SDavid du Colombier if (n/8+1 > pplistmaxsize) { 430219b2ee8SDavid du Colombier pplistmaxsize = n/8+1; 431219b2ee8SDavid du Colombier if ((pplist = realloc(pplist, n/8+1)) == 0) { 432219b2ee8SDavid du Colombier Bprint(Bstderr, "cannot allocate memory for page list\n"); 433219b2ee8SDavid du Colombier exits("malloc"); 434219b2ee8SDavid du Colombier } 435219b2ee8SDavid du Colombier } 436219b2ee8SDavid du Colombier for (m=start; m<=n; m++) 437219b2ee8SDavid du Colombier pplist[m/8] |= 1<<(m%8); 438219b2ee8SDavid du Colombier break; 439219b2ee8SDavid du Colombier } 440219b2ee8SDavid du Colombier switch (c) { 441219b2ee8SDavid du Colombier case '-': 442219b2ee8SDavid du Colombier state = 2; 443219b2ee8SDavid du Colombier list++; 444219b2ee8SDavid du Colombier break; 445219b2ee8SDavid du Colombier case ',': 446219b2ee8SDavid du Colombier state = 1; 447219b2ee8SDavid du Colombier list++; 448219b2ee8SDavid du Colombier break; 449219b2ee8SDavid du Colombier case '\0': 450219b2ee8SDavid du Colombier break; 451219b2ee8SDavid du Colombier } 452219b2ee8SDavid du Colombier } 453219b2ee8SDavid du Colombier } 454219b2ee8SDavid du Colombier 455219b2ee8SDavid du Colombier void 456219b2ee8SDavid du Colombier finish(void) { 457219b2ee8SDavid du Colombier int i; 458219b2ee8SDavid du Colombier 459219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", TRAILER); 460219b2ee8SDavid du Colombier Bprint(Bstdout, "done\n"); 461219b2ee8SDavid du Colombier Bprint(Bstdout, "%s", DOCUMENTFONTS); 462219b2ee8SDavid du Colombier 463219b2ee8SDavid du Colombier for (i=0; i<FONTABSIZE; i++) 464219b2ee8SDavid du Colombier if (fontname[i].used) 465219b2ee8SDavid du Colombier Bprint(Bstdout, " %s", fontname[i].str); 466219b2ee8SDavid du Colombier Bprint(Bstdout, "\n"); 467219b2ee8SDavid du Colombier 468219b2ee8SDavid du Colombier Bprint(Bstdout, "%s %d\n", PAGES, pages_printed); 469219b2ee8SDavid du Colombier 470219b2ee8SDavid du Colombier } 471219b2ee8SDavid du Colombier 472219b2ee8SDavid du Colombier main(int argc, char *argv[]) { 473219b2ee8SDavid du Colombier int i; 474219b2ee8SDavid du Colombier char *t; 475219b2ee8SDavid du Colombier Biobuf *input; 476219b2ee8SDavid du Colombier 477219b2ee8SDavid du Colombier if ((bstderr = (Biobuf *)malloc(sizeof(Biobuf))) < (Biobuf *)0) 478219b2ee8SDavid du Colombier exits("malloc"); 479219b2ee8SDavid du Colombier if (Binit(bstderr, 2, OWRITE) == Beof) 480219b2ee8SDavid du Colombier exits("Binit"); 481219b2ee8SDavid du Colombier Bstderr = &(bstderr->Biobufhdr); 482219b2ee8SDavid du Colombier 483219b2ee8SDavid du Colombier if ((bstdout = (Biobuf *)malloc(sizeof(Biobuf))) < (Biobuf *)0) 484219b2ee8SDavid du Colombier exits("malloc"); 485219b2ee8SDavid du Colombier if (Binit(bstdout, 1, OWRITE) == Beof) 486219b2ee8SDavid du Colombier exits("Binit"); 487219b2ee8SDavid du Colombier Bstdout = &(bstdout->Biobufhdr); 488219b2ee8SDavid du Colombier 489219b2ee8SDavid du Colombier ARGBEGIN{ 490219b2ee8SDavid du Colombier case 'a': /* aspect ratio */ 491219b2ee8SDavid du Colombier aspectratio = atof(ARGF()); 492219b2ee8SDavid du Colombier break; 493219b2ee8SDavid du Colombier case 'c': /* copies */ 494219b2ee8SDavid du Colombier copies = atoi(ARGF()); 495219b2ee8SDavid du Colombier break; 496219b2ee8SDavid du Colombier case 'f': /* primary font, for now */ 497219b2ee8SDavid du Colombier t = ARGF(); 498219b2ee8SDavid du Colombier fontname[0].str = malloc(strlen(t)+1); 499219b2ee8SDavid du Colombier strcpy(fontname[0].str, t); 500219b2ee8SDavid du Colombier break; 501219b2ee8SDavid du Colombier case 'l': /* lines per page */ 502219b2ee8SDavid du Colombier linesperpage = atoi(ARGF()); 503219b2ee8SDavid du Colombier break; 504219b2ee8SDavid du Colombier case 'm': /* magnification */ 505219b2ee8SDavid du Colombier magnification = atof(ARGF()); 506219b2ee8SDavid du Colombier break; 507219b2ee8SDavid du Colombier case 'n': /* forms per page */ 508219b2ee8SDavid du Colombier formsperpage = atoi(ARGF()); 509219b2ee8SDavid du Colombier break; 510219b2ee8SDavid du Colombier case 'o': /* output page list */ 511219b2ee8SDavid du Colombier pagelist(ARGF()); 512219b2ee8SDavid du Colombier break; 513219b2ee8SDavid du Colombier case 'p': /* landscape or portrait mode */ 514219b2ee8SDavid du Colombier if ( ARGF()[0] == 'l' ) 515219b2ee8SDavid du Colombier landscape = 1; 516219b2ee8SDavid du Colombier else 517219b2ee8SDavid du Colombier landscape = 0; 518219b2ee8SDavid du Colombier break; 519219b2ee8SDavid du Colombier case 's': /* point size */ 520219b2ee8SDavid du Colombier pointsize = atoi(ARGF()); 521219b2ee8SDavid du Colombier break; 522219b2ee8SDavid du Colombier case 'x': /* shift things horizontally */ 523219b2ee8SDavid du Colombier xoffset = atof(ARGF()); 524219b2ee8SDavid du Colombier break; 525219b2ee8SDavid du Colombier 526219b2ee8SDavid du Colombier case 'y': /* and vertically on the page */ 527219b2ee8SDavid du Colombier yoffset = atof(ARGF()); 528219b2ee8SDavid du Colombier break; 529219b2ee8SDavid du Colombier case 'P': /* PostScript pass through */ 530219b2ee8SDavid du Colombier t = ARGF(); 531219b2ee8SDavid du Colombier i = strlen(t) + 1; 532219b2ee8SDavid du Colombier passthrough = malloc(i); 533219b2ee8SDavid du Colombier if (passthrough == 0) { 534219b2ee8SDavid du Colombier Bprint(Bstderr, "cannot allocate memory for argument string\n"); 535219b2ee8SDavid du Colombier exits("malloc"); 536219b2ee8SDavid du Colombier } 537219b2ee8SDavid du Colombier strncpy(passthrough, t, i); 538219b2ee8SDavid du Colombier break; 539219b2ee8SDavid du Colombier default: /* don't know what to do for ch */ 540219b2ee8SDavid du Colombier Bprint(Bstderr, "unknown option %C\n", ARGC()); 541219b2ee8SDavid du Colombier break; 542219b2ee8SDavid du Colombier }ARGEND; 543219b2ee8SDavid du Colombier prologues(); 544219b2ee8SDavid du Colombier if (argc <= 0) { 545219b2ee8SDavid du Colombier if ((bstdin = (Biobuf *)malloc(sizeof(Biobuf))) < (Biobuf *)0) 546219b2ee8SDavid du Colombier exits("malloc"); 547219b2ee8SDavid du Colombier if (Binit(bstdin, 0, OREAD) == Beof) { 548219b2ee8SDavid du Colombier fprint(2, "cannot Binit stdin\n"); 549219b2ee8SDavid du Colombier exits("Binit"); 550219b2ee8SDavid du Colombier } 551219b2ee8SDavid du Colombier Bstdin = &(bstdin->Biobufhdr); 552219b2ee8SDavid du Colombier txt2post(); 553219b2ee8SDavid du Colombier } 554219b2ee8SDavid du Colombier for (i=0; i<argc; i++) { 555219b2ee8SDavid du Colombier bstdin = Bopen(argv[i], 0); 556219b2ee8SDavid du Colombier if (bstdin == 0) { 557219b2ee8SDavid du Colombier fprint(2, "cannot open file %s\n", argv[i]); 558219b2ee8SDavid du Colombier continue; 559219b2ee8SDavid du Colombier } 560219b2ee8SDavid du Colombier Bstdin = &(bstdin->Biobufhdr); 561219b2ee8SDavid du Colombier txt2post(); 562219b2ee8SDavid du Colombier } 563219b2ee8SDavid du Colombier finish(); 564219b2ee8SDavid du Colombier exits(""); 565219b2ee8SDavid du Colombier } 566