1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 /* $Id: gxhldevc.h 8022 2007-06-05 22:23:38Z giles $ */
14 /* High level device color save/compare procedures */
15 
16 #ifndef gxhldevc_INCLUDED
17 #  define gxhldevc_INCLUDED
18 
19 #include "gsdcolor.h"
20 
21 /*
22  * Most high level devices want more information about the color spaces
23  * which were used to create color values.
24  *
25  * There are some added complications:
26  *
27  * 1. Ghostscript has many dozens, if not hundreds, of device drivers which
28  * have been written for it.  Many of these devices are outside of our
29  * control.  (However we do receive questions and complaints when they no
30  * longer work.)  Thus we also want to avoid making changes in the device
31  * interface which would require changes to the code in these devices.
32  *
33  * 2. We also desire to not save pointers to color space structures, etc.
34  * within the high level device.  Many of these structures are temporary,
35  * stack based, or are deleted outside of the control of the device.  Thus
36  * it becomes almost impossible to prevent pointers to deleted objects.
37  *
38  * 3. Both color spaces and device colors are passed to devices via pointers
39  * to objects.  These objects, in turn, often contain pointers to other
40  * objects.
41  *
42  * These constraints imply the need within the device to save color spaces
43  * and colors in some form which will allows us to detect color space or
44  * color changes when a new color space and a color is compared to the old
45  * saved color space and color.  These 'saved' forms should not include
46  * pointers to objects outside of the control of the device.
47  *
48  * The functions below are desiged to assist the high level device in the
49  * saving, comparing, and getting high level color information.
50  */
51 
52 
53 #ifndef gs_imager_state_DEFINED
54 #  define gs_imager_state_DEFINED
55 typedef struct gs_imager_state_s gs_imager_state;
56 #endif
57 
58 #ifndef gx_device_color_DEFINED
59 #  define gx_device_color_DEFINED
60 typedef struct gx_device_color_s gx_device_color;
61 #endif
62 
63 /*
64  * A structure for saving high level color information for high level devices.
65  */
66 typedef struct gx_hl_saved_color_s {
67     gs_id color_space_id;
68     gs_id pattern_id;
69     bool ccolor_valid;
70     gs_client_color ccolor;
71     gx_device_color_saved saved_dev_color;
72 } gx_hl_saved_color;
73 
74 /*
75  * Initiailze a high level saved color to null
76  */
77 void gx_hld_saved_color_init(gx_hl_saved_color * psc);
78 
79 /*
80  * Get graphics state pointer (from imager state pointer)
81  * Return NULL if the imager state is not also a graphics state.
82  */
83 const gs_state * gx_hld_get_gstate_ptr(const gs_imager_state * pis);
84 
85 /*
86  * Save the device color information including the color space id and
87  * client color data (if available).  The pattern id is also saved for
88  * detection of changes in the pattern.
89  *
90  * This routine returns 'true' if sufficient information was provided
91  * to completely describe a full high level (non process color model)
92  * color.  Otherwise 'false' is returned.  Thus the return does both
93  * a save and test on the given color.
94  *
95  * If the device can't handle high level colors, it must pass NULL to
96  * the 'pis' argument.
97  */
98 bool gx_hld_save_color(const gs_imager_state * pis,
99 	const gx_device_color * pdevc, gx_hl_saved_color * psc);
100 
101 /*
102  * Compare two saved colors to check if match.  Note this routine assumes
103  * unused parts of the saved color have been zeroed.  See gx_hld_save_color()
104  * for what is actually being compared.
105  */
106 bool gx_hld_saved_color_equal(const gx_hl_saved_color * psc1,
107 			   const gx_hl_saved_color * psc2);
108 
109 /*
110  * Check whether two saved colors have same color space.
111  */
112 bool gx_hld_saved_color_same_cspace(const gx_hl_saved_color * psc1,
113 			   const gx_hl_saved_color * psc2);
114 
115 /*
116  * Check if a high level color is availavble.
117  */
118 bool
119 gx_hld_is_hl_color_available(const gs_imager_state * pis,
120 		const gx_device_color * pdevc);
121 
122 /*
123  * Return status from get_color_space_and_ccolor.  See that routine for
124  * more information.
125  *
126  * Hopefully I will be given more information to allow the choice of
127  * better names.
128  */
129 typedef enum {
130         non_pattern_color_space,
131         pattern_color_sapce,
132 	use_process_color
133 } gx_hld_get_color_space_and_ccolor_status;
134 
135 /*
136  * Get pointers to the current color space and client color.
137  *
138  * There are four possible cases:
139  * 1.  Either the device color or imager state pointer is NULL.  If so then
140  *     we do not have enough information.  Thus we need to fall back to the
141  *     process color model color.  Return NULL for both pointers.
142  * 2.  The device color was not created from a color space and a client color.
143  *     (See the set_non_client_color() macro.)  In this case NULL is returned
144  *     for both pointers.  (Use process color model color.)
145  * 3.  The device color is a 'pattern'.  Return pointers to both the current
146  *     color space and the ccolor (client color) field in the device color
147  *     structure.  Note:  For the shfill opeartor, a pattern color space will
148  *     be used to build the device color.  However the current color space
149  *     will not be the pattern color space.
150  * 4.  All other cases: the current color space is the color space used to
151  *     build the device color.  A pointer to the current color space is
152  *     returned.  The client color pointer will be NULL.
153  *
154  * The status returned indicates if the color space information is valid
155  * (non valid --> use_process_color) and whether the color space is
156  * a pattern or non pattern).
157  */
158 gx_hld_get_color_space_and_ccolor_status gx_hld_get_color_space_and_ccolor(
159 		const gs_imager_state * pis, const gx_device_color * pdevc,
160 		const gs_color_space ** ppcs, const gs_client_color ** ppcc);
161 
162 /*
163  * This routine will return the number of components in the current color
164  * space.
165  *
166  * The routine will return -1 if the imager state does not point to a
167  * graphics state (and thus we cannot get the current color space).
168  */
169 int gx_hld_get_number_color_components(const gs_imager_state * pis);
170 
171 /*
172  * This defines sthe possible status to be returned from get_color_component.
173  */
174 typedef enum {
175     valid_result = 1,
176     invalid_color_info = 2,
177     invalid_component_requested = 3
178 } gx_hld_get_color_component_status;
179 
180 /*
181  * Get the requested high level color value.
182  *
183  * This routine will get the specified high level color if it is available.
184  * If the value is not available (status equal either invalid_color_info or
185  * invalid_component_requested).  In this case, it is suggested that the
186  * device fall back to using the process color model.
187  */
188 gx_hld_get_color_component_status gx_hld_get_color_component(
189 		const gs_imager_state * pis, const gx_device_color * pdevc,
190 		int comp_numi, float * output);
191 
192 #endif
193 
194