2 * PostScript output functions
4 * Copyright 1998 Huw D M Davies
15 static char psheader[] = /* title llx lly urx ury orientation */
17 "%%%%Creator: Wine PostScript Driver\n"
19 "%%%%BoundingBox: %d %d %d %d\n"
20 "%%%%Pages: (atend)\n"
21 "%%%%Orientation: %s\n"
24 static char psbeginprolog[] =
27 static char psendprolog[] =
30 static char psvectorstart[] =
33 static char psvectorend[] =
36 static char psprolog[] = /* output ANSIEncoding vector first */
39 " dup length dict begin\n"
40 " {1 index /FID ne {def} {pop pop} ifelse} forall\n"
41 " /Encoding ANSIEncoding def\n"
46 "/tmpmtrx matrix def\n"
49 " /b exch def /r exch def /t exch def /l exch def /gap 32 def\n"
50 " l cvi gap idiv gap mul\n"
52 " r cvi gap idiv gap mul\n"
53 " {t moveto 0 b t sub rlineto}\n"
57 static char psbeginsetup[] =
60 static char psendsetup[] =
63 static char psbeginfeature[] = /* feature, value */
65 "%%%%BeginFeature: %s %s\n";
67 static char psendfeature[] =
69 "} stopped cleartomark\n";
71 static char psnewpage[] = /* name, number, xres, yres, xtrans, ytrans, rot */
73 "%%%%BeginPageSetup\n"
75 "72 %d div 72 %d div scale\n"
81 static char psendpage[] =
85 static char psfooter[] = /* pages */
90 static char psmoveto[] = /* x, y */
93 static char pslineto[] = /* x, y */
96 static char psstroke[] =
99 static char psrectangle[] = /* x, y, width, height, -width */
106 static char psshow[] = /* string */
109 static char pssetfont[] = /* fontname, xscale, yscale, ascent, escapement */
112 "%d 10 div matrix rotate\n"
113 "matrix concatmatrix\n"
114 "makefont setfont\n";
116 static char pssetlinewidth[] = /* width */
119 static char pssetdash[] = /* dash, offset */
122 static char pssetgray[] = /* gray */
125 static char pssetrgbcolor[] = /* r, g, b */
126 "%.2f %.2f %.2f setrgbcolor\n";
128 static char psarc[] = /* x, y, w, h, ang1, ang2 */
129 "tmpmtrx currentmatrix pop\n"
132 "0 0 0.5 %.1f %.1f arc\n"
133 "tmpmtrx setmatrix\n";
135 static char psgsave[] =
138 static char psgrestore[] =
141 static char psfill[] =
144 static char pseofill[] =
147 static char psclosepath[] =
150 static char psclip[] =
153 static char pseoclip[] =
156 static char pshatch[] =
159 static char psrotate[] = /* ang */
162 char *PSDRV_ANSIVector[256] = {
163 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
164 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
165 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
166 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
167 "space", "exclam", "quotedbl", "numbersign",
168 "dollar", "percent", "ampersand", "quotesingle",
169 "parenleft", "parenright", "asterisk", "plus",
170 "comma", "hyphen", "period", "slash",
171 "zero", "one", "two", "three",
172 "four", "five", "six", "seven",
173 "eight", "nine", "colon", "semicolon",
174 "less", "equal", "greater", "question",
181 "X", "Y", "Z", "bracketleft",
182 "backslash", "bracketright", "asciicircum", "underscore",
183 "grave", "a", "b", "c",
189 "x", "y", "z", "braceleft",
190 "bar", "braceright", "asciitilde", NULL,
191 NULL, NULL, NULL, NULL,
192 NULL, NULL, NULL, NULL,
193 NULL, NULL, NULL, NULL,
194 NULL, NULL, NULL, NULL,
195 NULL, "quoteleft", "quoteright", NULL,
196 NULL, NULL, NULL, NULL,
197 NULL, NULL, NULL, NULL,
198 NULL, NULL, NULL, NULL,
199 NULL, "exclamdown", "cent", "sterling",
200 "currency", "yen", "brokenbar", "section",
201 "dieresis", "copyright", "ordfeminine", "guillemotleft",
202 "logicalnot", "hyphen", "registered", "macron",
203 "degree", "plusminus", "twosuperior", "threesuperior",
204 "acute", "mu", "paragraph", "periodcentered",
205 "cedilla", "onesuperior", "ordmasculine", "guillemotright",
206 "onequarter", "onehalf", "threequarters","questiondown",
207 "Agrave", "Aacute", "Acircumflex", "Atilde",
208 "Adieresis", "Aring", "AE", "Ccedilla",
209 "Egrave", "Eacute", "Ecircumflex", "Edieresis",
210 "Igrave", "Iacute", "Icircumflex", "Idieresis",
211 "Eth", "Ntilde", "Ograve", "Oacute",
212 "Ocircumflex", "Otilde", "Odieresis", "multiply",
213 "Oslash", "Ugrave", "Uacute", "Ucircumflex",
214 "Udieresis", "Yacute", "Thorn", "germandbls",
215 "agrave", "aacute", "acircumflex", "atilde",
216 "adieresis", "aring", "ae", "ccedilla",
217 "egrave", "eacute", "ecircumflex", "edieresis",
218 "igrave", "iacute", "icircumflex", "idieresis",
219 "eth", "ntilde", "ograve", "oacute",
220 "ocircumflex", "otilde", "odieresis", "divide",
221 "oslash", "ugrave", "uacute", "ucircumflex",
222 "udieresis", "yacute", "thorn", "ydieresis"
226 char psreencodefont[] = /* newfontname basefontname*/
227 "/%s /%s reencodefont\n";
230 int PSDRV_WriteSpool(DC *dc, LPSTR lpData, WORD cch)
232 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
234 if(physDev->job.NeedPageHeader) {
235 physDev->job.PageNo++;
236 if( !PSDRV_WriteNewPage(dc) )
238 physDev->job.NeedPageHeader = FALSE;
240 return WriteSpool( physDev->job.hJob, lpData, cch );
244 INT32 PSDRV_WriteFeature(HANDLE16 hJob, char *feature, char *value,
248 char *buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psheader) +
249 strlen(feature) + strlen(value));
252 sprintf(buf, psbeginfeature, feature, value);
253 WriteSpool( hJob, buf, strlen(buf) );
255 WriteSpool( hJob, invocation, strlen(invocation) );
257 WriteSpool( hJob, psendfeature, strlen(psendfeature) );
259 HeapFree( PSDRV_Heap, 0, buf );
265 INT32 PSDRV_WriteHeader( DC *dc, char *title, int len )
267 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
268 char *buf, *titlebuf, *orient, vectbuf[256];
273 titlebuf = (char *)HeapAlloc( PSDRV_Heap, 0, len+1 );
275 WARN(psdrv, "HeapAlloc failed\n");
278 memcpy(titlebuf, title, len);
279 titlebuf[len] = '\0';
281 buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psheader) + len + 30);
283 WARN(psdrv, "HeapAlloc failed\n");
284 HeapFree( PSDRV_Heap, 0, titlebuf );
288 if(physDev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) {
289 /* BBox co-ords are in default user co-ord system so urx < ury even in
291 urx = (int) (dc->w.devCaps->vertSize * 72.0 / 25.4);
292 ury = (int) (dc->w.devCaps->horzSize * 72.0 / 25.4);
293 orient = "Landscape";
295 urx = (int) (dc->w.devCaps->horzSize * 72.0 / 25.4);
296 ury = (int) (dc->w.devCaps->vertSize * 72.0 / 25.4);
300 /* FIXME should do something better with BBox */
302 sprintf(buf, psheader, title, 0, 0, urx, ury, orient);
304 if( WriteSpool( physDev->job.hJob, buf, strlen(buf) ) !=
306 WARN(psdrv, "WriteSpool error\n");
307 HeapFree( PSDRV_Heap, 0, titlebuf );
308 HeapFree( PSDRV_Heap, 0, buf );
311 HeapFree( PSDRV_Heap, 0, titlebuf );
312 HeapFree( PSDRV_Heap, 0, buf );
314 WriteSpool( physDev->job.hJob, psbeginprolog, strlen(psbeginprolog) );
315 WriteSpool( physDev->job.hJob, psvectorstart, strlen(psvectorstart) );
317 for(i = 0; i < 256; i += 8) {
319 for(j = 0; j < 8; j++) {
320 strcat(vectbuf, "/");
321 if(PSDRV_ANSIVector[i+j]) {
322 strcat(vectbuf, PSDRV_ANSIVector[i+j]);
323 strcat(vectbuf, " ");
325 strcat(vectbuf, ".notdef ");
328 strcat(vectbuf, "\n");
329 WriteSpool( physDev->job.hJob, vectbuf, strlen(vectbuf) );
332 WriteSpool( physDev->job.hJob, psvectorend, strlen(psvectorend) );
333 WriteSpool( physDev->job.hJob, psprolog, strlen(psprolog) );
334 WriteSpool( physDev->job.hJob, psendprolog, strlen(psendprolog) );
337 WriteSpool( physDev->job.hJob, psbeginsetup, strlen(psbeginsetup) );
339 for(slot = physDev->pi->ppd->InputSlots; slot; slot = slot->next) {
340 if(slot->WinBin == physDev->Devmode->dmPublic.dmDefaultSource) {
341 if(slot->InvocationString) {
342 PSDRV_WriteFeature(physDev->job.hJob, "*InputSlot", slot->Name,
343 slot->InvocationString);
349 for(page = physDev->pi->ppd->PageSizes; page; page = page->next) {
350 if(page->WinPage == physDev->Devmode->dmPublic.dmPaperSize) {
351 if(page->InvocationString) {
352 PSDRV_WriteFeature(physDev->job.hJob, "*PageSize", page->Name,
353 page->InvocationString);
359 WriteSpool( physDev->job.hJob, psendsetup, strlen(psendsetup) );
366 INT32 PSDRV_WriteFooter( DC *dc )
368 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
371 buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psfooter) + 100 );
373 WARN(psdrv, "HeapAlloc failed\n");
377 sprintf(buf, psfooter, physDev->job.PageNo);
379 if( WriteSpool( physDev->job.hJob, buf, strlen(buf) ) !=
381 WARN(psdrv, "WriteSpool error\n");
382 HeapFree( PSDRV_Heap, 0, buf );
385 HeapFree( PSDRV_Heap, 0, buf );
391 INT32 PSDRV_WriteEndPage( DC *dc )
393 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
395 if( WriteSpool( physDev->job.hJob, psendpage, sizeof(psendpage)-1 ) !=
396 sizeof(psendpage)-1 ) {
397 WARN(psdrv, "WriteSpool error\n");
406 INT32 PSDRV_WriteNewPage( DC *dc )
408 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
411 signed int xtrans, ytrans, rotation;
413 sprintf(name, "%d", physDev->job.PageNo);
415 buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psnewpage) + 200 );
417 WARN(psdrv, "HeapAlloc failed\n");
421 if(physDev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) {
422 if(physDev->pi->ppd->LandscapeOrientation == -90) {
423 xtrans = dc->w.devCaps->vertRes;
424 ytrans = dc->w.devCaps->horzRes;
432 ytrans = dc->w.devCaps->vertRes;
436 sprintf(buf, psnewpage, name, physDev->job.PageNo,
437 dc->w.devCaps->logPixelsX, dc->w.devCaps->logPixelsY,
438 xtrans, ytrans, rotation);
440 if( WriteSpool( physDev->job.hJob, buf, strlen(buf) ) !=
442 WARN(psdrv, "WriteSpool error\n");
443 HeapFree( PSDRV_Heap, 0, buf );
446 HeapFree( PSDRV_Heap, 0, buf );
451 BOOL32 PSDRV_WriteMoveTo(DC *dc, INT32 x, INT32 y)
455 sprintf(buf, psmoveto, x, y);
456 return PSDRV_WriteSpool(dc, buf, strlen(buf));
459 BOOL32 PSDRV_WriteLineTo(DC *dc, INT32 x, INT32 y)
463 sprintf(buf, pslineto, x, y);
464 return PSDRV_WriteSpool(dc, buf, strlen(buf));
468 BOOL32 PSDRV_WriteStroke(DC *dc)
470 return PSDRV_WriteSpool(dc, psstroke, sizeof(psstroke)-1);
475 BOOL32 PSDRV_WriteRectangle(DC *dc, INT32 x, INT32 y, INT32 width,
480 sprintf(buf, psrectangle, x, y, width, height, -width);
481 return PSDRV_WriteSpool(dc, buf, strlen(buf));
484 BOOL32 PSDRV_WriteArc(DC *dc, INT32 x, INT32 y, INT32 w, INT32 h, double ang1,
489 /* Make angles -ve and swap order because we're working with an upside
491 sprintf(buf, psarc, x, y, w, h, -ang2, -ang1);
492 return PSDRV_WriteSpool(dc, buf, strlen(buf));
495 static char encodingext[] = "-ANSI";
497 BOOL32 PSDRV_WriteSetFont(DC *dc, BOOL32 UseANSI)
499 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
502 buf = (char *)HeapAlloc( PSDRV_Heap, 0,
503 sizeof(pssetfont) + strlen(physDev->font.afm->FontName) + 40);
506 WARN(psdrv, "HeapAlloc failed\n");
510 newbuf = (char *)HeapAlloc( PSDRV_Heap, 0,
511 strlen(physDev->font.afm->FontName) + sizeof(encodingext));
514 WARN(psdrv, "HeapAlloc failed\n");
515 HeapFree(PSDRV_Heap, 0, buf);
520 sprintf(newbuf, "%s%s", physDev->font.afm->FontName, encodingext);
522 strcpy(newbuf, physDev->font.afm->FontName);
524 sprintf(buf, pssetfont, newbuf,
525 physDev->font.size, -physDev->font.size,
526 -physDev->font.escapement);
528 PSDRV_WriteSpool(dc, buf, strlen(buf));
529 HeapFree(PSDRV_Heap, 0, buf);
533 BOOL32 PSDRV_WriteSetColor(DC *dc, PSCOLOR *color)
535 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
538 if(PSDRV_CmpColor(&physDev->inkColor, color))
541 PSDRV_CopyColor(&physDev->inkColor, color);
542 switch(color->type) {
544 sprintf(buf, pssetrgbcolor, color->value.rgb.r, color->value.rgb.g,
546 return PSDRV_WriteSpool(dc, buf, strlen(buf));
549 sprintf(buf, pssetgray, color->value.gray.i);
550 return PSDRV_WriteSpool(dc, buf, strlen(buf));
553 ERR(psdrv, "Unkonwn colour type %d\n", color->type);
560 BOOL32 PSDRV_WriteSetPen(DC *dc)
562 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
565 sprintf(buf, pssetlinewidth, physDev->pen.width);
566 PSDRV_WriteSpool(dc, buf, strlen(buf));
568 if(physDev->pen.dash) {
569 sprintf(buf, pssetdash, physDev->pen.dash, 0);
570 PSDRV_WriteSpool(dc, buf, strlen(buf));
576 BOOL32 PSDRV_WriteReencodeFont(DC *dc)
578 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
581 buf = (char *)HeapAlloc( PSDRV_Heap, 0,
582 sizeof(psreencodefont) + 2 * strlen(physDev->font.afm->FontName)
583 + sizeof(encodingext));
586 WARN(psdrv, "HeapAlloc failed\n");
590 newbuf = (char *)HeapAlloc( PSDRV_Heap, 0,
591 strlen(physDev->font.afm->FontName) + sizeof(encodingext));
594 WARN(psdrv, "HeapAlloc failed\n");
595 HeapFree(PSDRV_Heap, 0, buf);
599 sprintf(newbuf, "%s%s", physDev->font.afm->FontName, encodingext);
600 sprintf(buf, psreencodefont, newbuf, physDev->font.afm->FontName);
602 PSDRV_WriteSpool(dc, buf, strlen(buf));
604 HeapFree(PSDRV_Heap, 0, newbuf);
605 HeapFree(PSDRV_Heap, 0, buf);
609 BOOL32 PSDRV_WriteShow(DC *dc, char *str, INT32 count)
612 INT32 buflen = count + 10, i, done;
614 buf = (char *)HeapAlloc( PSDRV_Heap, 0, buflen );
616 for(i = done = 0; i < count; i++) {
617 if(!isprint(str[i])) {
618 if(done + 4 >= buflen)
619 buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
620 sprintf(buf + done, "\\%03o", (int)(unsigned char)str[i] );
622 } else if(str[i] == '\\' || str[i] == '(' || str[i] == ')' ) {
623 if(done + 2 >= buflen)
624 buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
626 buf[done++] = str[i];
628 if(done + 1 >= buflen)
629 buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
630 buf[done++] = str[i];
635 buf1 = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psshow) + done);
637 sprintf(buf1, psshow, buf);
639 PSDRV_WriteSpool(dc, buf1, strlen(buf1));
640 HeapFree(PSDRV_Heap, 0, buf);
641 HeapFree(PSDRV_Heap, 0, buf1);
646 BOOL32 PSDRV_WriteFill(DC *dc)
648 return PSDRV_WriteSpool(dc, psfill, sizeof(psfill)-1);
651 BOOL32 PSDRV_WriteEOFill(DC *dc)
653 return PSDRV_WriteSpool(dc, pseofill, sizeof(pseofill)-1);
656 BOOL32 PSDRV_WriteGSave(DC *dc)
658 return PSDRV_WriteSpool(dc, psgsave, sizeof(psgsave)-1);
661 BOOL32 PSDRV_WriteGRestore(DC *dc)
663 return PSDRV_WriteSpool(dc, psgrestore, sizeof(psgrestore)-1);
666 BOOL32 PSDRV_WriteClosePath(DC *dc)
668 return PSDRV_WriteSpool(dc, psclosepath, sizeof(psclosepath)-1);
671 BOOL32 PSDRV_WriteClip(DC *dc)
673 return PSDRV_WriteSpool(dc, psclip, sizeof(psclip)-1);
676 BOOL32 PSDRV_WriteEOClip(DC *dc)
678 return PSDRV_WriteSpool(dc, pseoclip, sizeof(pseoclip)-1);
681 BOOL32 PSDRV_WriteHatch(DC *dc)
683 return PSDRV_WriteSpool(dc, pshatch, sizeof(pshatch)-1);
686 BOOL32 PSDRV_WriteRotate(DC *dc, float ang)
690 sprintf(buf, psrotate, ang);
691 return PSDRV_WriteSpool(dc, buf, strlen(buf));