~ubuntu-branches/ubuntu/oneiric/ghostscript/oneiric

« back to all changes in this revision

Viewing changes to base/gdevwdib.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2011-07-15 16:49:55 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20110715164955-uga6qibao6kez05c
Tags: 9.04~dfsg~20110715-0ubuntu1
* New upstream release
   - GIT snapshot from Jult, 12 2011.
* debian/patches/020110406~a54df2d.patch,
  debian/patches/020110408~0791cc8.patch,
  debian/patches/020110408~507cbee.patch,
  debian/patches/020110411~4509a49.patch,
  debian/patches/020110412~78bb9a6.patch,
  debian/patches/020110418~a05ab8a.patch,
  debian/patches/020110420~20b6c78.patch,
  debian/patches/020110420~4ddefa2.patch: Removed upstream patches.
* debian/rules: Generate ABI version number (variable "abi") correctly,
  cutting off repackaging and pre-release parts.
* debian/rules: Added ./lcms2/ directory to DEB_UPSTREAM_REPACKAGE_EXCLUDES.
* debian/copyright: Added lcms2/* to the list of excluded files.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
2
   All Rights Reserved.
3
 
  
 
3
 
4
4
   This software is provided AS-IS with no warranty, either express or
5
5
   implied.
6
6
 
11
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
12
*/
13
13
 
14
 
/* $Id: gdevwdib.c 8250 2007-09-25 13:31:24Z giles $ */
 
14
/* $Id$ */
15
15
/* MS Windows 3.n driver for Ghostscript using a DIB for buffering. */
16
16
#include "gdevmswn.h"
17
17
#include "gxdevmem.h"
96
96
gx_device_win_dib far_data gs_mswindll_device =
97
97
{
98
98
    std_device_std_body(gx_device_win_dib, &win_dib_procs, "mswindll",
99
 
                        INITIAL_WIDTH, INITIAL_HEIGHT,/* win_open() fills these in later */
100
 
                        INITIAL_RESOLUTION, INITIAL_RESOLUTION  /* win_open() fills these in later */
 
99
                        INITIAL_WIDTH, INITIAL_HEIGHT,/* win_open() fills these in later */
 
100
                        INITIAL_RESOLUTION, INITIAL_RESOLUTION  /* win_open() fills these in later */
101
101
    ),
102
102
    {0},                        /* std_procs */
103
103
    0,                          /* BitsPerPixel */
111
111
static HGLOBAL win_dib_make_dib(gx_device_win * dev, int orgx, int orgy, int wx, int wy);
112
112
static int win_dib_lock_device(unsigned char *device, int flag);
113
113
 
114
 
 
115
114
/* Open the win_dib driver */
116
115
static int
117
116
win_dib_open(gx_device * dev)
119
118
    int code = win_open(dev);
120
119
 
121
120
    if (code < 0)
122
 
        return code;
 
121
        return code;
123
122
 
124
123
#ifdef __WIN32__
125
124
    if (!is_win32s)
126
 
        wdev->hmtx = CreateMutex(NULL, FALSE, NULL);    /* unnamed mutex, initially unowned */
 
125
        wdev->hmtx = CreateMutex(NULL, FALSE, NULL);    /* unnamed mutex, initially unowned */
127
126
#endif
128
127
    if (gdev_mem_device_for_bits(dev->color_info.depth) == 0) {
129
 
        win_close(dev);
130
 
        return gs_error_rangecheck;
 
128
        win_close(dev);
 
129
        return gs_error_rangecheck;
131
130
    }
132
131
    code = win_dib_alloc_bitmap((gx_device_win *) dev, dev);
133
132
    if (code < 0) {
134
 
        win_close(dev);
135
 
        return code;
 
133
        win_close(dev);
 
134
        return code;
136
135
    }
137
136
    /* notify caller about new device */
138
137
    if (pgsdll_callback) {
139
 
        (*pgsdll_callback) (GSDLL_DEVICE, (unsigned char *)dev, 1);
140
 
        (*pgsdll_callback) (GSDLL_SIZE, (unsigned char *)dev,
141
 
                        (dev->width & 0xffff) +
142
 
                        ((ulong) (dev->height & 0xffff) << 16));
 
138
        (*pgsdll_callback) (GSDLL_DEVICE, (unsigned char *)dev, 1);
 
139
        (*pgsdll_callback) (GSDLL_SIZE, (unsigned char *)dev,
 
140
                        (dev->width & 0xffff) +
 
141
                        ((ulong) (dev->height & 0xffff) << 16));
143
142
    }
144
143
    return code;
145
144
}
166
165
    /* wait until bitmap is not being used by caller */
