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