1*219b2ee8SDavid du Colombier #include <u.h> 2*219b2ee8SDavid du Colombier #include <libc.h> 3*219b2ee8SDavid du Colombier #include <bio.h> 4*219b2ee8SDavid du Colombier #include <stdio.h> 5*219b2ee8SDavid du Colombier #include "../common/common.h" 6*219b2ee8SDavid du Colombier #include "ps_include.h" 7*219b2ee8SDavid du Colombier 8*219b2ee8SDavid du Colombier extern int curpostfontid; 9*219b2ee8SDavid du Colombier extern int curfontsize; 10*219b2ee8SDavid du Colombier 11*219b2ee8SDavid du Colombier typedef struct {long start, end;} Section; 12*219b2ee8SDavid du Colombier static char *buf; 13*219b2ee8SDavid du Colombier 14*219b2ee8SDavid du Colombier static 15*219b2ee8SDavid du Colombier copy(Biobufhdr *fin, Biobufhdr *fout, Section *s) { 16*219b2ee8SDavid du Colombier 17*219b2ee8SDavid du Colombier if (s->end <= s->start) 18*219b2ee8SDavid du Colombier return; 19*219b2ee8SDavid du Colombier Bseek(fin, s->start, 0); 20*219b2ee8SDavid du Colombier while (Bseek(fin, 0L, 1) < s->end && (buf=Brdline(fin, '\n')) != NULL) 21*219b2ee8SDavid du Colombier if (buf[0] != '%') 22*219b2ee8SDavid du Colombier Bwrite(fout, buf, Blinelen(fin)); 23*219b2ee8SDavid du Colombier } 24*219b2ee8SDavid du Colombier 25*219b2ee8SDavid du Colombier /* 26*219b2ee8SDavid du Colombier * 27*219b2ee8SDavid du Colombier * Reads a PostScript file (*fin), and uses structuring comments to locate the 28*219b2ee8SDavid du Colombier * prologue, trailer, global definitions, and the requested page. After the whole 29*219b2ee8SDavid du Colombier * file is scanned, the special ps_include PostScript definitions are copied to 30*219b2ee8SDavid du Colombier * *fout, followed by the prologue, global definitions, the requested page, and 31*219b2ee8SDavid du Colombier * the trailer. Before returning the initial environment (saved in PS_head) is 32*219b2ee8SDavid du Colombier * restored. 33*219b2ee8SDavid du Colombier * 34*219b2ee8SDavid du Colombier * By default we assume the picture is 8.5 by 11 inches, but the BoundingBox 35*219b2ee8SDavid du Colombier * comment, if found, takes precedence. 36*219b2ee8SDavid du Colombier * 37*219b2ee8SDavid du Colombier */ 38*219b2ee8SDavid du Colombier /* *fin, *fout; /* input and output files */ 39*219b2ee8SDavid du Colombier /* page_no; /* physical page number from *fin */ 40*219b2ee8SDavid du Colombier /* whiteout; /* erase picture area */ 41*219b2ee8SDavid du Colombier /* outline; /* draw a box around it and */ 42*219b2ee8SDavid du Colombier /* scaleboth; /* scale both dimensions - if not zero */ 43*219b2ee8SDavid du Colombier /* cx, cy; /* center of the picture and */ 44*219b2ee8SDavid du Colombier /* sx, sy; /* its size - in current coordinates */ 45*219b2ee8SDavid du Colombier /* ax, ay; /* left-right, up-down adjustment */ 46*219b2ee8SDavid du Colombier /* rot; /* rotation - in clockwise degrees */ 47*219b2ee8SDavid du Colombier 48*219b2ee8SDavid du Colombier void 49*219b2ee8SDavid du Colombier ps_include(Biobufhdr *fin, Biobufhdr *fout, int page_no, int whiteout, 50*219b2ee8SDavid du Colombier int outline, int scaleboth, double cx, double cy, double sx, double sy, 51*219b2ee8SDavid du Colombier double ax, double ay, double rot) { 52*219b2ee8SDavid du Colombier char **strp; 53*219b2ee8SDavid du Colombier int foundpage = 0; /* found the page when non zero */ 54*219b2ee8SDavid du Colombier int foundpbox = 0; /* found the page bounding box */ 55*219b2ee8SDavid du Colombier int nglobal = 0; /* number of global defs so far */ 56*219b2ee8SDavid du Colombier int maxglobal = 0; /* and the number we've got room for */ 57*219b2ee8SDavid du Colombier Section prolog, page, trailer; /* prologue, page, and trailer offsets */ 58*219b2ee8SDavid du Colombier Section *global; /* offsets for all global definitions */ 59*219b2ee8SDavid du Colombier double llx, lly; /* lower left and */ 60*219b2ee8SDavid du Colombier double urx, ury; /* upper right corners - default coords */ 61*219b2ee8SDavid du Colombier double w = whiteout != 0; /* mostly for the var() macro */ 62*219b2ee8SDavid du Colombier double o = outline != 0; 63*219b2ee8SDavid du Colombier double s = scaleboth != 0; 64*219b2ee8SDavid du Colombier int i; /* loop index */ 65*219b2ee8SDavid du Colombier 66*219b2ee8SDavid du Colombier #define has(word) (strncmp(buf, word, strlen(word)) == 0) 67*219b2ee8SDavid du Colombier #define grab(n) ((Section *)(nglobal \ 68*219b2ee8SDavid du Colombier ? realloc((char *)global, n*sizeof(Section)) \ 69*219b2ee8SDavid du Colombier : calloc(n, sizeof(Section)))) 70*219b2ee8SDavid du Colombier 71*219b2ee8SDavid du Colombier llx = lly = 0; /* default BoundingBox - 8.5x11 inches */ 72*219b2ee8SDavid du Colombier urx = 72 * 8.5; 73*219b2ee8SDavid du Colombier ury = 72 * 11.0; 74*219b2ee8SDavid du Colombier 75*219b2ee8SDavid du Colombier /* section boundaries and bounding box */ 76*219b2ee8SDavid du Colombier 77*219b2ee8SDavid du Colombier prolog.start = prolog.end = 0; 78*219b2ee8SDavid du Colombier page.start = page.end = 0; 79*219b2ee8SDavid du Colombier trailer.start = 0; 80*219b2ee8SDavid du Colombier Bseek(fin, 0L, 0); 81*219b2ee8SDavid du Colombier 82*219b2ee8SDavid du Colombier while ((buf=Brdline(fin, '\n')) != NULL) { 83*219b2ee8SDavid du Colombier buf[Blinelen(fin)-1] = '\0'; 84*219b2ee8SDavid du Colombier if (!has("%%")) 85*219b2ee8SDavid du Colombier continue; 86*219b2ee8SDavid du Colombier else if (has("%%Page: ")) { 87*219b2ee8SDavid du Colombier if (!foundpage) 88*219b2ee8SDavid du Colombier page.start = Bseek(fin, 0L, 1); 89*219b2ee8SDavid du Colombier sscanf(buf, "%*s %*s %d", &i); 90*219b2ee8SDavid du Colombier if (i == page_no) 91*219b2ee8SDavid du Colombier foundpage = 1; 92*219b2ee8SDavid du Colombier else if (foundpage && page.end <= page.start) 93*219b2ee8SDavid du Colombier page.end = Bseek(fin, 0L, 1); 94*219b2ee8SDavid du Colombier } else if (has("%%EndPage: ")) { 95*219b2ee8SDavid du Colombier sscanf(buf, "%*s %*s %d", &i); 96*219b2ee8SDavid du Colombier if (i == page_no) { 97*219b2ee8SDavid du Colombier foundpage = 1; 98*219b2ee8SDavid du Colombier page.end = Bseek(fin, 0L, 1); 99*219b2ee8SDavid du Colombier } 100*219b2ee8SDavid du Colombier if (!foundpage) 101*219b2ee8SDavid du Colombier page.start = Bseek(fin, 0L, 1); 102*219b2ee8SDavid du Colombier } else if (has("%%PageBoundingBox: ")) { 103*219b2ee8SDavid du Colombier if (i == page_no) { 104*219b2ee8SDavid du Colombier foundpbox = 1; 105*219b2ee8SDavid du Colombier sscanf(buf, "%*s %lf %lf %lf %lf", 106*219b2ee8SDavid du Colombier &llx, &lly, &urx, &ury); 107*219b2ee8SDavid du Colombier } 108*219b2ee8SDavid du Colombier } else if (has("%%BoundingBox: ")) { 109*219b2ee8SDavid du Colombier if (!foundpbox) 110*219b2ee8SDavid du Colombier sscanf(buf,"%*s %lf %lf %lf %lf", 111*219b2ee8SDavid du Colombier &llx, &lly, &urx, &ury); 112*219b2ee8SDavid du Colombier } else if (has("%%EndProlog") || has("%%EndSetup") || has("%%EndDocumentSetup")) 113*219b2ee8SDavid du Colombier prolog.end = page.start = Bseek(fin, 0L, 1); 114*219b2ee8SDavid du Colombier else if (has("%%Trailer")) 115*219b2ee8SDavid du Colombier trailer.start = Bseek(fin, 0L, 1); 116*219b2ee8SDavid du Colombier else if (has("%%BeginGlobal")) { 117*219b2ee8SDavid du Colombier if (page.end <= page.start) { 118*219b2ee8SDavid du Colombier if (nglobal >= maxglobal) { 119*219b2ee8SDavid du Colombier maxglobal += 20; 120*219b2ee8SDavid du Colombier global = grab(maxglobal); 121*219b2ee8SDavid du Colombier } 122*219b2ee8SDavid du Colombier global[nglobal].start = Bseek(fin, 0L, 1); 123*219b2ee8SDavid du Colombier } 124*219b2ee8SDavid du Colombier } else if (has("%%EndGlobal")) 125*219b2ee8SDavid du Colombier if (page.end <= page.start) 126*219b2ee8SDavid du Colombier global[nglobal++].end = Bseek(fin, 0L, 1); 127*219b2ee8SDavid du Colombier } 128*219b2ee8SDavid du Colombier Bseek(fin, 0L, 2); 129*219b2ee8SDavid du Colombier if (trailer.start == 0) 130*219b2ee8SDavid du Colombier trailer.start = Bseek(fin, 0L, 1); 131*219b2ee8SDavid du Colombier trailer.end = Bseek(fin, 0L, 1); 132*219b2ee8SDavid du Colombier 133*219b2ee8SDavid du Colombier if (page.end <= page.start) 134*219b2ee8SDavid du Colombier page.end = trailer.start; 135*219b2ee8SDavid du Colombier 136*219b2ee8SDavid du Colombier /* 137*219b2ee8SDavid du Colombier fprint(2, "prolog=(%d,%d)\n", prolog.start, prolog.end); 138*219b2ee8SDavid du Colombier fprint(2, "page=(%d,%d)\n", page.start, page.end); 139*219b2ee8SDavid du Colombier for(i = 0; i < nglobal; i++) 140*219b2ee8SDavid du Colombier fprint(2, "global[%d]=(%d,%d)\n", i, global[i].start, global[i].end); 141*219b2ee8SDavid du Colombier fprint(2, "trailer=(%d,%d)\n", trailer.start, trailer.end); 142*219b2ee8SDavid du Colombier */ 143*219b2ee8SDavid du Colombier 144*219b2ee8SDavid du Colombier /* all output here */ 145*219b2ee8SDavid du Colombier for (strp = PS_head; *strp != NULL; strp++) 146*219b2ee8SDavid du Colombier Bwrite(fout, *strp, strlen(*strp)); 147*219b2ee8SDavid du Colombier 148*219b2ee8SDavid du Colombier Bprint(fout, "/llx %g def\n", llx); 149*219b2ee8SDavid du Colombier Bprint(fout, "/lly %g def\n", lly); 150*219b2ee8SDavid du Colombier Bprint(fout, "/urx %g def\n", urx); 151*219b2ee8SDavid du Colombier Bprint(fout, "/ury %g def\n", ury); 152*219b2ee8SDavid du Colombier Bprint(fout, "/w %g def\n", w); 153*219b2ee8SDavid du Colombier Bprint(fout, "/o %g def\n", o); 154*219b2ee8SDavid du Colombier Bprint(fout, "/s %g def\n", s); 155*219b2ee8SDavid du Colombier Bprint(fout, "/cx %g def\n", cx); 156*219b2ee8SDavid du Colombier Bprint(fout, "/cy %g def\n", cy); 157*219b2ee8SDavid du Colombier Bprint(fout, "/sx %g def\n", sx); 158*219b2ee8SDavid du Colombier Bprint(fout, "/sy %g def\n", sy); 159*219b2ee8SDavid du Colombier Bprint(fout, "/ax %g def\n", ax); 160*219b2ee8SDavid du Colombier Bprint(fout, "/ay %g def\n", ay); 161*219b2ee8SDavid du Colombier Bprint(fout, "/rot %g def\n", rot); 162*219b2ee8SDavid du Colombier 163*219b2ee8SDavid du Colombier for (strp = PS_setup; *strp != NULL; strp++) 164*219b2ee8SDavid du Colombier Bwrite(fout, *strp, strlen(*strp)); 165*219b2ee8SDavid du Colombier 166*219b2ee8SDavid du Colombier copy(fin, fout, &prolog); 167*219b2ee8SDavid du Colombier for(i = 0; i < nglobal; i++) 168*219b2ee8SDavid du Colombier copy(fin, fout, &global[i]); 169*219b2ee8SDavid du Colombier copy(fin, fout, &page); 170*219b2ee8SDavid du Colombier copy(fin, fout, &trailer); 171*219b2ee8SDavid du Colombier for (strp = PS_tail; *strp != NULL; strp++) 172*219b2ee8SDavid du Colombier Bwrite(fout, *strp, strlen(*strp)); 173*219b2ee8SDavid du Colombier 174*219b2ee8SDavid du Colombier if(nglobal) 175*219b2ee8SDavid du Colombier free(global); 176*219b2ee8SDavid du Colombier 177*219b2ee8SDavid du Colombier /* force the program to reestablish its state */ 178*219b2ee8SDavid du Colombier curpostfontid = -1; 179*219b2ee8SDavid du Colombier curfontsize = -1; 180*219b2ee8SDavid du Colombier } 181