167
166
    win_dib_lock_device((unsigned char *)dev, 1);
168
167
    if (pgsdll_callback)
169
 
        (*pgsdll_callback) (GSDLL_DEVICE, (unsigned char *)dev, 0);
 
168
        (*pgsdll_callback) (GSDLL_DEVICE, (unsigned char *)dev, 0);
170
169
    win_dib_lock_device((unsigned char *)dev, 0);
171
170
    win_dib_free_bitmap((gx_device_win *) dev);
172
171
#ifdef __WIN32__
173
172
    if (!is_win32s)
174
 
        CloseHandle(wdev->hmtx);
 
173
        CloseHandle(wdev->hmtx);
175
174
#endif
176
175
    code = win_close(dev);
177
176
    return code;
190
189
 
191
190
#define BEGIN_BLOCKS\
192
191
{       int by, bh, left = h;\
193
 
        for ( by = y; left > 0; by += bh, left -= bh )\
194
 
        {       bh = wdev->y_block - (by & wdev->y_mask);\
195
 
                if ( bh > left ) bh = left;
 
192
        for ( by = y; left > 0; by += bh, left -= bh )\
 
193
        {       bh = wdev->y_block - (by & wdev->y_mask);\
 
194
                if ( bh > left ) bh = left;
196
195
#define END_BLOCKS\
197
 
        }\
 
196
        }\
198
197
}
199
198
 
200
199
#endif /* (!)USE_SEGMENTS */
202
201
/* Fill a rectangle. */
203
202
static int
204
203
win_dib_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
205
 
                       gx_color_index color)
 
204
                       gx_color_index color)
206
205
{
207
206
#if USE_SEGMENTS
208
207
    if (single_block(y, h)) {
209
 
        wmproc(fill_rectangle) (wmdev, x, y, w, h, color);
 
208
        wmproc(fill_rectangle) (wmdev, x, y, w, h, color);
210
209
    } else {                    /* Divide the transfer into blocks. */
211
 
        BEGIN_BLOCKS
212
 
            wmproc(fill_rectangle) (wmdev, x, by, w, bh, color);
213
 
        END_BLOCKS
 
210
        BEGIN_BLOCKS
 
211
            wmproc(fill_rectangle) (wmdev, x, by, w, bh, color);
 
212
        END_BLOCKS
214
213
    }
215
214
#else
216
215
    wmproc(fill_rectangle) (wmdev, x, y, w, h, color);
222
221
/* Color = gx_no_color_index means transparent (no effect on the image). */
223
222
static int
224
223
win_dib_copy_mono(gx_device * dev,
225
 
                const byte * base, int sourcex, int raster, gx_bitmap_id id,
226
 
                  int x, int y, int w, int h,
227
 
                  gx_color_index zero, gx_color_index one)
 
224
                const byte * base, int sourcex, int raster, gx_bitmap_id id,
 
225
                  int x, int y, int w, int h,
 
226
                  gx_color_index zero, gx_color_index one)
228
227
{
229
228
#if USE_SEGMENTS
230
229
    if (single_block(y, h)) {
231
 
        wmproc(copy_mono) (wmdev, base, sourcex, raster, id,
232
 
                           x, y, w, h, zero, one);
 
230
        wmproc(copy_mono) (wmdev, base, sourcex, raster, id,
 
231
                           x, y, w, h, zero, one);
233
232
    } else {                    /* Divide the transfer into blocks. */
234
 
        const byte *source = base;
 
233
        const byte *source = base;
235
234
 
236
 
        BEGIN_BLOCKS
237
 
            wmproc(copy_mono) (wmdev, source, sourcex, raster,
238
 
                               gx_no_bitmap_id, x, by, w, bh,
239
 
                               zero, one);
240
 
        source += bh * raster;
241
 
        END_BLOCKS
 
235
        BEGIN_BLOCKS
 
236
            wmproc(copy_mono) (wmdev, source, sourcex, raster,
 
237
                               gx_no_bitmap_id, x, by, w, bh,
 
238
                               zero, one);
 
239
        source += bh * raster;
 
240
        END_BLOCKS
242
241
    }
243
242
#else
244
243
    wmproc(copy_mono) (wmdev, base, sourcex, raster, id,
245
 
                       x, y, w, h, zero, one);
 
244
                       x, y, w, h, zero, one);
246
245
#endif
247
246
    return 0;
248
247
}
251
250
/* each pixel takes 8 or 4 bits instead of 1 when device driver has color. */
252
251
static int
253
252
win_dib_copy_color(gx_device * dev,
254
 
                const byte * base, int sourcex, int raster, gx_bitmap_id id,
255
 
                   int x, int y, int w, int h)
 
