ps.c 21.1 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1
/*
Alexandre Julliard's avatar
Alexandre Julliard committed
2
 *	PostScript output functions
Alexandre Julliard's avatar
Alexandre Julliard committed
3 4 5
 *
 *	Copyright 1998  Huw D M Davies
 *
6 7 8 9 10 11 12 13 14 15 16 17 18
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
21
#include <ctype.h>
22
#include <stdio.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
23
#include <string.h>
24
#include "gdi.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
25
#include "psdrv.h"
26
#include "winspool.h"
27
#include "wine/debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
28

29
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
30

Alexandre Julliard's avatar
Alexandre Julliard committed
31 32
static char psheader[] = /* title llx lly urx ury orientation */
"%%!PS-Adobe-3.0\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
33
"%%%%Creator: Wine PostScript Driver\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
34
"%%%%Title: %s\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
35
"%%%%BoundingBox: %d %d %d %d\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
36
"%%%%Pages: (atend)\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
37 38 39
"%%%%Orientation: %s\n"
"%%%%EndComments\n";

40
static char psbeginprolog[] =
Alexandre Julliard's avatar
Alexandre Julliard committed
41 42 43 44 45
"%%BeginProlog\n";

static char psendprolog[] =
"%%EndProlog\n";

46
static char psprolog[] =
47 48 49 50 51 52 53 54 55
"/tmpmtrx matrix def\n"
"/hatch {\n"
"  pathbbox\n"
"  /b exch def /r exch def /t exch def /l exch def /gap 32 def\n"
"  l cvi gap idiv gap mul\n"
"  gap\n"
"  r cvi gap idiv gap mul\n"
"  {t moveto 0 b t sub rlineto}\n"
"  for\n"
56 57
"} bind def\n"
"/B {pop pop pop pop} def\n";
Alexandre Julliard's avatar
Alexandre Julliard committed
58

Alexandre Julliard's avatar
Alexandre Julliard committed
59
static char psbeginsetup[] =
Alexandre Julliard's avatar
Alexandre Julliard committed
60 61
"%%BeginSetup\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
62
static char psendsetup[] =
Alexandre Julliard's avatar
Alexandre Julliard committed
63 64
"%%EndSetup\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
65
static char psbeginfeature[] = /* feature, value */
Alexandre Julliard's avatar
Alexandre Julliard committed
66 67 68
"mark {\n"
"%%%%BeginFeature: %s %s\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
69
static char psendfeature[] =
Alexandre Julliard's avatar
Alexandre Julliard committed
70 71
"\n%%EndFeature\n"
"} stopped cleartomark\n";
Alexandre Julliard's avatar
Alexandre Julliard committed
72

Alexandre Julliard's avatar
Alexandre Julliard committed
73
static char psnewpage[] = /* name, number, xres, yres, xtrans, ytrans, rot */
Alexandre Julliard's avatar
Alexandre Julliard committed
74 75 76
"%%%%Page: %s %d\n"
"%%%%BeginPageSetup\n"
"/pgsave save def\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
77 78
"72 %d div 72 %d div scale\n"
"%d %d translate\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
79
"1 -1 scale\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
80
"%d rotate\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
81 82
"%%%%EndPageSetup\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
83
static char psendpage[] =
Alexandre Julliard's avatar
Alexandre Julliard committed
84 85 86
"pgsave restore\n"
"showpage\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
87
static char psfooter[] = /* pages */
Alexandre Julliard's avatar
Alexandre Julliard committed
88 89 90 91
"%%%%Trailer\n"
"%%%%Pages: %d\n"
"%%%%EOF\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
92
static char psmoveto[] = /* x, y */
Alexandre Julliard's avatar
Alexandre Julliard committed
93 94
"%d %d moveto\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
95
static char pslineto[] = /* x, y */
Alexandre Julliard's avatar
Alexandre Julliard committed
96 97
"%d %d lineto\n";

98
static char psstroke[] =
Alexandre Julliard's avatar
Alexandre Julliard committed
99 100
"stroke\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
101
static char psrectangle[] = /* x, y, width, height, -width */
Alexandre Julliard's avatar
Alexandre Julliard committed
102 103 104 105 106 107
"%d %d moveto\n"
"%d 0 rlineto\n"
"0 %d rlineto\n"
"%d 0 rlineto\n"
"closepath\n";

108 109 110 111 112 113 114
static char psrrectangle[] = /* x, y, width, height, -width */
"%d %d rmoveto\n"
"%d 0 rlineto\n"
"0 %d rlineto\n"
"%d 0 rlineto\n"
"closepath\n";

