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";
48 static char psbeginsetup
[] =
51 static char psendsetup
[] =
54 static char psbeginfeature
[] = /* feature, value */
56 "%%%%BeginFeature: %s %s\n";
58 static char psendfeature
[] =
60 "} stopped cleartomark\n";
62 static char psnewpage
[] = /* name, number, xres, yres, xtrans, ytrans, rot */
64 "%%%%BeginPageSetup\n"
66 "72 %d div 72 %d div scale\n"
72 static char psendpage
[] =
76 static char psfooter
[] = /* pages */
81 static char psmoveto
[] = /* x, y */
84 static char pslineto
[] = /* x, y */
87 static char psstroke
[] =
90 static char psrectangle
[] = /* x, y, width, height, -width */
97 static char psshow
[] = /* string */
100 static char pssetfont
[] = /* fontname, xscale, yscale, ascent, escapement */
103 "%d 10 div matrix rotate\n"
104 "matrix concatmatrix\n"
105 "makefont setfont\n";
107 static char pssetlinewidth
[] = /* width */
110 static char pssetdash
[] = /* dash, offset */
113 static char pssetgray
[] = /* gray */
116 static char pssetrgbcolor
[] = /* r, g, b */
117 "%.2f %.2f %.2f setrgbcolor\n";
119 static char psellipse
[] = /* x, y, a, b */
120 "tmpmtrx currentmatrix pop\n"
124 "tmpmtrx setmatrix\n";
126 static char psgsave
[] =
129 static char psgrestore
[] =
132 static char psfill
[] =
135 char *PSDRV_ANSIVector
[256] = {
136 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
137 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
138 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
139 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
140 "space", "exclam", "quotedbl", "numbersign",
141 "dollar", "percent", "ampersand", "quotesingle",
142 "parenleft", "parenright", "asterisk", "plus",
143 "comma", "hyphen", "period", "slash",
144 "zero", "one", "two", "three",
145 "four", "five", "six", "seven",
146 "eight", "nine", "colon", "semicolon",
147 "less", "equal", "greater", "question",
154 "X", "Y", "Z", "bracketleft",
155 "backslash", "bracketright", "asciicircum", "underscore",
156 "grave", "a", "b", "c",
162 "x", "y", "z", "braceleft",
163 "bar", "braceright", "asciitilde", NULL
,
164 NULL
, NULL
, NULL
, NULL
,
165 NULL
, NULL
, NULL
, NULL
,
166 NULL
, NULL
, NULL
, NULL
,
167 NULL
, NULL
, NULL
, NULL
,
168 NULL
, "quoteleft", "quoteright", NULL
,
169 NULL
, NULL
, NULL
, NULL
,
170 NULL
, NULL
, NULL
, NULL
,
171 NULL
, NULL
, NULL
, NULL
,
172 NULL
, "exclamdown", "cent", "sterling",
173 "currency", "yen", "brokenbar", "section",
174 "dieresis", "copyright", "ordfeminine", "guillemotleft",
175 "logicalnot", "hyphen", "registered", "macron",
176 "degree", "plusminus", "twosuperior", "threesuperior",
177 "acute", "mu", "paragraph", "periodcentered",
178 "cedilla", "onesuperior", "ordmasculine", "guillemotright",
179 "onequarter", "onehalf", "threequarters","questiondown",
180 "Agrave", "Aacute", "Acircumflex", "Atilde",
181 "Adieresis", "Aring", "AE", "Ccedilla",
182 "Egrave", "Eacute", "Ecircumflex", "Edieresis",
183 "Igrave", "Iacute", "Icircumflex", "Idieresis",
184 "Eth", "Ntilde", "Ograve", "Oacute",
185 "Ocircumflex", "Otilde", "Odieresis", "multiply",
186 "Oslash", "Ugrave", "Uacute", "Ucircumflex",
187 "Udieresis", "Yacute", "Thorn", "germandbls",
188 "agrave", "aacute", "acircumflex", "atilde",
189 "adieresis", "aring", "ae", "ccedilla",
190 "egrave", "eacute", "ecircumflex", "edieresis",
191 "igrave", "iacute", "icircumflex", "idieresis",
192 "eth", "ntilde", "ograve", "oacute",
193 "ocircumflex", "otilde", "odieresis", "divide",
194 "oslash", "ugrave", "uacute", "ucircumflex",
195 "udieresis", "yacute", "thorn", "ydieresis"
199 char psreencodefont
[] = /* newfontname basefontname*/
200 "/%s /%s reencodefont\n";
203 int PSDRV_WriteSpool(DC
*dc
, LPSTR lpData
, WORD cch
)
205 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
207 if(physDev
->job
.NeedPageHeader
) {
208 physDev
->job
.PageNo
++;
209 if( !PSDRV_WriteNewPage(dc
) )
211 physDev
->job
.NeedPageHeader
= FALSE
;
213 return WriteSpool( physDev
->job
.hJob
, lpData
, cch
);
217 INT32
PSDRV_WriteFeature(HANDLE16 hJob
, char *feature
, char *value
,
221 char *buf
= (char *)HeapAlloc( PSDRV_Heap
, 0, sizeof(psheader
) +
222 strlen(feature
) + strlen(value
));
225 sprintf(buf
, psbeginfeature
, feature
, value
);
226 WriteSpool( hJob
, buf
, strlen(buf
) );
228 WriteSpool( hJob
, invocation
, strlen(invocation
) );
230 WriteSpool( hJob
, psendfeature
, strlen(psendfeature
) );
232 HeapFree( PSDRV_Heap
, 0, buf
);
238 INT32
PSDRV_WriteHeader( DC
*dc
, char *title
, int len
)
240 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
241 char *buf
, *titlebuf
, *orient
, vectbuf
[256];
246 titlebuf
= (char *)HeapAlloc( PSDRV_Heap
, 0, len
+1 );
248 WARN(psdrv
, "HeapAlloc failed\n");
251 memcpy(titlebuf
, title
, len
);
252 titlebuf
[len
] = '\0';
254 buf
= (char *)HeapAlloc( PSDRV_Heap
, 0, sizeof(psheader
) + len
+ 30);
256 WARN(psdrv
, "HeapAlloc failed\n");
257 HeapFree( PSDRV_Heap
, 0, titlebuf
);
261 if(physDev
->Devmode
->dmPublic
.dmOrientation
== DMORIENT_LANDSCAPE
) {
262 /* BBox co-ords are in default user co-ord system so urx < ury even in
264 urx
= (int) (dc
->w
.devCaps
->vertSize
* 72.0 / 25.4);
265 ury
= (int) (dc
->w
.devCaps
->horzSize
* 72.0 / 25.4);
266 orient
= "Landscape";
268 urx
= (int) (dc
->w
.devCaps
->horzSize
* 72.0 / 25.4);
269 ury
= (int) (dc
->w
.devCaps
->vertSize
* 72.0 / 25.4);
273 /* FIXME should do something better with BBox */
275 sprintf(buf
, psheader
, title
, 0, 0, urx
, ury
, orient
);
277 if( WriteSpool( physDev
->job
.hJob
, buf
, strlen(buf
) ) !=
279 WARN(psdrv
, "WriteSpool error\n");
280 HeapFree( PSDRV_Heap
, 0, titlebuf
);
281 HeapFree( PSDRV_Heap
, 0, buf
);
284 HeapFree( PSDRV_Heap
, 0, titlebuf
);
285 HeapFree( PSDRV_Heap
, 0, buf
);
287 WriteSpool( physDev
->job
.hJob
, psbeginprolog
, strlen(psbeginprolog
) );
288 WriteSpool( physDev
->job
.hJob
, psvectorstart
, strlen(psvectorstart
) );
290 for(i
= 0; i
< 256; i
+= 8) {
292 for(j
= 0; j
< 8; j
++) {
293 strcat(vectbuf
, "/");
294 if(PSDRV_ANSIVector
[i
+j
]) {
295 strcat(vectbuf
, PSDRV_ANSIVector
[i
+j
]);
296 strcat(vectbuf
, " ");
298 strcat(vectbuf
, ".notdef ");
301 strcat(vectbuf
, "\n");
302 WriteSpool( physDev
->job
.hJob
, vectbuf
, strlen(vectbuf
) );
305 WriteSpool( physDev
->job
.hJob
, psvectorend
, strlen(psvectorend
) );
306 WriteSpool( physDev
->job
.hJob
, psprolog
, strlen(psprolog
) );
307 WriteSpool( physDev
->job
.hJob
, psendprolog
, strlen(psendprolog
) );
310 WriteSpool( physDev
->job
.hJob
, psbeginsetup
, strlen(psbeginsetup
) );
312 for(slot
= physDev
->pi
->ppd
->InputSlots
; slot
; slot
= slot
->next
) {
313 if(slot
->WinBin
== physDev
->Devmode
->dmPublic
.dmDefaultSource
) {
314 if(slot
->InvocationString
) {
315 PSDRV_WriteFeature(physDev
->job
.hJob
, "*InputSlot", slot
->Name
,
316 slot
->InvocationString
);
322 for(page
= physDev
->pi
->ppd
->PageSizes
; page
; page
= page
->next
) {
323 if(page
->WinPage
== physDev
->Devmode
->dmPublic
.dmPaperSize
) {
324 if(page
->InvocationString
) {
325 PSDRV_WriteFeature(physDev
->job
.hJob
, "*PageSize", page
->Name
,
326 page
->InvocationString
);
332 WriteSpool( physDev
->job
.hJob
, psendsetup
, strlen(psendsetup
) );
339 INT32
PSDRV_WriteFooter( DC
*dc
)
341 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
344 buf
= (char *)HeapAlloc( PSDRV_Heap
, 0, sizeof(psfooter
) + 100 );
346 WARN(psdrv
, "HeapAlloc failed\n");
350 sprintf(buf
, psfooter
, physDev
->job
.PageNo
);
352 if( WriteSpool( physDev
->job
.hJob
, buf
, strlen(buf
) ) !=
354 WARN(psdrv
, "WriteSpool error\n");
355 HeapFree( PSDRV_Heap
, 0, buf
);
358 HeapFree( PSDRV_Heap
, 0, buf
);
364 INT32
PSDRV_WriteEndPage( DC
*dc
)
366 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
368 if( WriteSpool( physDev
->job
.hJob
, psendpage
, sizeof(psendpage
)-1 ) !=
369 sizeof(psendpage
)-1 ) {
370 WARN(psdrv
, "WriteSpool error\n");
379 INT32
PSDRV_WriteNewPage( DC
*dc
)
381 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
384 signed int xtrans
, ytrans
, rotation
;
386 sprintf(name
, "%d", physDev
->job
.PageNo
);
388 buf
= (char *)HeapAlloc( PSDRV_Heap
, 0, sizeof(psnewpage
) + 200 );
390 WARN(psdrv
, "HeapAlloc failed\n");
394 if(physDev
->Devmode
->dmPublic
.dmOrientation
== DMORIENT_LANDSCAPE
) {
395 if(physDev
->pi
->ppd
->LandscapeOrientation
== -90) {
396 xtrans
= dc
->w
.devCaps
->vertRes
;
397 ytrans
= dc
->w
.devCaps
->horzRes
;
405 ytrans
= dc
->w
.devCaps
->vertRes
;
409 sprintf(buf
, psnewpage
, name
, physDev
->job
.PageNo
,
410 dc
->w
.devCaps
->logPixelsX
, dc
->w
.devCaps
->logPixelsY
,
411 xtrans
, ytrans
, rotation
);
413 if( WriteSpool( physDev
->job
.hJob
, buf
, strlen(buf
) ) !=
415 WARN(psdrv
, "WriteSpool error\n");
416 HeapFree( PSDRV_Heap
, 0, buf
);
419 HeapFree( PSDRV_Heap
, 0, buf
);
424 BOOL32
PSDRV_WriteMoveTo(DC
*dc
, INT32 x
, INT32 y
)
428 sprintf(buf
, psmoveto
, x
, y
);
429 return PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
432 BOOL32
PSDRV_WriteLineTo(DC
*dc
, INT32 x
, INT32 y
)
436 sprintf(buf
, pslineto
, x
, y
);
437 return PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
441 BOOL32
PSDRV_WriteStroke(DC
*dc
)
443 return PSDRV_WriteSpool(dc
, psstroke
, sizeof(psstroke
)-1);
448 BOOL32
PSDRV_WriteRectangle(DC
*dc
, INT32 x
, INT32 y
, INT32 width
,
453 sprintf(buf
, psrectangle
, x
, y
, width
, height
, -width
);
454 return PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
457 BOOL32
PSDRV_WriteEllispe(DC
*dc
, INT32 x
, INT32 y
, INT32 a
, INT32 b
)
461 sprintf(buf
, psellipse
, x
, y
, a
, b
);
462 return PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
465 static char encodingext
[] = "-ANSI";
467 BOOL32
PSDRV_WriteSetFont(DC
*dc
, BOOL32 UseANSI
)
469 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
472 buf
= (char *)HeapAlloc( PSDRV_Heap
, 0,
473 sizeof(pssetfont
) + strlen(physDev
->font
.afm
->FontName
) + 40);
476 WARN(psdrv
, "HeapAlloc failed\n");
480 newbuf
= (char *)HeapAlloc( PSDRV_Heap
, 0,
481 strlen(physDev
->font
.afm
->FontName
) + sizeof(encodingext
));
484 WARN(psdrv
, "HeapAlloc failed\n");
485 HeapFree(PSDRV_Heap
, 0, buf
);
490 sprintf(newbuf
, "%s%s", physDev
->font
.afm
->FontName
, encodingext
);
492 strcpy(newbuf
, physDev
->font
.afm
->FontName
);
494 sprintf(buf
, pssetfont
, newbuf
,
495 physDev
->font
.size
, -physDev
->font
.size
,
496 -physDev
->font
.escapement
);
498 PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
499 HeapFree(PSDRV_Heap
, 0, buf
);
503 BOOL32
PSDRV_WriteSetColor(DC
*dc
, PSCOLOR
*color
)
505 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
508 if(PSDRV_CmpColor(&physDev
->inkColor
, color
))
511 PSDRV_CopyColor(&physDev
->inkColor
, color
);
512 switch(color
->type
) {
514 sprintf(buf
, pssetrgbcolor
, color
->value
.rgb
.r
, color
->value
.rgb
.g
,
516 return PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
519 sprintf(buf
, pssetgray
, color
->value
.gray
.i
);
520 return PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
523 ERR(psdrv
, "Unkonwn colour type %d\n", color
->type
);
530 BOOL32
PSDRV_WriteSetPen(DC
*dc
)
532 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
535 sprintf(buf
, pssetlinewidth
, physDev
->pen
.width
);
536 PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
538 if(physDev
->pen
.dash
) {
539 sprintf(buf
, pssetdash
, physDev
->pen
.dash
, 0);
540 PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
546 BOOL32
PSDRV_WriteReencodeFont(DC
*dc
)
548 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
551 buf
= (char *)HeapAlloc( PSDRV_Heap
, 0,
552 sizeof(psreencodefont
) + 2 * strlen(physDev
->font
.afm
->FontName
)
553 + sizeof(encodingext
));
556 WARN(psdrv
, "HeapAlloc failed\n");
560 newbuf
= (char *)HeapAlloc( PSDRV_Heap
, 0,
561 strlen(physDev
->font
.afm
->FontName
) + sizeof(encodingext
));
564 WARN(psdrv
, "HeapAlloc failed\n");
565 HeapFree(PSDRV_Heap
, 0, buf
);
569 sprintf(newbuf
, "%s%s", physDev
->font
.afm
->FontName
, encodingext
);
570 sprintf(buf
, psreencodefont
, newbuf
, physDev
->font
.afm
->FontName
);
572 PSDRV_WriteSpool(dc
, buf
, strlen(buf
));
574 HeapFree(PSDRV_Heap
, 0, newbuf
);
575 HeapFree(PSDRV_Heap
, 0, buf
);
579 BOOL32
PSDRV_WriteShow(DC
*dc
, char *str
, INT32 count
)
582 INT32 buflen
= count
+ 10, i
, done
;
584 buf
= (char *)HeapAlloc( PSDRV_Heap
, 0, buflen
);
586 for(i
= done
= 0; i
< count
; i
++) {
587 if(!isprint(str
[i
])) {
588 if(done
+ 4 >= buflen
)
589 buf
= HeapReAlloc( PSDRV_Heap
, 0, buf
, buflen
+= 10 );
590 sprintf(buf
+ done
, "\\%03o", (int)(unsigned char)str
[i
] );
592 } else if(str
[i
] == '\\' || str
[i
] == '(' || str
[i
] == ')' ) {
593 if(done
+ 2 >= buflen
)
594 buf
= HeapReAlloc( PSDRV_Heap
, 0, buf
, buflen
+= 10 );
596 buf
[done
++] = str
[i
];
598 if(done
+ 1 >= buflen
)
599 buf
= HeapReAlloc( PSDRV_Heap
, 0, buf
, buflen
+= 10 );
600 buf
[done
++] = str
[i
];
605 buf1
= (char *)HeapAlloc( PSDRV_Heap
, 0, sizeof(psshow
) + done
);
607 sprintf(buf1
, psshow
, buf
);
609 PSDRV_WriteSpool(dc
, buf1
, strlen(buf1
));
610 HeapFree(PSDRV_Heap
, 0, buf
);
611 HeapFree(PSDRV_Heap
, 0, buf1
);
616 BOOL32
PSDRV_WriteFill(DC
*dc
)
618 return PSDRV_WriteSpool(dc
, psfill
, sizeof(psfill
)-1);
621 BOOL32
PSDRV_Writegsave(DC
*dc
)
623 return PSDRV_WriteSpool(dc
, psgsave
, sizeof(psgsave
)-1);
626 BOOL32
PSDRV_Writegrestore(DC
*dc
)
628 return PSDRV_WriteSpool(dc
, psgrestore
, sizeof(psgrestore
)-1);