1219b2ee8SDavid du Colombier #include <u.h> 2219b2ee8SDavid du Colombier #include <libc.h> 3219b2ee8SDavid du Colombier #include <bio.h> 4219b2ee8SDavid du Colombier #include <stdio.h> 5219b2ee8SDavid du Colombier #include "../common/common.h" 6219b2ee8SDavid du Colombier #include "ps_include.h" 7219b2ee8SDavid du Colombier 8219b2ee8SDavid du Colombier extern int curpostfontid; 9219b2ee8SDavid du Colombier extern int curfontsize; 10219b2ee8SDavid du Colombier 11219b2ee8SDavid du Colombier typedef struct {long start, end;} Section; 12219b2ee8SDavid du Colombier static char *buf; 13219b2ee8SDavid du Colombier 14219b2ee8SDavid du Colombier static 15219b2ee8SDavid du Colombier copy(Biobufhdr *fin, Biobufhdr *fout, Section *s) { 16*7dd7cddfSDavid du Colombier int cond; 17219b2ee8SDavid du Colombier if (s->end <= s->start) 18219b2ee8SDavid du Colombier return; 19219b2ee8SDavid du Colombier Bseek(fin, s->start, 0); 20*7dd7cddfSDavid du Colombier while (Bseek(fin, 0L, 1) < s->end && (buf=Brdline(fin, '\n')) != NULL){ 21*7dd7cddfSDavid du Colombier /* 22*7dd7cddfSDavid du Colombier * We have to be careful here, because % can legitimately appear 23*7dd7cddfSDavid du Colombier * in Ascii85 encodings, and must not be elided. 24*7dd7cddfSDavid du Colombier * The goal here is to make any DSC comments impotent without 25*7dd7cddfSDavid du Colombier * actually changing the behavior of the Postscript. 26*7dd7cddfSDavid du Colombier * Since stripping ``comments'' breaks Ascii85, we can instead just 27*7dd7cddfSDavid du Colombier * indent comments a space, which turns DSC comments into non-DSC comments 28*7dd7cddfSDavid du Colombier * and has no effect on binary encodings, which are whitespace-blind. 29*7dd7cddfSDavid du Colombier */ 30*7dd7cddfSDavid du Colombier if(buf[0] == '%') 31*7dd7cddfSDavid du Colombier Bputc(fout, ' '); 32219b2ee8SDavid du Colombier Bwrite(fout, buf, Blinelen(fin)); 33219b2ee8SDavid du Colombier } 34*7dd7cddfSDavid du Colombier } 35219b2ee8SDavid du Colombier 36219b2ee8SDavid du Colombier /* 37219b2ee8SDavid du Colombier * 38219b2ee8SDavid du Colombier * Reads a PostScript file (*fin), and uses structuring comments to locate the 39219b2ee8SDavid du Colombier * prologue, trailer, global definitions, and the requested page. After the whole 40219b2ee8SDavid du Colombier * file is scanned, the special ps_include PostScript definitions are copied to 41219b2ee8SDavid du Colombier * *fout, followed by the prologue, global definitions, the requested page, and 42219b2ee8SDavid du Colombier * the trailer. Before returning the initial environment (saved in PS_head) is 43219b2ee8SDavid du Colombier * restored. 44219b2ee8SDavid du Colombier * 45219b2ee8SDavid du Colombier * By default we assume the picture is 8.5 by 11 inches, but the BoundingBox 46219b2ee8SDavid du Colombier * comment, if found, takes precedence. 47219b2ee8SDavid du Colombier * 48219b2ee8SDavid du Colombier */ 49219b2ee8SDavid du Colombier /* *fin, *fout; /* input and output files */ 50219b2ee8SDavid du Colombier /* page_no; /* physical page number from *fin */ 51219b2ee8SDavid du Colombier /* whiteout; /* erase picture area */ 52219b2ee8SDavid du Colombier /* outline; /* draw a box around it and */ 53219b2ee8SDavid du Colombier /* scaleboth; /* scale both dimensions - if not zero */ 54219b2ee8SDavid du Colombier /* cx, cy; /* center of the picture and */ 55219b2ee8SDavid du Colombier /* sx, sy; /* its size - in current coordinates */ 56219b2ee8SDavid du Colombier /* ax, ay; /* left-right, up-down adjustment */ 57219b2ee8SDavid du Colombier /* rot; /* rotation - in clockwise degrees */ 58219b2ee8SDavid du Colombier 59219b2ee8SDavid du Colombier void 60219b2ee8SDavid du Colombier ps_include(Biobufhdr *fin, Biobufhdr *fout, int page_no, int whiteout, 61219b2ee8SDavid du Colombier int outline, int scaleboth, double cx, double cy, double sx, double sy, 62219b2ee8SDavid du Colombier double ax, double ay, double rot) { 63219b2ee8SDavid du Colombier char **strp; 64219b2ee8SDavid du Colombier int foundpage = 0; /* found the page when non zero */ 65219b2ee8SDavid du Colombier int foundpbox = 0; /* found the page bounding box */ 66219b2ee8SDavid du Colombier int nglobal = 0; /* number of global defs so far */ 67219b2ee8SDavid du Colombier int maxglobal = 0; /* and the number we've got room for */ 68219b2ee8SDavid du Colombier Section prolog, page, trailer; /* prologue, page, and trailer offsets */ 69219b2ee8SDavid du Colombier Section *global; /* offsets for all global definitions */ 70219b2ee8SDavid du Colombier double llx, lly; /* lower left and */ 71219b2ee8SDavid du Colombier double urx, ury; /* upper right corners - default coords */ 72219b2ee8SDavid du Colombier double w = whiteout != 0; /* mostly for the var() macro */ 73219b2ee8SDavid du Colombier double o = outline != 0; 74219b2ee8SDavid du Colombier double s = scaleboth != 0; 75219b2ee8SDavid du Colombier int i; /* loop index */ 76219b2ee8SDavid du Colombier 77219b2ee8SDavid du Colombier #define has(word) (strncmp(buf, word, strlen(word)) == 0) 78219b2ee8SDavid du Colombier #define grab(n) ((Section *)(nglobal \ 79219b2ee8SDavid du Colombier ? realloc((char *)global, n*sizeof(Section)) \ 80219b2ee8SDavid du Colombier : calloc(n, sizeof(Section)))) 81219b2ee8SDavid du Colombier 82219b2ee8SDavid du Colombier llx = lly = 0; /* default BoundingBox - 8.5x11 inches */ 83219b2ee8SDavid du Colombier urx = 72 * 8.5; 84219b2ee8SDavid du Colombier ury = 72 * 11.0; 85219b2ee8SDavid du Colombier 86219b2ee8SDavid du Colombier /* section boundaries and bounding box */ 87219b2ee8SDavid du Colombier 88219b2ee8SDavid du Colombier prolog.start = prolog.end = 0; 89219b2ee8SDavid du Colombier page.start = page.end = 0; 90219b2ee8SDavid du Colombier trailer.start = 0; 91219b2ee8SDavid du Colombier Bseek(fin, 0L, 0); 92219b2ee8SDavid du Colombier 93219b2ee8SDavid du Colombier while ((buf=Brdline(fin, '\n')) != NULL) { 94219b2ee8SDavid du Colombier buf[Blinelen(fin)-1] = '\0'; 95219b2ee8SDavid du Colombier if (!has("%%")) 96219b2ee8SDavid du Colombier continue; 97219b2ee8SDavid du Colombier else if (has("%%Page: ")) { 98219b2ee8SDavid du Colombier if (!foundpage) 99219b2ee8SDavid du Colombier page.start = Bseek(fin, 0L, 1); 100219b2ee8SDavid du Colombier sscanf(buf, "%*s %*s %d", &i); 101219b2ee8SDavid du Colombier if (i == page_no) 102219b2ee8SDavid du Colombier foundpage = 1; 103219b2ee8SDavid du Colombier else if (foundpage && page.end <= page.start) 104219b2ee8SDavid du Colombier page.end = Bseek(fin, 0L, 1); 105219b2ee8SDavid du Colombier } else if (has("%%EndPage: ")) { 106219b2ee8SDavid du Colombier sscanf(buf, "%*s %*s %d", &i); 107219b2ee8SDavid du Colombier if (i == page_no) { 108219b2ee8SDavid du Colombier foundpage = 1; 109219b2ee8SDavid du Colombier page.end = Bseek(fin, 0L, 1); 110219b2ee8SDavid du Colombier } 111219b2ee8SDavid du Colombier if (!foundpage) 112219b2ee8SDavid du Colombier page.start = Bseek(fin, 0L, 1); 113219b2ee8SDavid du Colombier } else if (has("%%PageBoundingBox: ")) { 114219b2ee8SDavid du Colombier if (i == page_no) { 115219b2ee8SDavid du Colombier foundpbox = 1; 116219b2ee8SDavid du Colombier sscanf(buf, "%*s %lf %lf %lf %lf", 117219b2ee8SDavid du Colombier &llx, &lly, &urx, &ury); 118219b2ee8SDavid du Colombier } 119219b2ee8SDavid du Colombier } else if (has("%%BoundingBox: ")) { 120219b2ee8SDavid du Colombier if (!foundpbox) 121219b2ee8SDavid du Colombier sscanf(buf,"%*s %lf %lf %lf %lf", 122219b2ee8SDavid du Colombier &llx, &lly, &urx, &ury); 123219b2ee8SDavid du Colombier } else if (has("%%EndProlog") || has("%%EndSetup") || has("%%EndDocumentSetup")) 124219b2ee8SDavid du Colombier prolog.end = page.start = Bseek(fin, 0L, 1); 125219b2ee8SDavid du Colombier else if (has("%%Trailer")) 126219b2ee8SDavid du Colombier trailer.start = Bseek(fin, 0L, 1); 127219b2ee8SDavid du Colombier else if (has("%%BeginGlobal")) { 128219b2ee8SDavid du Colombier if (page.end <= page.start) { 129219b2ee8SDavid du Colombier if (nglobal >= maxglobal) { 130219b2ee8SDavid du Colombier maxglobal += 20; 131219b2ee8SDavid du Colombier global = grab(maxglobal); 132219b2ee8SDavid du Colombier } 133219b2ee8SDavid du Colombier global[nglobal].start = Bseek(fin, 0L, 1); 134219b2ee8SDavid du Colombier } 135219b2ee8SDavid du Colombier } else if (has("%%EndGlobal")) 136219b2ee8SDavid du Colombier if (page.end <= page.start) 137219b2ee8SDavid du Colombier global[nglobal++].end = Bseek(fin, 0L, 1); 138219b2ee8SDavid du Colombier } 139219b2ee8SDavid du Colombier Bseek(fin, 0L, 2); 140219b2ee8SDavid du Colombier if (trailer.start == 0) 141219b2ee8SDavid du Colombier trailer.start = Bseek(fin, 0L, 1); 142219b2ee8SDavid du Colombier trailer.end = Bseek(fin, 0L, 1); 143219b2ee8SDavid du Colombier 144219b2ee8SDavid du Colombier if (page.end <= page.start) 145219b2ee8SDavid du Colombier page.end = trailer.start; 146219b2ee8SDavid du Colombier 147219b2ee8SDavid du Colombier /* 148219b2ee8SDavid du Colombier fprint(2, "prolog=(%d,%d)\n", prolog.start, prolog.end); 149219b2ee8SDavid du Colombier fprint(2, "page=(%d,%d)\n", page.start, page.end); 150219b2ee8SDavid du Colombier for(i = 0; i < nglobal; i++) 151219b2ee8SDavid du Colombier fprint(2, "global[%d]=(%d,%d)\n", i, global[i].start, global[i].end); 152219b2ee8SDavid du Colombier fprint(2, "trailer=(%d,%d)\n", trailer.start, trailer.end); 153219b2ee8SDavid du Colombier */ 154219b2ee8SDavid du Colombier 155219b2ee8SDavid du Colombier /* all output here */ 156219b2ee8SDavid du Colombier for (strp = PS_head; *strp != NULL; strp++) 157219b2ee8SDavid du Colombier Bwrite(fout, *strp, strlen(*strp)); 158219b2ee8SDavid du Colombier 159219b2ee8SDavid du Colombier Bprint(fout, "/llx %g def\n", llx); 160219b2ee8SDavid du Colombier Bprint(fout, "/lly %g def\n", lly); 161219b2ee8SDavid du Colombier Bprint(fout, "/urx %g def\n", urx); 162219b2ee8SDavid du Colombier Bprint(fout, "/ury %g def\n", ury); 163219b2ee8SDavid du Colombier Bprint(fout, "/w %g def\n", w); 164219b2ee8SDavid du Colombier Bprint(fout, "/o %g def\n", o); 165219b2ee8SDavid du Colombier Bprint(fout, "/s %g def\n", s); 166219b2ee8SDavid du Colombier Bprint(fout, "/cx %g def\n", cx); 167219b2ee8SDavid du Colombier Bprint(fout, "/cy %g def\n", cy); 168219b2ee8SDavid du Colombier Bprint(fout, "/sx %g def\n", sx); 169219b2ee8SDavid du Colombier Bprint(fout, "/sy %g def\n", sy); 170219b2ee8SDavid du Colombier Bprint(fout, "/ax %g def\n", ax); 171219b2ee8SDavid du Colombier Bprint(fout, "/ay %g def\n", ay); 172219b2ee8SDavid du Colombier Bprint(fout, "/rot %g def\n", rot); 173219b2ee8SDavid du Colombier 174219b2ee8SDavid du Colombier for (strp = PS_setup; *strp != NULL; strp++) 175219b2ee8SDavid du Colombier Bwrite(fout, *strp, strlen(*strp)); 176219b2ee8SDavid du Colombier 177219b2ee8SDavid du Colombier copy(fin, fout, &prolog); 178219b2ee8SDavid du Colombier for(i = 0; i < nglobal; i++) 179219b2ee8SDavid du Colombier copy(fin, fout, &global[i]); 180219b2ee8SDavid du Colombier copy(fin, fout, &page); 181219b2ee8SDavid du Colombier copy(fin, fout, &trailer); 182219b2ee8SDavid du Colombier for (strp = PS_tail; *strp != NULL; strp++) 183219b2ee8SDavid du Colombier Bwrite(fout, *strp, strlen(*strp)); 184219b2ee8SDavid du Colombier 185219b2ee8SDavid du Colombier if(nglobal) 186219b2ee8SDavid du Colombier free(global); 187219b2ee8SDavid du Colombier 188219b2ee8SDavid du Colombier /* force the program to reestablish its state */ 189219b2ee8SDavid du Colombier curpostfontid = -1; 190219b2ee8SDavid du Colombier curfontsize = -1; 191219b2ee8SDavid du Colombier } 192