115 116 117
static const char psglyphshow[] = /* glyph name */
"/%s glyphshow\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
118
static char pssetfont[] = /* fontname, xscale, yscale, ascent, escapement */
Alexandre Julliard's avatar
Alexandre Julliard committed
119
"/%s findfont\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
120
"[%d 0 0 %d 0 0]\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
121 122 123 124
"%d 10 div matrix rotate\n"
"matrix concatmatrix\n"
"makefont setfont\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
125 126 127 128 129 130 131 132 133 134 135 136
static char pssetlinewidth[] = /* width */
"%d setlinewidth\n";

static char pssetdash[] = /* dash, offset */
"[%s] %d setdash\n";

static char pssetgray[] = /* gray */
"%.2f setgray\n";

static char pssetrgbcolor[] = /* r, g, b */
"%.2f %.2f %.2f setrgbcolor\n";

137
static char psarc[] = /* x, y, w, h, ang1, ang2 */
Alexandre Julliard's avatar
Alexandre Julliard committed
138 139 140
"tmpmtrx currentmatrix pop\n"
"%d %d translate\n"
"%d %d scale\n"
141
"0 0 0.5 %.1f %.1f arc\n"
Alexandre Julliard's avatar
Alexandre Julliard committed
142 143 144 145 146 147 148 149 150 151 152
"tmpmtrx setmatrix\n";

static char psgsave[] =
"gsave\n";

static char psgrestore[] =
"grestore\n";

static char psfill[] =
"fill\n";

153 154 155
static char pseofill[] =
"eofill\n";

156 157 158
static char psnewpath[] =
"newpath\n";

159 160 161 162 163 164
static char psclosepath[] =
"closepath\n";

static char psclip[] =
"clip\n";

165 166 167
static char psinitclip[] =
"initclip\n";

168 169 170
static char pseoclip[] =
"eoclip\n";

171
static char psrectclip[] =
172
"%d %d %d %d rectclip\n";
173 174

static char psrectclip2[] =
175
"%s rectclip\n";
176

177 178 179 180 181 182
static char pshatch[] =
"hatch\n";

static char psrotate[] = /* ang */
"%.1f rotate\n";

183
static char psarrayget[] =
184 185
"%s %d get\n";

186
static char psarrayput[] =
187 188
"%s %d %ld put\n";

189
static char psarraydef[] =
190 191
"/%s %d array def\n";

Alexandre Julliard's avatar
Alexandre Julliard committed
192

193
int PSDRV_WriteSpool(PSDRV_PDEVICE *physDev, LPSTR lpData, WORD cch)
Alexandre Julliard's avatar
Alexandre Julliard committed
194
{
195 196 197 198 199
    if(physDev->job.quiet) {
        TRACE("ignoring output\n");
	return 0;
    }

200
    if(physDev->job.OutOfPage) { /* Will get here after NEWFRAME Escape */
201
        if( !PSDRV_StartPage(physDev) )
202
	    return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
203
    }
204
    return WriteSpool16( physDev->job.hJob, lpData, cch );
Alexandre Julliard's avatar
Alexandre Julliard committed
205 206 207
}


208
INT PSDRV_WriteFeature(HANDLE16 hJob, char *feature, char *value,
Alexandre Julliard's avatar
Alexandre Julliard committed
209 210 211
			 char *invocation)
{

212 213
    char *buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psbeginfeature) +
				   strlen(feature) + strlen(value));
Alexandre Julliard's avatar
Alexandre Julliard committed
214 215


Alexandre Julliard's avatar
Alexandre Julliard committed
216
    sprintf(buf, psbeginfeature, feature, value);
217
    WriteSpool16( hJob, buf, strlen(buf) );
Alexandre Julliard's avatar
Alexandre Julliard committed
218

219
    WriteSpool16( hJob, invocation, strlen(invocation) );
Alexandre Julliard's avatar
Alexandre Julliard committed
220

221
    WriteSpool16( hJob, psendfeature, strlen(psendfeature) );
222

Alexandre Julliard's avatar
Alexandre Julliard committed
223 224 225 226 227 228
    HeapFree( PSDRV_Heap, 0, buf );
    return 1;
}



229
INT PSDRV_WriteHeader( PSDRV_PDEVICE *physDev, LPCSTR title )
Alexandre Julliard's avatar
Alexandre Julliard committed
230
{
231
    char *buf, *orient;
Alexandre Julliard's avatar
Alexandre Julliard committed
232 233
    INPUTSLOT *slot;
    PAGESIZE *page;
234
    int llx, lly, urx, ury;
Alexandre Julliard's avatar
Alexandre Julliard committed
235

236
    TRACE("'%s'\n", title);
Alexandre Julliard's avatar
Alexandre Julliard committed
237

238 239
    buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psheader) +
			     strlen(title) + 30 );