253
                const byte * base, int sourcex, int raster, gx_bitmap_id id,
 
254
                   int x, int y, int w, int h)
256
255
{
257
256
#if USE_SEGMENTS
258
257
    if (single_block(y, h)) {
259
 
        wmproc(copy_color) (wmdev, base, sourcex, raster, id,
260
 
                            x, y, w, h);
 
258
        wmproc(copy_color) (wmdev, base, sourcex, raster, id,
 
259
                            x, y, w, h);
261
260
    } else {                    /* Divide the transfer into blocks. */
262
 
        const byte *source = base;
 
261
        const byte *source = base;
263
262
 
264
 
        BEGIN_BLOCKS
265
 
            wmproc(copy_color) (wmdev, source, sourcex, raster,
266
 
                                gx_no_bitmap_id, x, by, w, bh);
267
 
        source += by * raster;
268
 
        END_BLOCKS
 
263
        BEGIN_BLOCKS
 
264
            wmproc(copy_color) (wmdev, source, sourcex, raster,
 
265
                                gx_no_bitmap_id, x, by, w, bh);
 
266
        source += by * raster;
 
267
        END_BLOCKS
269
268
    }
270
269
#else
271
270
    wmproc(copy_color) (wmdev, base, sourcex, raster, id,
272
 
                        x, y, w, h);
 
271
                        x, y, w, h);
273
272
#endif
274
273
    return 0;
275
274
}
301
300
    gx_device_win_dib *dev = (gx_device_win_dib *) device;
302
301
 
303
302
    if (!dev || !dev->is_open || dev->mdev.width == 0 || dev->mdev.height == 0)
304
 
        return (HGLOBAL) NULL;
 
303
        return (HGLOBAL) NULL;
305
304
    return win_dib_make_dib((gx_device_win *) dev, 0, 0, dev->width, dev->height);
306
305
}
307
306
 
313
312
    gx_device_win_dib *dev = (gx_device_win_dib *) device;
314
313
 
315
314
    if (!dev || !dev->is_open || dev->mdev.width == 0 || dev->mdev.height == 0)
316
 
        return (HPALETTE) NULL;
 
315
        return (HPALETTE) NULL;
317
316
    if (wdev->nColors > 0)
318
 
        return CreatePalette(dev->limgpalette);
 
317
        return CreatePalette(dev->limgpalette);
319
318
    return (HPALETTE) NULL;
320
319
}
321
320
 
330
329
    HPALETTE oldpalette;
331
330
 
332
331
    if (!dev || !dev->is_open || dev->mdev.width == 0 || dev->mdev.height == 0)
333
 
        return;
 
332
        return;
334
333
    if (dev->nColors > 0) {
335
 
        oldpalette = SelectPalette(hdc, dev->himgpalette, FALSE);
336
 
        RealizePalette(hdc);
 
334
        oldpalette = SelectPalette(hdc, dev->himgpalette, FALSE);
 
335
        RealizePalette(hdc);
337
336
    }
338
337
    win_dib_repaint((gx_device_win *) dev, hdc, dest->left, dest->top,
339
 
                    dest->right - dest->left, dest->bottom - dest->top,
340
 
                    src->left, src->top);
 
338
                    dest->right - dest->left, dest->bottom - dest->top,
 
339
                    src->left, src->top);
341
340
    if (dev->nColors > 0) {
342
 
        SelectPalette(hdc, oldpalette, FALSE);
 
341
        SelectPalette(hdc, oldpalette, FALSE);
343
342
    }
344
343
    return;
345
344
}
346
345
 
347
346
/* ------ Windows-specific device procedures ------ */
348
347
 
349
 
 
350
348
/* Repaint a section of the window. */
351
349
static void
352
350
win_dib_repaint(gx_device_win * dev, HDC hdc, int dx, int dy, int wx, int wy,
353
 
                int sx, int sy)
 
351
                int sx, int sy)
