Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/gs/src/gdevmswn.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1989, 1995, 1996, 1998, 1999, 2000, 2001 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gdevmswn.c,v 1.12 2004/09/20 22:14:59 dan Exp $ */
18
/*
19
 * Microsoft Windows 3.n driver for Ghostscript.
20
 *
21
 * Original version by Russell Lang and Maurice Castro with help from
22
 * Programming Windows, 2nd Ed., Charles Petzold, Microsoft Press;
23
 * created from gdevbgi.c and gnuplot/term/win.trm 5th June 1992.
24
 * Extensively modified by L. Peter Deutsch, Aladdin Enterprises.
25
 */
26
#include "gdevmswn.h"
27
#include "gp.h"
28
#include "gpcheck.h"
29
#include "gsparam.h"
30
#include "gdevpccm.h"
31
#include "gsdll.h"
32
 
33
/* Forward references */
34
private int win_set_bits_per_pixel(gx_device_win *, int);
35
 
36
#define TIMER_ID 1
37
 
38
/* Open the win driver */
39
int
40
win_open(gx_device * dev)
41
{
42
    HDC hdc;
43
    int code;
44
 
45
    if (dev->width == INITIAL_WIDTH)
46
	dev->width = (int)(8.5 * dev->x_pixels_per_inch);
47
    if (dev->height == INITIAL_HEIGHT)
48
	dev->height = (int)(11.0 * dev->y_pixels_per_inch);
49
 
50
    if (wdev->BitsPerPixel == 0) {
51
	int depth;
52
 
53
	/* Set parameters that were unknown before opening device */
54
	/* Find out if the device supports color */
55
	/* We recognize 1, 4, 8, 16, 24 bit/pixel devices */
56
	hdc = GetDC(NULL);	/* get hdc for desktop */
57
	depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
58
	if (depth > 16) {
59
	    wdev->BitsPerPixel = 24;
60
	} else if (depth > 8) {
61
	    wdev->BitsPerPixel = 16;
62
	} else if (depth >= 8) {
63
	    wdev->BitsPerPixel = 8;
64
	} else if (depth >= 4) {
65
	    wdev->BitsPerPixel = 4;
66
	} else {
67
	    wdev->BitsPerPixel = 1;
68
	}
69
	ReleaseDC(NULL, hdc);
70
	wdev->mapped_color_flags = 0;
71
    }
72
    if ((code = win_set_bits_per_pixel(wdev, wdev->BitsPerPixel)) < 0)
73
	return code;
74
 
75
    if (wdev->nColors > 0) {
76
	/* create palette for display */
77
	if ((wdev->limgpalette = win_makepalette(wdev))
78
	    == (LPLOGPALETTE) NULL)
79
	    return win_nomemory();
80
	wdev->himgpalette = CreatePalette(wdev->limgpalette);
81
    }
82
    return 0;
83
}
84
 
85
/* Make the output appear on the screen. */
86
int
87
win_sync_output(gx_device * dev)
88
{
89
    if (pgsdll_callback)
90
	(*pgsdll_callback) (GSDLL_SYNC, (unsigned char *)wdev, 0);
91
    return (0);
92
}
93
 
94
/* Make the window visible, and display the output. */
95
int
96
win_output_page(gx_device * dev, int copies, int flush)
97
{
98
    if (pgsdll_callback)
99
	(*pgsdll_callback) (GSDLL_PAGE, (unsigned char *)wdev, 0);
100
    return gx_finish_output_page(dev, copies, flush);;
101
}
102
 
103
/* Close the win driver */
104
int
105
win_close(gx_device * dev)
106
{
107
    /* Free resources */
108
    if (wdev->nColors > 0) {
109
	gs_free(dev->memory, 
110
		wdev->mapped_color_flags, 4096, 1, "win_set_bits_per_pixel");
111
	DeleteObject(wdev->himgpalette);
112
	gs_free(dev->memory, 
113
		(char *)(wdev->limgpalette), 1, sizeof(LOGPALETTE) +
114
		(1 << (wdev->color_info.depth)) * sizeof(PALETTEENTRY),
115
		"win_close");
116
    }
117
    return (0);
118
}
119
 
