void ps_include( const char *name, /* file name */ FILE *fin, FILE *fout, /* input and output files */ int page_no, /* physical page number from *fin */ int whiteout, /* erase picture area */ int outline, /* draw a box around it and */ int scaleboth, /* scale both dimensions - if not zero */ double cx, double cy, /* center of the picture and */ double sx, double sy, /* its size - in current coordinates */ double ax, double ay, /* left-right, up-down adjustment */ double rot /* rotation - in clockwise degrees */ ) { static int gotinclude; int foundpage = 0; /* found the page when non zero */ int nglobal = 0; /* number of global defs so far */ int maxglobal = 0; /* and the number we've got room for */ Section prolog, page, trailer; /* prologue, page, and trailer offsets */ Section *global = 0; /* offsets for all global definitions */ double llx, lly; /* lower left and */ double urx, ury; /* upper right corners - default coords */ double w = whiteout != 0; /* mostly for the var() macro */ double o = outline != 0; double s = scaleboth != 0; int i; /* loop index */ int lineno = 0; int epsf = 0; int hires = 0; int state = 0; int indoc = 0; char *bp, *cp; enum { NORMAL, DOCUMENTFONTS, DOCUMENTNEEDEDRESOURCES, } cont = NORMAL; /* * * Reads a PostScript file (*fin), and uses structuring comments to locate the * prologue, trailer, global definitions, and the requested page. After the whole * file is scanned, the special ps_include PostScript definitions are copied to * *fout, followed by the prologue, global definitions, the requested page, and * the trailer. Before returning the initial environment (saved in PS_head) is * restored. * * By default we assume the picture is 8.5 by 11 inches, but the BoundingBox * comment, if found, takes precedence. * */ if (gotinclude == 0 && access(PSINCLUDEFILE, 04) == 0) { doglobal(PSINCLUDEFILE); gotinclude++; } llx = lly = 0; /* default BoundingBox - 8.5x11 inches */ urx = 72 * 8.5; ury = 72 * 11.0; /* section boundaries and bounding box */ prolog.start = prolog.end = 0; page.start = page.end = 0; trailer.start = 0; fseek(fin, 0L, SEEK_SET); while ( psgetline(&buf, &bufsize, NULL, fin) != NULL ) { if (++lineno == 1 && strncmp(buf, "%!PS-", 5) == 0) { for (bp = buf; !spacechar(*bp&0377); bp++); while (*bp && *bp != '\n' && *bp != '\r' && spacechar(*bp&0377)) bp++; if (strncmp(bp, "EPSF-", 5) == 0) epsf++; } if (state == 0 && (*buf == '\n' || has("%%EndComments") || buf[0] != '%' || buf[1] == ' ' || buf[1] == '\t' || buf[1] == '\r' || buf[1] == '\n')) { state = 1; continue; } if (buf[0] != '%' || buf[1] != '%') continue; if (state != 1 && (bp = has("%%+")) != NULL) { switch (cont) { case DOCUMENTFONTS: addfonts(bp); break; case DOCUMENTNEEDEDRESOURCES: goto needres; } continue; } else cont = NORMAL; if (has("%%Page: ")) { if (!foundpage) page.start = ftell(fin); sscanf(buf, "%*s %*s %d", &i); if (i == page_no) foundpage = 1; else if (foundpage && page.end <= page.start) page.end = ftell(fin); } else if (has("%%EndPage: ")) { sscanf(buf, "%*s %*s %d", &i); if (i == page_no) { foundpage = 1; page.end = ftell(fin); } if (!foundpage) page.start = ftell(fin); } else if (state != 1 && !indoc && has("%%BoundingBox:") && !hires) { sscanf(buf, "%%%%BoundingBox: %lf %lf %lf %lf", &llx, &lly, &urx, &ury); if (epsf) epsf++; } else if (state != 1 && !indoc && has("%%HiResBoundingBox:")) { sscanf(buf, "%%%%HiResBoundingBox: %lf %lf %lf %lf", &llx, &lly, &urx, &ury); hires++; if (epsf) epsf++; } else if (has("%%LanguageLevel:")) { int n; sscanf(buf, "%%%%LanguageLevel: %d", &n); LanguageLevel = MAX(LanguageLevel, n); } else if ((bp = has("%%DocumentNeededFonts:")) != NULL || (bp = has("%%DocumentFonts:")) != NULL) { cont = DOCUMENTFONTS; addfonts(bp); } else if ((bp = has("%%DocumentNeededResources:")) != NULL) { needres: if ((cp = _has(bp, "font"))) addfonts(cp); else { for (cp = bp; *cp && *cp != '\n' && *cp != '\r'; cp++); *cp = '\0'; needresource("%s", bp); } cont = DOCUMENTNEEDEDRESOURCES; } else if (indoc == 0 && (has("%%EndProlog") || has("%%EndSetup") || has("%%EndDocumentSetup"))) prolog.end = page.start = ftell(fin); else if (indoc == 0 && has("%%EOF")) break; else if (state == 1 && indoc == 0 && has("%%Trailer")) { trailer.start = ftell(fin); state = 2; } else if (state == 1 && has("%%BeginDocument:")) indoc++; else if (state == 1 && indoc > 0 && has("%%EndDocument")) indoc--; else if (state == 1 && (cp = has("%%BeginBinary:")) != NULL) { if ((i = strtol(cp, &cp, 10)) > 0) psskip(i, fin); } else if (state == 1 && (cp = has("%%BeginData:")) != NULL) { if ((i = strtol(cp, &cp, 10)) > 0) { while (*cp == ' ' || *cp == '\t') cp++; while (*cp && *cp != ' ' && *cp != '\t') cp++; while (*cp == ' ' || *cp == '\t') cp++; if (strncmp(cp, "Bytes", 5) == 0) psskip(i, fin); else if (strncmp(cp, "Lines", 5) == 0) { while (i-- && psgetline(&buf, &bufsize, NULL, fin) != NULL); } } } else if (has("%%BeginGlobal")) { if (page.end <= page.start) { if (nglobal >= maxglobal) { maxglobal += 20; global = grab(maxglobal); } global[nglobal].start = ftell(fin); } } else if (has("%%EndGlobal")) if (page.end <= page.start) global[nglobal++].end = ftell(fin); } fseek(fin, 0L, SEEK_END); if (trailer.start == 0) trailer.start = ftell(fin); trailer.end = ftell(fin); if (page.end <= page.start) page.end = trailer.start; /* fprintf(stderr, "prolog=(%d,%d)\n", prolog.start, prolog.end); fprintf(stderr, "page=(%d,%d)\n", page.start, page.end); for(i = 0; i < nglobal; i++) fprintf(stderr, "global[%d]=(%d,%d)\n", i, global[i].start, global[i].end); fprintf(stderr, "trailer=(%d,%d)\n", trailer.start, trailer.end); */ /* all output here */ fprintf(fout, "_ps_include_head\n"); var(llx); var(lly); var(urx); var(ury); var(w); var(o); var(s); var(cx); var(cy); var(sx); var(sy); var(ax); var(ay); var(rot); fprintf(fout, "_ps_include_setup\n"); if (epsf >= 2) { size_t len; rewind(fin); fprintf(fout, "%%%%BeginDocument: %s\n", name); while (psgetline(&buf, &bufsize, &len, fin) != NULL) { if (has("%%BeginPreview:")) { while (psgetline(&buf, &bufsize, &len, fin) != NULL && !has("%%EndPreview")); continue; } fwrite(buf, 1, len, fout); } fprintf(fout, "%%%%EndDocument\n"); } else { copy(fin, fout, &prolog); for(i = 0; i < nglobal; i++) copy(fin, fout, &global[i]); copy(fin, fout, &page); copy(fin, fout, &trailer); } fprintf(fout, "_ps_include_tail\n"); if(nglobal) free(global); }
static void getpsbb(const char *name, double bb[4]) { struct fg *fp; char *buf = NULL; char *cp; size_t size = 0; int fd, n, k; int lineno = 0; int found = 0; int atend = 0; int state = 0; int indoc = 0; if ((fd = open(name, O_RDONLY)) < 0) { errprint("can't open %s", name); return; } fp = calloc(1, sizeof *fp); fp->fd = fd; for (;;) { n = psgetline(fp, &buf, &size); if (++lineno == 1 && (n == 0 || strncmp(buf, "%!PS-", 5))) { errprint("%s is not a DSC-conforming " "PostScript document", name); break; } if (n > 0 && state != 1 && (cp = getcom(buf, "%%BoundingBox:")) != NULL) { while (*cp == ' ' || *cp == '\t') cp++; if (strncmp(cp, "(atend)", 7) == 0) { atend++; continue; } bb[0] = strtod(cp, &cp); if (*cp) bb[1] = strtod(cp, &cp); if (*cp) bb[2] = strtod(cp, &cp); if (*cp) { bb[3] = strtod(cp, &cp); found = 1; } else errprint("missing arguments to " "%%%%BoundingBox: in %s, line %d\n", name, lineno); continue; } if (n > 0 && state != 1 && (cp = getcom(buf, "%%HiResBoundingBox:")) != NULL) { while (*cp == ' ' || *cp == '\t') cp++; if (strncmp(cp, "(atend)", 7) == 0) { atend++; continue; } bb[0] = strtod(cp, &cp); if (*cp) bb[1] = strtod(cp, &cp); if (*cp) bb[2] = strtod(cp, &cp); if (*cp) { bb[3] = strtod(cp, &cp); break; } else { errprint("missing arguments to " "%%%%HiResBoundingBox: in %s, " "line %d\n", name, lineno); continue; } } if (n == 0 || (state == 0 && (getcom(buf, "%%EndComments") != NULL || buf[0] != '%' || buf[1] == ' ' || buf[1] == '\t' || buf[1] == '\r' || buf[1] == '\n'))) { eof: if (found == 0 && (atend == 0 || n == 0)) errprint("%s lacks a %%%%BoundingBox: DSC " "comment", name); if (atend == 0 || n == 0) break; state = 1; continue; } if (indoc == 0 && getcom(buf, "%%EOF") != NULL) { n = 0; goto eof; } if (state == 1 && indoc == 0 && getcom(buf, "%%Trailer") != NULL) { state = 2; continue; } if (state == 1 && getcom(buf, "%%BeginDocument:") != NULL) { indoc++; continue; } if (state == 1 && indoc > 0 && getcom(buf, "%%EndDocument") != NULL) { indoc--; continue; } if (state == 1 && (cp = getcom(buf, "%%BeginBinary:")) != NULL) { if ((k = strtol(cp, &cp, 10)) > 0) psskip(fp, k); continue; } if (state == 1 && (cp = getcom(buf, "%%BeginData:")) != NULL) { if ((k = strtol(cp, &cp, 10)) > 0) { while (*cp == ' ' || *cp == '\t') cp++; while (*cp && *cp != ' ' && *cp != '\t') cp++; while (*cp == ' ' || *cp == '\t') cp++; if (strncmp(cp, "Bytes", 5) == 0) psskip(fp, k); else if (strncmp(cp, "Lines", 5) == 0) { while (k--) { n = psgetline(fp, &buf, &size); if (n == 0) goto eof; } } } continue; } } free(fp); free(buf); close(fd); }