354
352
{
355
353
    struct bmi_s {
356
 
        BITMAPINFOHEADER h;
357
 
        ushort pal_index[256];
 
354
        BITMAPINFOHEADER h;
 
355
        ushort pal_index[256];
358
356
    } bmi;
359
357
    int i;
360
358
    UINT which_colors;
361
359
 
362
360
    memset(&bmi.h, 0, sizeof(bmi.h));
363
 
    
 
361
 
364
362
    bmi.h.biSize = sizeof(bmi.h);
365
363
    bmi.h.biWidth = wdev->mdev.width;
366
364
    bmi.h.biHeight = wy;
370
368
    bmi.h.biSizeImage = 0;      /* default */
371
369
    bmi.h.biXPelsPerMeter = 0;  /* default */
372
370
    bmi.h.biYPelsPerMeter = 0;  /* default */
373
 
    
 
371
 
374
372
    if (dev->BitsPerPixel <= 8) {
375
 
        bmi.h.biClrUsed = wdev->nColors;
376
 
        bmi.h.biClrImportant = wdev->nColors;
377
 
        for (i = 0; i < wdev->nColors; i++)
378
 
            bmi.pal_index[i] = i;
379
 
        which_colors = DIB_PAL_COLORS;
 
373
        bmi.h.biClrUsed = wdev->nColors;
 
374
        bmi.h.biClrImportant = wdev->nColors;
 
375
        for (i = 0; i < wdev->nColors; i++)
 
376
            bmi.pal_index[i] = i;
 
377
        which_colors = DIB_PAL_COLORS;
380
378
    } else if (dev->BitsPerPixel == 15) { /* 5-5-5 RGB mode */
381
 
        DWORD* bmi_colors = (DWORD*)(&bmi.pal_index[0]);
382
 
        bmi.h.biCompression = BI_BITFIELDS;
383
 
        bmi_colors[0] = 0x7c00;
384
 
        bmi_colors[1] = 0x03e0;
385
 
        bmi_colors[2] = 0x001f;
386
 
        which_colors = DIB_RGB_COLORS;
 
379
        DWORD* bmi_colors = (DWORD*)(&bmi.pal_index[0]);
 
380
        bmi.h.biCompression = BI_BITFIELDS;
 
381
        bmi_colors[0] = 0x7c00;
 
382
        bmi_colors[1] = 0x03e0;
 
383
        bmi_colors[2] = 0x001f;
 
384
        which_colors = DIB_RGB_COLORS;
387
385
    } else if (dev->BitsPerPixel == 16) { /* 5-6-5 RGB mode */
388
 
        DWORD* bmi_colors = (DWORD*)(&bmi.pal_index[0]);
389
 
        bmi.h.biCompression = BI_BITFIELDS;
390
 
        bmi_colors[0] = 0xf800;
391
 
        bmi_colors[1] = 0x07e0;
392
 
        bmi_colors[2] = 0x001f;
393
 
        which_colors = DIB_RGB_COLORS;
 
386
        DWORD* bmi_colors = (DWORD*)(&bmi.pal_index[0]);
 
387
        bmi.h.biCompression = BI_BITFIELDS;
 
388
        bmi_colors[0] = 0xf800;
 
389
        bmi_colors[1] = 0x07e0;
 
390
        bmi_colors[2] = 0x001f;
 
391
        which_colors = DIB_RGB_COLORS;
394
392
    } else {
395
 
        bmi.h.biClrUsed = 0;
396
 
        bmi.h.biClrImportant = 0;
397
 
        which_colors = DIB_RGB_COLORS;
 
393
        bmi.h.biClrUsed = 0;
 
394
        bmi.h.biClrImportant = 0;
 
395
        which_colors = DIB_RGB_COLORS;
398
396
    }
399
397
    /*
400
398
     * Windows apparently limits the size of a single transfer
403
401
     */
404
402
#define max_transfer 2000000
405
403
    if (wdev->mdev.raster > 0) {        /* just in case! */
406
 
        long ny = max_transfer / wdev->mdev.raster;
 
404
        long ny = max_transfer / wdev->mdev.raster;
407
405
 
408
 
        for (; wy > ny; dy += ny, wy -= ny, sy += ny)
409
 
            SetDIBitsToDevice(hdc, dx, dy, wx, ny,
410
 
                              sx, 0, 0, ny,
411
 
                              wdev->mdev.line_ptrs[wdev->height - (sy + ny)],
412
 
                              (BITMAPINFO FAR *) & bmi, which_colors);
 
406
        for (; wy > ny; dy += ny, wy -= ny, sy += ny)
 
407
            SetDIBitsToDevice(hdc, dx, dy, wx, ny,
 
408
                              sx, 0, 0, ny,
 
409
                              wdev->mdev.line_ptrs[wdev->height - (sy + ny)],
 
410
                              (BITMAPINFO FAR *) & bmi, which_colors);
413
411
    }
414
412
#undef max_transfer
415
413
    SetDIBitsToDevice(hdc, dx, dy, wx, wy,
416
 
                      sx, 0, 0, wy,
417
 
                      wdev->mdev.line_ptrs[wdev->height - (sy + wy)],
418
 
                      (BITMAPINFO FAR *) & bmi, which_colors);
 
414
                      sx, 0, 0, wy,
 
415
                      wdev->mdev.line_ptrs[wdev->height - (sy + wy)],
 
416
                      (BITMAPINFO FAR *) & bmi, which_colors);
