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 /* 31 * 32 * Picture inclusion code for PostScript printers. 33 * 34 */ 35 36 37 #include <stdio.h> 38 #include "ps_include.h" 39 40 41 #define var(x) fprintf(fout, "/%s %g def\n", #x, x) 42 #define has(word) (strncmp(buf, word, strlen(word)) == 0) 43 #define grab(n) ((Section *)(nglobal \ 44 ? realloc((char *)global, n * sizeof (Section)) \ 45 : calloc(n, sizeof (Section)))) 46 47 48 char buf[512]; 49 typedef struct { 50 long start; 51 long end; 52 } Section; 53 54 extern char *calloc(), *realloc(); 55 56 static void print(FILE *, char **); 57 static void copy(FILE *, FILE *, Section *); 58 59 60 /* 61 * fin, fout - input and output files 62 * page_no physical page number from *fin 63 * whiteout - erase picture area 64 * outline - draw a box around it and 65 * scaleboth - scale both dimensions - if not zero 66 * cx, cy - center of the picture and 67 * sx, sy - its size - in current coordinates 68 * ax, ay - left-right, up-down adjustment 69 * rot - rotation - in clockwise degrees 70 */ 71 void 72 ps_include(FILE *fin, FILE *fout, int page_no, int whiteout, 73 int outline, int scaleboth, double cx, double cy, 74 double sx, double sy, double ax, double ay, double rot) 75 { 76 /* found the page when non zero */ 77 int foundpage = 0; 78 /* number of global defs so far */ 79 int nglobal = 0; 80 /* and the number we've got room for */ 81 int maxglobal = 0; 82 /* prologue, page, and trailer offsets */ 83 Section prolog, page, trailer; 84 /* offsets for all global definitions */ 85 Section *global; 86 /* lower left and */ 87 double llx, lly; 88 /* upper right corners - default coords */ 89 double urx, ury; 90 /* mostly for the var() macro */ 91 double w = whiteout != 0; 92 double o = outline != 0; 93 double s = scaleboth != 0; 94 int i; 95 96 97 /* 98 * 99 * Reads a PostScript file (*fin), and uses structuring comments to 100 * locate the prologue, trailer, global definitions, and the requested 101 * page. After the whole file is scanned, the special ps_include 102 * PostScript definitions are copied to *fout, followed by the 103 * prologue, global definitions, the requested page, and the 104 * trailer. Before returning the initial environment (saved in 105 * PS_head) is restored. 106 * 107 * By default we assume the picture is 8.5 by 11 inches, but the 108 * BoundingBox comment, if found, takes precedence. 109 * 110 */ 111 112 /* default BoundingBox - 8.5x11 inches */ 113 llx = lly = 0; 114 urx = 72 * 8.5; 115 ury = 72 * 11.0; 116 117 /* section boundaries and bounding box */ 118 119 prolog.start = prolog.end = 0; 120 page.start = page.end = 0; 121 trailer.start = 0; 122 fseek(fin, 0L, 0); 123 124 while (fgets(buf, sizeof (buf), fin) != NULL) 125 if (!has("%%")) 126 continue; 127 else if (has("%%Page: ")) { 128 if (!foundpage) 129 page.start = ftell(fin); 130 sscanf(buf, "%*s %*s %d", &i); 131 if (i == page_no) 132 foundpage = 1; 133 else if (foundpage && page.end <= page.start) 134 page.end = ftell(fin); 135 } else if (has("%%EndPage: ")) { 136 sscanf(buf, "%*s %*s %d", &i); 137 if (i == page_no) { 138 foundpage = 1; 139 page.end = ftell(fin); 140 } 141 if (!foundpage) 142 page.start = ftell(fin); 143 } else if (has("%%BoundingBox:")) 144 sscanf(buf, "%%%%BoundingBox: %lf %lf %lf %lf", 145 &llx, &lly, &urx, &ury); 146 else if (has("%%EndProlog") || has("%%EndSetup") || 147 has("%%EndDocumentSetup")) 148 prolog.end = page.start = ftell(fin); 149 else if (has("%%Trailer")) 150 trailer.start = ftell(fin); 151 else if (has("%%BeginGlobal")) { 152 if (page.end <= page.start) { 153 if (nglobal >= maxglobal) { 154 maxglobal += 20; 155 global = grab(maxglobal); 156 } 157 global[nglobal].start = ftell(fin); 158 } 159 } else if (has("%%EndGlobal")) 160 if (page.end <= page.start) 161 global[nglobal++].end = ftell(fin); 162 163 fseek(fin, 0L, 2); 164 if (trailer.start == 0) 165 trailer.start = ftell(fin); 166 trailer.end = ftell(fin); 167 168 if (page.end <= page.start) 169 page.end = trailer.start; 170 171 /* all output here */ 172 print(fout, PS_head); 173 var(llx); var(lly); var(urx); var(ury); var(w); var(o); var(s); 174 var(cx); var(cy); var(sx); var(sy); var(ax); var(ay); var(rot); 175 print(fout, PS_setup); 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 print(fout, PS_tail); 182 183 if (nglobal) 184 free(global); 185 186 } 187 188 static void 189 print(FILE *fout, char **s) 190 { 191 while (*s) 192 fprintf(fout, "%s\n", *s++); 193 } 194 195 static void 196 copy(FILE *fin, FILE *fout, Section *s) 197 { 198 if (s->end <= s->start) 199 return; 200 fseek(fin, s->start, 0); 201 while (ftell(fin) < s->end && fgets(buf, sizeof (buf), fin) != NULL) 202 if (buf[0] != '%') 203 fprintf(fout, "%s", buf); 204 } 205