]> git.ipfire.org Git - thirdparty/cups.git/blame - filter/hpgl-prolog.c
Merge changes from CUPS 1.5svn-r8950.
[thirdparty/cups.git] / filter / hpgl-prolog.c
CommitLineData
ef416fc2 1/*
bc44d920 2 * "$Id: hpgl-prolog.c 6649 2007-07-11 21:46:42Z mike $"
ef416fc2 3 *
4 * HP-GL/2 prolog routines for for the Common UNIX Printing System (CUPS).
5 *
bc44d920 6 * Copyright 2007 by Apple Inc.
c0e1af83 7 * Copyright 1993-2007 by Easy Software Products.
ef416fc2 8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
19 * OutputProlog() - Output the PostScript prolog...
20 * OutputTrailer() - Output the PostScript trailer...
21 * Outputf() - Write a formatted string to the output file, creating the
22 * page header as needed...
23 */
24
25/*
26 * Include necessary headers...
27 */
28
29#include "hpgltops.h"
30#include <stdarg.h>
31
32
33/*
34 * 'OutputProlog()' - Output the PostScript prolog...
35 */
36
37void
38OutputProlog(char *title, /* I - Job title */
39 char *user, /* I - Username */
40 int shading) /* I - Type of shading */
41{
42 FILE *prolog; /* Prolog file */
43 char line[255]; /* Line from prolog file */
44 const char *datadir; /* CUPS_DATADIR environment variable */
45 char filename[1024]; /* Name of prolog file */
46 time_t curtime; /* Current time */
47 struct tm *curtm; /* Current date */
48
49
50 curtime = time(NULL);
51 curtm = localtime(&curtime);
52
53 puts("%!PS-Adobe-3.0");
54 printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n",
55 PageLeft, PageBottom, PageRight, PageTop);
56 puts("%%Pages: (atend)");
57 printf("%%%%LanguageLevel: %d\n", LanguageLevel);
58 puts("%%DocumentData: Clean7Bit");
59 puts("%%DocumentSuppliedResources: procset hpgltops 1.1 0");
60 puts("%%DocumentNeededResources: font Courier Helvetica");
61 puts("%%Creator: hpgltops/" CUPS_SVERSION);
62 strftime(line, sizeof(line), "%c", curtm);
63 printf("%%%%CreationDate: %s\n", line);
2abf387c 64 WriteTextComment("Title", title);
65 WriteTextComment("For", user);
ef416fc2 66 printf("%%cupsRotation: %d\n", (Orientation & 3) * 90);
67 puts("%%EndComments");
68 puts("%%BeginProlog");
69 printf("/DefaultPenWidth %.2f def\n", PenWidth * 72.0 / 25.4);
70 if (!shading) /* Black only */
71 puts("/setrgbcolor { pop pop pop } bind def");
72 else if (!ColorDevice) /* Greyscale */
73 puts("/setrgbcolor { 0.08 mul exch 0.61 mul add exch 0.31 mul add setgray } bind def\n");
74
75 if ((datadir = getenv("CUPS_DATADIR")) == NULL)
76 datadir = CUPS_DATADIR;
77
78 snprintf(filename, sizeof(filename), "%s/data/HPGLprolog", datadir);
79
80 if ((prolog = fopen(filename, "r")) == NULL)
81 {
c0e1af83 82 fprintf(stderr,
83 "DEBUG: Unable to open HPGL prolog \"%s\" for reading - %s\n",
ef416fc2 84 filename, strerror(errno));
85 exit(1);
86 }
87
88 while (fgets(line, sizeof(line), prolog) != NULL)
89 fputs(line, stdout);
90
91 fclose(prolog);
92
93 puts("%%EndProlog");
94
95 IN_initialize(0, NULL);
96}
97
98
99/*
100 * 'OutputTrailer()' - Output the PostScript trailer...
101 */
102
103void
104OutputTrailer(void)
105{
106 if (PageDirty)
107 PG_advance_page(0, NULL);
108
109 puts("%%Trailer");
110 printf("%%%%Pages: %d\n", PageCount);
111 puts("%%EOF");
112}
113
114
115/*
116 * 'Outputf()' - Write a formatted string to the output file, creating the
117 * page header as needed...
118 */
119
120int /* O - Number of bytes written */
121Outputf(const char *format, /* I - Printf-style string */
122 ...) /* I - Additional args as needed */
123{
124 va_list ap; /* Argument pointer */
125 int bytes; /* Number of bytes written */
126 float iw1[2], iw2[2]; /* Clipping window */
127 int i; /* Looping var */
128 ppd_size_t *size; /* Page size */
129 ppd_option_t *option; /* Page size option */
130 ppd_choice_t *choice; /* Page size choice */
131 float width, length; /* Page dimensions */
132 int landscape; /* Rotate for landscape orientation? */
133
134
135 /*
136 * Write the page header as needed...
137 */
138
139 if (!PageDirty)
140 {
141 PageDirty = 1;
142 PageCount ++;
143
144 printf("%%%%Page: %d %d\n", PageCount, PageCount);
145
146 landscape = 0;
147
148 if (!FitPlot && PlotSizeSet)
149 {
150 /*
151 * Set the page size for this page...
152 */
153
154 if (PageRotation == 0 || PageRotation == 180)
155 {
156 width = PlotSize[0];
157 length = PlotSize[1];
158 }
159 else
160 {
161 width = PlotSize[1];
162 length = PlotSize[0];
163 }
164
165 fprintf(stderr, "DEBUG: hpgltops setting page size (%.0f x %.0f)\n",
166 width, length);
167
168 if (PPD != NULL)
169 {
170 fputs("DEBUG: hpgltops has a PPD file!\n", stderr);
171
172 /*
173 * Lookup the closest PageSize and set it...
174 */
175
176 for (i = PPD->num_sizes, size = PPD->sizes; i > 0; i --, size ++)
177 if ((fabs(length - size->length) < 36.0 && size->width >= width) ||
178 (fabs(length - size->width) < 36.0 && size->length >= width))
179 break;
180
181 if (i == 0 && PPD->variable_sizes)
182 {
183 for (i = PPD->num_sizes, size = PPD->sizes; i > 0; i --, size ++)
184 if (strcasecmp(size->name, "custom") == 0)
185 break;
186 }
187
188 if (i > 0)
189 {
190 /*
191 * Found a matching size...
192 */
193
194 option = ppdFindOption(PPD, "PageSize");
195 choice = ppdFindChoice(option, size->name);
196
197 puts("%%BeginPageSetup");
198 printf("%%%%BeginFeature: PageSize %s\n", size->name);
199
200 if (strcasecmp(size->name, "custom") == 0)
201 {
202 PageLeft = PPD->custom_margins[0];
203 PageRight = width - PPD->custom_margins[2];
204 PageWidth = width;
205 PageBottom = PPD->custom_margins[1];
206 PageTop = length - PPD->custom_margins[3];
207 PageLength = length;
208
209 printf("%.0f %.0f 0 0 0\n", width, length);
210
211 if (choice->code == NULL)
212 {
213 /*
214 * This can happen with certain buggy PPD files that don't include
215 * a CustomPageSize command sequence... We just use a generic
216 * Level 2 command sequence...
217 */
218
219 puts("pop pop pop");
220 puts("<</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\n");
221 }
222 else
223 {
224 /*
225 * Use the vendor-supplied command...
226 */
227
228 printf("%s\n", choice->code);
229 }
230 }
231 else
232 {
233 if (choice->code)
234 printf("%s\n", choice->code);
235
236 if (fabs(length - size->width) < 36.0)
237 {
238 /*
239 * Do landscape orientation...
240 */
241
242 PageLeft = size->bottom;
243 PageRight = size->top;
244 PageWidth = size->length;
245 PageBottom = size->left;
246 PageTop = size->right;
247 PageLength = size->width;
248
249 landscape = 1;
250 }
251 else
252 {
253 /*
254 * Do portrait orientation...
255 */
256
257 PageLeft = size->left;
258 PageRight = size->right;
259 PageWidth = size->width;
260 PageBottom = size->bottom;
261 PageTop = size->top;
262 PageLength = size->length;
263 }
264 }
265
266 puts("%%EndFeature");
267 puts("%%EndPageSetup");
268 }
269 }
270 else
271 {
272 fputs("DEBUG: hpgltops does not have a PPD file!\n", stderr);
273
274 puts("%%BeginPageSetup");
275 printf("%%%%BeginFeature: PageSize w%.0fh%.0f\n", width, length);
276 printf("<</PageSize[%.0f %.0f]/ImageBBox null>>setpagedevice\n",
277 width, length);
278 puts("%%EndFeature");
279 puts("%%EndPageSetup");
280
281 PageLeft = 0.0;
282 PageRight = width;
283 PageWidth = width;
284 PageBottom = 0.0;
285 PageTop = length;
286 PageLength = length;
287 }
288 }
289
290 define_font(0);
291 define_font(1);
292
293 printf("%.1f setmiterlimit\n", MiterLimit);
294 printf("%d setlinecap\n", LineCap);
295 printf("%d setlinejoin\n", LineJoin);
296
297 printf("%.3f %.3f %.3f %.2f SP\n", Pens[1].rgb[0], Pens[1].rgb[1],
298 Pens[1].rgb[2], Pens[1].width * PenScaling);
299
300 puts("gsave");
301
302 if (Duplex && (PageCount & 1) == 0)
303 switch ((PageRotation / 90 + landscape) & 3)
304 {
305 case 0 :
306 printf("%.1f %.1f translate\n", PageWidth - PageRight, PageBottom);
307 break;
308 case 1 :
309 printf("%.0f 0 translate 90 rotate\n", PageLength);
310 printf("%.1f %.1f translate\n", PageLength - PageTop,
311 PageWidth - PageRight);
312 break;
313 case 2 :
314 printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength);
315 printf("%.1f %.1f translate\n", PageLeft, PageLength - PageTop);
316 break;
317 case 3 :
318 printf("0 %.0f translate -90 rotate\n", PageWidth);
319 printf("%.1f %.1f translate\n", PageBottom, PageLeft);
320 break;
321 }
322 else
323 switch ((PageRotation / 90 + landscape) & 3)
324 {
325 case 0 :
326 printf("%.1f %.1f translate\n", PageLeft, PageBottom);
327 break;
328 case 1 :
329 printf("%.0f 0 translate 90 rotate\n", PageLength);
330 printf("%.1f %.1f translate\n", PageBottom, PageWidth - PageRight);
331 break;
332 case 2 :
333 printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength);
334 printf("%.1f %.1f translate\n", PageWidth - PageRight,
335 PageLength - PageTop);
336 break;
337 case 3 :
338 printf("0 %.0f translate -90 rotate\n", PageWidth);
339 printf("%.1f %.1f translate\n", PageLength - PageTop, PageLeft);
340 break;
341 }
342
343 if (IW1[0] != IW2[0] && IW1[1] != IW2[1])
344 {
345 iw1[0] = IW1[0] * 72.0f / 1016.0f;
346 iw1[1] = IW1[1] * 72.0f / 1016.0f;
347 iw2[0] = IW2[0] * 72.0f / 1016.0f;
348 iw2[1] = IW2[1] * 72.0f / 1016.0f;
349
350 printf("initclip MP %.3f %.3f MO %.3f %.3f LI %.3f %.3f LI %.3f %.3f LI CP clip\n",
351 iw1[0], iw1[1], iw1[0], iw2[1], iw2[0], iw2[1], iw2[0], iw1[1]);
352 }
353 }
354
355 /*
356 * Write the string to the output file...
357 */
358
359 va_start(ap, format);
360 bytes = vprintf(format, ap);
361 va_end(ap);
362
363 return (bytes);
364}
365
366
367/*
bc44d920 368 * End of "$Id: hpgl-prolog.c 6649 2007-07-11 21:46:42Z mike $".
ef416fc2 369 */