120
/* Map a r-g-b color to the colors available under Windows */
121
gx_color_index
122
win_map_rgb_color(gx_device * dev, const gx_color_value cv[])
123
{
124
    gx_color_value r = cv[0];
125
    gx_color_value g = cv[1];
126
    gx_color_value b = cv[2];
127
    switch (wdev->BitsPerPixel) {
128
	case 24:
129
	    return (((unsigned long)b >> (gx_color_value_bits - 8)) << 16) +
130
		(((unsigned long)g >> (gx_color_value_bits - 8)) << 8) +
131
		(((unsigned long)r >> (gx_color_value_bits - 8)));
132
	case 16:{
133
		gx_color_index color = ((r >> (gx_color_value_bits - 5)) << 11) +
134
				       ((g >> (gx_color_value_bits - 6)) << 5) +
135
				       (b >> (gx_color_value_bits - 5));
136
#if arch_is_big_endian
137
		ushort color16 = (ushort)color;
138
#else
139
		ushort color16 = (ushort)((color << 8) | (color >> 8));
140
#endif
141
		return color16;
142
	    }
143
	case 15:{
144
		gx_color_index color = ((r >> (gx_color_value_bits - 5)) << 10) +
145
				       ((g >> (gx_color_value_bits - 5)) << 5) +
146
				       (b >> (gx_color_value_bits - 5));
147
#if arch_is_big_endian
148
		ushort color15 = (ushort)color;
149
#else
150
		ushort color15 = (ushort)((color << 8) | (color >> 8));
151
#endif
152
		return color15;
153
	    }
154
	case 8:{
155
		int i;
156
		LPLOGPALETTE lpal = wdev->limgpalette;
157
		PALETTEENTRY *pep;
158
		byte cr, cg, cb;
159
		int mc_index;
160
		byte mc_mask;
161
 
162
		/* Check for a color in the palette of 64. */
163
		{
164
		    static const byte pal64[32] =
165
		    {
166
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169
			1
170
		    };
171
 
172
		    if (pal64[r >> (gx_color_value_bits - 5)] &&
173
			pal64[g >> (gx_color_value_bits - 5)] &&
174
			pal64[b >> (gx_color_value_bits - 5)]
175
			)
176
			return (gx_color_index) (
177
				   ((r >> (gx_color_value_bits - 2)) << 4) +
178
				   ((g >> (gx_color_value_bits - 2)) << 2) +
179
					    (b >> (gx_color_value_bits - 2))
180
			    );
181
		}
182
 
183
		/* map colors to 0->255 in 32 steps */
184
		cr = win_color_value(r);
185
		cg = win_color_value(g);
186
		cb = win_color_value(b);
187
 
188
		/* Search in palette, skipping the first 64. */
189
		mc_index = ((cr >> 3) << 7) + ((cg >> 3) << 2) + (cb >> 6);
190
		mc_mask = 0x80 >> ((cb >> 3) & 7);
191
		if (wdev->mapped_color_flags[mc_index] & mc_mask)
192
		    for (i = wdev->nColors, pep = &lpal->palPalEntry[i];
193
			 --pep, --i >= 64;
194
			) {
195
			if (cr == pep->peRed &&
196
			    cg == pep->peGreen &&
197
			    cb == pep->peBlue
198
			    )
199
			    return ((gx_color_index) i);	/* found it */
200
		    }
201
		/* next try adding it to palette */
202
		i = wdev->nColors;
203
		if (i < 220) {	/* allow 36 for windows and other apps */
204
		    LPLOGPALETTE lipal = wdev->limgpalette;
205
 
206
		    wdev->nColors = i + 1;
207
 
208
		    DeleteObject(wdev->himgpalette);
209
		    lipal->palPalEntry[i].peFlags = 0;
210
		    lipal->palPalEntry[i].peRed = cr;
211
		    lipal->palPalEntry[i].peGreen = cg;
212
		    lipal->palPalEntry[i].peBlue = cb;
213
		    lipal->palNumEntries = wdev->nColors;
214
		    wdev->himgpalette = CreatePalette(lipal);
215
 
216
		    wdev->mapped_color_flags[mc_index] |= mc_mask;
217
		    return ((gx_color_index) i);	/* return new palette index */
218
		}
219
		return (gx_no_color_index);	/* not found - dither instead */
220
	    }
221
	case 4:
222
	    return pc_4bit_map_rgb_color(dev, cv);
223
    }
224
    return (gx_default_map_rgb_color(dev, cv));
225
}
226
 
