1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
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.
14
/* $Id: gdevdsp.c 8250 2007-09-25 13:31:24Z giles $ */
17
* DLL based display device driver.
19
* by Russell Lang, Ghostgum Software Pty Ltd
21
* This device is intended to be used for displays when
22
* Ghostscript is loaded as a DLL/shared library/static library.
23
* It is intended to work for Windows, OS/2, Linux, Mac OS 9 and
26
* Before this device is opened, the address of a structure must
27
* be provided using gsapi_set_display_callback(minst, callback);
28
* This structure contains callback functions to notify the
29
* caller when the device is opened, closed, resized, showpage etc.
30
* The structure is defined in gdevdsp.h.
32
* Not all combinations of display formats have been tested.
33
* At the end of this file is some example code showing which
34
* formats have been tested.
40
#include "gsdevice.h" /* for gs_copydevice */
47
#include "gdevpccm.h" /* 4-bit PC color */
54
/* Initial values for width and height */
55
#define INITIAL_RESOLUTION 96
56
#define INITIAL_WIDTH ((INITIAL_RESOLUTION * 85 + 5) / 10)
57
#define INITIAL_HEIGHT ((INITIAL_RESOLUTION * 110 + 5) / 10)
59
/* Device procedures */
61
/* See gxdevice.h for the definitions of the procedures. */
62
static dev_proc_open_device(display_open);
63
static dev_proc_get_initial_matrix(display_get_initial_matrix);
64
static dev_proc_sync_output(display_sync_output);
65
static dev_proc_output_page(display_output_page);
66
static dev_proc_close_device(display_close);
68
static dev_proc_map_rgb_color(display_map_rgb_color_device4);
69
static dev_proc_map_color_rgb(display_map_color_rgb_device4);
70
static dev_proc_encode_color(display_encode_color_device8);
71
static dev_proc_decode_color(display_decode_color_device8);
72
static dev_proc_map_rgb_color(display_map_rgb_color_device16);
73
static dev_proc_map_color_rgb(display_map_color_rgb_device16);
74
static dev_proc_map_rgb_color(display_map_rgb_color_rgb);
75
static dev_proc_map_color_rgb(display_map_color_rgb_rgb);
76
static dev_proc_map_rgb_color(display_map_rgb_color_bgr24);
77
static dev_proc_map_color_rgb(display_map_color_rgb_bgr24);
79
static dev_proc_fill_rectangle(display_fill_rectangle);
80
static dev_proc_copy_mono(display_copy_mono);
81
static dev_proc_copy_color(display_copy_color);
82
static dev_proc_get_bits(display_get_bits);
83
static dev_proc_get_params(display_get_params);
84
static dev_proc_put_params(display_put_params);
85
static dev_proc_finish_copydevice(display_finish_copydevice);
87
static dev_proc_get_color_mapping_procs(display_separation_get_color_mapping_procs);
88
static dev_proc_get_color_comp_index(display_separation_get_color_comp_index);
89
static dev_proc_encode_color(display_separation_encode_color);
90
static dev_proc_decode_color(display_separation_decode_color);
91
static dev_proc_update_spot_equivalent_colors(display_update_spot_equivalent_colors);
92
static dev_proc_ret_devn_params(display_ret_devn_params);
95
static const gx_device_procs display_procs =
98
display_get_initial_matrix,
102
gx_default_w_b_map_rgb_color,
103
gx_default_w_b_map_color_rgb,
104
display_fill_rectangle,
105
NULL, /* tile rectangle */
108
NULL, /* draw line */
112
gx_default_cmyk_map_cmyk_color, /* map_cmyk_color */
113
gx_default_get_xfont_procs,
114
NULL, /* get_xfont_device */
115
NULL, /* map_rgb_alpha_color */
116
gx_page_device_get_page_device,
118
NULL, /* get_alpha_bits */
119
NULL, /* copy_alpha */
122
NULL, /* fill_path */
123
NULL, /* stroke_path */
124
NULL, /* fill_mask */
125
NULL, /* fill_trapezoid */
126
NULL, /* fill_parallelogram */
127
NULL, /* fill_triangle */
128
NULL, /* draw_thin_line */
129
NULL, /* begin_image */
130
NULL, /* image_data */
131
NULL, /* end_image */
132
NULL, /* strip_tile_rectangle */
133
NULL, /* strip_copy_rop */
134
NULL, /* get_clipping_box */
135
NULL, /* begin_typed_image */
136
NULL, /* get_bits_rectangle */
137
NULL, /* map_color_rgb_alpha */
138
NULL, /* create_compositor */
139
NULL, /* get_hardware_params */
140
NULL, /* text_begin */
141
display_finish_copydevice, /* finish_copydevice */
142
NULL, /* begin_transparency_group */
143
NULL, /* end_transparency_group */
144
NULL, /* begin_transparency_mask */
145
NULL, /* end_transparency_mask */
146
NULL, /* discard_transparency_layer */
147
NULL, /* get_color_mapping_procs */
148
NULL, /* get_color_comp_index */
149
NULL, /* encode_color */
150
NULL, /* decode_color */
151
NULL, /* pattern_manage */
152
NULL, /* fill_rectangle_hl_color */\
153
NULL, /* include_color_space */\
154
NULL, /* fill_linear_color_scanline */\
155
NULL, /* fill_linear_color_trapezoid */\
156
NULL, /* fill_linear_color_triangle */\
157
display_update_spot_equivalent_colors, /* update_spot_equivalent_colors */
158
display_ret_devn_params /* ret_devn_params */\
162
public_st_device_display();
165
ENUM_PTRS_WITH(display_enum_ptrs, gx_device_display *ddev)
168
return ENUM_OBJ(gx_device_enum_ptr((gx_device *)ddev->mdev));
172
else if (index-1 < ddev->devn_params.separations.num_separations)
173
ENUM_RETURN(ddev->devn_params.separations.names[index-1].data);
179
RELOC_PTRS_WITH(display_reloc_ptrs, gx_device_display *ddev)
181
ddev->mdev = (gx_device_memory *)
182
gx_device_reloc_ptr((gx_device *)ddev->mdev, gcst);
185
for (i = 0; i < ddev->devn_params.separations.num_separations; ++i) {
186
RELOC_PTR(gx_device_display, devn_params.separations.names[i].data);
192
const gx_device_display gs_display_device =
194
std_device_std_body_type(gx_device_display, &display_procs, "display",
196
INITIAL_WIDTH, INITIAL_HEIGHT,
197
INITIAL_RESOLUTION, INITIAL_RESOLUTION),
204
0, /* ulBitmapSize */
205
0, /* HWResolution_set */
207
{ /* devn_params specific parameters */
208
8, /* Bits per color - must match ncomp, depth, etc. */
209
DeviceCMYKComponents, /* Names of color model colorants */
210
4, /* Number of colorants for CMYK */
211
0, /* MaxSeparations has not been specified */
212
-1, /* PageSpotColors has not been specified */
213
{0}, /* SeparationNames */
214
{0}, /* SeparationOrder names */
215
{0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
217
{ true } /* equivalent CMYK colors for spot colors */
222
/* prototypes for internal procedures */
223
static int display_check_structure(gx_device_display *dev);
224
static void display_free_bitmap(gx_device_display * dev);
225
static int display_alloc_bitmap(gx_device_display *, gx_device *);
226
static int display_set_color_format(gx_device_display *dev, int nFormat);
227
static int display_set_separations(gx_device_display *dev);
228
static int display_raster(gx_device_display *dev);
230
/* Open the display driver. */
232
display_open(gx_device * dev)
234
gx_device_display *ddev = (gx_device_display *) dev;
237
/* Erase these, in case we are opening a copied device. */
239
ddev->pBitmap = NULL;
240
ddev->ulBitmapSize = 0;
242
/* Allow device to be opened "disabled" without a callback. */
243
/* The callback will be set later and the device re-opened. */
244
if (ddev->callback == NULL)
247
/* Make sure we have been passed a valid callback structure. */
248
if ((ccode = display_check_structure(ddev)) < 0)
252
if ((ccode = display_set_color_format(ddev, ddev->nFormat)) < 0)
255
/* Tell caller that the device is open. */
256
/* This is always the first callback */
257
ccode = (*(ddev->callback->display_open))(ddev->pHandle, dev);
261
/* Tell caller the proposed device parameters */
262
ccode = (*(ddev->callback->display_presize)) (ddev->pHandle, dev,
263
dev->width, dev->height, display_raster(ddev), ddev->nFormat);
265
(*(ddev->callback->display_close))(ddev->pHandle, dev);
269
/* allocate the image */
270
ccode = display_alloc_bitmap(ddev, dev);
272
(*(ddev->callback->display_close))(ddev->pHandle, dev);
276
/* Tell caller the device parameters */
277
ccode = (*(ddev->callback->display_size)) (ddev->pHandle, dev,
278
dev->width, dev->height, display_raster(ddev), ddev->nFormat,
281
display_free_bitmap(ddev);
282
(*(ddev->callback->display_close))(ddev->pHandle, dev);
290
display_get_initial_matrix(gx_device * dev, gs_matrix * pmat)
292
gx_device_display *ddev = (gx_device_display *) dev;
293
if ((ddev->nFormat & DISPLAY_FIRSTROW_MASK) == DISPLAY_TOPFIRST)
294
gx_default_get_initial_matrix(dev, pmat);
296
gx_upright_get_initial_matrix(dev, pmat); /* Windows / OS/2 */
299
/* Update the display. */
301
display_sync_output(gx_device * dev)
303
gx_device_display *ddev = (gx_device_display *) dev;
304
if (ddev->callback == NULL)
306
display_set_separations(ddev);
308
(*(ddev->callback->display_sync))(ddev->pHandle, dev);
312
/* Update the display, bring to foreground. */
313
/* If you want to pause on showpage, delay your return from callback */
315
display_output_page(gx_device * dev, int copies, int flush)
317
gx_device_display *ddev = (gx_device_display *) dev;
319
if (ddev->callback == NULL)
321
display_set_separations(ddev);
323
code = (*(ddev->callback->display_page))
324
(ddev->pHandle, dev, copies, flush);
327
code = gx_finish_output_page(dev, copies, flush);
331
/* Close the display driver */
333
display_close(gx_device * dev)
335
gx_device_display *ddev = (gx_device_display *) dev;
336
if (ddev->callback == NULL)
339
/* Tell caller that device is about to be closed. */
340
(*(ddev->callback->display_preclose))(ddev->pHandle, dev);
342
/* Release memory. */
343
display_free_bitmap(ddev);
345
/* Tell caller that device is closed. */
346
/* This is always the last callback */
347
(*(ddev->callback->display_close))(ddev->pHandle, dev);
353
* This routine will encode a 1 Black on white color.
355
static gx_color_index
356
gx_b_w_gray_encode(gx_device * dev, const gx_color_value cv[])
358
return 1 - (cv[0] >> (gx_color_value_bits - 1));
361
/* DISPLAY_COLORS_NATIVE, 4bit/pixel */
362
/* Map a r-g-b color to a color code */
363
static gx_color_index
364
display_map_rgb_color_device4(gx_device * dev, const gx_color_value cv[])
366
return pc_4bit_map_rgb_color(dev, cv);
369
/* Map a color code to r-g-b. */
371
display_map_color_rgb_device4(gx_device * dev, gx_color_index color,
372
gx_color_value prgb[3])
374
pc_4bit_map_color_rgb(dev, color, prgb);
378
/* DISPLAY_COLORS_NATIVE, 8bit/pixel */
379
/* Map a r-g-b-k color to a color code */
380
static gx_color_index
381
display_encode_color_device8(gx_device * dev, const gx_color_value cv[])
383
/* palette of 96 colors */
384
/* 0->63 = 00RRGGBB, 64->95 = 010YYYYY */
385
gx_color_value r = cv[0];
386
gx_color_value g = cv[1];
387
gx_color_value b = cv[2];
388
gx_color_value k = cv[3]; /* 0 = black */
389
if ((r == 0) && (g == 0) && (b == 0)) {
390
k = ((k >> (gx_color_value_bits - 6)) + 1) >> 1;
396
/* The RGB->RGBK color mapping shouldn't generate this. */
397
r = ((r+k) > gx_max_color_value) ? gx_max_color_value :
398
(gx_color_value)(r+k);
399
g = ((g+k) > gx_max_color_value) ? gx_max_color_value :
400
(gx_color_value)(g+k);
401
b = ((b+k) > gx_max_color_value) ? gx_max_color_value :
402
(gx_color_value)(b+k);
404
r = ((r >> (gx_color_value_bits - 3)) + 1) >> 1;
407
g = ((g >> (gx_color_value_bits - 3)) + 1) >> 1;
410
b = ((b >> (gx_color_value_bits - 3)) + 1) >> 1;
413
return (r << 4) + (g << 2) + b;
416
/* Map a color code to r-g-b-k. */
418
display_decode_color_device8(gx_device * dev, gx_color_index color,
419
gx_color_value prgb[4])
422
/* palette of 96 colors */
423
/* 0->63 = 00RRGGBB, 64->95 = 010YYYYY */
425
one = (gx_color_value) (gx_max_color_value / 3);
426
prgb[0] = (gx_color_value) (((color >> 4) & 3) * one);
427
prgb[1] = (gx_color_value) (((color >> 2) & 3) * one);
428
prgb[2] = (gx_color_value) (((color) & 3) * one);
431
else if (color < 96) {
432
one = (gx_color_value) (gx_max_color_value / 31);
433
prgb[0] = prgb[1] = prgb[2] = 0;
434
prgb[3] = (gx_color_value) ((color & 0x1f) * one);
437
prgb[0] = prgb[1] = prgb[2] = prgb[3] = 0;
443
/* DISPLAY_COLORS_NATIVE, 16bit/pixel */
444
/* Map a r-g-b color to a color code */
445
static gx_color_index
446
display_map_rgb_color_device16(gx_device * dev, const gx_color_value cv[])
448
gx_device_display *ddev = (gx_device_display *) dev;
449
gx_color_value r = cv[0];
450
gx_color_value g = cv[1];
451
gx_color_value b = cv[2];
452
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
453
if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555)
454
/* byte0=0RRRRRGG byte1=GGGBBBBB */
455
return ((r >> (gx_color_value_bits - 5)) << 10) +
456
((g >> (gx_color_value_bits - 5)) << 5) +
457
(b >> (gx_color_value_bits - 5));
459
/* byte0=RRRRRGGG byte1=GGGBBBBB */
460
return ((r >> (gx_color_value_bits - 5)) << 11) +
461
((g >> (gx_color_value_bits - 6)) << 5) +
462
(b >> (gx_color_value_bits - 5));
465
if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555)
466
/* byte0=GGGBBBBB byte1=0RRRRRGG */
467
return ((r >> (gx_color_value_bits - 5)) << 2) +
468
(((g >> (gx_color_value_bits - 5)) & 0x7) << 13) +
469
(((g >> (gx_color_value_bits - 5)) & 0x18) >> 3) +
470
((b >> (gx_color_value_bits - 5)) << 8);
472
/* byte0=GGGBBBBB byte1=RRRRRGGG */
473
return ((r >> (gx_color_value_bits - 5)) << 3) +
474
(((g >> (gx_color_value_bits - 6)) & 0x7) << 13) +
475
(((g >> (gx_color_value_bits - 6)) & 0x38) >> 3) +
476
((b >> (gx_color_value_bits - 5)) << 8);
481
/* Map a color code to r-g-b. */
483
display_map_color_rgb_device16(gx_device * dev, gx_color_index color,
484
gx_color_value prgb[3])
486
gx_device_display *ddev = (gx_device_display *) dev;
489
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
490
if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555) {
491
/* byte0=0RRRRRGG byte1=GGGBBBBB */
492
value = (ushort) (color >> 10);
493
prgb[0] = (gx_color_value)
494
(((value << 11) + (value << 6) + (value << 1) +
495
(value >> 4)) >> (16 - gx_color_value_bits));
496
value = (ushort) ((color >> 5) & 0x1f);
497
prgb[1] = (gx_color_value)
498
(((value << 11) + (value << 6) + (value << 1) +
499
(value >> 4)) >> (16 - gx_color_value_bits));
500
value = (ushort) (color & 0x1f);
501
prgb[2] = (gx_color_value)
502
(((value << 11) + (value << 6) + (value << 1) +
503
(value >> 4)) >> (16 - gx_color_value_bits));
506
/* byte0=RRRRRGGG byte1=GGGBBBBB */
507
value = (ushort) (color >> 11);
508
prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
509
(value >> 4)) >> (16 - gx_color_value_bits);
510
value = (ushort) ((color >> 5) & 0x3f);
511
prgb[1] = (gx_color_value)
512
((value << 10) + (value << 4) + (value >> 2))
513
>> (16 - gx_color_value_bits);
514
value = (ushort) (color & 0x1f);
515
prgb[2] = (gx_color_value)
516
((value << 11) + (value << 6) + (value << 1) +
517
(value >> 4)) >> (16 - gx_color_value_bits);
521
if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555) {
522
/* byte0=GGGBBBBB byte1=0RRRRRGG */
523
value = (ushort) ((color >> 2) & 0x1f);
524
prgb[0] = (gx_color_value)
525
((value << 11) + (value << 6) + (value << 1) +
526
(value >> 4)) >> (16 - gx_color_value_bits);
528
(((color << 3) & 0x18) + ((color >> 13) & 0x7));
529
prgb[1] = (gx_color_value)
530
((value << 11) + (value << 6) + (value << 1) +
531
(value >> 4)) >> (16 - gx_color_value_bits);
532
value = (ushort) ((color >> 8) & 0x1f);
533
prgb[2] = (gx_color_value)
534
((value << 11) + (value << 6) + (value << 1) +
535
(value >> 4)) >> (16 - gx_color_value_bits);
538
/* byte0=GGGBBBBB byte1=RRRRRGGG */
539
value = (ushort) ((color >> 3) & 0x1f);
540
prgb[0] = (gx_color_value)
541
(((value << 11) + (value << 6) + (value << 1) +
542
(value >> 4)) >> (16 - gx_color_value_bits));
544
(((color << 3) & 0x38) + ((color >> 13) & 0x7));
545
prgb[1] = (gx_color_value)
546
(((value << 10) + (value << 4) + (value >> 2))
547
>> (16 - gx_color_value_bits));
548
value = (ushort) ((color >> 8) & 0x1f);
549
prgb[2] = (gx_color_value)
550
(((value << 11) + (value << 6) + (value << 1) +
551
(value >> 4)) >> (16 - gx_color_value_bits));
558
/* Map a r-g-b color to a color code */
559
static gx_color_index
560
display_map_rgb_color_rgb(gx_device * dev, const gx_color_value cv[])
562
gx_device_display *ddev = (gx_device_display *) dev;
563
gx_color_value r = cv[0];
564
gx_color_value g = cv[1];
565
gx_color_value b = cv[2];
566
int drop = gx_color_value_bits - 8;
567
gx_color_value red, green, blue;
573
switch (ddev->nFormat & DISPLAY_ALPHA_MASK) {
574
case DISPLAY_ALPHA_NONE:
575
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
576
gx_color_value rgb[3];
577
rgb[0] = r; rgb[1] = g; rgb[2] = b;
578
return gx_default_rgb_map_rgb_color(dev, rgb); /* RGB */
581
return (blue<<16) + (green<<8) + red; /* BGR */
582
case DISPLAY_ALPHA_FIRST:
583
case DISPLAY_UNUSED_FIRST:
584
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
585
return ((gx_color_index)red<<16) + (green<<8) + blue; /* xRGB */
587
return ((gx_color_index)blue<<16) + (green<<8) + red; /* xBGR */
588
case DISPLAY_ALPHA_LAST:
589
case DISPLAY_UNUSED_LAST:
590
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
591
return ((gx_color_index)red<<24) + (green<<16) + (blue<<8); /* RGBx */
593
return ((gx_color_index)blue<<24) + (green<<16) + (red<<8); /* BGRx */
598
/* Map a color code to r-g-b. */
600
display_map_color_rgb_rgb(gx_device * dev, gx_color_index color,
601
gx_color_value prgb[3])
603
gx_device_display *ddev = (gx_device_display *) dev;
604
uint bits_per_color = 8;
607
color_mask = (1 << bits_per_color) - 1;
609
switch (ddev->nFormat & DISPLAY_ALPHA_MASK) {
610
case DISPLAY_ALPHA_NONE:
611
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
612
return gx_default_rgb_map_color_rgb(dev, color, prgb); /* RGB */
615
prgb[0] = (gx_color_value) (((color) & color_mask) *
616
(ulong) gx_max_color_value / color_mask);
617
prgb[1] = (gx_color_value)
618
(((color >> bits_per_color) & color_mask) *
619
(ulong) gx_max_color_value / color_mask);
620
prgb[2] = (gx_color_value)
621
(((color >> 2*bits_per_color) & color_mask) *
622
(ulong) gx_max_color_value / color_mask);
625
case DISPLAY_ALPHA_FIRST:
626
case DISPLAY_UNUSED_FIRST:
627
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
629
prgb[0] = (gx_color_value)
630
(((color >> 2*bits_per_color) & color_mask) *
631
(ulong) gx_max_color_value / color_mask);
632
prgb[1] = (gx_color_value)
633
(((color >> bits_per_color) & color_mask) *
634
(ulong) gx_max_color_value / color_mask);
635
prgb[2] = (gx_color_value) (((color) & color_mask) *
636
(ulong) gx_max_color_value / color_mask);
640
prgb[0] = (gx_color_value)
641
(((color) & color_mask) *
642
(ulong) gx_max_color_value / color_mask);
643
prgb[1] = (gx_color_value)
644
(((color >> bits_per_color) & color_mask) *
645
(ulong) gx_max_color_value / color_mask);
646
prgb[2] = (gx_color_value)
647
(((color >> 2*bits_per_color) & color_mask) *
648
(ulong) gx_max_color_value / color_mask);
651
case DISPLAY_ALPHA_LAST:
652
case DISPLAY_UNUSED_LAST:
653
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
655
prgb[0] = (gx_color_value)
656
(((color >> 3*bits_per_color) & color_mask) *
657
(ulong) gx_max_color_value / color_mask);
658
prgb[1] = (gx_color_value)
659
(((color >> 2*bits_per_color) & color_mask) *
660
(ulong) gx_max_color_value / color_mask);
661
prgb[2] = (gx_color_value)
662
(((color >> bits_per_color) & color_mask) *
663
(ulong) gx_max_color_value / color_mask);
667
prgb[0] = (gx_color_value)
668
(((color >> bits_per_color) & color_mask) *
669
(ulong) gx_max_color_value / color_mask);
670
prgb[1] = (gx_color_value)
671
(((color >> 2*bits_per_color) & color_mask) *
672
(ulong) gx_max_color_value / color_mask);
673
prgb[2] = (gx_color_value)
674
(((color >> 3*bits_per_color) & color_mask) *
675
(ulong) gx_max_color_value / color_mask);
681
/* Map a r-g-b color to a color code */
682
static gx_color_index
683
display_map_rgb_color_bgr24(gx_device * dev, const gx_color_value cv[])
685
gx_color_value r = cv[0];
686
gx_color_value g = cv[1];
687
gx_color_value b = cv[2];
688
return (gx_color_value_to_byte(b)<<16) +
689
(gx_color_value_to_byte(g)<<8) +
690
gx_color_value_to_byte(r);
693
/* Map a color code to r-g-b. */
695
display_map_color_rgb_bgr24(gx_device * dev, gx_color_index color,
696
gx_color_value prgb[3])
698
prgb[0] = gx_color_value_from_byte(color & 0xff);
699
prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
700
prgb[2] = gx_color_value_from_byte((color >> 16) & 0xff);
704
/* Fill a rectangle */
706
display_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
707
gx_color_index color)
709
gx_device_display *ddev = (gx_device_display *) dev;
710
if (ddev->callback == NULL)
712
dev_proc(ddev->mdev, fill_rectangle)((gx_device *)ddev->mdev,
714
if (ddev->callback->display_update)
715
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
719
/* Copy a monochrome bitmap */
721
display_copy_mono(gx_device * dev,
722
const byte * base, int sourcex, int raster, gx_bitmap_id id,
723
int x, int y, int w, int h,
724
gx_color_index zero, gx_color_index one)
726
gx_device_display *ddev = (gx_device_display *) dev;
727
if (ddev->callback == NULL)
729
dev_proc(ddev->mdev, copy_mono)((gx_device *)ddev->mdev,
730
base, sourcex, raster, id, x, y, w, h, zero, one);
731
if (ddev->callback->display_update)
732
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
736
/* Copy a color pixel map */
738
display_copy_color(gx_device * dev,
739
const byte * base, int sourcex, int raster, gx_bitmap_id id,
740
int x, int y, int w, int h)
742
gx_device_display *ddev = (gx_device_display *) dev;
743
if (ddev->callback == NULL)
745
dev_proc(ddev->mdev, copy_color)((gx_device *)ddev->mdev,
746
base, sourcex, raster, id, x, y, w, h);
747
if (ddev->callback->display_update)
748
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
753
display_get_bits(gx_device * dev, int y, byte * str, byte ** actual_data)
755
gx_device_display *ddev = (gx_device_display *) dev;
756
if (ddev->callback == NULL)
758
return dev_proc(ddev->mdev, get_bits)((gx_device *)ddev->mdev,
759
y, str, actual_data);
763
display_get_params(gx_device * dev, gs_param_list * plist)
765
gx_device_display *ddev = (gx_device_display *) dev;
767
gs_param_string dhandle;
774
idx = ((int)sizeof(size_t)) * 8 - 4;
778
dptr = (size_t)(ddev->pHandle);
780
val = (int)(dptr >> idx) & 0xf;
782
buf[i++] = '0' + val;
784
buf[i++] = 'a' - 10 + val;
789
param_string_from_transient_string(dhandle, buf);
791
code = gx_default_get_params(dev, plist);
793
(code = param_write_string(plist,
794
"DisplayHandle", &dhandle)) < 0 ||
795
(code = param_write_int(plist,
796
"DisplayFormat", &ddev->nFormat)) < 0 ||
797
(code = param_write_float(plist,
798
"DisplayResolution", &ddev->HWResolution[1])) < 0);
800
(ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION)
801
code = devn_get_params(dev, plist, &ddev->devn_params,
802
&ddev->equiv_cmyk_colors);
806
/* Put parameters. */
807
/* The parameters "DisplayHandle" and "DisplayFormat"
808
* can be changed when the device is closed, but not when open.
809
* The device width and height can be changed when open.
812
display_put_params(gx_device * dev, gs_param_list * plist)
814
gx_device_display *ddev = (gx_device_display *) dev;
816
bool is_open = dev->is_open;
817
gs_param_float_array hwra;
820
int old_width = dev->width;
821
int old_height = dev->height;
822
int old_format = ddev->nFormat;
823
void *old_handle = ddev->pHandle;
825
gs_devn_params *pdevn_params = &ddev->devn_params;
826
equivalent_cmyk_color_params *pequiv_colors = &ddev->equiv_cmyk_colors;
827
/* Save current data in case we have a problem */
828
gs_devn_params saved_devn_params = *pdevn_params;
829
equivalent_cmyk_color_params saved_equiv_colors = *pequiv_colors;
833
int found_string_handle = 0;
834
gs_param_string dh = { 0 };
836
/* Handle extra parameters */
838
switch (code = param_read_int(plist, "DisplayFormat", &format)) {
841
if (ddev->nFormat != format)
842
ecode = gs_error_rangecheck;
847
code = display_set_color_format(ddev, format);
856
cfe:param_signal_error(plist, "DisplayFormat", ecode);
861
/* 64-bit systems need to use DisplayHandle as a string */
862
switch (code = param_read_string(plist, "DisplayHandle", &dh)) {
864
found_string_handle = 1;
867
if ((code == gs_error_typecheck) && (sizeof(size_t) <= 4)) {
868
/* 32-bit systems can use the older long type */
869
switch (code = param_read_long(plist, "DisplayHandle",
870
(long *)(&handle))) {
873
if (ddev->pHandle != handle)
874
ecode = gs_error_rangecheck;
879
ddev->pHandle = handle;
885
hdle:param_signal_error(plist, "DisplayHandle", ecode);
892
param_signal_error(plist, "DisplayHandle", ecode);
898
if (found_string_handle) {
900
* Convert from a string to a pointer.
901
* It is assumed that size_t has the same size as a pointer.
902
* Allow formats (1234), (10#1234) or (16#04d2).
909
for (i=0; i<dh.size; i++) {
911
if ((val >= '0') && (val <= '9'))
913
else if ((val >= 'A') && (val <= 'F'))
914
val = val - 'A' + 10;
915
else if ((val >= 'a') && (val <= 'f'))
916
val = val - 'a' + 10;
917
else if (val == '#') {
920
if ((base != 10) && (base != 16)) {
921
code = gs_error_rangecheck;
927
code = gs_error_rangecheck;
932
ptr = ptr * 10 + val;
934
ptr = ptr * 16 + val;
936
code = gs_error_rangecheck;
942
if (ddev->pHandle != (void *)ptr)
943
code = gs_error_rangecheck;
946
ddev->pHandle = (void *)ptr;
950
param_signal_error(plist, "DisplayHandle", ecode);
955
* Set the initial display resolution.
956
* If HWResolution is explicitly set, e.g. using -rDPI on the
957
* command line, then use that. Otherwise, use DisplayResolution
958
* which is typically set by the client to the display
959
* logical resolution. Once either of these have been
960
* used, ignore all further DisplayResolution parameters.
962
if (param_read_float_array(plist, "HWResolution", &hwra) == 0)
963
ddev->HWResolution_set = 1;
965
switch (code = param_read_float(plist, "DisplayResolution", &dispres)) {
967
if (!ddev->HWResolution_set) {
968
gx_device_set_resolution(dev, dispres, dispres);
969
ddev->HWResolution_set = 1;
974
param_signal_error(plist, "DisplayResolution", ecode);
980
(ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION) {
981
/* Use utility routine to handle devn parameters */
982
ecode = devn_put_params(dev, plist, pdevn_params, pequiv_colors);
984
* Setting MaxSeparations changes color_info.depth in
985
* devn_put_params, but we always use 64bpp,
986
* so reset it to the the correct value.
988
dev->color_info.depth = arch_sizeof_color_index * 8;
992
/* Prevent gx_default_put_params from closing the device. */
993
dev->is_open = false;
994
ecode = gx_default_put_params(dev, plist);
995
dev->is_open = is_open;
998
/* If we have an error then restore original data. */
999
*pdevn_params = saved_devn_params;
1000
*pequiv_colors = saved_equiv_colors;
1001
if (format != old_format)
1002
display_set_color_format(ddev, old_format);
1003
ddev->pHandle = old_handle;
1004
dev->width = old_width;
1005
dev->height = old_height;
1010
if ( is_open && ddev->callback &&
1011
((old_width != dev->width) || (old_height != dev->height)) ) {
1012
/* We can resize this device while it is open, but we cannot
1013
* change the color format or handle.
1015
/* Tell caller we are about to change the device parameters */
1016
if ((*ddev->callback->display_presize)(ddev->pHandle, dev,
1017
dev->width, dev->height, display_raster(ddev),
1018
ddev->nFormat) < 0) {
1019
/* caller won't let us change the size */
1020
/* restore parameters then return an error */
1021
*pdevn_params = saved_devn_params;
1022
*pequiv_colors = saved_equiv_colors;
1023
display_set_color_format(ddev, old_format);
1024
ddev->nFormat = old_format;
1025
ddev->pHandle = old_handle;
1026
dev->width = old_width;
1027
dev->height = old_height;
1028
return_error(gs_error_rangecheck);
1031
display_free_bitmap(ddev);
1033
code = display_alloc_bitmap(ddev, dev);
1035
/* No bitmap, so tell the caller it is zero size */
1036
(*ddev->callback->display_size)(ddev->pHandle, dev,
1037
0, 0, 0, ddev->nFormat, NULL);
1041
/* tell caller about the new size */
1042
if ((*ddev->callback->display_size)(ddev->pHandle, dev,
1043
dev->width, dev->height, display_raster(ddev),
1044
ddev->nFormat, ddev->mdev->base) < 0)
1045
return_error(gs_error_rangecheck);
1051
/* Clean up the instance after making a copy. */
1053
display_finish_copydevice(gx_device *dev, const gx_device *from_dev)
1055
gx_device_display *ddev = (gx_device_display *) dev;
1057
/* Mark the new instance as closed. */
1058
ddev->is_open = false;
1060
/* Clear pointers */
1062
ddev->pBitmap = NULL;
1063
ddev->ulBitmapSize = 0;
1069
* The following procedures are used to map the standard color spaces into
1070
* the separation color components for the display device.
1073
display_separation_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[])
1076
(int *)(&((gx_device_display *) dev)->devn_params.separation_order_map);
1078
gray_cs_to_devn_cm(dev, map, gray, out);
1082
display_separation_rgb_cs_to_cmyk_cm(gx_device * dev,
1083
const gs_imager_state *pis, frac r, frac g, frac b, frac out[])
1086
(int *)(&((gx_device_display *) dev)->devn_params.separation_order_map);
1088
rgb_cs_to_devn_cm(dev, map, pis, r, g, b, out);
1092
display_separation_cmyk_cs_to_cmyk_cm(gx_device * dev,
1093
frac c, frac m, frac y, frac k, frac out[])
1096
(int *)(&((gx_device_display *) dev)->devn_params.separation_order_map);
1098
cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
1101
static const gx_cm_color_map_procs display_separation_cm_procs = {
1102
display_separation_gray_cs_to_cmyk_cm,
1103
display_separation_rgb_cs_to_cmyk_cm,
1104
display_separation_cmyk_cs_to_cmyk_cm
1107
static const gx_cm_color_map_procs *
1108
display_separation_get_color_mapping_procs(const gx_device * dev)
1110
return &display_separation_cm_procs;
1115
* Encode a list of colorant values into a gx_color_index_value.
1117
static gx_color_index
1118
display_separation_encode_color(gx_device *dev, const gx_color_value colors[])
1120
int bpc = ((gx_device_display *)dev)->devn_params.bitspercomponent;
1121
int drop = sizeof(gx_color_value) * 8 - bpc;
1122
gx_color_index color = 0;
1124
int ncomp = dev->color_info.num_components;
1126
for (; i<ncomp; i++) {
1128
color |= (colors[i] >> drop);
1130
if (bpc*ncomp < arch_sizeof_color_index * 8)
1131
color <<= (arch_sizeof_color_index * 8 - ncomp * bpc);
1132
return (color == gx_no_color_index ? color ^ 1 : color);
1136
* Decode a gx_color_index value back to a list of colorant values.
1139
display_separation_decode_color(gx_device * dev, gx_color_index color,
1140
gx_color_value * out)
1142
int bpc = ((gx_device_display *)dev)->devn_params.bitspercomponent;
1143
int drop = sizeof(gx_color_value) * 8 - bpc;
1144
int mask = (1 << bpc) - 1;
1146
int ncomp = dev->color_info.num_components;
1148
if (bpc*ncomp < arch_sizeof_color_index * 8)
1149
color >>= (arch_sizeof_color_index * 8 - ncomp * bpc);
1150
for (; i<ncomp; i++) {
1151
out[ncomp - i - 1] = (gx_color_value) ((color & mask) << drop);
1158
* Device proc for updating the equivalent CMYK color for spot colors.
1161
display_update_spot_equivalent_colors(gx_device * dev, const gs_state * pgs)
1163
gx_device_display * ddev = (gx_device_display *)dev;
1165
if ((ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION)
1166
update_spot_equivalent_cmyk_colors(dev, pgs,
1167
&ddev->devn_params, &ddev->equiv_cmyk_colors);
1172
* Device proc for returning a pointer to DeviceN parameter structure
1174
static gs_devn_params *
1175
display_ret_devn_params(gx_device * dev)
1177
gx_device_display * pdev = (gx_device_display *)dev;
1179
return &pdev->devn_params;
1183
* This routine will check to see if the color component name match those
1184
* that are available amoung the current device's color components.
1187
* dev - pointer to device data structure.
1188
* pname - pointer to name (zero termination not required)
1189
* nlength - length of the name
1191
* This routine returns a positive value (0 to n) which is the device colorant
1192
* number if the name is found. It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
1193
* the colorant is not being used due to a SeparationOrder device parameter.
1194
* It returns a negative value if not found.
1197
display_separation_get_color_comp_index(gx_device * dev,
1198
const char * pname, int name_size, int component_type)
1200
return devn_get_color_comp_index(dev,
1201
&(((gx_device_display *)dev)->devn_params),
1202
&(((gx_device_display *)dev)->equiv_cmyk_colors),
1203
pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
1207
/* ------ Internal routines ------ */
1209
/* Make sure we have been given a valid structure */
1210
/* Return 0 on success, gs_error_rangecheck on failure */
1211
static int display_check_structure(gx_device_display *ddev)
1213
if (ddev->callback == 0)
1214
return_error(gs_error_rangecheck);
1216
if (ddev->callback->size == sizeof(struct display_callback_v1_s)) {
1217
/* Original V1 structure */
1218
if (ddev->callback->version_major != DISPLAY_VERSION_MAJOR_V1)
1219
return_error(gs_error_rangecheck);
1221
/* complain if caller asks for newer features */
1222
if (ddev->callback->version_minor > DISPLAY_VERSION_MINOR_V1)
1223
return_error(gs_error_rangecheck);
1226
/* V2 structure with added display_separation callback */
1227
if (ddev->callback->size != sizeof(display_callback))
1228
return_error(gs_error_rangecheck);
1230
if (ddev->callback->version_major != DISPLAY_VERSION_MAJOR)
1231
return_error(gs_error_rangecheck);
1233
/* complain if caller asks for newer features */
1234
if (ddev->callback->version_minor > DISPLAY_VERSION_MINOR)
1235
return_error(gs_error_rangecheck);
1238
if ((ddev->callback->display_open == NULL) ||
1239
(ddev->callback->display_close == NULL) ||
1240
(ddev->callback->display_presize == NULL) ||
1241
(ddev->callback->display_size == NULL) ||
1242
(ddev->callback->display_sync == NULL) ||
1243
(ddev->callback->display_page == NULL))
1244
return_error(gs_error_rangecheck);
1246
/* Don't test display_update, display_memalloc or display_memfree
1247
* since these may be NULL if not provided.
1248
* Don't test display_separation, since this may be NULL if
1249
* separation format is not supported.
1256
display_free_bitmap(gx_device_display * ddev)
1258
if (ddev->callback == NULL)
1260
if (ddev->pBitmap) {
1261
if (ddev->callback->display_memalloc
1262
&& ddev->callback->display_memfree
1264
(*ddev->callback->display_memfree)(ddev->pHandle, ddev,
1268
gs_free_object(ddev->memory->non_gc_memory,
1269
ddev->pBitmap, "display_free_bitmap");
1271
ddev->pBitmap = NULL;
1273
ddev->mdev->base = NULL;
1276
dev_proc(ddev->mdev, close_device)((gx_device *)ddev->mdev);
1277
gx_device_retain((gx_device *)(ddev->mdev), false);
1282
/* calculate byte length of a row */
1284
display_raster(gx_device_display *dev)
1287
int bytewidth = dev->width * dev->color_info.depth/8;
1288
switch (dev->nFormat & DISPLAY_ROW_ALIGN_MASK) {
1289
case DISPLAY_ROW_ALIGN_4:
1292
case DISPLAY_ROW_ALIGN_8:
1295
case DISPLAY_ROW_ALIGN_16:
1298
case DISPLAY_ROW_ALIGN_32:
1301
case DISPLAY_ROW_ALIGN_64:
1305
if (align < ARCH_ALIGN_PTR_MOD)
1306
align = ARCH_ALIGN_PTR_MOD;
1308
bytewidth = (bytewidth + align) & (~align);
1312
/* Allocate the backing bitmap. */
1314
display_alloc_bitmap(gx_device_display * ddev, gx_device * param_dev)
1317
const gx_device_memory *mdproto;
1318
if (ddev->callback == NULL)
1321
/* free old bitmap (if any) */
1322
display_free_bitmap(ddev);
1324
/* allocate a memory device for rendering */
1325
mdproto = gdev_mem_device_for_bits(ddev->color_info.depth);
1327
return_error(gs_error_rangecheck);
1329
ddev->mdev = gs_alloc_struct(gs_memory_stable(ddev->memory),
1330
gx_device_memory, &st_device_memory, "display_memory_device");
1331
if (ddev->mdev == 0)
1332
return_error(gs_error_VMerror);
1334
gs_make_mem_device(ddev->mdev, mdproto, gs_memory_stable(ddev->memory),
1335
0, (gx_device *) NULL);
1336
check_device_separable((gx_device *)(ddev->mdev));
1337
gx_device_fill_in_procs((gx_device *)(ddev->mdev));
1338
/* Mark the memory device as retained. When the bitmap is closed,
1339
* we will clear this and the memory device will be then be freed.
1341
gx_device_retain((gx_device *)(ddev->mdev), true);
1343
/* Memory device width may be larger than device width
1344
* if row alignment is not 4.
1346
ddev->mdev->width = param_dev->width;
1347
ddev->mdev->width = display_raster(ddev) * 8 / ddev->color_info.depth;
1348
ddev->mdev->height = param_dev->height;
1350
/* Tell the memory device to allocate the line pointers separately
1351
* so we can place the bitmap in special memory.
1353
ddev->mdev->line_pointer_memory = ddev->mdev->memory;
1354
if (gdev_mem_bits_size(ddev->mdev, ddev->mdev->width, ddev->mdev->height,
1355
&(ddev->ulBitmapSize)) < 0)
1356
return_error(gs_error_VMerror);
1358
/* allocate bitmap using an allocator not subject to GC */
1359
if (ddev->callback->display_memalloc
1360
&& ddev->callback->display_memfree) {
1361
ddev->pBitmap = (*ddev->callback->display_memalloc)(ddev->pHandle,
1362
ddev, ddev->ulBitmapSize);
1365
ddev->pBitmap = gs_alloc_byte_array_immovable(ddev->memory->non_gc_memory,
1366
(uint)ddev->ulBitmapSize, 1, "display_alloc_bitmap");
1369
if (ddev->pBitmap == NULL) {
1370
ddev->mdev->width = 0;
1371
ddev->mdev->height = 0;
1372
return_error(gs_error_VMerror);
1375
ddev->mdev->base = (byte *) ddev->pBitmap;
1376
ddev->mdev->foreign_bits = true;
1378
ccode = dev_proc(ddev->mdev, open_device)((gx_device *)ddev->mdev);
1380
display_free_bitmap(ddev);
1382
/* erase bitmap - before display gets redrawn */
1385
gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1386
for (i=0; i<GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
1387
cv[i] = (ddev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1388
? gx_max_color_value : 0;
1389
dev_proc(ddev, fill_rectangle)((gx_device *)ddev,
1390
0, 0, ddev->width, ddev->height,
1391
ddev->procs.encode_color((gx_device *)ddev, cv));
1398
display_set_separations(gx_device_display *dev)
1400
if (((dev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION) &&
1401
(dev->callback->version_major > DISPLAY_VERSION_MAJOR_V1) &&
1402
(dev->callback->display_separation != NULL)) {
1403
/* Tell the client about the separation to composite mapping */
1405
int num_spot = dev->devn_params.separations.num_separations;
1406
int num_std_colorants = dev->devn_params.num_std_colorant_names;
1407
int num_comp = num_std_colorants + num_spot;
1408
int comp_map[GX_DEVICE_COLOR_MAX_COMPONENTS];
1412
unsigned int c, m, y, k;
1414
/* Map the separation numbers to component numbers */
1415
memset(comp_map, 0, sizeof(comp_map));
1416
for (sep_num = 0; sep_num < num_comp; sep_num++) {
1417
comp_num = dev->devn_params.separation_order_map[sep_num];
1418
if (comp_num >= 0 && comp_num < GX_DEVICE_COLOR_MAX_COMPONENTS)
1419
comp_map[comp_num] = sep_num;
1421
/* For each component, tell the client the separation mapping */
1422
for (comp_num = 0; comp_num < num_comp; comp_num++) {
1424
sep_num = comp_map[comp_num];
1425
/* Get the CMYK equivalent */
1426
if (sep_num < dev->devn_params.num_std_colorant_names) {
1428
strlen(dev->devn_params.std_colorant_names[sep_num]);
1429
if (sep_name_size > sizeof(name)-2)
1430
sep_name_size = sizeof(name)-1;
1431
memcpy(name, dev->devn_params.std_colorant_names[sep_num],
1433
name[sep_name_size] = '\0';
1435
case 0: c = 65535; break;
1436
case 1: m = 65535; break;
1437
case 2: y = 65535; break;
1438
case 3: k = 65535; break;
1442
sep_num -= dev->devn_params.num_std_colorant_names;
1444
dev->devn_params.separations.names[sep_num].size;
1445
if (sep_name_size > sizeof(name)-2)
1446
sep_name_size = sizeof(name)-1;
1447
memcpy(name, dev->devn_params.separations.names[sep_num].data,
1449
name[sep_name_size] = '\0';
1450
if (dev->equiv_cmyk_colors.color[sep_num].color_info_valid) {
1451
c = dev->equiv_cmyk_colors.color[sep_num].c
1453
m = dev->equiv_cmyk_colors.color[sep_num].m
1455
y = dev->equiv_cmyk_colors.color[sep_num].y
1457
k = dev->equiv_cmyk_colors.color[sep_num].k
1461
(*dev->callback->display_separation)(dev->pHandle, dev,
1463
(unsigned short)c, (unsigned short)m,
1464
(unsigned short)y, (unsigned short)k);
1470
typedef enum DISPLAY_MODEL_e {
1471
DISPLAY_MODEL_GRAY=0,
1472
DISPLAY_MODEL_RGB=1,
1473
DISPLAY_MODEL_RGBK=2,
1474
DISPLAY_MODEL_CMYK=3,
1479
* This is a utility routine to build the display device's color_info
1480
* structure (except for the anti alias info).
1483
set_color_info(gx_device_color_info * pdci, DISPLAY_MODEL model,
1484
int nc, int depth, int maxgray, int maxcolor)
1486
pdci->num_components = pdci->max_components = nc;
1487
pdci->depth = depth;
1488
pdci->gray_index = 0;
1489
pdci->max_gray = maxgray;
1490
pdci->max_color = maxcolor;
1491
pdci->dither_grays = maxgray + 1;
1492
pdci->dither_colors = maxcolor + 1;
1493
pdci->separable_and_linear = GX_CINFO_UNKNOWN_SEP_LIN;
1495
case DISPLAY_MODEL_GRAY:
1496
pdci->polarity = GX_CINFO_POLARITY_ADDITIVE;
1497
pdci->cm_name = "DeviceGray";
1498
pdci->gray_index = 0;
1500
case DISPLAY_MODEL_RGB:
1501
pdci->polarity = GX_CINFO_POLARITY_ADDITIVE;
1502
pdci->cm_name = "DeviceRGB";
1503
pdci->gray_index = GX_CINFO_COMP_NO_INDEX;
1505
case DISPLAY_MODEL_RGBK:
1506
pdci->polarity = GX_CINFO_POLARITY_ADDITIVE;
1507
pdci->cm_name = "DeviceRGBK";
1508
pdci->gray_index = 3;
1510
case DISPLAY_MODEL_CMYK:
1511
pdci->polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
1512
pdci->cm_name = "DeviceCMYK";
1513
pdci->gray_index = 3;
1516
case DISPLAY_MODEL_SEP:
1517
/* Anything else is separations */
1518
pdci->polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
1519
pdci->cm_name = "DeviceCMYK";
1520
pdci->gray_index = GX_CINFO_COMP_NO_INDEX; /* may not have K */
1526
* This is an utility routine to set up the color procs for the display
1527
* device. The display device can change its setup.
1530
set_color_procs(gx_device * pdev,
1531
dev_t_proc_encode_color((*encode_color), gx_device),
1532
dev_t_proc_decode_color((*decode_color), gx_device),
1533
dev_t_proc_get_color_mapping_procs((*get_color_mapping_procs), gx_device),
1534
dev_t_proc_get_color_comp_index((*get_color_comp_index), gx_device))
1536
#if 0 /* These procs are no longer used */
1537
pdev->procs.map_rgb_color = encode_color;
1538
pdev->procs.map_color_rgb = decode_color;
1540
pdev->procs.get_color_mapping_procs = get_color_mapping_procs;
1541
pdev->procs.get_color_comp_index = get_color_comp_index;
1542
pdev->procs.encode_color = encode_color;
1543
pdev->procs.decode_color = decode_color;
1547
* This is an utility routine to set up the color procs for the display
1548
* device. This routine is used when the display device is Gray.
1551
set_gray_color_procs(gx_device * pdev,
1552
dev_t_proc_encode_color((*encode_color), gx_device),
1553
dev_t_proc_decode_color((*decode_color), gx_device))
1555
set_color_procs(pdev, encode_color, decode_color,
1556
gx_default_DevGray_get_color_mapping_procs,
1557
gx_default_DevGray_get_color_comp_index);
1561
* This is an utility routine to set up the color procs for the display
1562
* device. This routine is used when the display device is RGB.
1565
set_rgb_color_procs(gx_device * pdev,
1566
dev_t_proc_encode_color((*encode_color), gx_device),
1567
dev_t_proc_decode_color((*decode_color), gx_device))
1569
set_color_procs(pdev, encode_color, decode_color,
1570
gx_default_DevRGB_get_color_mapping_procs,
1571
gx_default_DevRGB_get_color_comp_index);
1575
* This is an utility routine to set up the color procs for the display
1576
* device. This routine is used when the display device is RGBK.
1579
set_rgbk_color_procs(gx_device * pdev,
1580
dev_t_proc_encode_color((*encode_color), gx_device),
1581
dev_t_proc_decode_color((*decode_color), gx_device))
1583
set_color_procs(pdev, encode_color, decode_color,
1584
gx_default_DevRGBK_get_color_mapping_procs,
1585
gx_default_DevRGBK_get_color_comp_index);
1589
* This is an utility routine to set up the color procs for the display
1590
* device. This routine is used when the display device is CMYK.
1593
set_cmyk_color_procs(gx_device * pdev,
1594
dev_t_proc_encode_color((*encode_color), gx_device),
1595
dev_t_proc_decode_color((*decode_color), gx_device))
1597
set_color_procs(pdev, encode_color, decode_color,
1598
gx_default_DevCMYK_get_color_mapping_procs,
1599
gx_default_DevCMYK_get_color_comp_index);
1602
/* Set the color_info and mapping functions for this instance of the device */
1604
display_set_color_format(gx_device_display *ddev, int nFormat)
1606
gx_device * pdev = (gx_device *) ddev;
1607
gx_device_color_info dci = ddev->color_info;
1608
int bpc; /* bits per component */
1609
int bpp; /* bits per pixel */
1613
switch (nFormat & DISPLAY_DEPTH_MASK) {
1614
case DISPLAY_DEPTH_1:
1617
case DISPLAY_DEPTH_2:
1620
case DISPLAY_DEPTH_4:
1623
case DISPLAY_DEPTH_8:
1626
case DISPLAY_DEPTH_12:
1629
case DISPLAY_DEPTH_16:
1633
return_error(gs_error_rangecheck);
1635
maxvalue = (1 << bpc) - 1;
1636
ddev->devn_params.bitspercomponent = bpc;
1638
switch (ddev->nFormat & DISPLAY_ROW_ALIGN_MASK) {
1639
case DISPLAY_ROW_ALIGN_DEFAULT:
1640
align = ARCH_ALIGN_PTR_MOD;
1642
case DISPLAY_ROW_ALIGN_4:
1645
case DISPLAY_ROW_ALIGN_8:
1648
case DISPLAY_ROW_ALIGN_16:
1651
case DISPLAY_ROW_ALIGN_32:
1654
case DISPLAY_ROW_ALIGN_64:
1658
align = 0; /* not permitted */
1660
if (align < ARCH_ALIGN_PTR_MOD)
1661
return_error(gs_error_rangecheck);
1663
switch (ddev->nFormat & DISPLAY_ALPHA_MASK) {
1664
case DISPLAY_ALPHA_FIRST:
1665
case DISPLAY_ALPHA_LAST:
1666
/* Not implemented and unlikely to ever be implemented
1667
* because they would interact with linear_and_separable
1669
return_error(gs_error_rangecheck);
1672
switch (nFormat & DISPLAY_COLORS_MASK) {
1673
case DISPLAY_COLORS_NATIVE:
1674
switch (nFormat & DISPLAY_DEPTH_MASK) {
1675
case DISPLAY_DEPTH_1:
1676
/* 1bit/pixel, black is 1, white is 0 */
1677
set_color_info(&dci, DISPLAY_MODEL_GRAY, 1, 1, 1, 0);
1678
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
1679
set_gray_color_procs(pdev, gx_b_w_gray_encode,
1680
gx_default_b_w_map_color_rgb);
1682
case DISPLAY_DEPTH_4:
1683
/* 4bit/pixel VGA color */
1684
set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 4, 3, 2);
1685
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
1686
set_rgb_color_procs(pdev, display_map_rgb_color_device4,
1687
display_map_color_rgb_device4);
1689
case DISPLAY_DEPTH_8:
1690
/* 8bit/pixel 96 color palette */
1691
set_color_info(&dci, DISPLAY_MODEL_RGBK, 4, 8, 31, 3);
1692
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
1693
set_rgbk_color_procs(pdev, display_encode_color_device8,
1694
display_decode_color_device8);
1696
case DISPLAY_DEPTH_16:
1697
/* Windows 16-bit display */
1698
/* Is maxgray = maxcolor = 63 correct? */
1699
if ((ddev->nFormat & DISPLAY_555_MASK)
1700
== DISPLAY_NATIVE_555)
1701
set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 16, 31, 31);
1703
set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 16, 63, 63);
1704
set_rgb_color_procs(pdev, display_map_rgb_color_device16,
1705
display_map_color_rgb_device16);
1708
return_error(gs_error_rangecheck);
1710
dci.gray_index = GX_CINFO_COMP_NO_INDEX;
1712
case DISPLAY_COLORS_GRAY:
1713
set_color_info(&dci, DISPLAY_MODEL_GRAY, 1, bpc, maxvalue, 0);
1715
set_gray_color_procs(pdev, gx_default_gray_encode,
1716
gx_default_w_b_map_color_rgb);
1718
set_gray_color_procs(pdev, gx_default_gray_encode,
1719
gx_default_gray_map_color_rgb);
1721
case DISPLAY_COLORS_RGB:
1722
if ((nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)
1726
set_color_info(&dci, DISPLAY_MODEL_RGB, 3, bpp, maxvalue, maxvalue);
1727
if (((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) &&
1728
((nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)) {
1729
if ((nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
1730
set_rgb_color_procs(pdev, gx_default_rgb_map_rgb_color,
1731
gx_default_rgb_map_color_rgb);
1733
set_rgb_color_procs(pdev, display_map_rgb_color_bgr24,
1734
display_map_color_rgb_bgr24);
1737
/* slower flexible functions for alpha/unused component */
1738
set_rgb_color_procs(pdev, display_map_rgb_color_rgb,
1739
display_map_color_rgb_rgb);
1742
case DISPLAY_COLORS_CMYK:
1744
set_color_info(&dci, DISPLAY_MODEL_CMYK, 4, bpp, maxvalue, maxvalue);
1745
if ((nFormat & DISPLAY_ALPHA_MASK) != DISPLAY_ALPHA_NONE)
1746
return_error(gs_error_rangecheck);
1747
if ((nFormat & DISPLAY_ENDIAN_MASK) != DISPLAY_BIGENDIAN)
1748
return_error(gs_error_rangecheck);
1750
if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_1)
1751
set_cmyk_color_procs(pdev, cmyk_1bit_map_cmyk_color,
1752
cmyk_1bit_map_color_cmyk);
1753
else if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8)
1754
set_cmyk_color_procs(pdev, cmyk_8bit_map_cmyk_color,
1755
cmyk_8bit_map_color_cmyk);
1757
return_error(gs_error_rangecheck);
1759
case DISPLAY_COLORS_SEPARATION:
1760
if ((nFormat & DISPLAY_ENDIAN_MASK) != DISPLAY_BIGENDIAN)
1761
return_error(gs_error_rangecheck);
1762
bpp = arch_sizeof_color_index * 8;
1763
set_color_info(&dci, DISPLAY_MODEL_SEP, bpp/bpc, bpp,
1764
maxvalue, maxvalue);
1765
if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) {
1766
ddev->devn_params.bitspercomponent = bpc;
1767
set_color_procs(pdev,
1768
display_separation_encode_color,
1769
display_separation_decode_color,
1770
display_separation_get_color_mapping_procs,
1771
display_separation_get_color_comp_index);
1774
return_error(gs_error_rangecheck);
1777
return_error(gs_error_rangecheck);
1780
/* restore old anti_alias info */
1781
dci.anti_alias = ddev->color_info.anti_alias;
1782
ddev->color_info = dci;
1783
check_device_separable(pdev);
1784
switch (nFormat & DISPLAY_COLORS_MASK) {
1785
case DISPLAY_COLORS_NATIVE:
1786
ddev->color_info.gray_index = GX_CINFO_COMP_NO_INDEX;
1787
if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_1)
1788
ddev->color_info.gray_index = 0;
1789
else if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8)
1790
ddev->color_info.gray_index = 3;
1792
case DISPLAY_COLORS_RGB:
1793
ddev->color_info.gray_index = GX_CINFO_COMP_NO_INDEX;
1795
case DISPLAY_COLORS_GRAY:
1796
ddev->color_info.gray_index = 0;
1798
case DISPLAY_COLORS_CMYK:
1799
ddev->color_info.gray_index = 3;
1801
case DISPLAY_COLORS_SEPARATION:
1802
ddev->color_info.gray_index = GX_CINFO_COMP_NO_INDEX;
1805
ddev->nFormat = nFormat;
1810
/* ------ Begin Test Code ------ */
1812
/*********************************************************************
1813
typedef struct test_mode_s test_mode;
1814
struct test_mode_s {
1816
unsigned int format;
1819
test_mode test_modes[] = {
1820
{"1bit/pixel native, black is 1, Windows",
1821
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
1822
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
1823
{"4bit/pixel native, Windows VGA 16 color palette",
1824
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_4 |
1825
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
1826
{"8bit/pixel native, Windows SVGA 96 color palette",
1827
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1828
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
1829
{"16bit/pixel native, Windows BGR555",
1830
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_16 |
1831
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_NATIVE_555},
1832
{"16bit/pixel native, Windows BGR565",
1833
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_16 |
1834
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_NATIVE_565},
1835
{"1bit/pixel gray, black is 0, topfirst",
1836
DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
1837
DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
1838
{"4bit/pixel gray, bottom first",
1839
DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_4 |
1840
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
1841
{"8bit/pixel gray, bottom first",
1842
DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1843
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
1844
{"24bit/pixel color, bottom first, Windows BGR24",
1845
DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1846
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
1847
{"24bit/pixel color, bottom first, RGB24",
1848
DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1849
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
1850
{"24bit/pixel color, top first, GdkRgb RGB24",
1851
DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1852
DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
1853
{"32bit/pixel color, top first, Macintosh xRGB",
1854
DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST | DISPLAY_DEPTH_8 |
1855
DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
1856
{"32bit/pixel color, bottom first, xBGR",
1857
DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST | DISPLAY_DEPTH_8 |
1858
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
1859
{"32bit/pixel color, bottom first, Windows BGRx",
1860
DISPLAY_COLORS_RGB | DISPLAY_UNUSED_LAST | DISPLAY_DEPTH_8 |
1861
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
1862
{"32bit/pixel color, bottom first, RGBx",
1863
DISPLAY_COLORS_RGB | DISPLAY_UNUSED_LAST | DISPLAY_DEPTH_8 |
1864
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
1865
{"32bit/pixel CMYK, bottom first",
1866
DISPLAY_COLORS_CMYK | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1867
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
1868
{"64bit/pixel separations, bottom first",
1869
DISPLAY_COLORS_SEPARATIONS | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1870
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
1871
{"4bit/pixel CMYK, bottom first",
1872
DISPLAY_COLORS_CMYK | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
1873
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
1874
{"1bit/pixel native, black is 1, 8 byte alignment",
1875
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
1876
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_ROW_ALIGN_8},
1877
{"24bit/pixel color, bottom first, BGR24, 64 byte alignment",
1878
DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1879
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_ROW_ALIGN_64}
1886
sprintf(buf, "gs -dDisplayFormat=16#%x examples/colorcir.ps -c quit", test_modes[index].format);
1890
int main(int argc, char *argv[])
1895
if (strcmp(argv[1], "-t") == 0)
1898
fprintf(stdout, "To show modes: disp\nTo run test: disp -t\n");
1902
for (i=0; i < sizeof(test_modes)/sizeof(test_mode); i++) {
1903
fprintf(stdout, "16#%x or %d: %s\n", test_modes[i].format,
1904
test_modes[i].format, test_modes[i].name);
1910
*********************************************************************/
1912
/* ------ End Test Code ------ */