419
417
}
420
418
 
421
419
/* This makes a DIB that contains all or part of the bitmap. */
442
440
#endif
443
441
 
444
442
    if (orgx + wx > wdev->width)
445
 
        wx = wdev->width - orgx;
 
443
        wx = wdev->width - orgx;
446
444
    if (orgy + wy > wdev->height)
447
 
        wy = wdev->height - orgy;
 
445
        wy = wdev->height - orgy;
448
446
 
449
447
    loffset = orgx * wdev->color_info.depth / 8;
450
448
    lwidth = ((wx * wdev->color_info.depth + 31) & ~31) >> 3;
451
449
    bitmapsize = (long)lwidth *wy;
452
450
 
453
451
    if (wdev->color_info.depth > 16)
454
 
        palcount = 0;
 
452
        palcount = 0;
455
453
    else if (wdev->color_info.depth > 8)
456
 
        palcount = 3;           /* 16-bit BI_BITFIELDS */
 
454
        palcount = 3;           /* 16-bit BI_BITFIELDS */
457
455
    else
458
 
        palcount = wdev->nColors;
 
456
        palcount = wdev->nColors;
459
457
 
460
458
    hglobal = GlobalAlloc(GHND | GMEM_SHARE, sizeof(BITMAPINFOHEADER)
461
 
                          + sizeof(RGBQUAD) * palcount + bitmapsize);
 
459
                          + sizeof(RGBQUAD) * palcount + bitmapsize);
462
460
    if (hglobal == (HGLOBAL) NULL) {
463
 
        MessageBeep(-1);
464
 
        return (HGLOBAL) NULL;
 
461
        MessageBeep(-1);
 
462
        return (HGLOBAL) NULL;
465
463
    }
466
464
    pDIB = (BYTE FAR *) GlobalLock(hglobal);
467
465
    if (pDIB == (BYTE FAR *) NULL) {
468
 
        MessageBeep(-1);
469
 
        return (HGLOBAL) NULL;
 
466
        MessageBeep(-1);
 
467
        return (HGLOBAL) NULL;
470
468
    }
471
469
    pbmih = (BITMAPINFOHEADER FAR *) (pDIB);
472
470
    pColors = (RGBQUAD FAR *) (pDIB + sizeof(BITMAPINFOHEADER));
485
483
    pbmih->biClrImportant = palcount;
486
484
 
487
485
    if (dev->BitsPerPixel == 15) { /* 5-5-5 RGB mode */
488
 
        DWORD* bmi_colors = (DWORD*)(pColors);
 
486
        DWORD* bmi_colors = (DWORD*)(pColors);
489
487
        pbmih->biCompression = BI_BITFIELDS;
490
 
        bmi_colors[0] = 0x7c00;
491
 
        bmi_colors[1] = 0x03e0;
492
 
        bmi_colors[2] = 0x001f;
493
 
    } 
 
488
        bmi_colors[0] = 0x7c00;
 
489
        bmi_colors[1] = 0x03e0;
 
490
        bmi_colors[2] = 0x001f;
 
491
    }
494
492
    else if (dev->BitsPerPixel == 16) { /* 5-6-5 RGB mode */
495
 
        DWORD* bmi_colors = (DWORD*)(pColors);
 
493
        DWORD* bmi_colors = (DWORD*)(pColors);
496
494
        pbmih->biCompression = BI_BITFIELDS;
497
 
        bmi_colors[0] = 0xf800;
498
 
        bmi_colors[1] = 0x07e0;
499
 
        bmi_colors[2] = 0x001f;
500
 
    } 
 
495
        bmi_colors[0] = 0xf800;
 
496
        bmi_colors[1] = 0x07e0;
 
497
        bmi_colors[2] = 0x001f;
 
498
    }
501
499
    else {
502
500
    for (i = 0; i < palcount; i++) {
503
 
        win_map_color_rgb((gx_device *) wdev, (gx_color_index) i, prgb);
504
 
        pColors[i].rgbRed = win_color_value(prgb[0]);
505
 
        pColors[i].rgbGreen = win_color_value(prgb[1]);
506
 
        pColors[i].rgbBlue = win_color_value(prgb[2]);
507
 
        pColors[i].rgbReserved = 0;
 
501
        win_map_color_rgb((gx_device *) wdev, (gx_color_index) i, prgb);
 
502
        pColors[i].rgbRed = win_color_value(prgb[0]);
 
503
        pColors[i].rgbGreen = win_color_value(prgb[1]);
 
504
        pColors[i].rgbBlue = win_color_value(prgb[2]);
 
505
        pColors[i].rgbReserved = 0;
508
506
    }
509
507
    }