227
/* Map a color code to r-g-b. */
228
int
229
win_map_color_rgb(gx_device * dev, gx_color_index color,
230
		  gx_color_value prgb[3])
231
{
232
    gx_color_value one;
233
    ushort value;
234
 
235
    switch (wdev->BitsPerPixel) {
236
	case 24:
237
	    one = (gx_color_value) (gx_max_color_value / 255);
238
	    prgb[0] = ((color) & 255) * one;
239
	    prgb[1] = ((color >> 8) & 255) * one;
240
	    prgb[2] = ((color >> 16) & 255) * one;
241
	    break;
242
	case 16:
243
	    value = (color >> 11) & 0x1f;
244
	    prgb[0] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
245
	    value = (color >> 5) & 0x3f;
246
	    prgb[1] = ((value << 10) + (value << 4) + (value >> 2)) >> (16 - gx_color_value_bits);
247
	    value = (color) & 0x1f;
248
	    prgb[2] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
249
	    break;
250
	case 15:
251
	    value = (color >> 10) & 0x1f;
252
	    prgb[0] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
253
	    value = (color >> 5) & 0x1f;
254
	    prgb[1] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
255
	    value = (color) & 0x1f;
256
	    prgb[2] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
257
	    break;
258
	case 8:
259
	    if (!dev->is_open)
260
		return -1;
261
	    one = (gx_color_value) (gx_max_color_value / 255);
262
	    prgb[0] = wdev->limgpalette->palPalEntry[(int)color].peRed * one;
263
	    prgb[1] = wdev->limgpalette->palPalEntry[(int)color].peGreen * one;
264
	    prgb[2] = wdev->limgpalette->palPalEntry[(int)color].peBlue * one;
265
	    break;
266
	case 4:
267
	    pc_4bit_map_color_rgb(dev, color, prgb);
268
	    break;
269
	default:
270
	    prgb[0] = prgb[1] = prgb[2] =
271
		(int)color ? gx_max_color_value : 0;
272
    }
273
    return 0;
274
}
275
 
276
/* Get Win parameters */
277
int
278
win_get_params(gx_device * dev, gs_param_list * plist)
279
{
280
    int code = gx_default_get_params(dev, plist);
281
 
282
    return code;
283
}
284
 