Alexandre Julliard's avatar
Alexandre Julliard committed
240
    if(!buf) {
241
        WARN("HeapAlloc failed\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
242 243
        return 0;
    }
244

245 246
    /* BBox co-ords are in default user co-ord system so urx < ury even in
       landscape mode */
247 248 249 250
    llx = physDev->ImageableArea.left * 72.0 / physDev->logPixelsX;
    lly = physDev->ImageableArea.bottom * 72.0 / physDev->logPixelsY;
    urx = physDev->ImageableArea.right * 72.0 / physDev->logPixelsX;
    ury = physDev->ImageableArea.top * 72.0 / physDev->logPixelsY;
Alexandre Julliard's avatar
Alexandre Julliard committed
251

252
    if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) {
Alexandre Julliard's avatar
Alexandre Julliard committed
253 254 255 256 257 258 259
	orient = "Landscape";
    } else {
	orient = "Portrait";
    }

    /* FIXME should do something better with BBox */

260
    sprintf(buf, psheader, title, llx, lly, urx, ury, orient);
Alexandre Julliard's avatar
Alexandre Julliard committed
261

262
    if( WriteSpool16( physDev->job.hJob, buf, strlen(buf) ) !=
Alexandre Julliard's avatar
Alexandre Julliard committed
263
	                                             strlen(buf) ) {
264
        WARN("WriteSpool error\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
265
	HeapFree( PSDRV_Heap, 0, buf );
Alexandre Julliard's avatar
Alexandre Julliard committed
266 267
	return 0;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
268 269
    HeapFree( PSDRV_Heap, 0, buf );

270 271 272
    WriteSpool16( physDev->job.hJob, psbeginprolog, strlen(psbeginprolog) );
    WriteSpool16( physDev->job.hJob, psprolog, strlen(psprolog) );
    WriteSpool16( physDev->job.hJob, psendprolog, strlen(psendprolog) );
Alexandre Julliard's avatar
Alexandre Julliard committed
273

274
    WriteSpool16( physDev->job.hJob, psbeginsetup, strlen(psbeginsetup) );
Alexandre Julliard's avatar
Alexandre Julliard committed
275 276 277 278 279 280 281 282 283 284 285 286

    for(slot = physDev->pi->ppd->InputSlots; slot; slot = slot->next) {
        if(slot->WinBin == physDev->Devmode->dmPublic.dmDefaultSource) {
	    if(slot->InvocationString) {
	        PSDRV_WriteFeature(physDev->job.hJob, "*InputSlot", slot->Name,
			     slot->InvocationString);
		break;
	    }
	}
    }

    for(page = physDev->pi->ppd->PageSizes; page; page = page->next) {
287
        if(page->WinPage == physDev->Devmode->dmPublic.u1.s1.dmPaperSize) {
Alexandre Julliard's avatar
Alexandre Julliard committed
288 289 290 291 292 293 294 295
	    if(page->InvocationString) {
	        PSDRV_WriteFeature(physDev->job.hJob, "*PageSize", page->Name,
			     page->InvocationString);
		break;
	    }
	}
    }

296
    WriteSpool16( physDev->job.hJob, psendsetup, strlen(psendsetup) );
Alexandre Julliard's avatar
Alexandre Julliard committed
297 298


Alexandre Julliard's avatar
Alexandre Julliard committed
299 300 301 302
    return 1;
}


303
INT PSDRV_WriteFooter( PSDRV_PDEVICE *physDev )
Alexandre Julliard's avatar
Alexandre Julliard committed
304 305 306
{
    char *buf;

Alexandre Julliard's avatar
Alexandre Julliard committed
307
    buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psfooter) + 100 );
