2 |
- |
1 |
/* Copyright (C) 1995, 2000 Aladdin Enterprises. 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 |
/* $Id: gdevdflt.c,v 1.25 2005/03/14 18:08:36 dan Exp $ */
|
|
|
18 |
/* Default device implementation */
|
|
|
19 |
#include "math_.h"
|
|
|
20 |
#include "gx.h"
|
|
|
21 |
#include "gserrors.h"
|
|
|
22 |
#include "gsropt.h"
|
|
|
23 |
#include "gxcomp.h"
|
|
|
24 |
#include "gxdevice.h"
|
|
|
25 |
|
|
|
26 |
/* ---------------- Default device procedures ---------------- */
|
|
|
27 |
|
|
|
28 |
/*
|
|
|
29 |
* Set a color model polarity to be additive or subtractive. In either
|
|
|
30 |
* case, indicate an error (and don't modify the polarity) if the current
|
|
|
31 |
* setting differs from the desired and is not GX_CINFO_POLARITY_UNKNOWN.
|
|
|
32 |
*/
|
|
|
33 |
static void
|
|
|
34 |
set_cinfo_polarity(gx_device * dev, gx_color_polarity_t new_polarity)
|
|
|
35 |
{
|
|
|
36 |
#ifdef DEBUG
|
|
|
37 |
/* sanity check */
|
|
|
38 |
if (new_polarity == GX_CINFO_POLARITY_UNKNOWN) {
|
|
|
39 |
dprintf("set_cinfo_polarity: illegal operand");
|
|
|
40 |
return;
|
|
|
41 |
}
|
|
|
42 |
#endif
|
|
|
43 |
/*
|
|
|
44 |
* The meory devices assume that single color devices are gray.
|
|
|
45 |
* This may not be true if SeparationOrder is specified. Thus only
|
|
|
46 |
* change the value if the current value is unknown.
|
|
|
47 |
*/
|
|
|
48 |
if (dev->color_info.polarity == GX_CINFO_POLARITY_UNKNOWN)
|
|
|
49 |
dev->color_info.polarity = new_polarity;
|
|
|
50 |
}
|
|
|
51 |
|
|
|
52 |
|
|
|
53 |
private gx_color_index
|
|
|
54 |
(*get_encode_color(gx_device *dev))(gx_device *, const gx_color_value *)
|
|
|
55 |
{
|
|
|
56 |
dev_proc_encode_color(*encode_proc);
|
|
|
57 |
|
|
|
58 |
/* use encode_color if it has been provided */
|
|
|
59 |
if ((encode_proc = dev_proc(dev, encode_color)) == 0) {
|
|
|
60 |
if (dev->color_info.num_components == 1 &&
|
|
|
61 |
dev_proc(dev, map_rgb_color) != 0) {
|
|
|
62 |
set_cinfo_polarity(dev, GX_CINFO_POLARITY_ADDITIVE);
|
|
|
63 |
encode_proc = gx_backwards_compatible_gray_encode;
|
|
|
64 |
} else if ( (dev->color_info.num_components == 3 ) &&
|
|
|
65 |
(encode_proc = dev_proc(dev, map_rgb_color)) != 0 )
|
|
|
66 |
set_cinfo_polarity(dev, GX_CINFO_POLARITY_ADDITIVE);
|
|
|
67 |
else if ( dev->color_info.num_components == 4 &&
|
|
|
68 |
(encode_proc = dev_proc(dev, map_cmyk_color)) != 0 )
|
|
|
69 |
set_cinfo_polarity(dev, GX_CINFO_POLARITY_SUBTRACTIVE);
|
|
|
70 |
}
|
|
|
71 |
|
|
|
72 |
/*
|
|
|
73 |
* If no encode_color procedure at this point, the color model had
|
|
|
74 |
* better be monochrome (though not necessarily bi-level). In this
|
|
|
75 |
* case, it is assumed to be additive, as that is consistent with
|
|
|
76 |
* the pre-DeviceN code.
|
|
|
77 |
*
|
|
|
78 |
* If this is not the case, then the color model had better be known
|
|
|
79 |
* to be separable and linear, for there is no other way to derive
|
|
|
80 |
* an encoding. This is the case even for weakly linear and separable
|
|
|
81 |
* color models with a known polarity.
|
|
|
82 |
*/
|
|
|
83 |
if (encode_proc == 0) {
|
|
|
84 |
if (dev->color_info.num_components == 1 && dev->color_info.depth != 0) {
|
|
|
85 |
set_cinfo_polarity(dev, GX_CINFO_POLARITY_ADDITIVE);
|
|
|
86 |
if (dev->color_info.max_gray == (1 << dev->color_info.depth) - 1)
|
|
|
87 |
encode_proc = gx_default_gray_fast_encode;
|
|
|
88 |
else
|
|
|
89 |
encode_proc = gx_default_gray_encode;
|
|
|
90 |
dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
|
|
|
91 |
} else if (dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN) {
|
|
|
92 |
gx_color_value max_gray = dev->color_info.max_gray;
|
|
|
93 |
gx_color_value max_color = dev->color_info.max_color;
|
|
|
94 |
|
|
|
95 |
if ( (max_gray & (max_gray + 1)) == 0 &&
|
|
|
96 |
(max_color & (max_color + 1)) == 0 )
|
|
|
97 |
/* NB should be gx_default_fast_encode_color */
|
|
|
98 |
encode_proc = gx_default_encode_color;
|
|
|
99 |
else
|
|
|
100 |
encode_proc = gx_default_encode_color;
|
|
|
101 |
} else
|
|
|
102 |
dprintf("get_encode_color: no color encoding information");
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
return encode_proc;
|
|
|
106 |
}
|
|
|
107 |
|
|
|
108 |
/*
|
|
|
109 |
* Determine if a color model has the properties of a DeviceRGB
|
|
|
110 |
* color model. This procedure is, in all likelihood, high-grade
|
|
|
111 |
* overkill, but since this is not a performance sensitive area
|
|
|
112 |
* no harm is done.
|
|
|
113 |
*
|
|
|
114 |
* Since there is little benefit to checking the values 0, 1, or
|
|
|
115 |
* 1/2, we use the values 1/4, 1/3, and 3/4 in their place. We
|
|
|
116 |
* compare the results to see if the intensities match to within
|
|
|
117 |
* a tolerance of .01, which is arbitrarily selected.
|
|
|
118 |
*/
|
|
|
119 |
|
|
|
120 |
private bool
|
|
|
121 |
is_like_DeviceRGB(gx_device * dev)
|
|
|
122 |
{
|
|
|
123 |
const gx_cm_color_map_procs * cm_procs;
|
|
|
124 |
frac cm_comp_fracs[3];
|
|
|
125 |
int i;
|
|
|
126 |
|
|
|
127 |
if ( dev->color_info.num_components != 3 ||
|
|
|
128 |
dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE )
|
|
|
129 |
return false;
|
|
|
130 |
cm_procs = dev_proc(dev, get_color_mapping_procs)(dev);
|
|
|
131 |
if (cm_procs == 0 || cm_procs->map_rgb == 0)
|
|
|
132 |
return false;
|
|
|
133 |
|
|
|
134 |
/* check the values 1/4, 1/3, and 3/4 */
|
|
|
135 |
cm_procs->map_rgb( dev,
|
|
|
136 |
0,
|
|
|
137 |
frac_1 / 4,
|
|
|
138 |
frac_1 / 3,
|
|
|
139 |
3 * frac_1 / 4,
|
|
|
140 |
cm_comp_fracs );
|
|
|
141 |
|
|
|
142 |
/* verify results to .01 */
|
|
|
143 |
cm_comp_fracs[0] -= frac_1 / 4;
|
|
|
144 |
cm_comp_fracs[1] -= frac_1 / 3;
|
|
|
145 |
cm_comp_fracs[2] -= 3 * frac_1 / 4;
|
|
|
146 |
for ( i = 0;
|
|
|
147 |
i < 3 &&
|
|
|
148 |
-frac_1 / 100 < cm_comp_fracs[i] &&
|
|
|
149 |
cm_comp_fracs[i] < frac_1 / 100;
|
|
|
150 |
i++ )
|
|
|
151 |
;
|
|
|
152 |
return i == 3;
|
|
|
153 |
}
|
|
|
154 |
|
|
|
155 |
/*
|
|
|
156 |
* Similar to is_like_DeviceRGB, but for DeviceCMYK.
|
|
|
157 |
*/
|
|
|
158 |
private bool
|
|
|
159 |
is_like_DeviceCMYK(gx_device * dev)
|
|
|
160 |
{
|
|
|
161 |
const gx_cm_color_map_procs * cm_procs;
|
|
|
162 |
frac cm_comp_fracs[4];
|
|
|
163 |
int i;
|
|
|
164 |
|
|
|
165 |
if ( dev->color_info.num_components != 4 ||
|
|
|
166 |
dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE )
|
|
|
167 |
return false;
|
|
|
168 |
cm_procs = dev_proc(dev, get_color_mapping_procs)(dev);
|
|
|
169 |
if (cm_procs == 0 || cm_procs->map_cmyk == 0)
|
|
|
170 |
return false;
|
|
|
171 |
|
|
|
172 |
/* check the values 1/4, 1/3, 3/4, and 1/8 */
|
|
|
173 |
cm_procs->map_cmyk( dev,
|
|
|
174 |
frac_1 / 4,
|
|
|
175 |
frac_1 / 3,
|
|
|
176 |
3 * frac_1 / 4,
|
|
|
177 |
frac_1 / 8,
|
|
|
178 |
cm_comp_fracs );
|
|
|
179 |
|
|
|
180 |
/* verify results to .01 */
|
|
|
181 |
cm_comp_fracs[0] -= frac_1 / 4;
|
|
|
182 |
cm_comp_fracs[1] -= frac_1 / 3;
|
|
|
183 |
cm_comp_fracs[2] -= 3 * frac_1 / 4;
|
|
|
184 |
cm_comp_fracs[3] -= frac_1 / 8;
|
|
|
185 |
for ( i = 0;
|
|
|
186 |
i < 4 &&
|
|
|
187 |
-frac_1 / 100 < cm_comp_fracs[i] &&
|
|
|
188 |
cm_comp_fracs[i] < frac_1 / 100;
|
|
|
189 |
i++ )
|
|
|
190 |
;
|
|
|
191 |
return i == 4;
|
|
|
192 |
}
|
|
|
193 |
|
|
|
194 |
/*
|
|
|
195 |
* Two default decode_color procedures to use for monochrome devices.
|
|
|
196 |
* These will make use of the map_color_rgb routine, and use the first
|
|
|
197 |
* component of the returned value or its inverse.
|
|
|
198 |
*/
|
|
|
199 |
private int
|
|
|
200 |
gx_default_1_add_decode_color(
|
|
|
201 |
gx_device * dev,
|
|
|
202 |
gx_color_index color,
|
|
|
203 |
gx_color_value cv[1] )
|
|
|
204 |
{
|
|
|
205 |
gx_color_value rgb[3];
|
|
|
206 |
int code = dev_proc(dev, map_color_rgb)(dev, color, rgb);
|
|
|
207 |
|
|
|
208 |
cv[0] = rgb[0];
|
|
|
209 |
return code;
|
|
|
210 |
}
|
|
|
211 |
|
|
|
212 |
private int
|
|
|
213 |
gx_default_1_sub_decode_color(
|
|
|
214 |
gx_device * dev,
|
|
|
215 |
gx_color_index color,
|
|
|
216 |
gx_color_value cv[1] )
|
|
|
217 |
{
|
|
|
218 |
gx_color_value rgb[3];
|
|
|
219 |
int code = dev_proc(dev, map_color_rgb)(dev, color, rgb);
|
|
|
220 |
|
|
|
221 |
cv[0] = gx_max_color_value - rgb[0];
|
|
|
222 |
return code;
|
|
|
223 |
}
|
|
|
224 |
|
|
|
225 |
/*
|
|
|
226 |
* A default decode_color procedure for DeviceCMYK color models.
|
|
|
227 |
*
|
|
|
228 |
* There is no generally accurate way of decode a DeviceCMYK color using
|
|
|
229 |
* the map_color_rgb method. Unfortunately, there are many older devices
|
|
|
230 |
* employ the DeviceCMYK color model but don't provide a decode_color
|
|
|
231 |
* method. The code below works on the assumption of full undercolor
|
|
|
232 |
* removal and black generation. This may not be accurate, but is the
|
|
|
233 |
* best that can be done in the general case without other information.
|
|
|
234 |
*/
|
|
|
235 |
private int
|
|
|
236 |
gx_default_cmyk_decode_color(
|
|
|
237 |
gx_device * dev,
|
|
|
238 |
gx_color_index color,
|
|
|
239 |
gx_color_value cv[4] )
|
|
|
240 |
{
|
|
|
241 |
/* The device may have been determined to be 'separable'. */
|
|
|
242 |
if (dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN)
|
|
|
243 |
return gx_default_decode_color(dev, color, cv);
|
|
|
244 |
else {
|
|
|
245 |
int i, code = dev_proc(dev, map_color_rgb)(dev, color, cv);
|
|
|
246 |
gx_color_value min_val = gx_max_color_value;
|
|
|
247 |
|
|
|
248 |
for (i = 0; i < 3; i++) {
|
|
|
249 |
if ((cv[i] = gx_max_color_value - cv[i]) < min_val)
|
|
|
250 |
min_val = cv[i];
|
|
|
251 |
}
|
|
|
252 |
for (i = 0; i < 3; i++)
|
|
|
253 |
cv[i] -= min_val;
|
|
|
254 |
cv[3] = min_val;
|
|
|
255 |
|
|
|
256 |
return code;
|
|
|
257 |
}
|
|
|
258 |
}
|
|
|
259 |
|
|
|
260 |
/*
|
|
|
261 |
* Special case default color decode routine for a canonical 1-bit per
|
|
|
262 |
* component DeviceCMYK color model.
|
|
|
263 |
*/
|
|
|
264 |
private int
|
|
|
265 |
gx_1bit_cmyk_decode_color(
|
|
|
266 |
gx_device * dev,
|
|
|
267 |
gx_color_index color,
|
|
|
268 |
gx_color_value cv[4] )
|
|
|
269 |
{
|
|
|
270 |
cv[0] = ((color & 0x8) != 0 ? gx_max_color_value : 0);
|
|
|
271 |
cv[1] = ((color & 0x4) != 0 ? gx_max_color_value : 0);
|
|
|
272 |
cv[2] = ((color & 0x2) != 0 ? gx_max_color_value : 0);
|
|
|
273 |
cv[3] = ((color & 0x1) != 0 ? gx_max_color_value : 0);
|
|
|
274 |
return 0;
|
|
|
275 |
}
|
|
|
276 |
|
|
|
277 |
private int
|
|
|
278 |
(*get_decode_color(gx_device * dev))(gx_device *, gx_color_index, gx_color_value *)
|
|
|
279 |
{
|
|
|
280 |
/* if a method has already been provided, use it */
|
|
|
281 |
if (dev_proc(dev, decode_color) != 0)
|
|
|
282 |
return dev_proc(dev, decode_color);
|
|
|
283 |
|
|
|
284 |
/*
|
|
|
285 |
* If a map_color_rgb method has been provided, we may be able to use it.
|
|
|
286 |
* Currently this will always be the case, as a default value will be
|
|
|
287 |
* provided this method. While this default may not be correct, we are not
|
|
|
288 |
* introducing any new errors by using it.
|
|
|
289 |
*/
|
|
|
290 |
if (dev_proc(dev, map_color_rgb) != 0) {
|
|
|
291 |
|
|
|
292 |
/* if the device has a DeviceRGB color model, use map_color_rgb */
|
|
|
293 |
if (is_like_DeviceRGB(dev))
|
|
|
294 |
return dev_proc(dev, map_color_rgb);
|
|
|
295 |
|
|
|
296 |
/* If separable ande linear then use default */
|
|
|
297 |
if ( dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN )
|
|
|
298 |
return &gx_default_decode_color;
|
|
|
299 |
|
|
|
300 |
/* gray devices can be handled based on their polarity */
|
|
|
301 |
if ( dev->color_info.num_components == 1 &&
|
|
|
302 |
dev->color_info.gray_index == 0 )
|
|
|
303 |
return dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE
|
|
|
304 |
? &gx_default_1_add_decode_color
|
|
|
305 |
: &gx_default_1_sub_decode_color;
|
|
|
306 |
|
|
|
307 |
/*
|
|
|
308 |
* There is no accurate way to decode colors for cmyk devices
|
|
|
309 |
* using the map_color_rgb procedure. Unfortunately, this cases
|
|
|
310 |
* arises with some frequency, so it is useful not to generate an
|
|
|
311 |
* error in this case. The mechanism below assumes full undercolor
|
|
|
312 |
* removal and black generation, which may not be accurate but are
|
|
|
313 |
* the best that can be done in the general case in the absence of
|
|
|
314 |
* other information.
|
|
|
315 |
*
|
|
|
316 |
* As a hack to handle certain common devices, if the map_rgb_color
|
|
|
317 |
* routine is cmyk_1bit_map_color_rgb, we provide a direct one-bit
|
|
|
318 |
* decoder.
|
|
|
319 |
*/
|
|
|
320 |
if (is_like_DeviceCMYK(dev)) {
|
|
|
321 |
if (dev_proc(dev, map_color_rgb) == cmyk_1bit_map_color_rgb)
|
|
|
322 |
return &gx_1bit_cmyk_decode_color;
|
|
|
323 |
else
|
|
|
324 |
return &gx_default_cmyk_decode_color;
|
|
|
325 |
}
|
|
|
326 |
}
|
|
|
327 |
|
|
|
328 |
/*
|
|
|
329 |
* The separable and linear case will already have been handled by
|
|
|
330 |
* code in gx_device_fill_in_procs, so at this point we can only hope
|
|
|
331 |
* the device doesn't use the decode_color method.
|
|
|
332 |
*/
|
|
|
333 |
if (dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN )
|
|
|
334 |
return &gx_default_decode_color;
|
|
|
335 |
else
|
|
|
336 |
return &gx_error_decode_color;
|
|
|
337 |
}
|
|
|
338 |
|
|
|
339 |
/*
|
|
|
340 |
* If a device has a linear and separable encode color function then
|
|
|
341 |
* set up the comp_bits, comp_mask, and comp_shift fields. Note: This
|
|
|
342 |
* routine assumes that the colorant shift factor decreases with the
|
|
|
343 |
* component number. See check_device_separable() for a general routine.
|
|
|
344 |
*/
|
|
|
345 |
void
|
|
|
346 |
set_linear_color_bits_mask_shift(gx_device * dev)
|
|
|
347 |
{
|
|
|
348 |
int i;
|
|
|
349 |
byte gray_index = dev->color_info.gray_index;
|
|
|
350 |
gx_color_value max_gray = dev->color_info.max_gray;
|
|
|
351 |
gx_color_value max_color = dev->color_info.max_color;
|
|
|
352 |
int num_components = dev->color_info.num_components;
|
|
|
353 |
|
|
|
354 |
#define comp_bits (dev->color_info.comp_bits)
|
|
|
355 |
#define comp_mask (dev->color_info.comp_mask)
|
|
|
356 |
#define comp_shift (dev->color_info.comp_shift)
|
|
|
357 |
comp_shift[num_components - 1] = 0;
|
|
|
358 |
for ( i = num_components - 1 - 1; i >= 0; i-- ) {
|
|
|
359 |
comp_shift[i] = comp_shift[i + 1] +
|
|
|
360 |
( i == gray_index ? ilog2(max_gray + 1) : ilog2(max_color + 1) );
|
|
|
361 |
}
|
|
|
362 |
for ( i = 0; i < num_components; i++ ) {
|
|
|
363 |
comp_bits[i] = ( i == gray_index ?
|
|
|
364 |
ilog2(max_gray + 1) :
|
|
|
365 |
ilog2(max_color + 1) );
|
|
|
366 |
comp_mask[i] = (((gx_color_index)1 << comp_bits[i]) - 1)
|
|
|
367 |
<< comp_shift[i];
|
|
|
368 |
}
|
|
|
369 |
#undef comp_bits
|
|
|
370 |
#undef comp_mask
|
|
|
371 |
#undef comp_shift
|
|
|
372 |
}
|
|
|
373 |
|
|
|
374 |
/* Determine if a number is a power of two. Works only for integers. */
|
|
|
375 |
#define is_power_of_two(x) ((((x) - 1) & (x)) == 0)
|
|
|
376 |
|
|
|
377 |
/*
|
|
|
378 |
* This routine attempts to determine if a device's encode_color procedure
|
|
|
379 |
* produces gx_color_index values which are 'separable'. A 'separable' value
|
|
|
380 |
* means two things. Each colorant has a group of bits in the gx_color_index
|
|
|
381 |
* value which is associated with the colorant. These bits are separate.
|
|
|
382 |
* I.e. no bit is associated with more than one colorant. If a colorant has
|
|
|
383 |
* a value of zero then the bits associated with that colorant are zero.
|
|
|
384 |
* These criteria allows the graphics library to build gx_color_index values
|
|
|
385 |
* from the colorant values and not using the encode_color routine. This is
|
|
|
386 |
* useful and necessary for overprinting, the WTS screeening, halftoning more
|
|
|
387 |
* than four colorants, and the fast shading logic. However this information
|
|
|
388 |
* is not setup by the default device macros. Thus we attempt to derive this
|
|
|
389 |
* information.
|
|
|
390 |
*
|
|
|
391 |
* This routine can be fooled. However it usually errors on the side of
|
|
|
392 |
* assuing that a device is not separable. In this case it does not create
|
|
|
393 |
* any new problems. In theory it can be fooled into believing that a device
|
|
|
394 |
* is separable when it is not. However we do not know of any real cases that
|
|
|
395 |
* will fool it.
|
|
|
396 |
*/
|
|
|
397 |
void
|
|
|
398 |
check_device_separable(gx_device * dev)
|
|
|
399 |
{
|
|
|
400 |
int i, j;
|
|
|
401 |
gx_device_color_info * pinfo = &(dev->color_info);
|
|
|
402 |
int num_components = pinfo->num_components;
|
|
|
403 |
byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
|
|
|
404 |
byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
|
|
|
405 |
gx_color_index comp_mask[GX_DEVICE_COLOR_MAX_COMPONENTS];
|
|
|
406 |
gx_color_index color_index;
|
|
|
407 |
gx_color_index current_bits = 0;
|
|
|
408 |
gx_color_value colorants[GX_DEVICE_COLOR_MAX_COMPONENTS] = { 0 };
|
|
|
409 |
|
|
|
410 |
/* If this is already known then we do not need to do anything. */
|
|
|
411 |
if (pinfo->separable_and_linear != GX_CINFO_UNKNOWN_SEP_LIN)
|
|
|
412 |
return;
|
|
|
413 |
/* If there is not an encode_color_routine then we cannot proceed. */
|
|
|
414 |
if (dev_proc(dev, encode_color) == NULL)
|
|
|
415 |
return;
|
|
|
416 |
/*
|
|
|
417 |
* If these values do not check then we should have an error. However
|
|
|
418 |
* we do not know what to do so we are simply exitting and hoping that
|
|
|
419 |
* the device will clean up its values.
|
|
|
420 |
*/
|
|
|
421 |
if (pinfo->gray_index < num_components &&
|
|
|
422 |
(!pinfo->dither_grays || pinfo->dither_grays != (pinfo->max_gray + 1)))
|
|
|
423 |
return;
|
|
|
424 |
if ((num_components > 1 || pinfo->gray_index != 0) &&
|
|
|
425 |
(!pinfo->dither_colors || pinfo->dither_colors != (pinfo->max_color + 1)))
|
|
|
426 |
return;
|
|
|
427 |
/*
|
|
|
428 |
* If dither_grays or dither_colors is not a power of two then we assume
|
|
|
429 |
* that the device is not separable. In theory this not a requirement
|
|
|
430 |
* but it has been true for all of the devices that we have seen so far.
|
|
|
431 |
* This assumption also makes the logic in the next section easier.
|
|
|
432 |
*/
|
|
|
433 |
if (!is_power_of_two(pinfo->dither_grays)
|
|
|
434 |
|| !is_power_of_two(pinfo->dither_colors))
|
|
|
435 |
return;
|
|
|
436 |
/*
|
|
|
437 |
* Use the encode_color routine to try to verify that the device is
|
|
|
438 |
* separable and to determine the shift count, etc. for each colorant.
|
|
|
439 |
*/
|
|
|
440 |
color_index = dev_proc(dev, encode_color)(dev, colorants);
|
|
|
441 |
if (color_index != 0)
|
|
|
442 |
return; /* Exit if zero colorants produce a non zero index */
|
|
|
443 |
for (i = 0; i < num_components; i++) {
|
|
|
444 |
/* Check this colorant = max with all others = 0 */
|
|
|
445 |
for (j = 0; j < num_components; j++)
|
|
|
446 |
colorants[j] = 0;
|
|
|
447 |
colorants[i] = gx_max_color_value;
|
|
|
448 |
color_index = dev_proc(dev, encode_color)(dev, colorants);
|
|
|
449 |
if (color_index == 0) /* If no bits then we have a problem */
|
|
|
450 |
return;
|
|
|
451 |
if (color_index & current_bits) /* Check for overlapping bits */
|
|
|
452 |
return;
|
|
|
453 |
current_bits |= color_index;
|
|
|
454 |
comp_mask[i] = color_index;
|
|
|
455 |
/* Determine the shift count for the colorant */
|
|
|
456 |
for (j = 0; (color_index & 1) == 0 && color_index != 0; j++)
|
|
|
457 |
color_index >>= 1;
|
|
|
458 |
comp_shift[i] = j;
|
|
|
459 |
/* Determine the bit count for the colorant */
|
|
|
460 |
for (j = 0; color_index != 0; j++) {
|
|
|
461 |
if ((color_index & 1) == 0) /* check for non-consecutive bits */
|
|
|
462 |
return;
|
|
|
463 |
color_index >>= 1;
|
|
|
464 |
}
|
|
|
465 |
comp_bits[i] = j;
|
|
|
466 |
/*
|
|
|
467 |
* We could verify that the bit count matches the dither_grays or
|
|
|
468 |
* dither_colors values, but this is not really required unless we
|
|
|
469 |
* are halftoning. Thus we are allowing for non equal colorant sizes.
|
|
|
470 |
*/
|
|
|
471 |
/* Check for overlap with other colorant if they are all maxed */
|
|
|
472 |
for (j = 0; j < num_components; j++)
|
|
|
473 |
colorants[j] = gx_max_color_value;
|
|
|
474 |
colorants[i] = 0;
|
|
|
475 |
color_index = dev_proc(dev, encode_color)(dev, colorants);
|
|
|
476 |
if (color_index & comp_mask[i]) /* Check for overlapping bits */
|
|
|
477 |
return;
|
|
|
478 |
}
|
|
|
479 |
/* If we get to here then the device is very likely to be separable. */
|
|
|
480 |
pinfo->separable_and_linear = GX_CINFO_SEP_LIN;
|
|
|
481 |
for (i = 0; i < num_components; i++) {
|
|
|
482 |
pinfo->comp_shift[i] = comp_shift[i];
|
|
|
483 |
pinfo->comp_bits[i] = comp_bits[i];
|
|
|
484 |
pinfo->comp_mask[i] = comp_mask[i];
|
|
|
485 |
}
|
|
|
486 |
/*
|
|
|
487 |
* The 'gray_index' value allows one colorant to have a different number
|
|
|
488 |
* of shades from the remainder. Since the default macros only guess at
|
|
|
489 |
* an appropriate value, we are setting its value based upon the data that
|
|
|
490 |
* we just determined. Note: In some cases the macros set max_gray to 0
|
|
|
491 |
* and dither_grays to 1. This is not valid so ignore this case.
|
|
|
492 |
*/
|
|
|
493 |
for (i = 0; i < num_components; i++) {
|
|
|
494 |
int dither = 1 << comp_bits[i];
|
|
|
495 |
|
|
|
496 |
if (pinfo->dither_grays != 1 && dither == pinfo->dither_grays) {
|
|
|
497 |
pinfo->gray_index = i;
|
|
|
498 |
break;
|
|
|
499 |
}
|
|
|
500 |
}
|
|
|
501 |
}
|
|
|
502 |
#undef is_power_of_two
|
|
|
503 |
|
|
|
504 |
/* Fill in NULL procedures in a device procedure record. */
|
|
|
505 |
void
|
|
|
506 |
gx_device_fill_in_procs(register gx_device * dev)
|
|
|
507 |
{
|
|
|
508 |
gx_device_set_procs(dev);
|
|
|
509 |
fill_dev_proc(dev, open_device, gx_default_open_device);
|
|
|
510 |
fill_dev_proc(dev, get_initial_matrix, gx_default_get_initial_matrix);
|
|
|
511 |
fill_dev_proc(dev, sync_output, gx_default_sync_output);
|
|
|
512 |
fill_dev_proc(dev, output_page, gx_default_output_page);
|
|
|
513 |
fill_dev_proc(dev, close_device, gx_default_close_device);
|
|
|
514 |
/* see below for map_rgb_color */
|
|
|
515 |
fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
|
|
|
516 |
/* NOT fill_rectangle */
|
|
|
517 |
fill_dev_proc(dev, tile_rectangle, gx_default_tile_rectangle);
|
|
|
518 |
fill_dev_proc(dev, copy_mono, gx_default_copy_mono);
|
|
|
519 |
fill_dev_proc(dev, copy_color, gx_default_copy_color);
|
|
|
520 |
fill_dev_proc(dev, obsolete_draw_line, gx_default_draw_line);
|
|
|
521 |
fill_dev_proc(dev, get_bits, gx_default_get_bits);
|
|
|
522 |
fill_dev_proc(dev, get_params, gx_default_get_params);
|
|
|
523 |
fill_dev_proc(dev, put_params, gx_default_put_params);
|
|
|
524 |
/* see below for map_cmyk_color */
|
|
|
525 |
fill_dev_proc(dev, get_xfont_procs, gx_default_get_xfont_procs);
|
|
|
526 |
fill_dev_proc(dev, get_xfont_device, gx_default_get_xfont_device);
|
|
|
527 |
fill_dev_proc(dev, map_rgb_alpha_color, gx_default_map_rgb_alpha_color);
|
|
|
528 |
fill_dev_proc(dev, get_page_device, gx_default_get_page_device);
|
|
|
529 |
fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
|
|
|
530 |
fill_dev_proc(dev, copy_alpha, gx_default_copy_alpha);
|
|
|
531 |
fill_dev_proc(dev, get_band, gx_default_get_band);
|
|
|
532 |
fill_dev_proc(dev, copy_rop, gx_default_copy_rop);
|
|
|
533 |
fill_dev_proc(dev, fill_path, gx_default_fill_path);
|
|
|
534 |
fill_dev_proc(dev, stroke_path, gx_default_stroke_path);
|
|
|
535 |
fill_dev_proc(dev, fill_mask, gx_default_fill_mask);
|
|
|
536 |
fill_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid);
|
|
|
537 |
fill_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram);
|
|
|
538 |
fill_dev_proc(dev, fill_triangle, gx_default_fill_triangle);
|
|
|
539 |
fill_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line);
|
|
|
540 |
fill_dev_proc(dev, begin_image, gx_default_begin_image);
|
|
|
541 |
/*
|
|
|
542 |
* We always replace get_alpha_bits, image_data, and end_image with the
|
|
|
543 |
* new procedures, and, if in a DEBUG configuration, print a warning if
|
|
|
544 |
* the definitions aren't the default ones.
|
|
|
545 |
*/
|
|
|
546 |
#ifdef DEBUG
|
|
|
547 |
# define CHECK_NON_DEFAULT(proc, default, procname)\
|
|
|
548 |
BEGIN\
|
|
|
549 |
if ( dev_proc(dev, proc) != NULL && dev_proc(dev, proc) != default )\
|
|
|
550 |
dprintf2("**** Warning: device %s implements obsolete procedure %s\n",\
|
|
|
551 |
dev->dname, procname);\
|
|
|
552 |
END
|
|
|
553 |
#else
|
|
|
554 |
# define CHECK_NON_DEFAULT(proc, default, procname)\
|
|
|
555 |
DO_NOTHING
|
|
|
556 |
#endif
|
|
|
557 |
CHECK_NON_DEFAULT(get_alpha_bits, gx_default_get_alpha_bits,
|
|
|
558 |
"get_alpha_bits");
|
|
|
559 |
set_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits);
|
|
|
560 |
CHECK_NON_DEFAULT(image_data, gx_default_image_data, "image_data");
|
|
|
561 |
set_dev_proc(dev, image_data, gx_default_image_data);
|
|
|
562 |
CHECK_NON_DEFAULT(end_image, gx_default_end_image, "end_image");
|
|
|
563 |
set_dev_proc(dev, end_image, gx_default_end_image);
|
|
|
564 |
#undef CHECK_NON_DEFAULT
|
|
|
565 |
fill_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle);
|
|
|
566 |
fill_dev_proc(dev, strip_copy_rop, gx_default_strip_copy_rop);
|
|
|
567 |
fill_dev_proc(dev, get_clipping_box, gx_default_get_clipping_box);
|
|
|
568 |
fill_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image);
|
|
|
569 |
fill_dev_proc(dev, get_bits_rectangle, gx_default_get_bits_rectangle);
|
|
|
570 |
fill_dev_proc(dev, map_color_rgb_alpha, gx_default_map_color_rgb_alpha);
|
|
|
571 |
fill_dev_proc(dev, create_compositor, gx_default_create_compositor);
|
|
|
572 |
fill_dev_proc(dev, get_hardware_params, gx_default_get_hardware_params);
|
|
|
573 |
fill_dev_proc(dev, text_begin, gx_default_text_begin);
|
|
|
574 |
fill_dev_proc(dev, finish_copydevice, gx_default_finish_copydevice);
|
|
|
575 |
|
|
|
576 |
set_dev_proc(dev, encode_color, get_encode_color(dev));
|
|
|
577 |
if (dev->color_info.num_components == 3)
|
|
|
578 |
set_dev_proc(dev, map_rgb_color, dev_proc(dev, encode_color));
|
|
|
579 |
if (dev->color_info.num_components == 4)
|
|
|
580 |
set_dev_proc(dev, map_cmyk_color, dev_proc(dev, encode_color));
|
|
|
581 |
|
|
|
582 |
if ( dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ) {
|
|
|
583 |
fill_dev_proc(dev, encode_color, gx_default_encode_color);
|
|
|
584 |
fill_dev_proc(dev, map_cmyk_color, gx_default_encode_color);
|
|
|
585 |
fill_dev_proc(dev, map_rgb_color, gx_default_encode_color);
|
|
|
586 |
} else {
|
|
|
587 |
/* if it isn't set now punt */
|
|
|
588 |
fill_dev_proc(dev, encode_color, gx_error_encode_color);
|
|
|
589 |
fill_dev_proc(dev, map_cmyk_color, gx_error_encode_color);
|
|
|
590 |
fill_dev_proc(dev, map_rgb_color, gx_error_encode_color);
|
|
|
591 |
}
|
|
|
592 |
|
|
|
593 |
/*
|
|
|
594 |
* Fill in the color mapping procedures and the component index
|
|
|
595 |
* assignment procedure if they have not been provided by the client.
|
|
|
596 |
*
|
|
|
597 |
* Because it is difficult to provide default encoding procedures
|
|
|
598 |
* that handle level inversion, this code needs to check both
|
|
|
599 |
* the number of components and the polarity of color model.
|
|
|
600 |
*/
|
|
|
601 |
switch (dev->color_info.num_components) {
|
|
|
602 |
case 1: /* DeviceGray or DeviceInvertGray */
|
|
|
603 |
if (dev_proc(dev, get_color_mapping_procs) == NULL) {
|
|
|
604 |
/*
|
|
|
605 |
* If not gray then the device must provide the color
|
|
|
606 |
* mapping procs.
|
|
|
607 |
*/
|
|
|
608 |
if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
|
|
|
609 |
fill_dev_proc( dev,
|
|
|
610 |
get_color_mapping_procs,
|
|
|
611 |
gx_default_DevGray_get_color_mapping_procs );
|
|
|
612 |
}
|
|
|
613 |
}
|
|
|
614 |
fill_dev_proc( dev,
|
|
|
615 |
get_color_comp_index,
|
|
|
616 |
gx_default_DevGray_get_color_comp_index );
|
|
|
617 |
break;
|
|
|
618 |
|
|
|
619 |
case 3:
|
|
|
620 |
if (dev_proc(dev, get_color_mapping_procs) == NULL) {
|
|
|
621 |
if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
|
|
|
622 |
fill_dev_proc( dev,
|
|
|
623 |
get_color_mapping_procs,
|
|
|
624 |
gx_default_DevRGB_get_color_mapping_procs );
|
|
|
625 |
fill_dev_proc( dev,
|
|
|
626 |
get_color_comp_index,
|
|
|
627 |
gx_default_DevRGB_get_color_comp_index );
|
|
|
628 |
} else {
|
|
|
629 |
#if 0
|
|
|
630 |
fill_dev_proc( dev,
|
|
|
631 |
get_color_mapping_procs,
|
|
|
632 |
gx_default_DevCMY_get_color_mapping_procs );
|
|
|
633 |
fill_dev_proc( dev,
|
|
|
634 |
get_color_comp_index,
|
|
|
635 |
gx_default_DevCMY_get_color_comp_index );
|
|
|
636 |
#endif
|
|
|
637 |
}
|
|
|
638 |
}
|
|
|
639 |
break;
|
|
|
640 |
|
|
|
641 |
case 4:
|
|
|
642 |
fill_dev_proc(dev, get_color_mapping_procs, gx_default_DevCMYK_get_color_mapping_procs);
|
|
|
643 |
fill_dev_proc(dev, get_color_comp_index, gx_default_DevCMYK_get_color_comp_index);
|
|
|
644 |
break;
|
|
|
645 |
default: /* Unknown color model - set error handlers */
|
|
|
646 |
fill_dev_proc(dev, get_color_mapping_procs, gx_error_get_color_mapping_procs);
|
|
|
647 |
fill_dev_proc(dev, get_color_comp_index, gx_error_get_color_comp_index);
|
|
|
648 |
}
|
|
|
649 |
|
|
|
650 |
set_dev_proc(dev, decode_color, get_decode_color(dev));
|
|
|
651 |
fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb);
|
|
|
652 |
|
|
|
653 |
/*
|
|
|
654 |
* If the device is known not to support overprint mode, indicate this now.
|
|
|
655 |
* Note that we do not insist that a device be use a strict DeviceCMYK
|
|
|
656 |
* encoding; any color model that is subtractive and supports the cyan,
|
|
|
657 |
* magenta, yellow, and black color components will do. We defer a more
|
|
|
658 |
* explicit check until this information is explicitly required.
|
|
|
659 |
*/
|
|
|
660 |
if ( dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN &&
|
|
|
661 |
(dev->color_info.num_components < 4 ||
|
|
|
662 |
dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
|
|
|
663 |
dev->color_info.gray_index == GX_CINFO_COMP_NO_INDEX ) )
|
|
|
664 |
dev->color_info.opmode = GX_CINFO_OPMODE_NOT;
|
|
|
665 |
|
|
|
666 |
fill_dev_proc(dev, pattern_manage, gx_default_pattern_manage);
|
|
|
667 |
fill_dev_proc(dev, fill_rectangle_hl_color, gx_default_fill_rectangle_hl_color);
|
|
|
668 |
fill_dev_proc(dev, include_color_space, gx_default_include_color_space);
|
|
|
669 |
fill_dev_proc(dev, fill_linear_color_scanline, gx_default_fill_linear_color_scanline);
|
|
|
670 |
fill_dev_proc(dev, fill_linear_color_trapezoid, gx_default_fill_linear_color_trapezoid);
|
|
|
671 |
fill_dev_proc(dev, fill_linear_color_triangle, gx_default_fill_linear_color_triangle);
|
|
|
672 |
fill_dev_proc(dev, update_spot_equivalent_colors, gx_default_update_spot_equivalent_colors);
|
|
|
673 |
}
|
|
|
674 |
|
|
|
675 |
int
|
|
|
676 |
gx_default_open_device(gx_device * dev)
|
|
|
677 |
{
|
|
|
678 |
/* Initialize the separable status if not known. */
|
|
|
679 |
check_device_separable(dev);
|
|
|
680 |
return 0;
|
|
|
681 |
}
|
|
|
682 |
|
|
|
683 |
/* Get the initial matrix for a device with inverted Y. */
|
|
|
684 |
/* This includes essentially all printers and displays. */
|
|
|
685 |
void
|
|
|
686 |
gx_default_get_initial_matrix(gx_device * dev, register gs_matrix * pmat)
|
|
|
687 |
{
|
|
|
688 |
pmat->xx = dev->HWResolution[0] / 72.0; /* x_pixels_per_inch */
|
|
|
689 |
pmat->xy = 0;
|
|
|
690 |
pmat->yx = 0;
|
|
|
691 |
pmat->yy = dev->HWResolution[1] / -72.0; /* y_pixels_per_inch */
|
|
|
692 |
/****** tx/y is WRONG for devices with ******/
|
|
|
693 |
/****** arbitrary initial matrix ******/
|
|
|
694 |
pmat->tx = 0;
|
|
|
695 |
pmat->ty = (float)dev->height;
|
|
|
696 |
}
|
|
|
697 |
/* Get the initial matrix for a device with upright Y. */
|
|
|
698 |
/* This includes just a few printers and window systems. */
|
|
|
699 |
void
|
|
|
700 |
gx_upright_get_initial_matrix(gx_device * dev, register gs_matrix * pmat)
|
|
|
701 |
{
|
|
|
702 |
pmat->xx = dev->HWResolution[0] / 72.0; /* x_pixels_per_inch */
|
|
|
703 |
pmat->xy = 0;
|
|
|
704 |
pmat->yx = 0;
|
|
|
705 |
pmat->yy = dev->HWResolution[1] / 72.0; /* y_pixels_per_inch */
|
|
|
706 |
/****** tx/y is WRONG for devices with ******/
|
|
|
707 |
/****** arbitrary initial matrix ******/
|
|
|
708 |
pmat->tx = 0;
|
|
|
709 |
pmat->ty = 0;
|
|
|
710 |
}
|
|
|
711 |
|
|
|
712 |
int
|
|
|
713 |
gx_default_sync_output(gx_device * dev)
|
|
|
714 |
{
|
|
|
715 |
return 0;
|
|
|
716 |
}
|
|
|
717 |
|
|
|
718 |
int
|
|
|
719 |
gx_default_output_page(gx_device * dev, int num_copies, int flush)
|
|
|
720 |
{
|
|
|
721 |
int code = dev_proc(dev, sync_output)(dev);
|
|
|
722 |
|
|
|
723 |
if (code >= 0)
|
|
|
724 |
code = gx_finish_output_page(dev, num_copies, flush);
|
|
|
725 |
return code;
|
|
|
726 |
}
|
|
|
727 |
|
|
|
728 |
int
|
|
|
729 |
gx_default_close_device(gx_device * dev)
|
|
|
730 |
{
|
|
|
731 |
return 0;
|
|
|
732 |
}
|
|
|
733 |
|
|
|
734 |
const gx_xfont_procs *
|
|
|
735 |
gx_default_get_xfont_procs(gx_device * dev)
|
|
|
736 |
{
|
|
|
737 |
return NULL;
|
|
|
738 |
}
|
|
|
739 |
|
|
|
740 |
gx_device *
|
|
|
741 |
gx_default_get_xfont_device(gx_device * dev)
|
|
|
742 |
{
|
|
|
743 |
return dev;
|
|
|
744 |
}
|
|
|
745 |
|
|
|
746 |
gx_device *
|
|
|
747 |
gx_default_get_page_device(gx_device * dev)
|
|
|
748 |
{
|
|
|
749 |
return NULL;
|
|
|
750 |
}
|
|
|
751 |
gx_device *
|
|
|
752 |
gx_page_device_get_page_device(gx_device * dev)
|
|
|
753 |
{
|
|
|
754 |
return dev;
|
|
|
755 |
}
|
|
|
756 |
|
|
|
757 |
int
|
|
|
758 |
gx_default_get_alpha_bits(gx_device * dev, graphics_object_type type)
|
|
|
759 |
{
|
|
|
760 |
return (type == go_text ? dev->color_info.anti_alias.text_bits :
|
|
|
761 |
dev->color_info.anti_alias.graphics_bits);
|
|
|
762 |
}
|
|
|
763 |
|
|
|
764 |
int
|
|
|
765 |
gx_default_get_band(gx_device * dev, int y, int *band_start)
|
|
|
766 |
{
|
|
|
767 |
return 0;
|
|
|
768 |
}
|
|
|
769 |
|
|
|
770 |
void
|
|
|
771 |
gx_default_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox)
|
|
|
772 |
{
|
|
|
773 |
pbox->p.x = 0;
|
|
|
774 |
pbox->p.y = 0;
|
|
|
775 |
pbox->q.x = int2fixed(dev->width);
|
|
|
776 |
pbox->q.y = int2fixed(dev->height);
|
|
|
777 |
}
|
|
|
778 |
void
|
|
|
779 |
gx_get_largest_clipping_box(gx_device * dev, gs_fixed_rect * pbox)
|
|
|
780 |
{
|
|
|
781 |
pbox->p.x = min_fixed;
|
|
|
782 |
pbox->p.y = min_fixed;
|
|
|
783 |
pbox->q.x = max_fixed;
|
|
|
784 |
pbox->q.y = max_fixed;
|
|
|
785 |
}
|
|
|
786 |
|
|
|
787 |
int
|
|
|
788 |
gx_no_create_compositor(gx_device * dev, gx_device ** pcdev,
|
|
|
789 |
const gs_composite_t * pcte,
|
|
|
790 |
gs_imager_state * pis, gs_memory_t * memory)
|
|
|
791 |
{
|
|
|
792 |
return_error(gs_error_unknownerror); /* not implemented */
|
|
|
793 |
}
|
|
|
794 |
int
|
|
|
795 |
gx_default_create_compositor(gx_device * dev, gx_device ** pcdev,
|
|
|
796 |
const gs_composite_t * pcte,
|
|
|
797 |
gs_imager_state * pis, gs_memory_t * memory)
|
|
|
798 |
{
|
|
|
799 |
return pcte->type->procs.create_default_compositor
|
|
|
800 |
(pcte, pcdev, dev, pis, memory);
|
|
|
801 |
}
|
|
|
802 |
int
|
|
|
803 |
gx_null_create_compositor(gx_device * dev, gx_device ** pcdev,
|
|
|
804 |
const gs_composite_t * pcte,
|
|
|
805 |
gs_imager_state * pis, gs_memory_t * memory)
|
|
|
806 |
{
|
|
|
807 |
*pcdev = dev;
|
|
|
808 |
return 0;
|
|
|
809 |
}
|
|
|
810 |
|
|
|
811 |
/*
|
|
|
812 |
* Default handler for creating a compositor device when writing the clist. */
|
|
|
813 |
int
|
|
|
814 |
gx_default_composite_clist_write_update(const gs_composite_t *pcte, gx_device * dev,
|
|
|
815 |
gx_device ** pcdev, gs_imager_state * pis, gs_memory_t * mem)
|
|
|
816 |
{
|
|
|
817 |
*pcdev = dev; /* Do nothing -> return the same device */
|
|
|
818 |
return 0;
|
|
|
819 |
}
|
|
|
820 |
|
|
|
821 |
/*
|
|
|
822 |
* Default handler for updating the clist device when reading a compositing
|
|
|
823 |
* device.
|
|
|
824 |
*/
|
|
|
825 |
int
|
|
|
826 |
gx_default_composite_clist_read_update(gs_composite_t *pxcte, gx_device * cdev,
|
|
|
827 |
gx_device * tdev, gs_imager_state * pis, gs_memory_t * mem)
|
|
|
828 |
{
|
|
|
829 |
return 0; /* Do nothing */
|
|
|
830 |
}
|
|
|
831 |
|
|
|
832 |
int
|
|
|
833 |
gx_default_finish_copydevice(gx_device *dev, const gx_device *from_dev)
|
|
|
834 |
{
|
|
|
835 |
/* Only allow copying the prototype. */
|
|
|
836 |
return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0);
|
|
|
837 |
}
|
|
|
838 |
|
|
|
839 |
int
|
|
|
840 |
gx_default_pattern_manage(gx_device *pdev, gx_bitmap_id id,
|
|
|
841 |
gs_pattern1_instance_t *pinst, pattern_manage_t function)
|
|
|
842 |
{
|
|
|
843 |
return 0;
|
|
|
844 |
}
|
|
|
845 |
|
|
|
846 |
int
|
|
|
847 |
gx_default_fill_rectangle_hl_color(gx_device *pdev,
|
|
|
848 |
const gs_fixed_rect *rect,
|
|
|
849 |
const gs_imager_state *pis, const gx_drawing_color *pdcolor,
|
|
|
850 |
const gx_clip_path *pcpath)
|
|
|
851 |
{
|
|
|
852 |
return_error(gs_error_rangecheck);
|
|
|
853 |
}
|
|
|
854 |
|
|
|
855 |
int
|
|
|
856 |
gx_default_include_color_space(gx_device *pdev, gs_color_space *cspace,
|
|
|
857 |
const byte *res_name, int name_length)
|
|
|
858 |
{
|
|
|
859 |
return 0;
|
|
|
860 |
}
|
|
|
861 |
|
|
|
862 |
/*
|
|
|
863 |
* If a device want to determine an equivalent color for its spot colors then
|
|
|
864 |
* it needs to implement this method. See comments at the start of
|
|
|
865 |
* src/gsequivc.c.
|
|
|
866 |
*/
|
|
|
867 |
int
|
|
|
868 |
gx_default_update_spot_equivalent_colors(gx_device *pdev, const gs_state * pgs)
|
|
|
869 |
{
|
|
|
870 |
return 0;
|
|
|
871 |
}
|
|
|
872 |
|
|
|
873 |
/* ---------------- Default per-instance procedures ---------------- */
|
|
|
874 |
|
|
|
875 |
int
|
|
|
876 |
gx_default_install(gx_device * dev, gs_state * pgs)
|
|
|
877 |
{
|
|
|
878 |
return 0;
|
|
|
879 |
}
|
|
|
880 |
|
|
|
881 |
int
|
|
|
882 |
gx_default_begin_page(gx_device * dev, gs_state * pgs)
|
|
|
883 |
{
|
|
|
884 |
return 0;
|
|
|
885 |
}
|
|
|
886 |
|
|
|
887 |
int
|
|
|
888 |
gx_default_end_page(gx_device * dev, int reason, gs_state * pgs)
|
|
|
889 |
{
|
|
|
890 |
return (reason != 2 ? 1 : 0);
|
|
|
891 |
}
|