285
/* Put parameters. */
286
/* Set window parameters -- size and resolution. */
287
/* We implement this ourselves so that we can do it without */
288
/* closing and opening the device. */
289
int
290
win_put_params(gx_device * dev, gs_param_list * plist)
291
{
292
    int ecode = 0, code;
293
    bool is_open = dev->is_open;
294
    int width = dev->width;
295
    int height = dev->height;
296
    int old_bpp = dev->color_info.depth;
297
    int bpp = old_bpp;
298
    byte *old_flags = wdev->mapped_color_flags;
299
 
300
    /* Handle extra parameters */
301
 
302
    switch (code = param_read_int(plist, "BitsPerPixel", &bpp)) {
303
	case 0:
304
	    if (dev->is_open && bpp != old_bpp)
305
		ecode = gs_error_rangecheck;
306
	    else {		/* Don't release existing mapped_color_flags. */
307
		if (bpp != 8)
308
		    wdev->mapped_color_flags = 0;
309
		code = win_set_bits_per_pixel(wdev, bpp);
310
		if (code < 0)
311
		    ecode = code;
312
		else
313
		    break;
314
	    }
315
	    goto bppe;
316
	default:
317
	    ecode = code;
318
	  bppe:param_signal_error(plist, "BitsPerPixel", ecode);
319
	case 1:
320
	    break;
321
    }
322
 
323
    if (ecode >= 0) {		/* Prevent gx_default_put_params from closing the device. */
324
	dev->is_open = false;
325
	ecode = gx_default_put_params(dev, plist);
326
	dev->is_open = is_open;
327
    }
328
    if (ecode < 0) {		/* If we allocated mapped_color_flags, release it. */
329
	if (wdev->mapped_color_flags != 0 && old_flags == 0)
330
	    gs_free(wdev->memory,
331
		    wdev->mapped_color_flags, 4096, 1,
332
		    "win_put_params");
333
	wdev->mapped_color_flags = old_flags;
334
	if (bpp != old_bpp)
335
	    win_set_bits_per_pixel(wdev, old_bpp);
336
	return ecode;
337
    }
338
    if (wdev->mapped_color_flags == 0 && old_flags != 0) {	/* Release old mapped_color_flags. */
339
	gs_free(dev->memory,
340
		old_flags, 4096, 1, "win_put_params");
341
    }
342
    /* Hand off the change to the implementation. */
343
    if (is_open && (bpp != old_bpp ||
344
		    dev->width != width || dev->height != height)
345
	) {
346
	int ccode;
347
 
348
	(*wdev->free_bitmap) (wdev);
349
	ccode = (*wdev->alloc_bitmap) (wdev, (gx_device *) wdev);
350
	if (ccode < 0) {	/* Bad news!  Some of the other device parameters */
351
	    /* may have changed.  We don't handle this. */
352
	    /* This is ****** WRONG ******. */
353
	    dev->width = width;
354
	    dev->height = height;
355
	    win_set_bits_per_pixel(wdev, old_bpp);
356
	    (*wdev->alloc_bitmap) (wdev, dev);
357
	    return ccode;
358
	}
359
    }
360
    return 0;
361
}
362
 
363
/* ------ Internal routines ------ */
364
 
365
#undef wdev
366
 
367
 
368
 
369
/* out of memory error message box */
370
int
371
win_nomemory(void)
372
{
373
    MessageBox((HWND) NULL, (LPSTR) "Not enough memory", (LPSTR) szAppName, MB_ICONSTOP);
374
    return gs_error_limitcheck;
375
}
376
 
377
 
378
LPLOGPALETTE
379
win_makepalette(gx_device_win * wdev)
380
{
381
    int i, val;
382
    LPLOGPALETTE logpalette;
383
 
384
    logpalette = (LPLOGPALETTE) gs_malloc(wdev->memory, 1, sizeof(LOGPALETTE) +
385
		     (1 << (wdev->color_info.depth)) * sizeof(PALETTEENTRY),
386
					  "win_makepalette");
387
    if (logpalette == (LPLOGPALETTE) NULL)
388
	return (0);
389
    logpalette->palVersion = 0x300;
390
    logpalette->palNumEntries = wdev->nColors;
391
    for (i = 0; i < wdev->nColors; i++) {
392
	logpalette->palPalEntry[i].peFlags = 0;
393
	switch (wdev->nColors) {
394
	    case 64:
395
		/* colors are rrggbb */
396
		logpalette->palPalEntry[i].peRed = ((i & 0x30) >> 4) * 85;
397
		logpalette->palPalEntry[i].peGreen = ((i & 0xC) >> 2) * 85;
398
		logpalette->palPalEntry[i].peBlue = (i & 3) * 85;
399
		break;
400
	    case 16:
401
		/* colors are irgb */
402
		val = (i & 8 ? 255 : 128);
403
		logpalette->palPalEntry[i].peRed = i & 4 ? val : 0;
404
		logpalette->palPalEntry[i].peGreen = i & 2 ? val : 0;
405
		logpalette->palPalEntry[i].peBlue = i & 1 ? val : 0;
406
		if (i == 8) {	/* light gray */
407
		    logpalette->palPalEntry[i].peRed =
408
			logpalette->palPalEntry[i].peGreen =
409
			logpalette->palPalEntry[i].peBlue = 192;
410
		}
411
		break;
412
	    case 2:
413
		logpalette->palPalEntry[i].peRed =
414
		    logpalette->palPalEntry[i].peGreen =
415
		    logpalette->palPalEntry[i].peBlue = (i ? 255 : 0);
416
		break;
417
	}
418
    }
419
    return (logpalette);
420
}
421
 
