~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/gdevmswn.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

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