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