510
508
 
511
509
    pLine = pBits;
512
510
    for (i = orgy; i < orgy + wy; i++) {
513
511
#if USE_SEGMENTS
514
 
        /* Window 3.1 has hmemcpy, but 3.0 doesn't */
515
 
        lseg = (UINT) (-OFFSETOF(pLine));       /* remaining bytes in this segment */
516
 
        if (lseg >= lwidth) {
517
 
            _fmemcpy(pLine, xwdev->mdev.line_ptrs[i] + loffset, lwidth);
518
 
        } else {                /* break up transfer to avoid crossing segment boundary */
519
 
            _fmemcpy(pLine, xwdev->mdev.line_ptrs[i] + loffset, lseg);
520
 
            _fmemcpy(pLine + lseg, xwdev->mdev.line_ptrs[i] + loffset + lseg, lwidth - lseg);
521
 
        }
 
512
        /* Window 3.1 has hmemcpy, but 3.0 doesn't */
 
513
        lseg = (UINT) (-OFFSETOF(pLine));       /* remaining bytes in this segment */
 
514
        if (lseg >= lwidth) {
 
515
            _fmemcpy(pLine, xwdev->mdev.line_ptrs[i] + loffset, lwidth);
 
516
        } else {                /* break up transfer to avoid crossing segment boundary */
 
517
            _fmemcpy(pLine, xwdev->mdev.line_ptrs[i] + loffset, lseg);
 
518
            _fmemcpy(pLine + lseg, xwdev->mdev.line_ptrs[i] + loffset + lseg, lwidth - lseg);
 
519
        }
522
520
#else
523
 
        memcpy(pLine, xwdev->mdev.line_ptrs[i], lwidth);
 
521
        memcpy(pLine, xwdev->mdev.line_ptrs[i], lwidth);
524
522
#endif
525
 
        pLine += lwidth;
 
523
        pLine += lwidth;
526
524
    }
527
525
 
528
526
    GlobalUnlock(hglobal);
529
527
    return hglobal;
530
528
}
531
529
 
532
 
 
533
530
/* Allocate the backing bitmap. */
534
531
static int
535
532
win_dib_alloc_bitmap(gx_device_win * dev, gx_device * param_dev)
549
546
#ifdef __WIN32__
550
547
    if (is_win32s) {
551
548
#endif
552
 
        /* Round up the width so that the scan line size is a power of 2. */
553
 
        if (dev->color_info.depth == 24) {
554
 
            width = param_dev->width * 3 - 1;
555
 
            while (width & (width + 1))
556
 
                width |= width >> 1;
557
 
            width = (width + 1) / 3;
558
 
        } else {
559
 
            width = param_dev->width - 1;
560
 
            while (width & (width + 1))
561
 
                width |= width >> 1;
562
 
            width++;
563
 
        }
 
549
        /* Round up the width so that the scan line size is a power of 2. */
 
550
        if (dev->color_info.depth == 24) {
 
551
            width = param_dev->width * 3 - 1;
 
552
            while (width & (width + 1))
 
553
                width |= width >> 1;
 
554
            width = (width + 1) / 3;
 
555
        } else {
 
556
            width = param_dev->width - 1;
 
557
            while (width & (width + 1))
 
558
                width |= width >> 1;
 
559
            width++;
 
560
        }
564
561
#ifdef __WIN32__
565
562
    } else {                    /* don't have to worry about segments so use less memory */
566
 
        width = param_dev->width;
 
563
        width = param_dev->width;
567
564
    }
568
565
#endif
569
566
 
578
575
    ptr_size = sizeof(byte **) * mdev.height;
579
576
    hmdata = GlobalAlloc(0, raster + data_size + ptr_size * 2);
580
577
    if (hmdata == 0) {
581
 
        return win_nomemory();
 
578
        return win_nomemory();
582
579
    }
583
580
    /* Nothing can go wrong now.... */
584
581
 
590
587
    base += (-PTR_OFF(base) & (raster - 1));
591
588
    ptr_base = base + data_size;
592
589
    if (PTR_OFF(ptr_base + ptr_size) < ptr_size)
593
 
        base += (uint) - PTR_OFF(ptr_base);
 
