96
96
gx_device_win_dib far_data gs_mswindll_device =
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 */
102
102
{0}, /* std_procs */
103
103
0, /* BitsPerPixel */
119
118
int code = win_open(dev);
126
wdev->hmtx = CreateMutex(NULL, FALSE, NULL); /* unnamed mutex, initially unowned */
125
wdev->hmtx = CreateMutex(NULL, FALSE, NULL); /* unnamed mutex, initially unowned */
128
127
if (gdev_mem_device_for_bits(dev->color_info.depth) == 0) {
130
return gs_error_rangecheck;
129
return gs_error_rangecheck;
132
131
code = win_dib_alloc_bitmap((gx_device_win *) dev, dev);
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));
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);
174
CloseHandle(wdev->hmtx);
173
CloseHandle(wdev->hmtx);
176
175
code = win_close(dev);
202
201
/* Fill a rectangle. */
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)
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. */
212
wmproc(fill_rectangle) (wmdev, x, by, w, bh, color);
211
wmproc(fill_rectangle) (wmdev, x, by, w, bh, color);
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). */
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)
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;
237
wmproc(copy_mono) (wmdev, source, sourcex, raster,
238
gx_no_bitmap_id, x, by, w, bh,
240
source += bh * raster;
236
wmproc(copy_mono) (wmdev, source, sourcex, raster,
237
gx_no_bitmap_id, x, by, w, bh,
239
source += bh * raster;
244
243
wmproc(copy_mono) (wmdev, base, sourcex, raster, id,
245
x, y, w, h, zero, one);
244
x, y, w, h, zero, one);
251
250
/* each pixel takes 8 or 4 bits instead of 1 when device driver has color. */
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)
258
257
if (single_block(y, h)) {
259
wmproc(copy_color) (wmdev, base, sourcex, raster, id,
258
wmproc(copy_color) (wmdev, base, sourcex, raster, id,
261
260
} else { /* Divide the transfer into blocks. */
262
const byte *source = base;
261
const byte *source = base;
265
wmproc(copy_color) (wmdev, source, sourcex, raster,
266
gx_no_bitmap_id, x, by, w, bh);
267
source += by * raster;
264
wmproc(copy_color) (wmdev, source, sourcex, raster,
265
gx_no_bitmap_id, x, by, w, bh);
266
source += by * raster;
271
270
wmproc(copy_color) (wmdev, base, sourcex, raster, id,
330
329
HPALETTE oldpalette;
332
331
if (!dev || !dev->is_open || dev->mdev.width == 0 || dev->mdev.height == 0)
334
333
if (dev->nColors > 0) {
335
oldpalette = SelectPalette(hdc, dev->himgpalette, FALSE);
334
oldpalette = SelectPalette(hdc, dev->himgpalette, FALSE);
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);
347
346
/* ------ Windows-specific device procedures ------ */
350
348
/* Repaint a section of the window. */
352
350
win_dib_repaint(gx_device_win * dev, HDC hdc, int dx, int dy, int wx, int wy,
357
ushort pal_index[256];
355
ushort pal_index[256];
360
358
UINT which_colors;
362
360
memset(&bmi.h, 0, sizeof(bmi.h));
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 */
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;
396
bmi.h.biClrImportant = 0;
397
which_colors = DIB_RGB_COLORS;
394
bmi.h.biClrImportant = 0;
395
which_colors = DIB_RGB_COLORS;
400
398
* Windows apparently limits the size of a single transfer
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;
408
for (; wy > ny; dy += ny, wy -= ny, sy += ny)
409
SetDIBitsToDevice(hdc, dx, dy, wx, 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,
409
wdev->mdev.line_ptrs[wdev->height - (sy + ny)],
410
(BITMAPINFO FAR *) & bmi, which_colors);
414
412
#undef max_transfer
415
413
SetDIBitsToDevice(hdc, dx, dy, wx, wy,
417
wdev->mdev.line_ptrs[wdev->height - (sy + wy)],
418
(BITMAPINFO FAR *) & bmi, which_colors);
415
wdev->mdev.line_ptrs[wdev->height - (sy + wy)],
416
(BITMAPINFO FAR *) & bmi, which_colors);
421
419
/* This makes a DIB that contains all or part of the bitmap. */
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;
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;
453
451
if (wdev->color_info.depth > 16)
455
453
else if (wdev->color_info.depth > 8)
456
palcount = 3; /* 16-bit BI_BITFIELDS */
454
palcount = 3; /* 16-bit BI_BITFIELDS */
458
palcount = wdev->nColors;
456
palcount = wdev->nColors;
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) {
464
return (HGLOBAL) NULL;
462
return (HGLOBAL) NULL;
466
464
pDIB = (BYTE FAR *) GlobalLock(hglobal);
467
465
if (pDIB == (BYTE FAR *) NULL) {
469
return (HGLOBAL) NULL;
467
return (HGLOBAL) NULL;
471
469
pbmih = (BITMAPINFOHEADER FAR *) (pDIB);
472
470
pColors = (RGBQUAD FAR *) (pDIB + sizeof(BITMAPINFOHEADER));
485
483
pbmih->biClrImportant = palcount;
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;
488
bmi_colors[0] = 0x7c00;
489
bmi_colors[1] = 0x03e0;
490
bmi_colors[2] = 0x001f;
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;
495
bmi_colors[0] = 0xf800;
496
bmi_colors[1] = 0x07e0;
497
bmi_colors[2] = 0x001f;
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;
512
510
for (i = orgy; i < orgy + wy; i++) {
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);
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);
523
memcpy(pLine, xwdev->mdev.line_ptrs[i], lwidth);
521
memcpy(pLine, xwdev->mdev.line_ptrs[i], lwidth);
528
526
GlobalUnlock(hglobal);
533
530
/* Allocate the backing bitmap. */
535
532
win_dib_alloc_bitmap(gx_device_win * dev, gx_device * param_dev)
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))
557
width = (width + 1) / 3;
559
width = param_dev->width - 1;
560
while (width & (width + 1))
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))
554
width = (width + 1) / 3;
556
width = param_dev->width - 1;
557
while (width & (width + 1))
565
562
} else { /* don't have to worry about segments so use less memory */
566
width = param_dev->width;
563
width = param_dev->width;
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);
599
596
wdev->mdev = mdev;
600
597
wdev->mdev.base = (byte *) base;
601
598
wmproc(open_device) ((gx_device *) & wdev->mdev);
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));
612
608
/* Free the backing bitmap. */
614
610
win_dib_free_bitmap(gx_device_win * dev)
681
676
palcount = (dev->color_info.depth == 24) ? 0 : dev->nColors;
684
pbmih->biSize = sizeof(BITMAPINFOHEADER);
685
pbmih->biWidth = dev->width;
686
pbmih->biHeight = dev->mdev.height;
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;
683
pbmih->biBitCount = dev->color_info.depth;
684
if ((dev->BitsPerPixel == 15) || (dev->BitsPerPixel == 16))
690
685
pbmih->biCompression = BI_BITFIELDS;
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;
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;
701
gx_color_value prgb[3];
696
gx_color_value prgb[3];
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;
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;
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;
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;
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;
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;
728
if (row < dev->mdev.height)
729
*ppbyte = dev->mdev.line_ptrs[row];
723
if (row < dev->mdev.height)
724
*ppbyte = dev->mdev.line_ptrs[row];
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));