422
 
423
private int
424
win_set_bits_per_pixel(gx_device_win * wdev, int bpp)
425
{
426
    static const gx_device_color_info win_24bit_color = dci_color(24, 255, 255);
427
    static const gx_device_color_info win_16bit_color = dci_color(16, 255, 255);
428
    static const gx_device_color_info win_8bit_color = dci_color(8, 31, 4);
429
    static const gx_device_color_info win_ega_color = dci_pc_4bit;
430
    static const gx_device_color_info win_vga_color = dci_pc_4bit;
431
    static const gx_device_color_info win_mono_color = dci_black_and_white;
432
    /* remember old anti_alias info */
433
    gx_device_anti_alias_info anti_alias = wdev->color_info.anti_alias;
434
    HDC hdc;
435
 
436
    switch (bpp) {
437
	case 24:
438
	    wdev->color_info = win_24bit_color;
439
	    wdev->nColors = -1;
440
	    break;
441
	case 16:
442
	case 15:
443
	    wdev->color_info = win_16bit_color;
444
	    wdev->nColors = -1;
445
	    break;
446
	case 8:
447
	    /* use 64 static colors and 166 dynamic colors from 8 planes */
448
	    wdev->color_info = win_8bit_color;
449
	    wdev->nColors = 64;
450
	    break;
451
	case 4:
452
	    hdc = GetDC(NULL);
453
	    if (GetDeviceCaps(hdc, VERTRES) <= 350)
454
		wdev->color_info = win_ega_color;
455
	    else
456
		wdev->color_info = win_vga_color;
457
	    ReleaseDC(NULL, hdc);
458
	    wdev->nColors = 16;
459
	    break;
460
	case 1:
461
	    wdev->color_info = win_mono_color;
462
	    wdev->nColors = 2;
463
	    break;
464
	default:
465
	    return (gs_error_rangecheck);
466
    }
467
    wdev->BitsPerPixel = bpp;
468
 
469
    /* If necessary, allocate and clear the mapped color flags. */
470
    if (bpp == 8) {
471
	if (wdev->mapped_color_flags == 0) {
472
	    wdev->mapped_color_flags = gs_malloc(wdev->memory,
473
						 4096, 1, "win_set_bits_per_pixel");
474
	    if (wdev->mapped_color_flags == 0)
475
		return_error(gs_error_VMerror);
476
	}
477
	memset(wdev->mapped_color_flags, 0, 4096);
478
    } else {
479
	gs_free(wdev->memory, 
480
		wdev->mapped_color_flags, 4096, 1, "win_set_bits_per_pixel");
481
	wdev->mapped_color_flags = 0;
482
    }
483
 
484
    /* copy encode/decode procedures */
485
    wdev->procs.encode_color = wdev->procs.map_rgb_color;
486
    wdev->procs.decode_color = wdev->procs.map_color_rgb;
487
    if (bpp == 1) {
488
	wdev->procs.get_color_mapping_procs = 
489
	    gx_default_DevGray_get_color_mapping_procs;
490
	wdev->procs.get_color_comp_index = 
491
	    gx_default_DevGray_get_color_comp_index;
492
    }
493
    else {
494
	wdev->procs.get_color_mapping_procs = 
495
	    gx_default_DevRGB_get_color_mapping_procs;
496
	wdev->procs.get_color_comp_index = 
497
	    gx_default_DevRGB_get_color_comp_index;
498
    }
499
 
500
    /* restore old anti_alias info */
501
    wdev->color_info.anti_alias = anti_alias;
502
    return 0;
503
}