590
        base += (uint) - PTR_OFF(ptr_base);
594
591
    wdev->y_block = 0x10000L / raster;
595
592
    wdev->y_mask = wdev->y_block - 1;
596
593
    if ((wdev->y_base = PTR_OFF(base)) != 0)
597
 
        wdev->y_base = -(PTR_OFF(base) / raster);
 
594
        wdev->y_base = -(PTR_OFF(base) / raster);
598
595
#endif
599
596
    wdev->mdev = mdev;
600
597
    wdev->mdev.base = (byte *) base;
601
598
    wmproc(open_device) ((gx_device *) & wdev->mdev);
602
599
 
603
600
    if (wdev->is_open && pgsdll_callback)
604
 
        (*pgsdll_callback) (GSDLL_SIZE, (unsigned char *)dev,
605
 
                            (dev->width & 0xffff) +
606
 
                            ((ulong) (dev->height & 0xffff) << 16));
 
601
        (*pgsdll_callback) (GSDLL_SIZE, (unsigned char *)dev,
 
602
                            (dev->width & 0xffff) +
 
603
                            ((ulong) (dev->height & 0xffff) << 16));
607
604
 
608
605
    return 0;
609
606
}
610
607
 
611
 
 
612
608
/* Free the backing bitmap. */
613
609
static void
614
610
win_dib_free_bitmap(gx_device_win * dev)
629
625
 
630
626
#ifdef __WIN32__
631
627
    if (!is_win32s) {
632
 
        if (flag) {
633
 
            if (WaitForSingleObject(wdev->hmtx, 60000) == WAIT_TIMEOUT)
634
 
                return 2;
635
 
            return 1;
636
 
        }
637
 
        ReleaseMutex(wdev->hmtx);
638
 
        return 0;
 
628
        if (flag) {
 
629
            if (WaitForSingleObject(wdev->hmtx, 60000) == WAIT_TIMEOUT)
 
630
                return 2;
 
631
            return 1;
 
632
        }
 
633
        ReleaseMutex(wdev->hmtx);
 
634
        return 0;
639
635
    }
640
636
#endif
641
637
    if (flag)
642
 
        wdev->lock_count++;
 
638
        wdev->lock_count++;
643
639
    else
644
 
        wdev->lock_count--;
 
640
        wdev->lock_count--;
645
641
    if (wdev->lock_count < 0)
646
 
        wdev->lock_count = 0;
 
642
        wdev->lock_count = 0;
647
643
    return wdev->lock_count;
648
644
}
649
645
 
653
649
    return win_dib_lock_device(device, flag);
654
650
}
655
651
 
656
 
 
657
652
/* Copy bitmap
658
653
 * If pbmih nonzero, copy the BITMAPINFOHEADER.
659
654
 * If prgbquad nonzero, copy the palette.
673
668
 */
674
669
int GSDLLAPI _export
675
670
gsdll_get_bitmap_row(unsigned char *device, LPBITMAPINFOHEADER pbmih,
676
 
                     LPRGBQUAD prgbquad, LPBYTE * ppbyte, unsigned int row)
 
671
                     LPRGBQUAD prgbquad, LPBYTE * ppbyte, unsigned int row)