Alexandre Julliard's avatar
Alexandre Julliard committed
308
    if(!buf) {
309
        WARN("HeapAlloc failed\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
310 311 312
        return 0;
    }

Alexandre Julliard's avatar
Alexandre Julliard committed
313
    sprintf(buf, psfooter, physDev->job.PageNo);
Alexandre Julliard's avatar
Alexandre Julliard committed
314

315
    if( WriteSpool16( physDev->job.hJob, buf, strlen(buf) ) !=
Alexandre Julliard's avatar
Alexandre Julliard committed
316
	                                             strlen(buf) ) {
317
        WARN("WriteSpool error\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
318
	HeapFree( PSDRV_Heap, 0, buf );
Alexandre Julliard's avatar
Alexandre Julliard committed
319 320
	return 0;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
321
    HeapFree( PSDRV_Heap, 0, buf );
Alexandre Julliard's avatar
Alexandre Julliard committed
322 323 324 325 326
    return 1;
}



327
INT PSDRV_WriteEndPage( PSDRV_PDEVICE *physDev )
Alexandre Julliard's avatar
Alexandre Julliard committed
328
{
329
    if( WriteSpool16( physDev->job.hJob, psendpage, sizeof(psendpage)-1 ) !=
Alexandre Julliard's avatar
Alexandre Julliard committed
330
	                                             sizeof(psendpage)-1 ) {
331
        WARN("WriteSpool error\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
332 333 334 335 336 337 338 339
	return 0;
    }
    return 1;
}




340
INT PSDRV_WriteNewPage( PSDRV_PDEVICE *physDev )
Alexandre Julliard's avatar
Alexandre Julliard committed
341 342 343
{
    char *buf;
    char name[100];
Alexandre Julliard's avatar
Alexandre Julliard committed
344 345 346
    signed int xtrans, ytrans, rotation;

    sprintf(name, "%d", physDev->job.PageNo);
Alexandre Julliard's avatar
Alexandre Julliard committed
347

Alexandre Julliard's avatar
Alexandre Julliard committed
348
    buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psnewpage) + 200 );
Alexandre Julliard's avatar
Alexandre Julliard committed
349
    if(!buf) {
350
        WARN("HeapAlloc failed\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
351 352 353
        return 0;
    }

354
    if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) {
Alexandre Julliard's avatar
Alexandre Julliard committed
355
        if(physDev->pi->ppd->LandscapeOrientation == -90) {
356 357
	    xtrans = physDev->ImageableArea.right;
	    ytrans = physDev->ImageableArea.top;
Alexandre Julliard's avatar
Alexandre Julliard committed
358 359
	    rotation = 90;
	} else {
360 361
	    xtrans = physDev->ImageableArea.left;
	    ytrans = physDev->ImageableArea.bottom;
Alexandre Julliard's avatar
Alexandre Julliard committed
362 363 364
	    rotation = -90;
	}
    } else {
365 366
        xtrans = physDev->ImageableArea.left;
	ytrans = physDev->ImageableArea.top;
Alexandre Julliard's avatar
Alexandre Julliard committed
367 368 369 370
	rotation = 0;
    }

    sprintf(buf, psnewpage, name, physDev->job.PageNo,
371
	    physDev->logPixelsX, physDev->logPixelsY,
Alexandre Julliard's avatar
Alexandre Julliard committed
372 373
	    xtrans, ytrans, rotation);

374
    if( WriteSpool16( physDev->job.hJob, buf, strlen(buf) ) !=
Alexandre Julliard's avatar
Alexandre Julliard committed
375
	                                             strlen(buf) ) {
376
        WARN("WriteSpool error\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
377
	HeapFree( PSDRV_Heap, 0, buf );
Alexandre Julliard's avatar
Alexandre Julliard committed
378 379
	return 0;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
380
    HeapFree( PSDRV_Heap, 0, buf );
Alexandre Julliard's avatar
Alexandre Julliard committed
381 382 383 384
    return 1;
}


385
BOOL PSDRV_WriteMoveTo(PSDRV_PDEVICE *physDev, INT x, INT y)
Alexandre Julliard's avatar
Alexandre Julliard committed
386 387 388
{
    char buf[100];

Alexandre Julliard's avatar
Alexandre Julliard committed
389
    sprintf(buf, psmoveto, x, y);
390
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
Alexandre Julliard's avatar
Alexandre Julliard committed
391 392
}

393
BOOL PSDRV_WriteLineTo(PSDRV_PDEVICE *physDev, INT x, INT y)
Alexandre Julliard's avatar
Alexandre Julliard committed
394 395 396
{
    char buf[100];

Alexandre Julliard's avatar
Alexandre Julliard committed
397
    sprintf(buf, pslineto, x, y);
398
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
Alexandre Julliard's avatar
Alexandre Julliard committed
399 400 401
}


402
BOOL PSDRV_WriteStroke(PSDRV_PDEVICE *physDev)
Alexandre Julliard's avatar
Alexandre Julliard committed
403
{
404
    return PSDRV_WriteSpool(physDev, psstroke, sizeof(psstroke)-1);
Alexandre Julliard's avatar
Alexandre Julliard committed
405 406 407 408
}



409
BOOL PSDRV_WriteRectangle(PSDRV_PDEVICE *physDev, INT x, INT y, INT width,
410
			INT height)
Alexandre Julliard's avatar
Alexandre Julliard committed
411 412 413
{
    char buf[100];

Alexandre Julliard's avatar
Alexandre Julliard committed
414
    sprintf(buf, psrectangle, x, y, width, height, -width);
415
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
Alexandre Julliard's avatar
Alexandre Julliard committed
416 417
}

418
BOOL PSDRV_WriteRRectangle(PSDRV_PDEVICE *physDev, INT x, INT y, INT width,
419 420 421 422 423
      INT height)
{
    char buf[100];

    sprintf(buf, psrrectangle, x, y, width, height, -width);
424
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
425 426
}

427
BOOL PSDRV_WriteArc(PSDRV_PDEVICE *physDev, INT x, INT y, INT w, INT h, double ang1,
428
		      double ang2)
Alexandre Julliard's avatar
Alexandre Julliard committed
429 430 431
{
    char buf[256];

432 433 434
    /* Make angles -ve and swap order because we're working with an upside
       down y-axis */
    sprintf(buf, psarc, x, y, w, h, -ang2, -ang1);
435
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
Alexandre Julliard's avatar
Alexandre Julliard committed
436 437
}

438 439

BOOL PSDRV_WriteSetFont(PSDRV_PDEVICE *physDev, const char *name, INT size, INT escapement)
Alexandre Julliard's avatar
Alexandre Julliard committed
440
{
441
    char *buf;
Alexandre Julliard's avatar
Alexandre Julliard committed
442

443 444
    buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(pssetfont) +
			     strlen(name) + 40);
Alexandre Julliard's avatar
Alexandre Julliard committed
445 446

    if(!buf) {
447
        WARN("HeapAlloc failed\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
448 449
        return FALSE;
    }
450

451
    sprintf(buf, pssetfont, name, size, -size, -escapement);
Alexandre Julliard's avatar
Alexandre Julliard committed
452

453
    PSDRV_WriteSpool(physDev, buf, strlen(buf));
Alexandre Julliard's avatar
Alexandre Julliard committed
454
    HeapFree(PSDRV_Heap, 0, buf);
Alexandre Julliard's avatar
Alexandre Julliard committed
455
    return TRUE;
456
}
Alexandre Julliard's avatar
Alexandre Julliard committed
457

458
BOOL PSDRV_WriteSetColor(PSDRV_PDEVICE *physDev, PSCOLOR *color)
Alexandre Julliard's avatar
Alexandre Julliard committed
459 460 461 462 463 464 465 466
{
    char buf[256];

    PSDRV_CopyColor(&physDev->inkColor, color);
    switch(color->type) {
    case PSCOLOR_RGB:
        sprintf(buf, pssetrgbcolor, color->value.rgb.r, color->value.rgb.g,
		color->value.rgb.b);
467
	return PSDRV_WriteSpool(physDev, buf, strlen(buf));
Alexandre Julliard's avatar
Alexandre Julliard committed
468

469
    case PSCOLOR_GRAY:
Alexandre Julliard's avatar
Alexandre Julliard committed
470
        sprintf(buf, pssetgray, color->value.gray.i);
471
	return PSDRV_WriteSpool(physDev, buf, strlen(buf));
472

Alexandre Julliard's avatar
Alexandre Julliard committed
473
    default:
474
        ERR("Unkonwn colour type %d\n", color->type);
Alexandre Julliard's avatar
Alexandre Julliard committed
475 476 477 478 479 480
	break;
    }

    return FALSE;
}

481
BOOL PSDRV_WriteSetPen(PSDRV_PDEVICE *physDev)
Alexandre Julliard's avatar
Alexandre Julliard committed
482 483 484 485
{
    char buf[256];

    sprintf(buf, pssetlinewidth, physDev->pen.width);
486
    PSDRV_WriteSpool(physDev, buf, strlen(buf));
Alexandre Julliard's avatar
Alexandre Julliard committed
487 488 489

    if(physDev->pen.dash) {
        sprintf(buf, pssetdash, physDev->pen.dash, 0);
490
	PSDRV_WriteSpool(physDev, buf, strlen(buf));
Alexandre Julliard's avatar
Alexandre Julliard committed
491 492 493 494 495
    }

    return TRUE;
}

496
BOOL PSDRV_WriteGlyphShow(PSDRV_PDEVICE *physDev, LPCSTR g_name)
497 498
{
    char    buf[128];
499
    int     l;
500

501
    l = snprintf(buf, sizeof(buf), psglyphshow, g_name);
502

503 504 505
    if (l < sizeof(psglyphshow) - 2 || l > sizeof(buf) - 1) {
	WARN("Unusable glyph name '%s' - ignoring\n", g_name);
	return FALSE;
506
    }
507

508
    PSDRV_WriteSpool(physDev, buf, l);
509 510
    return TRUE;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
511

512
BOOL PSDRV_WriteFill(PSDRV_PDEVICE *physDev)
Alexandre Julliard's avatar
Alexandre Julliard committed
513
{
514
    return PSDRV_WriteSpool(physDev, psfill, sizeof(psfill)-1);
Alexandre Julliard's avatar
Alexandre Julliard committed
515 516
}

517
BOOL PSDRV_WriteEOFill(PSDRV_PDEVICE *physDev)
518
{
519
    return PSDRV_WriteSpool(physDev, pseofill, sizeof(pseofill)-1);
520 521
}

522
BOOL PSDRV_WriteGSave(PSDRV_PDEVICE *physDev)
Alexandre Julliard's avatar
Alexandre Julliard committed
523
{
524
    return PSDRV_WriteSpool(physDev, psgsave, sizeof(psgsave)-1);
Alexandre Julliard's avatar
Alexandre Julliard committed
525 526
}

527
BOOL PSDRV_WriteGRestore(PSDRV_PDEVICE *physDev)
Alexandre Julliard's avatar
Alexandre Julliard committed
528
{
529
    return PSDRV_WriteSpool(physDev, psgrestore, sizeof(psgrestore)-1);
Alexandre Julliard's avatar
Alexandre Julliard committed
530 531
}

532
BOOL PSDRV_WriteNewPath(PSDRV_PDEVICE *physDev)
533
{
534
    return PSDRV_WriteSpool(physDev, psnewpath, sizeof(psnewpath)-1);
535 536
}

537
BOOL PSDRV_WriteClosePath(PSDRV_PDEVICE *physDev)
538
{
539
    return PSDRV_WriteSpool(physDev, psclosepath, sizeof(psclosepath)-1);
540
}
Alexandre Julliard's avatar
Alexandre Julliard committed
541

542
BOOL PSDRV_WriteClip(PSDRV_PDEVICE *physDev)
543
{
544
    return PSDRV_WriteSpool(physDev, psclip, sizeof(psclip)-1);
545 546
}

547
BOOL PSDRV_WriteEOClip(PSDRV_PDEVICE *physDev)
548
{
549
    return PSDRV_WriteSpool(physDev, pseoclip, sizeof(pseoclip)-1);
550 551
}

552
BOOL PSDRV_WriteInitClip(PSDRV_PDEVICE *physDev)
553
{
554
    return PSDRV_WriteSpool(physDev, psinitclip, sizeof(psinitclip)-1);
555 556
}

557
BOOL PSDRV_WriteHatch(PSDRV_PDEVICE *physDev)
558
{
559
    return PSDRV_WriteSpool(physDev, pshatch, sizeof(pshatch)-1);
560 561
}

562
BOOL PSDRV_WriteRotate(PSDRV_PDEVICE *physDev, float ang)
563 564
{
    char buf[256];
Alexandre Julliard's avatar
Alexandre Julliard committed
565

566
    sprintf(buf, psrotate, ang);
567
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
568
}
Alexandre Julliard's avatar
Alexandre Julliard committed
569

570
BOOL PSDRV_WriteIndexColorSpaceBegin(PSDRV_PDEVICE *physDev, int size)
571 572 573
{
    char buf[256];
    sprintf(buf, "[/Indexed /DeviceRGB %d\n<\n", size);
574
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
575 576
}

577
BOOL PSDRV_WriteIndexColorSpaceEnd(PSDRV_PDEVICE *physDev)
578 579
{
    char buf[] = ">\n] setcolorspace\n";
580
    return PSDRV_WriteSpool(physDev, buf, sizeof(buf) - 1);
581
}
582

583
BOOL PSDRV_WriteRGB(PSDRV_PDEVICE *physDev, COLORREF *map, int number)
584 585 586 587 588 589
{
    char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1), *ptr;
    int i;

    ptr = buf;
    for(i = 0; i < number; i++) {
590
        sprintf(ptr, "%02x%02x%02x%c", (int)GetRValue(map[i]),
591 592 593 594
		(int)GetGValue(map[i]), (int)GetBValue(map[i]),
		((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' ');
	ptr += 7;
    }
595
    PSDRV_WriteSpool(physDev, buf, number * 7);
596 597 598 599 600
    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}


601
BOOL PSDRV_WriteImageDict(PSDRV_PDEVICE *physDev, WORD depth, INT xDst, INT yDst,
602
			  INT widthDst, INT heightDst, INT widthSrc,
603
			  INT heightSrc, char *bits)
604 605 606 607 608 609 610 611 612
{
    char start[] = "%d %d translate\n%d %d scale\n<<\n"
      " /ImageType 1\n /Width %d\n /Height %d\n /BitsPerComponent %d\n"
      " /ImageMatrix [%d 0 0 %d 0 %d]\n";

    char decode1[] = " /Decode [0 %d]\n";
    char decode3[] = " /Decode [0 1 0 1 0 1]\n";

    char end[] = " /DataSource currentfile /ASCIIHexDecode filter\n>> image\n";
613
    char endbits[] = " /DataSource <%s>\n>> image\n";
614 615 616 617 618

    char *buf = HeapAlloc(PSDRV_Heap, 0, 1000);

    sprintf(buf, start, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc,
	    (depth < 8) ? depth : 8, widthSrc, -heightSrc, heightSrc);
Alexandre Julliard's avatar
Alexandre Julliard committed
619

620
    PSDRV_WriteSpool(physDev, buf, strlen(buf));
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639

    switch(depth) {
    case 8:
        sprintf(buf, decode1, 255);
	break;

    case 4:
        sprintf(buf, decode1, 15);
	break;

    case 1:
        sprintf(buf, decode1, 1);
	break;

    default:
        strcpy(buf, decode3);
	break;
    }

640
    PSDRV_WriteSpool(physDev, buf, strlen(buf));
641

642
    if(!bits)
643
        PSDRV_WriteSpool(physDev, end, sizeof(end) - 1);
644 645
    else {
        sprintf(buf, endbits, bits);
646
        PSDRV_WriteSpool(physDev, buf, strlen(buf));
647
    }
648 649 650 651 652

    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}

653

654
BOOL PSDRV_WriteBytes(PSDRV_PDEVICE *physDev, const BYTE *bytes, int number)
655 656 657 658
{
    char *buf = HeapAlloc(PSDRV_Heap, 0, number * 3 + 1);
    char *ptr;
    int i;
659

660
    ptr = buf;
661

662 663 664 665 666
    for(i = 0; i < number; i++) {
        sprintf(ptr, "%02x%c", bytes[i],
		((i & 0xf) == 0xf) || (i == number - 1) ? '\n' : ' ');
	ptr += 3;
    }
667
    PSDRV_WriteSpool(physDev, buf, number * 3);
668 669 670 671 672

    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}

673
BOOL PSDRV_WriteDIBits16(PSDRV_PDEVICE *physDev, const WORD *words, int number)
674 675 676 677
{
    char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1);
    char *ptr;
    int i;
678

679
    ptr = buf;
680

681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
    for(i = 0; i < number; i++) {
        int r, g, b;

	/* We want 0x0 -- 0x1f to map to 0x0 -- 0xff */

	r = words[i] >> 10 & 0x1f;
	r = r << 3 | r >> 2;
	g = words[i] >> 5 & 0x1f;
	g = g << 3 | g >> 2;
	b = words[i] & 0x1f;
	b = b << 3 | b >> 2;
        sprintf(ptr, "%02x%02x%02x%c", r, g, b,
		((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' ');
	ptr += 7;
    }
696
    PSDRV_WriteSpool(physDev, buf, number * 7);
697 698 699 700 701

    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}

702
BOOL PSDRV_WriteDIBits24(PSDRV_PDEVICE *physDev, const BYTE *bits, int number)
703 704 705 706
{
    char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1);
    char *ptr;
    int i;
707

708
    ptr = buf;
709

710 711 712 713 714 715
    for(i = 0; i < number; i++) {
        sprintf(ptr, "%02x%02x%02x%c", bits[i * 3 + 2], bits[i * 3 + 1],
		bits[i * 3],
		((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' ');
	ptr += 7;
    }
716
    PSDRV_WriteSpool(physDev, buf, number * 7);
717 718 719 720 721

    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}

722
BOOL PSDRV_WriteDIBits32(PSDRV_PDEVICE *physDev, const BYTE *bits, int number)
723 724 725 726
{
    char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1);
    char *ptr;
    int i;
727

728
    ptr = buf;
729

730 731 732 733 734 735
    for(i = 0; i < number; i++) {
        sprintf(ptr, "%02x%02x%02x%c", bits[i * 4 + 2], bits[i * 4 + 1],
		bits[i * 4],
		((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' ');
	ptr += 7;
    }
736
    PSDRV_WriteSpool(physDev, buf, number * 7);
737 738 739 740

    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}
741

742
BOOL PSDRV_WriteArrayGet(PSDRV_PDEVICE *physDev, CHAR *pszArrayName, INT nIndex)
743 744 745 746
{
    char buf[100];

    sprintf(buf, psarrayget, pszArrayName, nIndex);
747
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
748 749
}

750
BOOL PSDRV_WriteArrayPut(PSDRV_PDEVICE *physDev, CHAR *pszArrayName, INT nIndex, LONG lObject)
751 752 753 754
{
    char buf[100];

    sprintf(buf, psarrayput, pszArrayName, nIndex, lObject);
755
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
756 757
}

758
BOOL PSDRV_WriteArrayDef(PSDRV_PDEVICE *physDev, CHAR *pszArrayName, INT nSize)
759 760 761 762
{
    char buf[100];

    sprintf(buf, psarraydef, pszArrayName, nSize);
763
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
764 765
}

766
BOOL PSDRV_WriteRectClip(PSDRV_PDEVICE *physDev, INT x, INT y, INT w, INT h)
767 768 769
{
    char buf[100];

770
    sprintf(buf, psrectclip, x, y, w, h);
771
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
772 773
}

774
BOOL PSDRV_WriteRectClip2(PSDRV_PDEVICE *physDev, CHAR *pszArrayName)
775 776 777 778
{
    char buf[100];

    sprintf(buf, psrectclip2, pszArrayName);
779
    return PSDRV_WriteSpool(physDev, buf, strlen(buf));
780
}
781

782
BOOL PSDRV_WritePatternDict(PSDRV_PDEVICE *physDev, BITMAP *bm, BYTE *bits)
783 784 785 786 787 788 789 790 791 792 793 794 795 796
{
    char start[] = "<<\n /PaintType 1\n /PatternType 1\n /TilingType 1\n "
      "/BBox [0 0 %d %d]\n /XStep %d\n /YStep %d\n /PaintProc {\n  begin\n";

    char end[] = "  end\n }\n>>\n matrix makepattern setpattern\n";
    char *buf, *ptr;
    INT w, h, x, y;
    COLORREF map[2];

    w = bm->bmWidth & ~0x7;
    h = bm->bmHeight & ~0x7;

    buf = HeapAlloc(PSDRV_Heap, 0, sizeof(start) + 100);
    sprintf(buf, start, w, h, w, h);
797 798 799 800 801 802
    PSDRV_WriteSpool(physDev,  buf, strlen(buf));
    PSDRV_WriteIndexColorSpaceBegin(physDev, 1);
    map[0] = GetTextColor( physDev->hdc );
    map[1] = GetBkColor( physDev->hdc );
    PSDRV_WriteRGB(physDev, map, 2);
    PSDRV_WriteIndexColorSpaceEnd(physDev);
803 804 805 806 807 808 809
    ptr = buf;
    for(y = h-1; y >= 0; y--) {
        for(x = 0; x < w/8; x++) {
	    sprintf(ptr, "%02x", *(bits + x/8 + y * bm->bmWidthBytes));
	    ptr += 2;
	}
    }
810 811
    PSDRV_WriteImageDict(physDev, 1, 0, 0, 8, 8, 8, 8, buf);
    PSDRV_WriteSpool(physDev, end, sizeof(end) - 1);
812 813 814
    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862

BOOL PSDRV_WriteDIBPatternDict(PSDRV_PDEVICE *physDev, BITMAPINFO *bmi, UINT usage)
{
    char start[] = "<<\n /PaintType 1\n /PatternType 1\n /TilingType 1\n "
      "/BBox [0 0 %d %d]\n /XStep %d\n /YStep %d\n /PaintProc {\n  begin\n";

    char end[] = "  end\n }\n>>\n matrix makepattern setpattern\n";
    char *buf, *ptr;
    BYTE *bits;
    INT w, h, x, y, colours;
    COLORREF map[2];

    if(bmi->bmiHeader.biBitCount != 1) {
        FIXME("dib depth %d not supported\n", bmi->bmiHeader.biBitCount);
	return FALSE;
    }

    bits = (char*)bmi + bmi->bmiHeader.biSize;
    colours = bmi->bmiHeader.biClrUsed;
    if(!colours && bmi->bmiHeader.biBitCount <= 8)
        colours = 1 << bmi->bmiHeader.biBitCount;
    bits += colours * ((usage == DIB_RGB_COLORS) ?
		       sizeof(RGBQUAD) : sizeof(WORD));

    w = bmi->bmiHeader.biWidth & ~0x7;
    h = bmi->bmiHeader.biHeight & ~0x7;

    buf = HeapAlloc(PSDRV_Heap, 0, sizeof(start) + 100);
    sprintf(buf, start, w, h, w, h);
    PSDRV_WriteSpool(physDev,  buf, strlen(buf));
    PSDRV_WriteIndexColorSpaceBegin(physDev, 1);
    map[0] = physDev->dc->textColor;
    map[1] = physDev->dc->backgroundColor;
    PSDRV_WriteRGB(physDev, map, 2);
    PSDRV_WriteIndexColorSpaceEnd(physDev);
    ptr = buf;
    for(y = h-1; y >= 0; y--) {
        for(x = 0; x < w/8; x++) {
	    sprintf(ptr, "%02x", *(bits + x/8 + y *
				   (bmi->bmiHeader.biWidth + 31) / 32 * 4));
	    ptr += 2;
	}
    }
    PSDRV_WriteImageDict(physDev, 1, 0, 0, 8, 8, 8, 8, buf);
    PSDRV_WriteSpool(physDev, end, sizeof(end) - 1);
    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}