1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * 34 * Picture inclusion code for PostScript printers. 35 * 36 */ 37 38 39 #include <stdio.h> 40 #include "ps_include.h" 41 42 43 #if defined(__STDC__) 44 #define var(x) fprintf(fout, "/%s %g def\n", #x, x) 45 #else 46 #define lq(x) "x 47 #define rq(x) x" 48 #define quote(x) rq(lq(x)) 49 #define var(x) fprintf(fout, "/%s %g def\n", quote(x), x) 50 #endif 51 52 #define has(word) (strncmp(buf, word, strlen(word)) == 0) 53 #define grab(n) ((Section *)(nglobal \ 54 ? realloc((char *)global, n*sizeof(Section)) \ 55 : calloc(n, sizeof(Section)))) 56 57 58 char buf[512]; 59 typedef struct {long start, end;} Section; 60 61 extern char *calloc(), *realloc(); 62 63 static void print(FILE *, char **); 64 static void copy(FILE *, FILE *, Section *); 65 66 /*****************************************************************************/ 67 68 69 void 70 ps_include(FILE *fin, FILE *fout, int page_no, int whiteout, 71 int outline, int scaleboth, double cx, double cy, 72 double sx, double sy, double ax, double ay, double rot) 73 /* fin, fout - input and output files */ 74 /* page_no physical page number from *fin */ 75 /* whiteout - erase picture area */ 76 /* outline - draw a box around it and */ 77 /* scaleboth - scale both dimensions - if not zero */ 78 /* cx, cy - center of the picture and */ 79 /* sx, sy - its size - in current coordinates */ 80 /* ax, ay - left-right, up-down adjustment */ 81 /* rot - rotation - in clockwise degrees */ 82 { 83 int foundpage = 0; /* found the page when non zero */ 84 int nglobal = 0; /* number of global defs so far */ 85 int maxglobal = 0; /* and the number we've got room for */ 86 Section prolog, page, trailer; /* prologue, page, and trailer offsets */ 87 Section *global; /* offsets for all global definitions */ 88 double llx, lly; /* lower left and */ 89 double urx, ury; /* upper right corners - default coords */ 90 double w = whiteout != 0; /* mostly for the var() macro */ 91 double o = outline != 0; 92 double s = scaleboth != 0; 93 int i; /* loop index */ 94 95 96 /* 97 * 98 * Reads a PostScript file (*fin), and uses structuring comments to locate the 99 * prologue, trailer, global definitions, and the requested page. After the whole 100 * file is scanned, the special ps_include PostScript definitions are copied to 101 * *fout, followed by the prologue, global definitions, the requested page, and 102 * the trailer. Before returning the initial environment (saved in PS_head) is 103 * restored. 104 * 105 * By default we assume the picture is 8.5 by 11 inches, but the BoundingBox 106 * comment, if found, takes precedence. 107 * 108 */ 109 110 111 llx = lly = 0; /* default BoundingBox - 8.5x11 inches */ 112 urx = 72 * 8.5; 113 ury = 72 * 11.0; 114 115 /* section boundaries and bounding box */ 116 117 prolog.start = prolog.end = 0; 118 page.start = page.end = 0; 119 trailer.start = 0; 120 fseek(fin, 0L, 0); 121 122 while ( fgets(buf, sizeof(buf), fin) != NULL ) 123 if (!has("%%")) 124 continue; 125 else if (has("%%Page: ")) { 126 if (!foundpage) 127 page.start = ftell(fin); 128 sscanf(buf, "%*s %*s %d", &i); 129 if (i == page_no) 130 foundpage = 1; 131 else if (foundpage && page.end <= page.start) 132 page.end = ftell(fin); 133 } else if (has("%%EndPage: ")) { 134 sscanf(buf, "%*s %*s %d", &i); 135 if (i == page_no) { 136 foundpage = 1; 137 page.end = ftell(fin); 138 } 139 if (!foundpage) 140 page.start = ftell(fin); 141 } else if (has("%%BoundingBox:")) 142 sscanf(buf, "%%%%BoundingBox: %lf %lf %lf %lf", &llx, &lly, &urx, &ury); 143 else if (has("%%EndProlog") || has("%%EndSetup") || has("%%EndDocumentSetup")) 144 prolog.end = page.start = ftell(fin); 145 else if (has("%%Trailer")) 146 trailer.start = ftell(fin); 147 else if (has("%%BeginGlobal")) { 148 if (page.end <= page.start) { 149 if (nglobal >= maxglobal) { 150 maxglobal += 20; 151 global = grab(maxglobal); 152 } 153 global[nglobal].start = ftell(fin); 154 } 155 } else if (has("%%EndGlobal")) 156 if (page.end <= page.start) 157 global[nglobal++].end = ftell(fin); 158 159 fseek(fin, 0L, 2); 160 if (trailer.start == 0) 161 trailer.start = ftell(fin); 162 trailer.end = ftell(fin); 163 164 if (page.end <= page.start) 165 page.end = trailer.start; 166 167 /* 168 fprintf(stderr, "prolog=(%d,%d)\n", prolog.start, prolog.end); 169 fprintf(stderr, "page=(%d,%d)\n", page.start, page.end); 170 for(i = 0; i < nglobal; i++) 171 fprintf(stderr, "global[%d]=(%d,%d)\n", i, global[i].start, global[i].end); 172 fprintf(stderr, "trailer=(%d,%d)\n", trailer.start, trailer.end); 173 */ 174 175 /* all output here */ 176 print(fout, PS_head); 177 var(llx); var(lly); var(urx); var(ury); var(w); var(o); var(s); 178 var(cx); var(cy); var(sx); var(sy); var(ax); var(ay); var(rot); 179 print(fout, PS_setup); 180 copy(fin, fout, &prolog); 181 for(i = 0; i < nglobal; i++) 182 copy(fin, fout, &global[i]); 183 copy(fin, fout, &page); 184 copy(fin, fout, &trailer); 185 print(fout, PS_tail); 186 187 if(nglobal) 188 free(global); 189 190 } 191 192 static void 193 print(FILE *fout, char **s) 194 { 195 while (*s) 196 fprintf(fout, "%s\n", *s++); 197 } 198 199 static void 200 copy(FILE *fin, FILE *fout, Section *s) 201 { 202 if (s->end <= s->start) 203 return; 204 fseek(fin, s->start, 0); 205 while (ftell(fin) < s->end && fgets(buf, sizeof(buf), fin) != NULL) 206 if (buf[0] != '%') 207 fprintf(fout, "%s", buf); 208 } 209