677
672
{
678
673
    int palcount;
679
674
    gx_device_win_dib *dev = (gx_device_win_dib *) device;
681
676
    palcount = (dev->color_info.depth == 24) ? 0 : dev->nColors;
682
677
 
683
678
    if (pbmih) {
684
 
        pbmih->biSize = sizeof(BITMAPINFOHEADER);
685
 
        pbmih->biWidth = dev->width;
686
 
        pbmih->biHeight = dev->mdev.height;
687
 
        pbmih->biPlanes = 1;
688
 
        pbmih->biBitCount = dev->color_info.depth;
689
 
        if ((dev->BitsPerPixel == 15) || (dev->BitsPerPixel == 16))
 
679
        pbmih->biSize = sizeof(BITMAPINFOHEADER);
 
680
        pbmih->biWidth = dev->width;
 
681
        pbmih->biHeight = dev->mdev.height;
 
682
        pbmih->biPlanes = 1;
 
683
        pbmih->biBitCount = dev->color_info.depth;
 
684
        if ((dev->BitsPerPixel == 15) || (dev->BitsPerPixel == 16))
690
685
            pbmih->biCompression = BI_BITFIELDS;
691
 
        else
692
 
        pbmih->biCompression = 0;
693
 
        pbmih->biSizeImage = 0; /* default */
694
 
        pbmih->biXPelsPerMeter = (DWORD) (dev->x_pixels_per_inch / 25.4 * 1000);
695
 
        pbmih->biYPelsPerMeter = (DWORD) (dev->y_pixels_per_inch / 25.4 * 1000);
696
 
        pbmih->biClrUsed = palcount;
697
 
        pbmih->biClrImportant = palcount;
 
686
        else
 
687
        pbmih->biCompression = 0;
 
688
        pbmih->biSizeImage = 0; /* default */
 
689
        pbmih->biXPelsPerMeter = (DWORD) (dev->x_pixels_per_inch / 25.4 * 1000);
 
690
        pbmih->biYPelsPerMeter = (DWORD) (dev->y_pixels_per_inch / 25.4 * 1000);
 
691
        pbmih->biClrUsed = palcount;
 
692
        pbmih->biClrImportant = palcount;
698
693
    }
699
694
    if (prgbquad) {
700
 
        int i;
701
 
        gx_color_value prgb[3];
 
695
        int i;
 
696
        gx_color_value prgb[3];
702
697
 
703
 
        if (dev->BitsPerPixel == 15) { /* 5-5-5 RGB mode */
704
 
            DWORD* bmi_colors = (DWORD*)(prgbquad);
705
 
            pbmih->biCompression = BI_BITFIELDS;
706
 
            bmi_colors[0] = 0x7c00;
707
 
            bmi_colors[1] = 0x03e0;
708
 
            bmi_colors[2] = 0x001f;
709
 
        } 
710
 
        else if (dev->BitsPerPixel == 16) { /* 5-6-5 RGB mode */
711
 
            DWORD* bmi_colors = (DWORD*)(prgbquad);
712
 
            pbmih->biCompression = BI_BITFIELDS;
713
 
            bmi_colors[0] = 0xf800;
714
 
            bmi_colors[1] = 0x07e0;
715
 
            bmi_colors[2] = 0x001f;
716
 
        } 
717
 
        else {
718
 
        for (i = 0; i < palcount; i++) {
719
 
            win_map_color_rgb((gx_device *) wdev, (gx_color_index) i, prgb);
720
 
            prgbquad[i].rgbRed = win_color_value(prgb[0]);
721
 
            prgbquad[i].rgbGreen = win_color_value(prgb[1]);
722
 
            prgbquad[i].rgbBlue = win_color_value(prgb[2]);
723
 
            prgbquad[i].rgbReserved = 0;
724
 
            }
725
 
        }
 
698
        if (dev->BitsPerPixel == 15) { /* 5-5-5 RGB mode */
 
699
            DWORD* bmi_colors = (DWORD*)(prgbquad);
 
700
            pbmih->biCompression = BI_BITFIELDS;
 
701
            bmi_colors[0] = 0x7c00;
 
702
            bmi_colors[1] = 0x03e0;
 
703
            bmi_colors[2] = 0x001f;
 
704
        }
 
705
        else if (dev->BitsPerPixel == 16) { /* 5-6-5 RGB mode */
 
706
            DWORD* bmi_colors = (DWORD*)(prgbquad);
 
707
            pbmih->biCompression = BI_BITFIELDS;
 
708
            bmi_colors[0] = 0xf800;
 
709
            bmi_colors[1] = 0x07e0;
 
710
            bmi_colors[2] = 0x001f;
 
711
        }
 
712
        else {
 
713
        for (i = 0; i < palcount; i++) {
 
714
            win_map_color_rgb((gx_device *) wdev, (gx_color_index) i, prgb);
 
715
            prgbquad[i].rgbRed = win_color_value(prgb[0]);
 
716
            prgbquad[i].rgbGreen = win_color_value(prgb[1]);
 
717
            prgbquad[i].rgbBlue = win_color_value(prgb[2]);
 
718
            prgbquad[i].rgbReserved = 0;
 
719
            }
 
720
        }
726
721
    }
727
722
    if (ppbyte) {
728
 
        if (row < dev->mdev.height)
729
 
            *ppbyte = dev->mdev.line_ptrs[row];
730
 
        else
731
 
            *ppbyte = NULL;
 
723
        if (row < dev->mdev.height)
 
724
            *ppbyte = dev->mdev.line_ptrs[row];
 
725
        else
 
726
            *ppbyte = NULL;
732
727
    }
733
728
    if ((pbmih == NULL) && (prgbquad == NULL) && (ppbyte == NULL))
734
 
        return sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)
735
 
            + gdev_mem_raster(&(dev->mdev));
 
729
        return sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)
 
730
            + gdev_mem_raster(&(dev->mdev));
736
731
    return 0;
737
732
}