2 |
- |
1 |
/* Copyright (C) 2001-2005, Ghostgum Software Pty Ltd. All rights reserved.
|
|
|
2 |
|
|
|
3 |
This software is provided AS-IS with no warranty, either express or
|
|
|
4 |
implied.
|
|
|
5 |
|
|
|
6 |
This software is distributed under license and may not be copied,
|
|
|
7 |
modified or distributed except as expressly authorized under the terms
|
|
|
8 |
of the license contained in the file LICENSE in this distribution.
|
|
|
9 |
|
|
|
10 |
For more information about licensing, please refer to
|
|
|
11 |
http://www.ghostscript.com/licensing/. For information on
|
|
|
12 |
commercial licensing, go to http://www.artifex.com/licensing/ or
|
|
|
13 |
contact Artifex Software, Inc., 101 Lucas Valley Road #110,
|
|
|
14 |
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
|
|
|
15 |
*/
|
|
|
16 |
|
|
|
17 |
/* gdevdsp.c */
|
|
|
18 |
/* $Id: gdevdsp.c,v 1.35 2005/09/04 05:44:43 dan Exp $ */
|
|
|
19 |
|
|
|
20 |
/*
|
|
|
21 |
* DLL based display device driver.
|
|
|
22 |
*
|
|
|
23 |
* by Russell Lang, Ghostgum Software Pty Ltd
|
|
|
24 |
*
|
|
|
25 |
* This device is intended to be used for displays when
|
|
|
26 |
* Ghostscript is loaded as a DLL/shared library/static library.
|
|
|
27 |
* It is intended to work for Windows, OS/2, Linux, Mac OS 9 and
|
|
|
28 |
* hopefully others.
|
|
|
29 |
*
|
|
|
30 |
* Before this device is opened, the address of a structure must
|
|
|
31 |
* be provided using gsapi_set_display_callback(minst, callback);
|
|
|
32 |
* This structure contains callback functions to notify the
|
|
|
33 |
* caller when the device is opened, closed, resized, showpage etc.
|
|
|
34 |
* The structure is defined in gdevdsp.h.
|
|
|
35 |
*
|
|
|
36 |
* Not all combinations of display formats have been tested.
|
|
|
37 |
* At the end of this file is some example code showing which
|
|
|
38 |
* formats have been tested.
|
|
|
39 |
*/
|
|
|
40 |
|
|
|
41 |
#include "string_.h"
|
|
|
42 |
#include "gx.h"
|
|
|
43 |
#include "gserrors.h"
|
|
|
44 |
#include "gsdevice.h" /* for gs_copydevice */
|
|
|
45 |
#include "gxdevice.h"
|
|
|
46 |
|
|
|
47 |
#include "gp.h"
|
|
|
48 |
#include "gpcheck.h"
|
|
|
49 |
#include "gsparam.h"
|
|
|
50 |
|
|
|
51 |
#include "gdevpccm.h" /* 4-bit PC color */
|
|
|
52 |
#include "gxdevmem.h"
|
|
|
53 |
#include "gdevdevn.h"
|
|
|
54 |
#include "gsequivc.h"
|
|
|
55 |
#include "gdevdsp.h"
|
|
|
56 |
#include "gdevdsp2.h"
|
|
|
57 |
|
|
|
58 |
/* Initial values for width and height */
|
|
|
59 |
#define INITIAL_RESOLUTION 96
|
|
|
60 |
#define INITIAL_WIDTH ((INITIAL_RESOLUTION * 85 + 5) / 10)
|
|
|
61 |
#define INITIAL_HEIGHT ((INITIAL_RESOLUTION * 110 + 5) / 10)
|
|
|
62 |
|
|
|
63 |
/* Device procedures */
|
|
|
64 |
|
|
|
65 |
/* See gxdevice.h for the definitions of the procedures. */
|
|
|
66 |
private dev_proc_open_device(display_open);
|
|
|
67 |
private dev_proc_get_initial_matrix(display_get_initial_matrix);
|
|
|
68 |
private dev_proc_sync_output(display_sync_output);
|
|
|
69 |
private dev_proc_output_page(display_output_page);
|
|
|
70 |
private dev_proc_close_device(display_close);
|
|
|
71 |
|
|
|
72 |
private dev_proc_map_rgb_color(display_map_rgb_color_device4);
|
|
|
73 |
private dev_proc_map_color_rgb(display_map_color_rgb_device4);
|
|
|
74 |
private dev_proc_encode_color(display_encode_color_device8);
|
|
|
75 |
private dev_proc_decode_color(display_decode_color_device8);
|
|
|
76 |
private dev_proc_map_rgb_color(display_map_rgb_color_device16);
|
|
|
77 |
private dev_proc_map_color_rgb(display_map_color_rgb_device16);
|
|
|
78 |
private dev_proc_map_rgb_color(display_map_rgb_color_rgb);
|
|
|
79 |
private dev_proc_map_color_rgb(display_map_color_rgb_rgb);
|
|
|
80 |
private dev_proc_map_rgb_color(display_map_rgb_color_bgr24);
|
|
|
81 |
private dev_proc_map_color_rgb(display_map_color_rgb_bgr24);
|
|
|
82 |
|
|
|
83 |
private dev_proc_fill_rectangle(display_fill_rectangle);
|
|
|
84 |
private dev_proc_copy_mono(display_copy_mono);
|
|
|
85 |
private dev_proc_copy_color(display_copy_color);
|
|
|
86 |
private dev_proc_get_bits(display_get_bits);
|
|
|
87 |
private dev_proc_get_params(display_get_params);
|
|
|
88 |
private dev_proc_put_params(display_put_params);
|
|
|
89 |
private dev_proc_finish_copydevice(display_finish_copydevice);
|
|
|
90 |
|
|
|
91 |
private dev_proc_get_color_mapping_procs(display_separation_get_color_mapping_procs);
|
|
|
92 |
private dev_proc_get_color_comp_index(display_separation_get_color_comp_index);
|
|
|
93 |
private dev_proc_encode_color(display_separation_encode_color);
|
|
|
94 |
private dev_proc_decode_color(display_separation_decode_color);
|
|
|
95 |
private dev_proc_update_spot_equivalent_colors(display_update_spot_equivalent_colors);
|
|
|
96 |
|
|
|
97 |
|
|
|
98 |
private const gx_device_procs display_procs =
|
|
|
99 |
{
|
|
|
100 |
display_open,
|
|
|
101 |
display_get_initial_matrix,
|
|
|
102 |
display_sync_output,
|
|
|
103 |
display_output_page,
|
|
|
104 |
display_close,
|
|
|
105 |
gx_default_w_b_map_rgb_color,
|
|
|
106 |
gx_default_w_b_map_color_rgb,
|
|
|
107 |
display_fill_rectangle,
|
|
|
108 |
NULL, /* tile rectangle */
|
|
|
109 |
display_copy_mono,
|
|
|
110 |
display_copy_color,
|
|
|
111 |
NULL, /* draw line */
|
|
|
112 |
display_get_bits,
|
|
|
113 |
display_get_params,
|
|
|
114 |
display_put_params,
|
|
|
115 |
gx_default_cmyk_map_cmyk_color, /* map_cmyk_color */
|
|
|
116 |
gx_default_get_xfont_procs,
|
|
|
117 |
NULL, /* get_xfont_device */
|
|
|
118 |
NULL, /* map_rgb_alpha_color */
|
|
|
119 |
gx_page_device_get_page_device,
|
|
|
120 |
/* extra entries */
|
|
|
121 |
NULL, /* get_alpha_bits */
|
|
|
122 |
NULL, /* copy_alpha */
|
|
|
123 |
NULL, /* get_band */
|
|
|
124 |
NULL, /* copy_rop */
|
|
|
125 |
NULL, /* fill_path */
|
|
|
126 |
NULL, /* stroke_path */
|
|
|
127 |
NULL, /* fill_mask */
|
|
|
128 |
NULL, /* fill_trapezoid */
|
|
|
129 |
NULL, /* fill_parallelogram */
|
|
|
130 |
NULL, /* fill_triangle */
|
|
|
131 |
NULL, /* draw_thin_line */
|
|
|
132 |
NULL, /* begin_image */
|
|
|
133 |
NULL, /* image_data */
|
|
|
134 |
NULL, /* end_image */
|
|
|
135 |
NULL, /* strip_tile_rectangle */
|
|
|
136 |
NULL, /* strip_copy_rop */
|
|
|
137 |
NULL, /* get_clipping_box */
|
|
|
138 |
NULL, /* begin_typed_image */
|
|
|
139 |
NULL, /* get_bits_rectangle */
|
|
|
140 |
NULL, /* map_color_rgb_alpha */
|
|
|
141 |
NULL, /* create_compositor */
|
|
|
142 |
NULL, /* get_hardware_params */
|
|
|
143 |
NULL, /* text_begin */
|
|
|
144 |
display_finish_copydevice, /* finish_copydevice */
|
|
|
145 |
NULL, /* begin_transparency_group */
|
|
|
146 |
NULL, /* end_transparency_group */
|
|
|
147 |
NULL, /* begin_transparency_mask */
|
|
|
148 |
NULL, /* end_transparency_mask */
|
|
|
149 |
NULL, /* discard_transparency_layer */
|
|
|
150 |
NULL, /* get_color_mapping_procs */
|
|
|
151 |
NULL, /* get_color_comp_index */
|
|
|
152 |
NULL, /* encode_color */
|
|
|
153 |
NULL, /* decode_color */
|
|
|
154 |
NULL, /* pattern_manage */
|
|
|
155 |
NULL, /* fill_rectangle_hl_color */\
|
|
|
156 |
NULL, /* include_color_space */\
|
|
|
157 |
NULL, /* fill_linear_color_scanline */\
|
|
|
158 |
NULL, /* fill_linear_color_trapezoid */\
|
|
|
159 |
NULL, /* fill_linear_color_triangle */\
|
|
|
160 |
display_update_spot_equivalent_colors /* update_spot_equivalent_colors */
|
|
|
161 |
};
|
|
|
162 |
|
|
|
163 |
/* GC descriptor */
|
|
|
164 |
public_st_device_display();
|
|
|
165 |
|
|
|
166 |
private
|
|
|
167 |
ENUM_PTRS_WITH(display_enum_ptrs, gx_device_display *ddev)
|
|
|
168 |
if (index == 0) {
|
|
|
169 |
if (ddev->mdev) {
|
|
|
170 |
return ENUM_OBJ(gx_device_enum_ptr((gx_device *)ddev->mdev));
|
|
|
171 |
}
|
|
|
172 |
return 0;
|
|
|
173 |
}
|
|
|
174 |
else if (index-1 < ddev->devn_params.separations.num_separations)
|
|
|
175 |
ENUM_RETURN(ddev->devn_params.separations.names[index-1].data);
|
|
|
176 |
else
|
|
|
177 |
return 0;
|
|
|
178 |
ENUM_PTRS_END
|
|
|
179 |
|
|
|
180 |
private
|
|
|
181 |
RELOC_PTRS_WITH(display_reloc_ptrs, gx_device_display *ddev)
|
|
|
182 |
if (ddev->mdev) {
|
|
|
183 |
ddev->mdev = (gx_device_memory *)
|
|
|
184 |
gx_device_reloc_ptr((gx_device *)ddev->mdev, gcst);
|
|
|
185 |
}
|
|
|
186 |
{ int i;
|
|
|
187 |
for (i = 0; i < ddev->devn_params.separations.num_separations; ++i) {
|
|
|
188 |
RELOC_PTR(gx_device_display, devn_params.separations.names[i].data);
|
|
|
189 |
}
|
|
|
190 |
}
|
|
|
191 |
RELOC_PTRS_END
|
|
|
192 |
|
|
|
193 |
|
|
|
194 |
const gx_device_display gs_display_device =
|
|
|
195 |
{
|
|
|
196 |
std_device_std_body_type(gx_device_display, &display_procs, "display",
|
|
|
197 |
&st_device_display,
|
|
|
198 |
INITIAL_WIDTH, INITIAL_HEIGHT,
|
|
|
199 |
INITIAL_RESOLUTION, INITIAL_RESOLUTION),
|
|
|
200 |
{0}, /* std_procs */
|
|
|
201 |
NULL, /* mdev */
|
|
|
202 |
NULL, /* callback */
|
|
|
203 |
NULL, /* pHandle */
|
|
|
204 |
0, /* nFormat */
|
|
|
205 |
NULL, /* pBitmap */
|
|
|
206 |
0, /* ulBitmapSize */
|
|
|
207 |
0, /* HWResolution_set */
|
|
|
208 |
|
|
|
209 |
{ /* devn_params specific parameters */
|
|
|
210 |
8, /* Bits per color - must match ncomp, depth, etc. */
|
|
|
211 |
DeviceCMYKComponents, /* Names of color model colorants */
|
|
|
212 |
4, /* Number of colorants for CMYK */
|
|
|
213 |
0, /* MaxSeparations has not been specified */
|
|
|
214 |
{0}, /* SeparationNames */
|
|
|
215 |
{0}, /* SeparationOrder names */
|
|
|
216 |
{0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
|
|
|
217 |
},
|
|
|
218 |
{ true } /* equivalent CMYK colors for spot colors */
|
|
|
219 |
};
|
|
|
220 |
|
|
|
221 |
|
|
|
222 |
|
|
|
223 |
/* prototypes for internal procedures */
|
|
|
224 |
private int display_check_structure(gx_device_display *dev);
|
|
|
225 |
private void display_free_bitmap(gx_device_display * dev);
|
|
|
226 |
private int display_alloc_bitmap(gx_device_display *, gx_device *);
|
|
|
227 |
private int display_set_color_format(gx_device_display *dev, int nFormat);
|
|
|
228 |
private int display_set_separations(gx_device_display *dev);
|
|
|
229 |
private int display_raster(gx_device_display *dev);
|
|
|
230 |
|
|
|
231 |
/* Open the display driver. */
|
|
|
232 |
private int
|
|
|
233 |
display_open(gx_device * dev)
|
|
|
234 |
{
|
|
|
235 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
236 |
int ccode;
|
|
|
237 |
|
|
|
238 |
/* Erase these, in case we are opening a copied device. */
|
|
|
239 |
ddev->mdev = NULL;
|
|
|
240 |
ddev->pBitmap = NULL;
|
|
|
241 |
ddev->ulBitmapSize = 0;
|
|
|
242 |
|
|
|
243 |
/* Allow device to be opened "disabled" without a callback. */
|
|
|
244 |
/* The callback will be set later and the device re-opened. */
|
|
|
245 |
if (ddev->callback == NULL)
|
|
|
246 |
return 0;
|
|
|
247 |
|
|
|
248 |
/* Make sure we have been passed a valid callback structure. */
|
|
|
249 |
if ((ccode = display_check_structure(ddev)) < 0)
|
|
|
250 |
return_error(ccode);
|
|
|
251 |
|
|
|
252 |
/* set color info */
|
|
|
253 |
if ((ccode = display_set_color_format(ddev, ddev->nFormat)) < 0)
|
|
|
254 |
return_error(ccode);
|
|
|
255 |
|
|
|
256 |
/* Tell caller that the device is open. */
|
|
|
257 |
/* This is always the first callback */
|
|
|
258 |
ccode = (*(ddev->callback->display_open))(ddev->pHandle, dev);
|
|
|
259 |
if (ccode < 0)
|
|
|
260 |
return_error(ccode);
|
|
|
261 |
|
|
|
262 |
/* Tell caller the proposed device parameters */
|
|
|
263 |
ccode = (*(ddev->callback->display_presize)) (ddev->pHandle, dev,
|
|
|
264 |
dev->width, dev->height, display_raster(ddev), ddev->nFormat);
|
|
|
265 |
if (ccode < 0) {
|
|
|
266 |
(*(ddev->callback->display_close))(ddev->pHandle, dev);
|
|
|
267 |
return_error(ccode);
|
|
|
268 |
}
|
|
|
269 |
|
|
|
270 |
/* allocate the image */
|
|
|
271 |
ccode = display_alloc_bitmap(ddev, dev);
|
|
|
272 |
if (ccode < 0) {
|
|
|
273 |
(*(ddev->callback->display_close))(ddev->pHandle, dev);
|
|
|
274 |
return_error(ccode);
|
|
|
275 |
}
|
|
|
276 |
|
|
|
277 |
/* Tell caller the device parameters */
|
|
|
278 |
ccode = (*(ddev->callback->display_size)) (ddev->pHandle, dev,
|
|
|
279 |
dev->width, dev->height, display_raster(ddev), ddev->nFormat,
|
|
|
280 |
ddev->mdev->base);
|
|
|
281 |
if (ccode < 0) {
|
|
|
282 |
display_free_bitmap(ddev);
|
|
|
283 |
(*(ddev->callback->display_close))(ddev->pHandle, dev);
|
|
|
284 |
return_error(ccode);
|
|
|
285 |
}
|
|
|
286 |
|
|
|
287 |
return 0;
|
|
|
288 |
}
|
|
|
289 |
|
|
|
290 |
private void
|
|
|
291 |
display_get_initial_matrix(gx_device * dev, gs_matrix * pmat)
|
|
|
292 |
{
|
|
|
293 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
294 |
if ((ddev->nFormat & DISPLAY_FIRSTROW_MASK) == DISPLAY_TOPFIRST)
|
|
|
295 |
gx_default_get_initial_matrix(dev, pmat);
|
|
|
296 |
else
|
|
|
297 |
gx_upright_get_initial_matrix(dev, pmat); /* Windows / OS/2 */
|
|
|
298 |
}
|
|
|
299 |
|
|
|
300 |
/* Update the display. */
|
|
|
301 |
int
|
|
|
302 |
display_sync_output(gx_device * dev)
|
|
|
303 |
{
|
|
|
304 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
305 |
if (ddev->callback == NULL)
|
|
|
306 |
return 0;
|
|
|
307 |
display_set_separations(ddev);
|
|
|
308 |
|
|
|
309 |
(*(ddev->callback->display_sync))(ddev->pHandle, dev);
|
|
|
310 |
return (0);
|
|
|
311 |
}
|
|
|
312 |
|
|
|
313 |
/* Update the display, bring to foreground. */
|
|
|
314 |
/* If you want to pause on showpage, delay your return from callback */
|
|
|
315 |
int
|
|
|
316 |
display_output_page(gx_device * dev, int copies, int flush)
|
|
|
317 |
{
|
|
|
318 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
319 |
int code;
|
|
|
320 |
if (ddev->callback == NULL)
|
|
|
321 |
return 0;
|
|
|
322 |
display_set_separations(ddev);
|
|
|
323 |
|
|
|
324 |
code = (*(ddev->callback->display_page))
|
|
|
325 |
(ddev->pHandle, dev, copies, flush);
|
|
|
326 |
|
|
|
327 |
if (code >= 0)
|
|
|
328 |
code = gx_finish_output_page(dev, copies, flush);
|
|
|
329 |
return code;
|
|
|
330 |
}
|
|
|
331 |
|
|
|
332 |
/* Close the display driver */
|
|
|
333 |
private int
|
|
|
334 |
display_close(gx_device * dev)
|
|
|
335 |
{
|
|
|
336 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
337 |
if (ddev->callback == NULL)
|
|
|
338 |
return 0;
|
|
|
339 |
|
|
|
340 |
/* Tell caller that device is about to be closed. */
|
|
|
341 |
(*(ddev->callback->display_preclose))(ddev->pHandle, dev);
|
|
|
342 |
|
|
|
343 |
/* Release memory. */
|
|
|
344 |
display_free_bitmap(ddev);
|
|
|
345 |
|
|
|
346 |
/* Tell caller that device is closed. */
|
|
|
347 |
/* This is always the last callback */
|
|
|
348 |
(*(ddev->callback->display_close))(ddev->pHandle, dev);
|
|
|
349 |
|
|
|
350 |
return 0;
|
|
|
351 |
}
|
|
|
352 |
|
|
|
353 |
/*
|
|
|
354 |
* This routine will encode a 1 Black on white color.
|
|
|
355 |
*/
|
|
|
356 |
private gx_color_index
|
|
|
357 |
gx_b_w_gray_encode(gx_device * dev, const gx_color_value cv[])
|
|
|
358 |
{
|
|
|
359 |
return 1 - (cv[0] >> (gx_color_value_bits - 1));
|
|
|
360 |
}
|
|
|
361 |
|
|
|
362 |
/* DISPLAY_COLORS_NATIVE, 4bit/pixel */
|
|
|
363 |
/* Map a r-g-b color to a color code */
|
|
|
364 |
private gx_color_index
|
|
|
365 |
display_map_rgb_color_device4(gx_device * dev, const gx_color_value cv[])
|
|
|
366 |
{
|
|
|
367 |
return pc_4bit_map_rgb_color(dev, cv);
|
|
|
368 |
}
|
|
|
369 |
|
|
|
370 |
/* Map a color code to r-g-b. */
|
|
|
371 |
private int
|
|
|
372 |
display_map_color_rgb_device4(gx_device * dev, gx_color_index color,
|
|
|
373 |
gx_color_value prgb[3])
|
|
|
374 |
{
|
|
|
375 |
pc_4bit_map_color_rgb(dev, color, prgb);
|
|
|
376 |
return 0;
|
|
|
377 |
}
|
|
|
378 |
|
|
|
379 |
/* DISPLAY_COLORS_NATIVE, 8bit/pixel */
|
|
|
380 |
/* Map a r-g-b-k color to a color code */
|
|
|
381 |
private gx_color_index
|
|
|
382 |
display_encode_color_device8(gx_device * dev, const gx_color_value cv[])
|
|
|
383 |
{
|
|
|
384 |
/* palette of 96 colors */
|
|
|
385 |
/* 0->63 = 00RRGGBB, 64->95 = 010YYYYY */
|
|
|
386 |
gx_color_value r = cv[0];
|
|
|
387 |
gx_color_value g = cv[1];
|
|
|
388 |
gx_color_value b = cv[2];
|
|
|
389 |
gx_color_value k = cv[3]; /* 0 = black */
|
|
|
390 |
if ((r == 0) && (g == 0) && (b == 0)) {
|
|
|
391 |
k = ((k >> (gx_color_value_bits - 6)) + 1) >> 1;
|
|
|
392 |
if (k > 0x1f)
|
|
|
393 |
k = 0x1f;
|
|
|
394 |
return (k + 0x40);
|
|
|
395 |
}
|
|
|
396 |
if (k > 0) {
|
|
|
397 |
/* The RGB->RGBK color mapping shouldn't generate this. */
|
|
|
398 |
r = ((r+k) > gx_max_color_value) ? gx_max_color_value :
|
|
|
399 |
(gx_color_value)(r+k);
|
|
|
400 |
g = ((g+k) > gx_max_color_value) ? gx_max_color_value :
|
|
|
401 |
(gx_color_value)(g+k);
|
|
|
402 |
b = ((b+k) > gx_max_color_value) ? gx_max_color_value :
|
|
|
403 |
(gx_color_value)(b+k);
|
|
|
404 |
}
|
|
|
405 |
r = ((r >> (gx_color_value_bits - 3)) + 1) >> 1;
|
|
|
406 |
if (r > 0x3)
|
|
|
407 |
r = 0x3;
|
|
|
408 |
g = ((g >> (gx_color_value_bits - 3)) + 1) >> 1;
|
|
|
409 |
if (g > 0x3)
|
|
|
410 |
g = 0x3;
|
|
|
411 |
b = ((b >> (gx_color_value_bits - 3)) + 1) >> 1;
|
|
|
412 |
if (b > 0x3)
|
|
|
413 |
b = 0x3;
|
|
|
414 |
return (r << 4) + (g << 2) + b;
|
|
|
415 |
}
|
|
|
416 |
|
|
|
417 |
/* Map a color code to r-g-b-k. */
|
|
|
418 |
private int
|
|
|
419 |
display_decode_color_device8(gx_device * dev, gx_color_index color,
|
|
|
420 |
gx_color_value prgb[4])
|
|
|
421 |
{
|
|
|
422 |
gx_color_value one;
|
|
|
423 |
/* palette of 96 colors */
|
|
|
424 |
/* 0->63 = 00RRGGBB, 64->95 = 010YYYYY */
|
|
|
425 |
if (color < 64) {
|
|
|
426 |
one = (gx_color_value) (gx_max_color_value / 3);
|
|
|
427 |
prgb[0] = (gx_color_value) (((color >> 4) & 3) * one);
|
|
|
428 |
prgb[1] = (gx_color_value) (((color >> 2) & 3) * one);
|
|
|
429 |
prgb[2] = (gx_color_value) (((color) & 3) * one);
|
|
|
430 |
prgb[3] = 0;
|
|
|
431 |
}
|
|
|
432 |
else if (color < 96) {
|
|
|
433 |
one = (gx_color_value) (gx_max_color_value / 31);
|
|
|
434 |
prgb[0] = prgb[1] = prgb[2] = 0;
|
|
|
435 |
prgb[3] = (gx_color_value) ((color & 0x1f) * one);
|
|
|
436 |
}
|
|
|
437 |
else {
|
|
|
438 |
prgb[0] = prgb[1] = prgb[2] = prgb[3] = 0;
|
|
|
439 |
}
|
|
|
440 |
return 0;
|
|
|
441 |
}
|
|
|
442 |
|
|
|
443 |
|
|
|
444 |
/* DISPLAY_COLORS_NATIVE, 16bit/pixel */
|
|
|
445 |
/* Map a r-g-b color to a color code */
|
|
|
446 |
private gx_color_index
|
|
|
447 |
display_map_rgb_color_device16(gx_device * dev, const gx_color_value cv[])
|
|
|
448 |
{
|
|
|
449 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
450 |
gx_color_value r = cv[0];
|
|
|
451 |
gx_color_value g = cv[1];
|
|
|
452 |
gx_color_value b = cv[2];
|
|
|
453 |
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
|
|
|
454 |
if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555)
|
|
|
455 |
/* byte0=0RRRRRGG byte1=GGGBBBBB */
|
|
|
456 |
return ((r >> (gx_color_value_bits - 5)) << 10) +
|
|
|
457 |
((g >> (gx_color_value_bits - 5)) << 5) +
|
|
|
458 |
(b >> (gx_color_value_bits - 5));
|
|
|
459 |
else
|
|
|
460 |
/* byte0=RRRRRGGG byte1=GGGBBBBB */
|
|
|
461 |
return ((r >> (gx_color_value_bits - 5)) << 11) +
|
|
|
462 |
((g >> (gx_color_value_bits - 6)) << 5) +
|
|
|
463 |
(b >> (gx_color_value_bits - 5));
|
|
|
464 |
}
|
|
|
465 |
|
|
|
466 |
if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555)
|
|
|
467 |
/* byte0=GGGBBBBB byte1=0RRRRRGG */
|
|
|
468 |
return ((r >> (gx_color_value_bits - 5)) << 2) +
|
|
|
469 |
(((g >> (gx_color_value_bits - 5)) & 0x7) << 13) +
|
|
|
470 |
(((g >> (gx_color_value_bits - 5)) & 0x18) >> 3) +
|
|
|
471 |
((b >> (gx_color_value_bits - 5)) << 8);
|
|
|
472 |
|
|
|
473 |
/* byte0=GGGBBBBB byte1=RRRRRGGG */
|
|
|
474 |
return ((r >> (gx_color_value_bits - 5)) << 3) +
|
|
|
475 |
(((g >> (gx_color_value_bits - 6)) & 0x7) << 13) +
|
|
|
476 |
(((g >> (gx_color_value_bits - 6)) & 0x38) >> 3) +
|
|
|
477 |
((b >> (gx_color_value_bits - 5)) << 8);
|
|
|
478 |
}
|
|
|
479 |
|
|
|
480 |
|
|
|
481 |
|
|
|
482 |
/* Map a color code to r-g-b. */
|
|
|
483 |
private int
|
|
|
484 |
display_map_color_rgb_device16(gx_device * dev, gx_color_index color,
|
|
|
485 |
gx_color_value prgb[3])
|
|
|
486 |
{
|
|
|
487 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
488 |
ushort value;
|
|
|
489 |
|
|
|
490 |
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
|
|
|
491 |
if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555) {
|
|
|
492 |
/* byte0=0RRRRRGG byte1=GGGBBBBB */
|
|
|
493 |
value = (ushort) (color >> 10);
|
|
|
494 |
prgb[0] = (gx_color_value)
|
|
|
495 |
(((value << 11) + (value << 6) + (value << 1) +
|
|
|
496 |
(value >> 4)) >> (16 - gx_color_value_bits));
|
|
|
497 |
value = (ushort) ((color >> 5) & 0x1f);
|
|
|
498 |
prgb[1] = (gx_color_value)
|
|
|
499 |
(((value << 11) + (value << 6) + (value << 1) +
|
|
|
500 |
(value >> 4)) >> (16 - gx_color_value_bits));
|
|
|
501 |
value = (ushort) (color & 0x1f);
|
|
|
502 |
prgb[2] = (gx_color_value)
|
|
|
503 |
(((value << 11) + (value << 6) + (value << 1) +
|
|
|
504 |
(value >> 4)) >> (16 - gx_color_value_bits));
|
|
|
505 |
}
|
|
|
506 |
else {
|
|
|
507 |
/* byte0=RRRRRGGG byte1=GGGBBBBB */
|
|
|
508 |
value = (ushort) (color >> 11);
|
|
|
509 |
prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
|
|
|
510 |
(value >> 4)) >> (16 - gx_color_value_bits);
|
|
|
511 |
value = (ushort) ((color >> 5) & 0x3f);
|
|
|
512 |
prgb[1] = (gx_color_value)
|
|
|
513 |
((value << 10) + (value << 4) + (value >> 2))
|
|
|
514 |
>> (16 - gx_color_value_bits);
|
|
|
515 |
value = (ushort) (color & 0x1f);
|
|
|
516 |
prgb[2] = (gx_color_value)
|
|
|
517 |
((value << 11) + (value << 6) + (value << 1) +
|
|
|
518 |
(value >> 4)) >> (16 - gx_color_value_bits);
|
|
|
519 |
}
|
|
|
520 |
}
|
|
|
521 |
else {
|
|
|
522 |
if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555) {
|
|
|
523 |
/* byte0=GGGBBBBB byte1=0RRRRRGG */
|
|
|
524 |
value = (ushort) ((color >> 2) & 0x1f);
|
|
|
525 |
prgb[0] = (gx_color_value)
|
|
|
526 |
((value << 11) + (value << 6) + (value << 1) +
|
|
|
527 |
(value >> 4)) >> (16 - gx_color_value_bits);
|
|
|
528 |
value = (ushort)
|
|
|
529 |
(((color << 3) & 0x18) + ((color >> 13) & 0x7));
|
|
|
530 |
prgb[1] = (gx_color_value)
|
|
|
531 |
((value << 11) + (value << 6) + (value << 1) +
|
|
|
532 |
(value >> 4)) >> (16 - gx_color_value_bits);
|
|
|
533 |
value = (ushort) ((color >> 8) & 0x1f);
|
|
|
534 |
prgb[2] = (gx_color_value)
|
|
|
535 |
((value << 11) + (value << 6) + (value << 1) +
|
|
|
536 |
(value >> 4)) >> (16 - gx_color_value_bits);
|
|
|
537 |
}
|
|
|
538 |
else {
|
|
|
539 |
/* byte0=GGGBBBBB byte1=RRRRRGGG */
|
|
|
540 |
value = (ushort) ((color >> 3) & 0x1f);
|
|
|
541 |
prgb[0] = (gx_color_value)
|
|
|
542 |
(((value << 11) + (value << 6) + (value << 1) +
|
|
|
543 |
(value >> 4)) >> (16 - gx_color_value_bits));
|
|
|
544 |
value = (ushort)
|
|
|
545 |
(((color << 3) & 0x38) + ((color >> 13) & 0x7));
|
|
|
546 |
prgb[1] = (gx_color_value)
|
|
|
547 |
(((value << 10) + (value << 4) + (value >> 2))
|
|
|
548 |
>> (16 - gx_color_value_bits));
|
|
|
549 |
value = (ushort) ((color >> 8) & 0x1f);
|
|
|
550 |
prgb[2] = (gx_color_value)
|
|
|
551 |
(((value << 11) + (value << 6) + (value << 1) +
|
|
|
552 |
(value >> 4)) >> (16 - gx_color_value_bits));
|
|
|
553 |
}
|
|
|
554 |
}
|
|
|
555 |
return 0;
|
|
|
556 |
}
|
|
|
557 |
|
|
|
558 |
|
|
|
559 |
/* Map a r-g-b color to a color code */
|
|
|
560 |
private gx_color_index
|
|
|
561 |
display_map_rgb_color_rgb(gx_device * dev, const gx_color_value cv[])
|
|
|
562 |
{
|
|
|
563 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
564 |
gx_color_value r = cv[0];
|
|
|
565 |
gx_color_value g = cv[1];
|
|
|
566 |
gx_color_value b = cv[2];
|
|
|
567 |
int drop = gx_color_value_bits - 8;
|
|
|
568 |
gx_color_value red, green, blue;
|
|
|
569 |
|
|
|
570 |
red = r >> drop;
|
|
|
571 |
green = g >> drop;
|
|
|
572 |
blue = b >> drop;
|
|
|
573 |
|
|
|
574 |
switch (ddev->nFormat & DISPLAY_ALPHA_MASK) {
|
|
|
575 |
case DISPLAY_ALPHA_NONE:
|
|
|
576 |
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
|
|
|
577 |
gx_color_value rgb[3];
|
|
|
578 |
rgb[0] = r; rgb[1] = g; rgb[2] = b;
|
|
|
579 |
return gx_default_rgb_map_rgb_color(dev, rgb); /* RGB */
|
|
|
580 |
}
|
|
|
581 |
else
|
|
|
582 |
return (blue<<16) + (green<<8) + red; /* BGR */
|
|
|
583 |
case DISPLAY_ALPHA_FIRST:
|
|
|
584 |
case DISPLAY_UNUSED_FIRST:
|
|
|
585 |
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
|
|
|
586 |
return ((gx_color_index)red<<16) + (green<<8) + blue; /* xRGB */
|
|
|
587 |
else
|
|
|
588 |
return ((gx_color_index)blue<<16) + (green<<8) + red; /* xBGR */
|
|
|
589 |
case DISPLAY_ALPHA_LAST:
|
|
|
590 |
case DISPLAY_UNUSED_LAST:
|
|
|
591 |
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
|
|
|
592 |
return ((gx_color_index)red<<24) + (green<<16) + (blue<<8); /* RGBx */
|
|
|
593 |
else
|
|
|
594 |
return ((gx_color_index)blue<<24) + (green<<16) + (red<<8); /* BGRx */
|
|
|
595 |
}
|
|
|
596 |
return 0;
|
|
|
597 |
}
|
|
|
598 |
|
|
|
599 |
/* Map a color code to r-g-b. */
|
|
|
600 |
private int
|
|
|
601 |
display_map_color_rgb_rgb(gx_device * dev, gx_color_index color,
|
|
|
602 |
gx_color_value prgb[3])
|
|
|
603 |
{
|
|
|
604 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
605 |
uint bits_per_color = 8;
|
|
|
606 |
uint color_mask;
|
|
|
607 |
|
|
|
608 |
color_mask = (1 << bits_per_color) - 1;
|
|
|
609 |
|
|
|
610 |
switch (ddev->nFormat & DISPLAY_ALPHA_MASK) {
|
|
|
611 |
case DISPLAY_ALPHA_NONE:
|
|
|
612 |
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
|
|
|
613 |
return gx_default_rgb_map_color_rgb(dev, color, prgb); /* RGB */
|
|
|
614 |
else {
|
|
|
615 |
/* BGR */
|
|
|
616 |
prgb[0] = (gx_color_value) (((color) & color_mask) *
|
|
|
617 |
(ulong) gx_max_color_value / color_mask);
|
|
|
618 |
prgb[1] = (gx_color_value)
|
|
|
619 |
(((color >> bits_per_color) & color_mask) *
|
|
|
620 |
(ulong) gx_max_color_value / color_mask);
|
|
|
621 |
prgb[2] = (gx_color_value)
|
|
|
622 |
(((color >> 2*bits_per_color) & color_mask) *
|
|
|
623 |
(ulong) gx_max_color_value / color_mask);
|
|
|
624 |
}
|
|
|
625 |
break;
|
|
|
626 |
case DISPLAY_ALPHA_FIRST:
|
|
|
627 |
case DISPLAY_UNUSED_FIRST:
|
|
|
628 |
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
|
|
|
629 |
/* xRGB */
|
|
|
630 |
prgb[0] = (gx_color_value)
|
|
|
631 |
(((color >> 2*bits_per_color) & color_mask) *
|
|
|
632 |
(ulong) gx_max_color_value / color_mask);
|
|
|
633 |
prgb[1] = (gx_color_value)
|
|
|
634 |
(((color >> bits_per_color) & color_mask) *
|
|
|
635 |
(ulong) gx_max_color_value / color_mask);
|
|
|
636 |
prgb[2] = (gx_color_value) (((color) & color_mask) *
|
|
|
637 |
(ulong) gx_max_color_value / color_mask);
|
|
|
638 |
}
|
|
|
639 |
else {
|
|
|
640 |
/* xBGR */
|
|
|
641 |
prgb[0] = (gx_color_value)
|
|
|
642 |
(((color) & color_mask) *
|
|
|
643 |
(ulong) gx_max_color_value / color_mask);
|
|
|
644 |
prgb[1] = (gx_color_value)
|
|
|
645 |
(((color >> bits_per_color) & color_mask) *
|
|
|
646 |
(ulong) gx_max_color_value / color_mask);
|
|
|
647 |
prgb[2] = (gx_color_value)
|
|
|
648 |
(((color >> 2*bits_per_color) & color_mask) *
|
|
|
649 |
(ulong) gx_max_color_value / color_mask);
|
|
|
650 |
}
|
|
|
651 |
break;
|
|
|
652 |
case DISPLAY_ALPHA_LAST:
|
|
|
653 |
case DISPLAY_UNUSED_LAST:
|
|
|
654 |
if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
|
|
|
655 |
/* RGBx */
|
|
|
656 |
prgb[0] = (gx_color_value)
|
|
|
657 |
(((color >> 3*bits_per_color) & color_mask) *
|
|
|
658 |
(ulong) gx_max_color_value / color_mask);
|
|
|
659 |
prgb[1] = (gx_color_value)
|
|
|
660 |
(((color >> 2*bits_per_color) & color_mask) *
|
|
|
661 |
(ulong) gx_max_color_value / color_mask);
|
|
|
662 |
prgb[2] = (gx_color_value)
|
|
|
663 |
(((color >> bits_per_color) & color_mask) *
|
|
|
664 |
(ulong) gx_max_color_value / color_mask);
|
|
|
665 |
}
|
|
|
666 |
else {
|
|
|
667 |
/* BGRx */
|
|
|
668 |
prgb[0] = (gx_color_value)
|
|
|
669 |
(((color >> bits_per_color) & color_mask) *
|
|
|
670 |
(ulong) gx_max_color_value / color_mask);
|
|
|
671 |
prgb[1] = (gx_color_value)
|
|
|
672 |
(((color >> 2*bits_per_color) & color_mask) *
|
|
|
673 |
(ulong) gx_max_color_value / color_mask);
|
|
|
674 |
prgb[2] = (gx_color_value)
|
|
|
675 |
(((color >> 3*bits_per_color) & color_mask) *
|
|
|
676 |
(ulong) gx_max_color_value / color_mask);
|
|
|
677 |
}
|
|
|
678 |
}
|
|
|
679 |
return 0;
|
|
|
680 |
}
|
|
|
681 |
|
|
|
682 |
/* Map a r-g-b color to a color code */
|
|
|
683 |
private gx_color_index
|
|
|
684 |
display_map_rgb_color_bgr24(gx_device * dev, const gx_color_value cv[])
|
|
|
685 |
{
|
|
|
686 |
gx_color_value r = cv[0];
|
|
|
687 |
gx_color_value g = cv[1];
|
|
|
688 |
gx_color_value b = cv[2];
|
|
|
689 |
return (gx_color_value_to_byte(b)<<16) +
|
|
|
690 |
(gx_color_value_to_byte(g)<<8) +
|
|
|
691 |
gx_color_value_to_byte(r);
|
|
|
692 |
}
|
|
|
693 |
|
|
|
694 |
/* Map a color code to r-g-b. */
|
|
|
695 |
private int
|
|
|
696 |
display_map_color_rgb_bgr24(gx_device * dev, gx_color_index color,
|
|
|
697 |
gx_color_value prgb[3])
|
|
|
698 |
{
|
|
|
699 |
prgb[0] = gx_color_value_from_byte(color & 0xff);
|
|
|
700 |
prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
|
|
|
701 |
prgb[2] = gx_color_value_from_byte((color >> 16) & 0xff);
|
|
|
702 |
return 0;
|
|
|
703 |
}
|
|
|
704 |
|
|
|
705 |
/* Fill a rectangle */
|
|
|
706 |
private int
|
|
|
707 |
display_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
|
|
|
708 |
gx_color_index color)
|
|
|
709 |
{
|
|
|
710 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
711 |
if (ddev->callback == NULL)
|
|
|
712 |
return 0;
|
|
|
713 |
dev_proc(ddev->mdev, fill_rectangle)((gx_device *)ddev->mdev,
|
|
|
714 |
x, y, w, h, color);
|
|
|
715 |
if (ddev->callback->display_update)
|
|
|
716 |
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
|
|
|
717 |
return 0;
|
|
|
718 |
}
|
|
|
719 |
|
|
|
720 |
/* Copy a monochrome bitmap */
|
|
|
721 |
private int
|
|
|
722 |
display_copy_mono(gx_device * dev,
|
|
|
723 |
const byte * base, int sourcex, int raster, gx_bitmap_id id,
|
|
|
724 |
int x, int y, int w, int h,
|
|
|
725 |
gx_color_index zero, gx_color_index one)
|
|
|
726 |
{
|
|
|
727 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
728 |
if (ddev->callback == NULL)
|
|
|
729 |
return 0;
|
|
|
730 |
dev_proc(ddev->mdev, copy_mono)((gx_device *)ddev->mdev,
|
|
|
731 |
base, sourcex, raster, id, x, y, w, h, zero, one);
|
|
|
732 |
if (ddev->callback->display_update)
|
|
|
733 |
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
|
|
|
734 |
return 0;
|
|
|
735 |
}
|
|
|
736 |
|
|
|
737 |
/* Copy a color pixel map */
|
|
|
738 |
private int
|
|
|
739 |
display_copy_color(gx_device * dev,
|
|
|
740 |
const byte * base, int sourcex, int raster, gx_bitmap_id id,
|
|
|
741 |
int x, int y, int w, int h)
|
|
|
742 |
{
|
|
|
743 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
744 |
if (ddev->callback == NULL)
|
|
|
745 |
return 0;
|
|
|
746 |
dev_proc(ddev->mdev, copy_color)((gx_device *)ddev->mdev,
|
|
|
747 |
base, sourcex, raster, id, x, y, w, h);
|
|
|
748 |
if (ddev->callback->display_update)
|
|
|
749 |
(*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
|
|
|
750 |
return 0;
|
|
|
751 |
}
|
|
|
752 |
|
|
|
753 |
private int
|
|
|
754 |
display_get_bits(gx_device * dev, int y, byte * str, byte ** actual_data)
|
|
|
755 |
{
|
|
|
756 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
757 |
if (ddev->callback == NULL)
|
|
|
758 |
return 0;
|
|
|
759 |
return dev_proc(ddev->mdev, get_bits)((gx_device *)ddev->mdev,
|
|
|
760 |
y, str, actual_data);
|
|
|
761 |
}
|
|
|
762 |
|
|
|
763 |
private int
|
|
|
764 |
display_get_params(gx_device * dev, gs_param_list * plist)
|
|
|
765 |
{
|
|
|
766 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
767 |
int code;
|
|
|
768 |
gs_param_string dhandle;
|
|
|
769 |
int idx;
|
|
|
770 |
int val;
|
|
|
771 |
int i = 0;
|
|
|
772 |
size_t dptr;
|
|
|
773 |
char buf[64];
|
|
|
774 |
|
|
|
775 |
idx = ((int)sizeof(size_t)) * 8 - 4;
|
|
|
776 |
buf[i++] = '1';
|
|
|
777 |
buf[i++] = '6';
|
|
|
778 |
buf[i++] = '#';
|
|
|
779 |
dptr = (size_t)(ddev->pHandle);
|
|
|
780 |
while (idx >= 0) {
|
|
|
781 |
val = (int)(dptr >> idx) & 0xf;
|
|
|
782 |
if (val <= 9)
|
|
|
783 |
buf[i++] = '0' + val;
|
|
|
784 |
else
|
|
|
785 |
buf[i++] = 'a' - 10 + val;
|
|
|
786 |
idx -= 4;
|
|
|
787 |
}
|
|
|
788 |
buf[i] = '\0';
|
|
|
789 |
|
|
|
790 |
param_string_from_transient_string(dhandle, buf);
|
|
|
791 |
|
|
|
792 |
code = gx_default_get_params(dev, plist);
|
|
|
793 |
(void)(code < 0 ||
|
|
|
794 |
(code = param_write_string(plist,
|
|
|
795 |
"DisplayHandle", &dhandle)) < 0 ||
|
|
|
796 |
(code = param_write_int(plist,
|
|
|
797 |
"DisplayFormat", &ddev->nFormat)) < 0 ||
|
|
|
798 |
(code = param_write_float(plist,
|
|
|
799 |
"DisplayResolution", &ddev->HWResolution[1])) < 0);
|
|
|
800 |
if (code >= 0 &&
|
|
|
801 |
(ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION)
|
|
|
802 |
code = devn_get_params(dev, plist, &ddev->devn_params,
|
|
|
803 |
&ddev->equiv_cmyk_colors);
|
|
|
804 |
return code;
|
|
|
805 |
}
|
|
|
806 |
|
|
|
807 |
/* Put parameters. */
|
|
|
808 |
/* The parameters "DisplayHandle" and "DisplayFormat"
|
|
|
809 |
* can be changed when the device is closed, but not when open.
|
|
|
810 |
* The device width and height can be changed when open.
|
|
|
811 |
*/
|
|
|
812 |
private int
|
|
|
813 |
display_put_params(gx_device * dev, gs_param_list * plist)
|
|
|
814 |
{
|
|
|
815 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
816 |
int ecode = 0, code;
|
|
|
817 |
bool is_open = dev->is_open;
|
|
|
818 |
gs_param_float_array hwra;
|
|
|
819 |
float dispres = 0.0;
|
|
|
820 |
|
|
|
821 |
int old_width = dev->width;
|
|
|
822 |
int old_height = dev->height;
|
|
|
823 |
int old_format = ddev->nFormat;
|
|
|
824 |
void *old_handle = ddev->pHandle;
|
|
|
825 |
|
|
|
826 |
gs_devn_params *pdevn_params = &ddev->devn_params;
|
|
|
827 |
equivalent_cmyk_color_params *pequiv_colors = &ddev->equiv_cmyk_colors;
|
|
|
828 |
/* Save current data in case we have a problem */
|
|
|
829 |
gs_devn_params saved_devn_params = *pdevn_params;
|
|
|
830 |
equivalent_cmyk_color_params saved_equiv_colors = *pequiv_colors;
|
|
|
831 |
|
|
|
832 |
int format;
|
|
|
833 |
void *handle;
|
|
|
834 |
int found_string_handle = 0;
|
|
|
835 |
gs_param_string dh = { 0 };
|
|
|
836 |
|
|
|
837 |
/* Handle extra parameters */
|
|
|
838 |
|
|
|
839 |
switch (code = param_read_int(plist, "DisplayFormat", &format)) {
|
|
|
840 |
case 0:
|
|
|
841 |
if (dev->is_open) {
|
|
|
842 |
if (ddev->nFormat != format)
|
|
|
843 |
ecode = gs_error_rangecheck;
|
|
|
844 |
else
|
|
|
845 |
break;
|
|
|
846 |
}
|
|
|
847 |
else {
|
|
|
848 |
code = display_set_color_format(ddev, format);
|
|
|
849 |
if (code < 0)
|
|
|
850 |
ecode = code;
|
|
|
851 |
else
|
|
|
852 |
break;
|
|
|
853 |
}
|
|
|
854 |
goto cfe;
|
|
|
855 |
default:
|
|
|
856 |
ecode = code;
|
|
|
857 |
cfe:param_signal_error(plist, "DisplayFormat", ecode);
|
|
|
858 |
case 1:
|
|
|
859 |
break;
|
|
|
860 |
}
|
|
|
861 |
|
|
|
862 |
/* 64-bit systems need to use DisplayHandle as a string */
|
|
|
863 |
switch (code = param_read_string(plist, "DisplayHandle", &dh)) {
|
|
|
864 |
case 0:
|
|
|
865 |
found_string_handle = 1;
|
|
|
866 |
break;
|
|
|
867 |
default:
|
|
|
868 |
if ((code == gs_error_typecheck) && (sizeof(size_t) <= 4)) {
|
|
|
869 |
/* 32-bit systems can use the older long type */
|
|
|
870 |
switch (code = param_read_long(plist, "DisplayHandle",
|
|
|
871 |
(long *)(&handle))) {
|
|
|
872 |
case 0:
|
|
|
873 |
if (dev->is_open) {
|
|
|
874 |
if (ddev->pHandle != handle)
|
|
|
875 |
ecode = gs_error_rangecheck;
|
|
|
876 |
else
|
|
|
877 |
break;
|
|
|
878 |
}
|
|
|
879 |
else {
|
|
|
880 |
ddev->pHandle = handle;
|
|
|
881 |
break;
|
|
|
882 |
}
|
|
|
883 |
goto hdle;
|
|
|
884 |
default:
|
|
|
885 |
ecode = code;
|
|
|
886 |
hdle:param_signal_error(plist, "DisplayHandle", ecode);
|
|
|
887 |
case 1:
|
|
|
888 |
break;
|
|
|
889 |
}
|
|
|
890 |
break;
|
|
|
891 |
}
|
|
|
892 |
ecode = code;
|
|
|
893 |
param_signal_error(plist, "DisplayHandle", ecode);
|
|
|
894 |
/* fall through */
|
|
|
895 |
case 1:
|
|
|
896 |
dh.data = 0;
|
|
|
897 |
break;
|
|
|
898 |
}
|
|
|
899 |
if (found_string_handle) {
|
|
|
900 |
/*
|
|
|
901 |
* Convert from a string to a pointer.
|
|
|
902 |
* It is assumed that size_t has the same size as a pointer.
|
|
|
903 |
* Allow formats (1234), (10#1234) or (16#04d2).
|
|
|
904 |
*/
|
|
|
905 |
size_t ptr = 0;
|
|
|
906 |
int i;
|
|
|
907 |
int base = 10;
|
|
|
908 |
int val;
|
|
|
909 |
code = 0;
|
|
|
910 |
for (i=0; i<dh.size; i++) {
|
|
|
911 |
val = dh.data[i];
|
|
|
912 |
if ((val >= '0') && (val <= '9'))
|
|
|
913 |
val = val - '0';
|
|
|
914 |
else if ((val >= 'A') && (val <= 'F'))
|
|
|
915 |
val = val - 'A' + 10;
|
|
|
916 |
else if ((val >= 'a') && (val <= 'f'))
|
|
|
917 |
val = val - 'a' + 10;
|
|
|
918 |
else if (val == '#') {
|
|
|
919 |
base = (int)ptr;
|
|
|
920 |
ptr = 0;
|
|
|
921 |
if ((base != 10) && (base != 16)) {
|
|
|
922 |
code = gs_error_rangecheck;
|
|
|
923 |
break;
|
|
|
924 |
}
|
|
|
925 |
continue;
|
|
|
926 |
}
|
|
|
927 |
else {
|
|
|
928 |
code = gs_error_rangecheck;
|
|
|
929 |
break;
|
|
|
930 |
}
|
|
|
931 |
|
|
|
932 |
if (base == 10)
|
|
|
933 |
ptr = ptr * 10 + val;
|
|
|
934 |
else if (base == 16)
|
|
|
935 |
ptr = ptr * 16 + val;
|
|
|
936 |
else {
|
|
|
937 |
code = gs_error_rangecheck;
|
|
|
938 |
break;
|
|
|
939 |
}
|
|
|
940 |
}
|
|
|
941 |
if (code == 0) {
|
|
|
942 |
if (dev->is_open) {
|
|
|
943 |
if (ddev->pHandle != (void *)ptr)
|
|
|
944 |
code = gs_error_rangecheck;
|
|
|
945 |
}
|
|
|
946 |
else
|
|
|
947 |
ddev->pHandle = (void *)ptr;
|
|
|
948 |
}
|
|
|
949 |
if (code < 0) {
|
|
|
950 |
ecode = code;
|
|
|
951 |
param_signal_error(plist, "DisplayHandle", ecode);
|
|
|
952 |
}
|
|
|
953 |
}
|
|
|
954 |
|
|
|
955 |
/*
|
|
|
956 |
* Set the initial display resolution.
|
|
|
957 |
* If HWResolution is explicitly set, e.g. using -rDPI on the
|
|
|
958 |
* command line, then use that. Otherwise, use DisplayResolution
|
|
|
959 |
* which is typically set by the client to the display
|
|
|
960 |
* logical resolution. Once either of these have been
|
|
|
961 |
* used, ignore all further DisplayResolution parameters.
|
|
|
962 |
*/
|
|
|
963 |
if (param_read_float_array(plist, "HWResolution", &hwra) == 0)
|
|
|
964 |
ddev->HWResolution_set = 1;
|
|
|
965 |
|
|
|
966 |
switch (code = param_read_float(plist, "DisplayResolution", &dispres)) {
|
|
|
967 |
case 0:
|
|
|
968 |
if (!ddev->HWResolution_set) {
|
|
|
969 |
gx_device_set_resolution(dev, dispres, dispres);
|
|
|
970 |
ddev->HWResolution_set = 1;
|
|
|
971 |
}
|
|
|
972 |
break;
|
|
|
973 |
default:
|
|
|
974 |
ecode = code;
|
|
|
975 |
param_signal_error(plist, "DisplayResolution", ecode);
|
|
|
976 |
case 1:
|
|
|
977 |
break;
|
|
|
978 |
}
|
|
|
979 |
|
|
|
980 |
if (ecode >= 0 &&
|
|
|
981 |
(ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION) {
|
|
|
982 |
/* Use utility routine to handle devn parameters */
|
|
|
983 |
ecode = devn_put_params(dev, plist, pdevn_params, pequiv_colors);
|
|
|
984 |
/*
|
|
|
985 |
* Setting MaxSeparations changes color_info.depth in
|
|
|
986 |
* devn_put_params, but we always use 64bpp,
|
|
|
987 |
* so reset it to the the correct value.
|
|
|
988 |
*/
|
|
|
989 |
dev->color_info.depth = arch_sizeof_color_index * 8;
|
|
|
990 |
}
|
|
|
991 |
|
|
|
992 |
if (ecode >= 0) {
|
|
|
993 |
/* Prevent gx_default_put_params from closing the device. */
|
|
|
994 |
dev->is_open = false;
|
|
|
995 |
ecode = gx_default_put_params(dev, plist);
|
|
|
996 |
dev->is_open = is_open;
|
|
|
997 |
}
|
|
|
998 |
if (ecode < 0) {
|
|
|
999 |
/* If we have an error then restore original data. */
|
|
|
1000 |
*pdevn_params = saved_devn_params;
|
|
|
1001 |
*pequiv_colors = saved_equiv_colors;
|
|
|
1002 |
if (format != old_format)
|
|
|
1003 |
display_set_color_format(ddev, old_format);
|
|
|
1004 |
ddev->pHandle = old_handle;
|
|
|
1005 |
dev->width = old_width;
|
|
|
1006 |
dev->height = old_height;
|
|
|
1007 |
return ecode;
|
|
|
1008 |
}
|
|
|
1009 |
|
|
|
1010 |
|
|
|
1011 |
if ( is_open && ddev->callback &&
|
|
|
1012 |
((old_width != dev->width) || (old_height != dev->height)) ) {
|
|
|
1013 |
/* We can resize this device while it is open, but we cannot
|
|
|
1014 |
* change the color format or handle.
|
|
|
1015 |
*/
|
|
|
1016 |
/* Tell caller we are about to change the device parameters */
|
|
|
1017 |
if ((*ddev->callback->display_presize)(ddev->pHandle, dev,
|
|
|
1018 |
dev->width, dev->height, display_raster(ddev),
|
|
|
1019 |
ddev->nFormat) < 0) {
|
|
|
1020 |
/* caller won't let us change the size */
|
|
|
1021 |
/* restore parameters then return an error */
|
|
|
1022 |
*pdevn_params = saved_devn_params;
|
|
|
1023 |
*pequiv_colors = saved_equiv_colors;
|
|
|
1024 |
display_set_color_format(ddev, old_format);
|
|
|
1025 |
ddev->nFormat = old_format;
|
|
|
1026 |
ddev->pHandle = old_handle;
|
|
|
1027 |
dev->width = old_width;
|
|
|
1028 |
dev->height = old_height;
|
|
|
1029 |
return_error(gs_error_rangecheck);
|
|
|
1030 |
}
|
|
|
1031 |
|
|
|
1032 |
display_free_bitmap(ddev);
|
|
|
1033 |
|
|
|
1034 |
code = display_alloc_bitmap(ddev, dev);
|
|
|
1035 |
if (code < 0) {
|
|
|
1036 |
/* No bitmap, so tell the caller it is zero size */
|
|
|
1037 |
(*ddev->callback->display_size)(ddev->pHandle, dev,
|
|
|
1038 |
0, 0, 0, ddev->nFormat, NULL);
|
|
|
1039 |
return_error(code);
|
|
|
1040 |
}
|
|
|
1041 |
|
|
|
1042 |
/* tell caller about the new size */
|
|
|
1043 |
if ((*ddev->callback->display_size)(ddev->pHandle, dev,
|
|
|
1044 |
dev->width, dev->height, display_raster(ddev),
|
|
|
1045 |
ddev->nFormat, ddev->mdev->base) < 0)
|
|
|
1046 |
return_error(gs_error_rangecheck);
|
|
|
1047 |
}
|
|
|
1048 |
|
|
|
1049 |
return 0;
|
|
|
1050 |
}
|
|
|
1051 |
|
|
|
1052 |
/* Clean up the instance after making a copy. */
|
|
|
1053 |
int
|
|
|
1054 |
display_finish_copydevice(gx_device *dev, const gx_device *from_dev)
|
|
|
1055 |
{
|
|
|
1056 |
gx_device_display *ddev = (gx_device_display *) dev;
|
|
|
1057 |
|
|
|
1058 |
/* Mark the new instance as closed. */
|
|
|
1059 |
ddev->is_open = false;
|
|
|
1060 |
|
|
|
1061 |
/* Clear pointers */
|
|
|
1062 |
ddev->mdev = NULL;
|
|
|
1063 |
ddev->pBitmap = NULL;
|
|
|
1064 |
ddev->ulBitmapSize = 0;
|
|
|
1065 |
|
|
|
1066 |
return 0;
|
|
|
1067 |
}
|
|
|
1068 |
|
|
|
1069 |
/*
|
|
|
1070 |
* The following procedures are used to map the standard color spaces into
|
|
|
1071 |
* the separation color components for the display device.
|
|
|
1072 |
*/
|
|
|
1073 |
private void
|
|
|
1074 |
display_separation_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[])
|
|
|
1075 |
{
|
|
|
1076 |
int * map =
|
|
|
1077 |
(int *)(&((gx_device_display *) dev)->devn_params.separation_order_map);
|
|
|
1078 |
|
|
|
1079 |
gray_cs_to_devn_cm(dev, map, gray, out);
|
|
|
1080 |
}
|
|
|
1081 |
|
|
|
1082 |
private void
|
|
|
1083 |
display_separation_rgb_cs_to_cmyk_cm(gx_device * dev,
|
|
|
1084 |
const gs_imager_state *pis, frac r, frac g, frac b, frac out[])
|
|
|
1085 |
{
|
|
|
1086 |
int * map =
|
|
|
1087 |
(int *)(&((gx_device_display *) dev)->devn_params.separation_order_map);
|
|
|
1088 |
|
|
|
1089 |
rgb_cs_to_devn_cm(dev, map, pis, r, g, b, out);
|
|
|
1090 |
}
|
|
|
1091 |
|
|
|
1092 |
private void
|
|
|
1093 |
display_separation_cmyk_cs_to_cmyk_cm(gx_device * dev,
|
|
|
1094 |
frac c, frac m, frac y, frac k, frac out[])
|
|
|
1095 |
{
|
|
|
1096 |
int * map =
|
|
|
1097 |
(int *)(&((gx_device_display *) dev)->devn_params.separation_order_map);
|
|
|
1098 |
|
|
|
1099 |
cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
|
|
|
1100 |
}
|
|
|
1101 |
|
|
|
1102 |
private const gx_cm_color_map_procs display_separation_cm_procs = {
|
|
|
1103 |
display_separation_gray_cs_to_cmyk_cm,
|
|
|
1104 |
display_separation_rgb_cs_to_cmyk_cm,
|
|
|
1105 |
display_separation_cmyk_cs_to_cmyk_cm
|
|
|
1106 |
};
|
|
|
1107 |
|
|
|
1108 |
private const gx_cm_color_map_procs *
|
|
|
1109 |
display_separation_get_color_mapping_procs(const gx_device * dev)
|
|
|
1110 |
{
|
|
|
1111 |
return &display_separation_cm_procs;
|
|
|
1112 |
}
|
|
|
1113 |
|
|
|
1114 |
|
|
|
1115 |
/*
|
|
|
1116 |
* Encode a list of colorant values into a gx_color_index_value.
|
|
|
1117 |
*/
|
|
|
1118 |
private gx_color_index
|
|
|
1119 |
display_separation_encode_color(gx_device *dev, const gx_color_value colors[])
|
|
|
1120 |
{
|
|
|
1121 |
int bpc = ((gx_device_display *)dev)->devn_params.bitspercomponent;
|
|
|
1122 |
int drop = sizeof(gx_color_value) * 8 - bpc;
|
|
|
1123 |
gx_color_index color = 0;
|
|
|
1124 |
int i = 0;
|
|
|
1125 |
int ncomp = dev->color_info.num_components;
|
|
|
1126 |
|
|
|
1127 |
for (; i<ncomp; i++) {
|
|
|
1128 |
color <<= bpc;
|
|
|
1129 |
color |= (colors[i] >> drop);
|
|
|
1130 |
}
|
|
|
1131 |
if (bpc*ncomp < arch_sizeof_color_index * 8)
|
|
|
1132 |
color <<= (arch_sizeof_color_index * 8 - ncomp * bpc);
|
|
|
1133 |
return (color == gx_no_color_index ? color ^ 1 : color);
|
|
|
1134 |
}
|
|
|
1135 |
|
|
|
1136 |
/*
|
|
|
1137 |
* Decode a gx_color_index value back to a list of colorant values.
|
|
|
1138 |
*/
|
|
|
1139 |
private int
|
|
|
1140 |
display_separation_decode_color(gx_device * dev, gx_color_index color,
|
|
|
1141 |
gx_color_value * out)
|
|
|
1142 |
{
|
|
|
1143 |
int bpc = ((gx_device_display *)dev)->devn_params.bitspercomponent;
|
|
|
1144 |
int drop = sizeof(gx_color_value) * 8 - bpc;
|
|
|
1145 |
int mask = (1 << bpc) - 1;
|
|
|
1146 |
int i = 0;
|
|
|
1147 |
int ncomp = dev->color_info.num_components;
|
|
|
1148 |
|
|
|
1149 |
if (bpc*ncomp < arch_sizeof_color_index * 8)
|
|
|
1150 |
color >>= (arch_sizeof_color_index * 8 - ncomp * bpc);
|
|
|
1151 |
for (; i<ncomp; i++) {
|
|
|
1152 |
out[ncomp - i - 1] = (gx_color_value) ((color & mask) << drop);
|
|
|
1153 |
color >>= bpc;
|
|
|
1154 |
}
|
|
|
1155 |
return 0;
|
|
|
1156 |
}
|
|
|
1157 |
|
|
|
1158 |
/*
|
|
|
1159 |
* Device proc for updating the equivalent CMYK color for spot colors.
|
|
|
1160 |
*/
|
|
|
1161 |
private int
|
|
|
1162 |
display_update_spot_equivalent_colors(gx_device * dev, const gs_state * pgs)
|
|
|
1163 |
{
|
|
|
1164 |
gx_device_display * ddev = (gx_device_display *)dev;
|
|
|
1165 |
|
|
|
1166 |
if ((ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION)
|
|
|
1167 |
update_spot_equivalent_cmyk_colors(dev, pgs,
|
|
|
1168 |
&ddev->devn_params, &ddev->equiv_cmyk_colors);
|
|
|
1169 |
return 0;
|
|
|
1170 |
}
|
|
|
1171 |
|
|
|
1172 |
/*
|
|
|
1173 |
* This routine will check to see if the color component name match those
|
|
|
1174 |
* that are available amoung the current device's color components.
|
|
|
1175 |
*
|
|
|
1176 |
* Parameters:
|
|
|
1177 |
* dev - pointer to device data structure.
|
|
|
1178 |
* pname - pointer to name (zero termination not required)
|
|
|
1179 |
* nlength - length of the name
|
|
|
1180 |
*
|
|
|
1181 |
* This routine returns a positive value (0 to n) which is the device colorant
|
|
|
1182 |
* number if the name is found. It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
|
|
|
1183 |
* the colorant is not being used due to a SeparationOrder device parameter.
|
|
|
1184 |
* It returns a negative value if not found.
|
|
|
1185 |
*/
|
|
|
1186 |
private int
|
|
|
1187 |
display_separation_get_color_comp_index(gx_device * dev,
|
|
|
1188 |
const char * pname, int name_size, int component_type)
|
|
|
1189 |
{
|
|
|
1190 |
return devn_get_color_comp_index(dev,
|
|
|
1191 |
&(((gx_device_display *)dev)->devn_params),
|
|
|
1192 |
&(((gx_device_display *)dev)->equiv_cmyk_colors),
|
|
|
1193 |
pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
|
|
|
1194 |
}
|
|
|
1195 |
|
|
|
1196 |
|
|
|
1197 |
/* ------ Internal routines ------ */
|
|
|
1198 |
|
|
|
1199 |
/* Make sure we have been given a valid structure */
|
|
|
1200 |
/* Return 0 on success, gs_error_rangecheck on failure */
|
|
|
1201 |
private int display_check_structure(gx_device_display *ddev)
|
|
|
1202 |
{
|
|
|
1203 |
if (ddev->callback == 0)
|
|
|
1204 |
return_error(gs_error_rangecheck);
|
|
|
1205 |
|
|
|
1206 |
if (ddev->callback->size == sizeof(struct display_callback_v1_s)) {
|
|
|
1207 |
/* Original V1 structure */
|
|
|
1208 |
if (ddev->callback->version_major != DISPLAY_VERSION_MAJOR_V1)
|
|
|
1209 |
return_error(gs_error_rangecheck);
|
|
|
1210 |
|
|
|
1211 |
/* complain if caller asks for newer features */
|
|
|
1212 |
if (ddev->callback->version_minor > DISPLAY_VERSION_MINOR_V1)
|
|
|
1213 |
return_error(gs_error_rangecheck);
|
|
|
1214 |
}
|
|
|
1215 |
else {
|
|
|
1216 |
/* V2 structure with added display_separation callback */
|
|
|
1217 |
if (ddev->callback->size != sizeof(display_callback))
|
|
|
1218 |
return_error(gs_error_rangecheck);
|
|
|
1219 |
|
|
|
1220 |
if (ddev->callback->version_major != DISPLAY_VERSION_MAJOR)
|
|
|
1221 |
return_error(gs_error_rangecheck);
|
|
|
1222 |
|
|
|
1223 |
/* complain if caller asks for newer features */
|
|
|
1224 |
if (ddev->callback->version_minor > DISPLAY_VERSION_MINOR)
|
|
|
1225 |
return_error(gs_error_rangecheck);
|
|
|
1226 |
}
|
|
|
1227 |
|
|
|
1228 |
if ((ddev->callback->display_open == NULL) ||
|
|
|
1229 |
(ddev->callback->display_close == NULL) ||
|
|
|
1230 |
(ddev->callback->display_presize == NULL) ||
|
|
|
1231 |
(ddev->callback->display_size == NULL) ||
|
|
|
1232 |
(ddev->callback->display_sync == NULL) ||
|
|
|
1233 |
(ddev->callback->display_page == NULL))
|
|
|
1234 |
return_error(gs_error_rangecheck);
|
|
|
1235 |
|
|
|
1236 |
/* Don't test display_update, display_memalloc or display_memfree
|
|
|
1237 |
* since these may be NULL if not provided.
|
|
|
1238 |
* Don't test display_separation, since this may be NULL if
|
|
|
1239 |
* separation format is not supported.
|
|
|
1240 |
*/
|
|
|
1241 |
|
|
|
1242 |
return 0;
|
|
|
1243 |
}
|
|
|
1244 |
|
|
|
1245 |
private void
|
|
|
1246 |
display_free_bitmap(gx_device_display * ddev)
|
|
|
1247 |
{
|
|
|
1248 |
if (ddev->callback == NULL)
|
|
|
1249 |
return;
|
|
|
1250 |
if (ddev->pBitmap) {
|
|
|
1251 |
if (ddev->callback->display_memalloc
|
|
|
1252 |
&& ddev->callback->display_memfree
|
|
|
1253 |
&& ddev->pBitmap) {
|
|
|
1254 |
(*ddev->callback->display_memfree)(ddev->pHandle, ddev,
|
|
|
1255 |
ddev->pBitmap);
|
|
|
1256 |
}
|
|
|
1257 |
else {
|
|
|
1258 |
gs_free_object(ddev->memory->non_gc_memory,
|
|
|
1259 |
ddev->pBitmap, "display_free_bitmap");
|
|
|
1260 |
}
|
|
|
1261 |
ddev->pBitmap = NULL;
|
|
|
1262 |
if (ddev->mdev)
|
|
|
1263 |
ddev->mdev->base = NULL;
|
|
|
1264 |
}
|
|
|
1265 |
if (ddev->mdev) {
|
|
|
1266 |
dev_proc(ddev->mdev, close_device)((gx_device *)ddev->mdev);
|
|
|
1267 |
gx_device_retain((gx_device *)(ddev->mdev), false);
|
|
|
1268 |
ddev->mdev = NULL;
|
|
|
1269 |
}
|
|
|
1270 |
}
|
|
|
1271 |
|
|
|
1272 |
/* calculate byte length of a row */
|
|
|
1273 |
private int
|
|
|
1274 |
display_raster(gx_device_display *dev)
|
|
|
1275 |
{
|
|
|
1276 |
int align = 0;
|
|
|
1277 |
int bytewidth = dev->width * dev->color_info.depth/8;
|
|
|
1278 |
switch (dev->nFormat & DISPLAY_ROW_ALIGN_MASK) {
|
|
|
1279 |
case DISPLAY_ROW_ALIGN_4:
|
|
|
1280 |
align = 4;
|
|
|
1281 |
break;
|
|
|
1282 |
case DISPLAY_ROW_ALIGN_8:
|
|
|
1283 |
align = 8;
|
|
|
1284 |
break;
|
|
|
1285 |
case DISPLAY_ROW_ALIGN_16:
|
|
|
1286 |
align = 16;
|
|
|
1287 |
break;
|
|
|
1288 |
case DISPLAY_ROW_ALIGN_32:
|
|
|
1289 |
align = 32;
|
|
|
1290 |
break;
|
|
|
1291 |
case DISPLAY_ROW_ALIGN_64:
|
|
|
1292 |
align = 64;
|
|
|
1293 |
break;
|
|
|
1294 |
}
|
|
|
1295 |
if (align < ARCH_ALIGN_PTR_MOD)
|
|
|
1296 |
align = ARCH_ALIGN_PTR_MOD;
|
|
|
1297 |
align -= 1;
|
|
|
1298 |
bytewidth = (bytewidth + align) & (~align);
|
|
|
1299 |
return bytewidth;
|
|
|
1300 |
}
|
|
|
1301 |
|
|
|
1302 |
/* Allocate the backing bitmap. */
|
|
|
1303 |
private int
|
|
|
1304 |
display_alloc_bitmap(gx_device_display * ddev, gx_device * param_dev)
|
|
|
1305 |
{
|
|
|
1306 |
int ccode;
|
|
|
1307 |
const gx_device_memory *mdproto;
|
|
|
1308 |
if (ddev->callback == NULL)
|
|
|
1309 |
return 0;
|
|
|
1310 |
|
|
|
1311 |
/* free old bitmap (if any) */
|
|
|
1312 |
display_free_bitmap(ddev);
|
|
|
1313 |
|
|
|
1314 |
/* allocate a memory device for rendering */
|
|
|
1315 |
mdproto = gdev_mem_device_for_bits(ddev->color_info.depth);
|
|
|
1316 |
if (mdproto == 0)
|
|
|
1317 |
return_error(gs_error_rangecheck);
|
|
|
1318 |
|
|
|
1319 |
ddev->mdev = gs_alloc_struct(gs_memory_stable(ddev->memory),
|
|
|
1320 |
gx_device_memory, &st_device_memory, "display_memory_device");
|
|
|
1321 |
if (ddev->mdev == 0)
|
|
|
1322 |
return_error(gs_error_VMerror);
|
|
|
1323 |
|
|
|
1324 |
gs_make_mem_device(ddev->mdev, mdproto, gs_memory_stable(ddev->memory),
|
|
|
1325 |
0, (gx_device *) NULL);
|
|
|
1326 |
check_device_separable((gx_device *)(ddev->mdev));
|
|
|
1327 |
gx_device_fill_in_procs((gx_device *)(ddev->mdev));
|
|
|
1328 |
/* Mark the memory device as retained. When the bitmap is closed,
|
|
|
1329 |
* we will clear this and the memory device will be then be freed.
|
|
|
1330 |
*/
|
|
|
1331 |
gx_device_retain((gx_device *)(ddev->mdev), true);
|
|
|
1332 |
|
|
|
1333 |
/* Memory device width may be larger than device width
|
|
|
1334 |
* if row alignment is not 4.
|
|
|
1335 |
*/
|
|
|
1336 |
ddev->mdev->width = param_dev->width;
|
|
|
1337 |
ddev->mdev->width = display_raster(ddev) * 8 / ddev->color_info.depth;
|
|
|
1338 |
ddev->mdev->height = param_dev->height;
|
|
|
1339 |
|
|
|
1340 |
/* Tell the memory device to allocate the line pointers separately
|
|
|
1341 |
* so we can place the bitmap in special memory.
|
|
|
1342 |
*/
|
|
|
1343 |
ddev->mdev->line_pointer_memory = ddev->mdev->memory;
|
|
|
1344 |
ddev->ulBitmapSize = gdev_mem_bits_size(ddev->mdev,
|
|
|
1345 |
ddev->mdev->width, ddev->mdev->height);
|
|
|
1346 |
|
|
|
1347 |
/* allocate bitmap using an allocator not subject to GC */
|
|
|
1348 |
if (ddev->callback->display_memalloc
|
|
|
1349 |
&& ddev->callback->display_memfree) {
|
|
|
1350 |
ddev->pBitmap = (*ddev->callback->display_memalloc)(ddev->pHandle,
|
|
|
1351 |
ddev, ddev->ulBitmapSize);
|
|
|
1352 |
}
|
|
|
1353 |
else {
|
|
|
1354 |
ddev->pBitmap = gs_alloc_byte_array_immovable(ddev->memory->non_gc_memory,
|
|
|
1355 |
(uint)ddev->ulBitmapSize, 1, "display_alloc_bitmap");
|
|
|
1356 |
}
|
|
|
1357 |
|
|
|
1358 |
if (ddev->pBitmap == NULL) {
|
|
|
1359 |
ddev->mdev->width = 0;
|
|
|
1360 |
ddev->mdev->height = 0;
|
|
|
1361 |
return_error(gs_error_VMerror);
|
|
|
1362 |
}
|
|
|
1363 |
|
|
|
1364 |
ddev->mdev->base = (byte *) ddev->pBitmap;
|
|
|
1365 |
ddev->mdev->foreign_bits = true;
|
|
|
1366 |
|
|
|
1367 |
ccode = dev_proc(ddev->mdev, open_device)((gx_device *)ddev->mdev);
|
|
|
1368 |
if (ccode < 0)
|
|
|
1369 |
display_free_bitmap(ddev);
|
|
|
1370 |
|
|
|
1371 |
/* erase bitmap - before display gets redrawn */
|
|
|
1372 |
if (ccode == 0) {
|
|
|
1373 |
int i;
|
|
|
1374 |
gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
|
|
|
1375 |
for (i=0; i<GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
|
|
|
1376 |
cv[i] = (ddev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
|
|
|
1377 |
? gx_max_color_value : 0;
|
|
|
1378 |
dev_proc(ddev, fill_rectangle)((gx_device *)ddev,
|
|
|
1379 |
0, 0, ddev->width, ddev->height,
|
|
|
1380 |
ddev->procs.encode_color((gx_device *)ddev, cv));
|
|
|
1381 |
}
|
|
|
1382 |
|
|
|
1383 |
return ccode;
|
|
|
1384 |
}
|
|
|
1385 |
|
|
|
1386 |
private int
|
|
|
1387 |
display_set_separations(gx_device_display *dev)
|
|
|
1388 |
{
|
|
|
1389 |
if (((dev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION) &&
|
|
|
1390 |
(dev->callback->version_major > DISPLAY_VERSION_MAJOR_V1) &&
|
|
|
1391 |
(dev->callback->display_separation != NULL)) {
|
|
|
1392 |
/* Tell the client about the separation to composite mapping */
|
|
|
1393 |
char name[64];
|
|
|
1394 |
int num_spot = dev->devn_params.separations.num_separations;
|
|
|
1395 |
int num_std_colorants = dev->devn_params.num_std_colorant_names;
|
|
|
1396 |
int num_comp = num_std_colorants + num_spot;
|
|
|
1397 |
int comp_map[GX_DEVICE_COLOR_MAX_COMPONENTS];
|
|
|
1398 |
int comp_num;
|
|
|
1399 |
int sep_num;
|
|
|
1400 |
int sep_name_size;
|
|
|
1401 |
unsigned int c, m, y, k;
|
|
|
1402 |
|
|
|
1403 |
/* Map the separation numbers to component numbers */
|
|
|
1404 |
memset(comp_map, 0, sizeof(comp_map));
|
|
|
1405 |
for (sep_num = 0; sep_num < num_comp; sep_num++) {
|
|
|
1406 |
comp_num = dev->devn_params.separation_order_map[sep_num];
|
|
|
1407 |
if (comp_num >= 0 && comp_num < GX_DEVICE_COLOR_MAX_COMPONENTS)
|
|
|
1408 |
comp_map[comp_num] = sep_num;
|
|
|
1409 |
}
|
|
|
1410 |
/* For each component, tell the client the separation mapping */
|
|
|
1411 |
for (comp_num = 0; comp_num < num_comp; comp_num++) {
|
|
|
1412 |
c = y = m = k = 0;
|
|
|
1413 |
sep_num = comp_map[comp_num];
|
|
|
1414 |
/* Get the CMYK equivalent */
|
|
|
1415 |
if (sep_num < dev->devn_params.num_std_colorant_names) {
|
|
|
1416 |
sep_name_size =
|
|
|
1417 |
strlen(dev->devn_params.std_colorant_names[sep_num]);
|
|
|
1418 |
if (sep_name_size > sizeof(name)-2)
|
|
|
1419 |
sep_name_size = sizeof(name)-1;
|
|
|
1420 |
memcpy(name, dev->devn_params.std_colorant_names[sep_num],
|
|
|
1421 |
sep_name_size);
|
|
|
1422 |
name[sep_name_size] = '\0';
|
|
|
1423 |
switch (sep_num) {
|
|
|
1424 |
case 0: c = 65535; break;
|
|
|
1425 |
case 1: m = 65535; break;
|
|
|
1426 |
case 2: y = 65535; break;
|
|
|
1427 |
case 3: k = 65535; break;
|
|
|
1428 |
}
|
|
|
1429 |
}
|
|
|
1430 |
else {
|
|
|
1431 |
sep_num -= dev->devn_params.num_std_colorant_names;
|
|
|
1432 |
sep_name_size =
|
|
|
1433 |
dev->devn_params.separations.names[sep_num].size;
|
|
|
1434 |
if (sep_name_size > sizeof(name)-2)
|
|
|
1435 |
sep_name_size = sizeof(name)-1;
|
|
|
1436 |
memcpy(name, dev->devn_params.separations.names[sep_num].data,
|
|
|
1437 |
sep_name_size);
|
|
|
1438 |
name[sep_name_size] = '\0';
|
|
|
1439 |
if (dev->equiv_cmyk_colors.color[sep_num].color_info_valid) {
|
|
|
1440 |
c = dev->equiv_cmyk_colors.color[sep_num].c
|
|
|
1441 |
* 65535 / frac_1;
|
|
|
1442 |
m = dev->equiv_cmyk_colors.color[sep_num].m
|
|
|
1443 |
* 65535 / frac_1;
|
|
|
1444 |
y = dev->equiv_cmyk_colors.color[sep_num].y
|
|
|
1445 |
* 65535 / frac_1;
|
|
|
1446 |
k = dev->equiv_cmyk_colors.color[sep_num].k
|
|
|
1447 |
* 65535 / frac_1;
|
|
|
1448 |
}
|
|
|
1449 |
}
|
|
|
1450 |
(*dev->callback->display_separation)(dev->pHandle, dev,
|
|
|
1451 |
comp_num, name,
|
|
|
1452 |
(unsigned short)c, (unsigned short)m,
|
|
|
1453 |
(unsigned short)y, (unsigned short)k);
|
|
|
1454 |
}
|
|
|
1455 |
}
|
|
|
1456 |
return 0;
|
|
|
1457 |
}
|
|
|
1458 |
|
|
|
1459 |
typedef enum DISPLAY_MODEL_e {
|
|
|
1460 |
DISPLAY_MODEL_GRAY=0,
|
|
|
1461 |
DISPLAY_MODEL_RGB=1,
|
|
|
1462 |
DISPLAY_MODEL_RGBK=2,
|
|
|
1463 |
DISPLAY_MODEL_CMYK=3,
|
|
|
1464 |
DISPLAY_MODEL_SEP=4
|
|
|
1465 |
} DISPLAY_MODEL;
|
|
|
1466 |
|
|
|
1467 |
/*
|
|
|
1468 |
* This is a utility routine to build the display device's color_info
|
|
|
1469 |
* structure (except for the anti alias info).
|
|
|
1470 |
*/
|
|
|
1471 |
private void
|
|
|
1472 |
set_color_info(gx_device_color_info * pdci, DISPLAY_MODEL model,
|
|
|
1473 |
int nc, int depth, int maxgray, int maxcolor)
|
|
|
1474 |
{
|
|
|
1475 |
pdci->num_components = pdci->max_components = nc;
|
|
|
1476 |
pdci->depth = depth;
|
|
|
1477 |
pdci->gray_index = 0;
|
|
|
1478 |
pdci->max_gray = maxgray;
|
|
|
1479 |
pdci->max_color = maxcolor;
|
|
|
1480 |
pdci->dither_grays = maxgray + 1;
|
|
|
1481 |
pdci->dither_colors = maxcolor + 1;
|
|
|
1482 |
pdci->separable_and_linear = GX_CINFO_UNKNOWN_SEP_LIN;
|
|
|
1483 |
switch (model) {
|
|
|
1484 |
case DISPLAY_MODEL_GRAY:
|
|
|
1485 |
pdci->polarity = GX_CINFO_POLARITY_ADDITIVE;
|
|
|
1486 |
pdci->cm_name = "DeviceGray";
|
|
|
1487 |
pdci->gray_index = 0;
|
|
|
1488 |
break;
|
|
|
1489 |
case DISPLAY_MODEL_RGB:
|
|
|
1490 |
pdci->polarity = GX_CINFO_POLARITY_ADDITIVE;
|
|
|
1491 |
pdci->cm_name = "DeviceRGB";
|
|
|
1492 |
pdci->gray_index = GX_CINFO_COMP_NO_INDEX;
|
|
|
1493 |
break;
|
|
|
1494 |
case DISPLAY_MODEL_RGBK:
|
|
|
1495 |
pdci->polarity = GX_CINFO_POLARITY_ADDITIVE;
|
|
|
1496 |
pdci->cm_name = "DeviceRGBK";
|
|
|
1497 |
pdci->gray_index = 3;
|
|
|
1498 |
break;
|
|
|
1499 |
case DISPLAY_MODEL_CMYK:
|
|
|
1500 |
pdci->polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
|
|
|
1501 |
pdci->cm_name = "DeviceCMYK";
|
|
|
1502 |
pdci->gray_index = 3;
|
|
|
1503 |
break;
|
|
|
1504 |
default:
|
|
|
1505 |
case DISPLAY_MODEL_SEP:
|
|
|
1506 |
/* Anything else is separations */
|
|
|
1507 |
pdci->polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
|
|
|
1508 |
pdci->cm_name = "DeviceCMYK";
|
|
|
1509 |
pdci->gray_index = GX_CINFO_COMP_NO_INDEX; /* may not have K */
|
|
|
1510 |
break;
|
|
|
1511 |
}
|
|
|
1512 |
}
|
|
|
1513 |
|
|
|
1514 |
/*
|
|
|
1515 |
* This is an utility routine to set up the color procs for the display
|
|
|
1516 |
* device. The display device can change its setup.
|
|
|
1517 |
*/
|
|
|
1518 |
private void
|
|
|
1519 |
set_color_procs(gx_device * pdev,
|
|
|
1520 |
dev_t_proc_encode_color((*encode_color), gx_device),
|
|
|
1521 |
dev_t_proc_decode_color((*decode_color), gx_device),
|
|
|
1522 |
dev_t_proc_get_color_mapping_procs((*get_color_mapping_procs), gx_device),
|
|
|
1523 |
dev_t_proc_get_color_comp_index((*get_color_comp_index), gx_device))
|
|
|
1524 |
{
|
|
|
1525 |
#if 0 /* These procs are no longer used */
|
|
|
1526 |
pdev->procs.map_rgb_color = encode_color;
|
|
|
1527 |
pdev->procs.map_color_rgb = decode_color;
|
|
|
1528 |
#endif
|
|
|
1529 |
pdev->procs.get_color_mapping_procs = get_color_mapping_procs;
|
|
|
1530 |
pdev->procs.get_color_comp_index = get_color_comp_index;
|
|
|
1531 |
pdev->procs.encode_color = encode_color;
|
|
|
1532 |
pdev->procs.decode_color = decode_color;
|
|
|
1533 |
}
|
|
|
1534 |
|
|
|
1535 |
/*
|
|
|
1536 |
* This is an utility routine to set up the color procs for the display
|
|
|
1537 |
* device. This routine is used when the display device is Gray.
|
|
|
1538 |
*/
|
|
|
1539 |
private void
|
|
|
1540 |
set_gray_color_procs(gx_device * pdev,
|
|
|
1541 |
dev_t_proc_encode_color((*encode_color), gx_device),
|
|
|
1542 |
dev_t_proc_decode_color((*decode_color), gx_device))
|
|
|
1543 |
{
|
|
|
1544 |
set_color_procs(pdev, encode_color, decode_color,
|
|
|
1545 |
gx_default_DevGray_get_color_mapping_procs,
|
|
|
1546 |
gx_default_DevGray_get_color_comp_index);
|
|
|
1547 |
}
|
|
|
1548 |
|
|
|
1549 |
/*
|
|
|
1550 |
* This is an utility routine to set up the color procs for the display
|
|
|
1551 |
* device. This routine is used when the display device is RGB.
|
|
|
1552 |
*/
|
|
|
1553 |
private void
|
|
|
1554 |
set_rgb_color_procs(gx_device * pdev,
|
|
|
1555 |
dev_t_proc_encode_color((*encode_color), gx_device),
|
|
|
1556 |
dev_t_proc_decode_color((*decode_color), gx_device))
|
|
|
1557 |
{
|
|
|
1558 |
set_color_procs(pdev, encode_color, decode_color,
|
|
|
1559 |
gx_default_DevRGB_get_color_mapping_procs,
|
|
|
1560 |
gx_default_DevRGB_get_color_comp_index);
|
|
|
1561 |
}
|
|
|
1562 |
|
|
|
1563 |
/*
|
|
|
1564 |
* This is an utility routine to set up the color procs for the display
|
|
|
1565 |
* device. This routine is used when the display device is RGBK.
|
|
|
1566 |
*/
|
|
|
1567 |
private void
|
|
|
1568 |
set_rgbk_color_procs(gx_device * pdev,
|
|
|
1569 |
dev_t_proc_encode_color((*encode_color), gx_device),
|
|
|
1570 |
dev_t_proc_decode_color((*decode_color), gx_device))
|
|
|
1571 |
{
|
|
|
1572 |
set_color_procs(pdev, encode_color, decode_color,
|
|
|
1573 |
gx_default_DevRGBK_get_color_mapping_procs,
|
|
|
1574 |
gx_default_DevRGBK_get_color_comp_index);
|
|
|
1575 |
}
|
|
|
1576 |
|
|
|
1577 |
/*
|
|
|
1578 |
* This is an utility routine to set up the color procs for the display
|
|
|
1579 |
* device. This routine is used when the display device is CMYK.
|
|
|
1580 |
*/
|
|
|
1581 |
private void
|
|
|
1582 |
set_cmyk_color_procs(gx_device * pdev,
|
|
|
1583 |
dev_t_proc_encode_color((*encode_color), gx_device),
|
|
|
1584 |
dev_t_proc_decode_color((*decode_color), gx_device))
|
|
|
1585 |
{
|
|
|
1586 |
set_color_procs(pdev, encode_color, decode_color,
|
|
|
1587 |
gx_default_DevCMYK_get_color_mapping_procs,
|
|
|
1588 |
gx_default_DevCMYK_get_color_comp_index);
|
|
|
1589 |
}
|
|
|
1590 |
|
|
|
1591 |
/* Set the color_info and mapping functions for this instance of the device */
|
|
|
1592 |
private int
|
|
|
1593 |
display_set_color_format(gx_device_display *ddev, int nFormat)
|
|
|
1594 |
{
|
|
|
1595 |
gx_device * pdev = (gx_device *) ddev;
|
|
|
1596 |
gx_device_color_info dci = ddev->color_info;
|
|
|
1597 |
int bpc; /* bits per component */
|
|
|
1598 |
int bpp; /* bits per pixel */
|
|
|
1599 |
int maxvalue;
|
|
|
1600 |
int align;
|
|
|
1601 |
|
|
|
1602 |
switch (nFormat & DISPLAY_DEPTH_MASK) {
|
|
|
1603 |
case DISPLAY_DEPTH_1:
|
|
|
1604 |
bpc = 1;
|
|
|
1605 |
break;
|
|
|
1606 |
case DISPLAY_DEPTH_2:
|
|
|
1607 |
bpc = 2;
|
|
|
1608 |
break;
|
|
|
1609 |
case DISPLAY_DEPTH_4:
|
|
|
1610 |
bpc = 4;
|
|
|
1611 |
break;
|
|
|
1612 |
case DISPLAY_DEPTH_8:
|
|
|
1613 |
bpc = 8;
|
|
|
1614 |
break;
|
|
|
1615 |
case DISPLAY_DEPTH_12:
|
|
|
1616 |
bpc = 12;
|
|
|
1617 |
break;
|
|
|
1618 |
case DISPLAY_DEPTH_16:
|
|
|
1619 |
bpc = 16;
|
|
|
1620 |
break;
|
|
|
1621 |
default:
|
|
|
1622 |
return_error(gs_error_rangecheck);
|
|
|
1623 |
}
|
|
|
1624 |
maxvalue = (1 << bpc) - 1;
|
|
|
1625 |
ddev->devn_params.bitspercomponent = bpc;
|
|
|
1626 |
|
|
|
1627 |
switch (ddev->nFormat & DISPLAY_ROW_ALIGN_MASK) {
|
|
|
1628 |
case DISPLAY_ROW_ALIGN_DEFAULT:
|
|
|
1629 |
align = ARCH_ALIGN_PTR_MOD;
|
|
|
1630 |
break;
|
|
|
1631 |
case DISPLAY_ROW_ALIGN_4:
|
|
|
1632 |
align = 4;
|
|
|
1633 |
break;
|
|
|
1634 |
case DISPLAY_ROW_ALIGN_8:
|
|
|
1635 |
align = 8;
|
|
|
1636 |
break;
|
|
|
1637 |
case DISPLAY_ROW_ALIGN_16:
|
|
|
1638 |
align = 16;
|
|
|
1639 |
break;
|
|
|
1640 |
case DISPLAY_ROW_ALIGN_32:
|
|
|
1641 |
align = 32;
|
|
|
1642 |
break;
|
|
|
1643 |
case DISPLAY_ROW_ALIGN_64:
|
|
|
1644 |
align = 64;
|
|
|
1645 |
break;
|
|
|
1646 |
default:
|
|
|
1647 |
align = 0; /* not permitted */
|
|
|
1648 |
}
|
|
|
1649 |
if (align < ARCH_ALIGN_PTR_MOD)
|
|
|
1650 |
return_error(gs_error_rangecheck);
|
|
|
1651 |
|
|
|
1652 |
switch (ddev->nFormat & DISPLAY_ALPHA_MASK) {
|
|
|
1653 |
case DISPLAY_ALPHA_FIRST:
|
|
|
1654 |
case DISPLAY_ALPHA_LAST:
|
|
|
1655 |
/* Not implemented and unlikely to ever be implemented
|
|
|
1656 |
* because they would interact with linear_and_separable
|
|
|
1657 |
*/
|
|
|
1658 |
return_error(gs_error_rangecheck);
|
|
|
1659 |
}
|
|
|
1660 |
|
|
|
1661 |
switch (nFormat & DISPLAY_COLORS_MASK) {
|
|
|
1662 |
case DISPLAY_COLORS_NATIVE:
|
|
|
1663 |
switch (nFormat & DISPLAY_DEPTH_MASK) {
|
|
|
1664 |
case DISPLAY_DEPTH_1:
|
|
|
1665 |
/* 1bit/pixel, black is 1, white is 0 */
|
|
|
1666 |
set_color_info(&dci, DISPLAY_MODEL_GRAY, 1, 1, 1, 0);
|
|
|
1667 |
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
|
|
|
1668 |
set_gray_color_procs(pdev, gx_b_w_gray_encode,
|
|
|
1669 |
gx_default_b_w_map_color_rgb);
|
|
|
1670 |
break;
|
|
|
1671 |
case DISPLAY_DEPTH_4:
|
|
|
1672 |
/* 4bit/pixel VGA color */
|
|
|
1673 |
set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 4, 3, 2);
|
|
|
1674 |
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
|
|
|
1675 |
set_rgb_color_procs(pdev, display_map_rgb_color_device4,
|
|
|
1676 |
display_map_color_rgb_device4);
|
|
|
1677 |
break;
|
|
|
1678 |
case DISPLAY_DEPTH_8:
|
|
|
1679 |
/* 8bit/pixel 96 color palette */
|
|
|
1680 |
set_color_info(&dci, DISPLAY_MODEL_RGBK, 4, 8, 31, 3);
|
|
|
1681 |
dci.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
|
|
|
1682 |
set_rgbk_color_procs(pdev, display_encode_color_device8,
|
|
|
1683 |
display_decode_color_device8);
|
|
|
1684 |
break;
|
|
|
1685 |
case DISPLAY_DEPTH_16:
|
|
|
1686 |
/* Windows 16-bit display */
|
|
|
1687 |
/* Is maxgray = maxcolor = 63 correct? */
|
|
|
1688 |
if ((ddev->nFormat & DISPLAY_555_MASK)
|
|
|
1689 |
== DISPLAY_NATIVE_555)
|
|
|
1690 |
set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 16, 31, 31);
|
|
|
1691 |
else
|
|
|
1692 |
set_color_info(&dci, DISPLAY_MODEL_RGB, 3, 16, 63, 63);
|
|
|
1693 |
set_rgb_color_procs(pdev, display_map_rgb_color_device16,
|
|
|
1694 |
display_map_color_rgb_device16);
|
|
|
1695 |
break;
|
|
|
1696 |
default:
|
|
|
1697 |
return_error(gs_error_rangecheck);
|
|
|
1698 |
}
|
|
|
1699 |
dci.gray_index = GX_CINFO_COMP_NO_INDEX;
|
|
|
1700 |
break;
|
|
|
1701 |
case DISPLAY_COLORS_GRAY:
|
|
|
1702 |
set_color_info(&dci, DISPLAY_MODEL_GRAY, 1, bpc, maxvalue, 0);
|
|
|
1703 |
if (bpc == 1)
|
|
|
1704 |
set_gray_color_procs(pdev, gx_default_gray_encode,
|
|
|
1705 |
gx_default_w_b_map_color_rgb);
|
|
|
1706 |
else
|
|
|
1707 |
set_gray_color_procs(pdev, gx_default_gray_encode,
|
|
|
1708 |
gx_default_gray_map_color_rgb);
|
|
|
1709 |
break;
|
|
|
1710 |
case DISPLAY_COLORS_RGB:
|
|
|
1711 |
if ((nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)
|
|
|
1712 |
bpp = bpc * 3;
|
|
|
1713 |
else
|
|
|
1714 |
bpp = bpc * 4;
|
|
|
1715 |
set_color_info(&dci, DISPLAY_MODEL_RGB, 3, bpp, maxvalue, maxvalue);
|
|
|
1716 |
if (((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) &&
|
|
|
1717 |
((nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)) {
|
|
|
1718 |
if ((nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
|
|
|
1719 |
set_rgb_color_procs(pdev, gx_default_rgb_map_rgb_color,
|
|
|
1720 |
gx_default_rgb_map_color_rgb);
|
|
|
1721 |
else
|
|
|
1722 |
set_rgb_color_procs(pdev, display_map_rgb_color_bgr24,
|
|
|
1723 |
display_map_color_rgb_bgr24);
|
|
|
1724 |
}
|
|
|
1725 |
else {
|
|
|
1726 |
/* slower flexible functions for alpha/unused component */
|
|
|
1727 |
set_rgb_color_procs(pdev, display_map_rgb_color_rgb,
|
|
|
1728 |
display_map_color_rgb_rgb);
|
|
|
1729 |
}
|
|
|
1730 |
break;
|
|
|
1731 |
case DISPLAY_COLORS_CMYK:
|
|
|
1732 |
bpp = bpc * 4;
|
|
|
1733 |
set_color_info(&dci, DISPLAY_MODEL_CMYK, 4, bpp, maxvalue, maxvalue);
|
|
|
1734 |
if ((nFormat & DISPLAY_ALPHA_MASK) != DISPLAY_ALPHA_NONE)
|
|
|
1735 |
return_error(gs_error_rangecheck);
|
|
|
1736 |
if ((nFormat & DISPLAY_ENDIAN_MASK) != DISPLAY_BIGENDIAN)
|
|
|
1737 |
return_error(gs_error_rangecheck);
|
|
|
1738 |
|
|
|
1739 |
if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_1)
|
|
|
1740 |
set_cmyk_color_procs(pdev, cmyk_1bit_map_cmyk_color,
|
|
|
1741 |
cmyk_1bit_map_color_cmyk);
|
|
|
1742 |
else if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8)
|
|
|
1743 |
set_cmyk_color_procs(pdev, cmyk_8bit_map_cmyk_color,
|
|
|
1744 |
cmyk_8bit_map_color_cmyk);
|
|
|
1745 |
else
|
|
|
1746 |
return_error(gs_error_rangecheck);
|
|
|
1747 |
break;
|
|
|
1748 |
case DISPLAY_COLORS_SEPARATION:
|
|
|
1749 |
if ((nFormat & DISPLAY_ENDIAN_MASK) != DISPLAY_BIGENDIAN)
|
|
|
1750 |
return_error(gs_error_rangecheck);
|
|
|
1751 |
bpp = arch_sizeof_color_index * 8;
|
|
|
1752 |
set_color_info(&dci, DISPLAY_MODEL_SEP, bpp/bpc, bpp,
|
|
|
1753 |
maxvalue, maxvalue);
|
|
|
1754 |
if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) {
|
|
|
1755 |
ddev->devn_params.bitspercomponent = bpc;
|
|
|
1756 |
set_color_procs(pdev,
|
|
|
1757 |
display_separation_encode_color,
|
|
|
1758 |
display_separation_decode_color,
|
|
|
1759 |
display_separation_get_color_mapping_procs,
|
|
|
1760 |
display_separation_get_color_comp_index);
|
|
|
1761 |
}
|
|
|
1762 |
else
|
|
|
1763 |
return_error(gs_error_rangecheck);
|
|
|
1764 |
break;
|
|
|
1765 |
default:
|
|
|
1766 |
return_error(gs_error_rangecheck);
|
|
|
1767 |
}
|
|
|
1768 |
|
|
|
1769 |
/* restore old anti_alias info */
|
|
|
1770 |
dci.anti_alias = ddev->color_info.anti_alias;
|
|
|
1771 |
ddev->color_info = dci;
|
|
|
1772 |
check_device_separable(pdev);
|
|
|
1773 |
switch (nFormat & DISPLAY_COLORS_MASK) {
|
|
|
1774 |
case DISPLAY_COLORS_NATIVE:
|
|
|
1775 |
ddev->color_info.gray_index = GX_CINFO_COMP_NO_INDEX;
|
|
|
1776 |
if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_1)
|
|
|
1777 |
ddev->color_info.gray_index = 0;
|
|
|
1778 |
else if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8)
|
|
|
1779 |
ddev->color_info.gray_index = 3;
|
|
|
1780 |
break;
|
|
|
1781 |
case DISPLAY_COLORS_RGB:
|
|
|
1782 |
ddev->color_info.gray_index = GX_CINFO_COMP_NO_INDEX;
|
|
|
1783 |
break;
|
|
|
1784 |
case DISPLAY_COLORS_GRAY:
|
|
|
1785 |
ddev->color_info.gray_index = 0;
|
|
|
1786 |
break;
|
|
|
1787 |
case DISPLAY_COLORS_CMYK:
|
|
|
1788 |
ddev->color_info.gray_index = 3;
|
|
|
1789 |
break;
|
|
|
1790 |
case DISPLAY_COLORS_SEPARATION:
|
|
|
1791 |
ddev->color_info.gray_index = GX_CINFO_COMP_NO_INDEX;
|
|
|
1792 |
break;
|
|
|
1793 |
}
|
|
|
1794 |
ddev->nFormat = nFormat;
|
|
|
1795 |
|
|
|
1796 |
return 0;
|
|
|
1797 |
}
|
|
|
1798 |
|
|
|
1799 |
/* ------ Begin Test Code ------ */
|
|
|
1800 |
|
|
|
1801 |
/*********************************************************************
|
|
|
1802 |
typedef struct test_mode_s test_mode;
|
|
|
1803 |
struct test_mode_s {
|
|
|
1804 |
char *name;
|
|
|
1805 |
unsigned int format;
|
|
|
1806 |
};
|
|
|
1807 |
|
|
|
1808 |
test_mode test_modes[] = {
|
|
|
1809 |
{"1bit/pixel native, black is 1, Windows",
|
|
|
1810 |
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
|
|
|
1811 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1812 |
{"4bit/pixel native, Windows VGA 16 color palette",
|
|
|
1813 |
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_4 |
|
|
|
1814 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1815 |
{"8bit/pixel native, Windows SVGA 96 color palette",
|
|
|
1816 |
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
|
|
|
1817 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1818 |
{"16bit/pixel native, Windows BGR555",
|
|
|
1819 |
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_16 |
|
|
|
1820 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_NATIVE_555},
|
|
|
1821 |
{"16bit/pixel native, Windows BGR565",
|
|
|
1822 |
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_16 |
|
|
|
1823 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_NATIVE_565},
|
|
|
1824 |
{"1bit/pixel gray, black is 0, topfirst",
|
|
|
1825 |
DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
|
|
|
1826 |
DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
|
|
|
1827 |
{"4bit/pixel gray, bottom first",
|
|
|
1828 |
DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_4 |
|
|
|
1829 |
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1830 |
{"8bit/pixel gray, bottom first",
|
|
|
1831 |
DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
|
|
|
1832 |
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1833 |
{"24bit/pixel color, bottom first, Windows BGR24",
|
|
|
1834 |
DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
|
|
|
1835 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1836 |
{"24bit/pixel color, bottom first, RGB24",
|
|
|
1837 |
DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
|
|
|
1838 |
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1839 |
{"24bit/pixel color, top first, GdkRgb RGB24",
|
|
|
1840 |
DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
|
|
|
1841 |
DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
|
|
|
1842 |
{"32bit/pixel color, top first, Macintosh xRGB",
|
|
|
1843 |
DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST | DISPLAY_DEPTH_8 |
|
|
|
1844 |
DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
|
|
|
1845 |
{"32bit/pixel color, bottom first, xBGR",
|
|
|
1846 |
DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST | DISPLAY_DEPTH_8 |
|
|
|
1847 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1848 |
{"32bit/pixel color, bottom first, Windows BGRx",
|
|
|
1849 |
DISPLAY_COLORS_RGB | DISPLAY_UNUSED_LAST | DISPLAY_DEPTH_8 |
|
|
|
1850 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1851 |
{"32bit/pixel color, bottom first, RGBx",
|
|
|
1852 |
DISPLAY_COLORS_RGB | DISPLAY_UNUSED_LAST | DISPLAY_DEPTH_8 |
|
|
|
1853 |
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1854 |
{"32bit/pixel CMYK, bottom first",
|
|
|
1855 |
DISPLAY_COLORS_CMYK | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
|
|
|
1856 |
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1857 |
{"64bit/pixel separations, bottom first",
|
|
|
1858 |
DISPLAY_COLORS_SEPARATIONS | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
|
|
|
1859 |
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1860 |
{"4bit/pixel CMYK, bottom first",
|
|
|
1861 |
DISPLAY_COLORS_CMYK | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
|
|
|
1862 |
DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
|
|
|
1863 |
{"1bit/pixel native, black is 1, 8 byte alignment",
|
|
|
1864 |
DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
|
|
|
1865 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_ROW_ALIGN_8},
|
|
|
1866 |
{"24bit/pixel color, bottom first, BGR24, 64 byte alignment",
|
|
|
1867 |
DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
|
|
|
1868 |
DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_ROW_ALIGN_64}
|
|
|
1869 |
};
|
|
|
1870 |
|
|
|
1871 |
void
|
|
|
1872 |
test(int index)
|
|
|
1873 |
{
|
|
|
1874 |
char buf[1024];
|
|
|
1875 |
sprintf(buf, "gs -dDisplayFormat=16#%x examples/colorcir.ps -c quit", test_modes[index].format);
|
|
|
1876 |
system(buf);
|
|
|
1877 |
}
|
|
|
1878 |
|
|
|
1879 |
int main(int argc, char *argv[])
|
|
|
1880 |
{
|
|
|
1881 |
int i;
|
|
|
1882 |
int dotest = 0;
|
|
|
1883 |
if (argc >=2) {
|
|
|
1884 |
if (strcmp(argv[1], "-t") == 0)
|
|
|
1885 |
dotest = 1;
|
|
|
1886 |
else {
|
|
|
1887 |
fprintf(stdout, "To show modes: disp\nTo run test: disp -t\n");
|
|
|
1888 |
return 1;
|
|
|
1889 |
}
|
|
|
1890 |
}
|
|
|
1891 |
for (i=0; i < sizeof(test_modes)/sizeof(test_mode); i++) {
|
|
|
1892 |
fprintf(stdout, "16#%x or %d: %s\n", test_modes[i].format,
|
|
|
1893 |
test_modes[i].format, test_modes[i].name);
|
|
|
1894 |
if (dotest)
|
|
|
1895 |
test(i);
|
|
|
1896 |
}
|
|
|
1897 |
return 0;
|
|
|
1898 |
}
|
|
|
1899 |
*********************************************************************/
|
|
|
1900 |
|
|
|
1901 |
/* ------ End Test Code ------ */
|