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 
14 /* $Id: zcolor.h  $ */
15 /* Definitions for setcolorspace */
16 
17 #ifndef zcolor_INCLUDED
18 #  define zcolor_INCLUDED
19 
20 /*
21  * The code to set color space and color values has been moved from PostScript
22  * into C (mostly). The new C code broadly follows the old PostScript method, each
23  * possible color space is defined by an instance of the PS_colour_space_s object below. These
24  * are stored in an array (in zcolor.c) called colorProcs. When color spaces or
25  * color values are set, or values retrieved, we examine the array or name which
26  * represents the space, and extract a C string representation of the color space
27  * name. We compare the name with each of the names in the colorProcs array to
28  * retrieve the instance which handles that color space.
29  *
30  * When setting a new color space, we must follow the existing Ghostscript policy
31  * which requires us to set the spaces 'backwards'. That is, before we set a space
32  * which has an alternate color space (eg Separation) we must first set the
33  * alternate space as the current.
34  *
35  * Now, when setting a color space, we convert any tint transform procedure from
36  * a PostScript procedure into a PostScript Function, either a type 4 PostScript
37  * calculator or a type 0 sampled function. This has performance benefits, especially
38  * wehn dealing with images. Now, if we are converting into a type 4 function this is
39  * easy, however a type 0 function requires us to sample the color space and in order
40  * to do this, we must actually execute the tint transform procedure. This means we
41  * must exit the C world and hand control back to the PostScript interpreter
42  * temporarily.
43  *
44  * We do this with a 'continuation function', we store our procdure on the PostScript
45  * execution stack, and when we need to run a tint transform, we push the procedure
46  * onto the execution stack after our function, and exit back to the interpreter.
47  * When the interpreter has finished executing the transform, it executes the next
48  * entry on the execution stack, which is our C procedure, and returns control back
49  * to our code. Of course, we need to know what stage of processing we were up to
50  * and so we also store some variables on the execution stack. Continuation
51  * procedures are basically state machines.
52  *
53  * In fact, we need quite a few of these, for setting the color space, the current
54  * color (we may need to execute tint transforms), converting the current color into
55  * a device space (for currentcmykcolor and so on). These are all defined in zcolor.c.
56  */
57 typedef struct PS_colour_space_s PS_colour_space_t;
58 struct PS_colour_space_s {
59     char *name;					/* C string representing the name of the space */
60     int (*setproc)(i_ctx_t * i_ctx_p, ref *r,	/* Routine to set the color space, if CIESubst */
61 	int *stage, int *cont, int CIESubst);	/* is true then we are already doing CIE substitution */
62     int (*validateproc)(i_ctx_t * i_ctx_p,	/* Validates the color space operands */
63 	ref **r);
64     int (*alternateproc)(i_ctx_t * i_ctx_p,	/* Retrieve the alternate color space (if any) */
65 	ref *space, ref **r, int *CIESubst);	/* If CIESubst comes back true, then don't do further CIE substitution */
66     int (*numcomponents)(i_ctx_t * i_ctx_p,	/* Returns the number of components in the space */
67 	ref *space, int *n);
68     int (*range)(i_ctx_t * i_ctx_p, ref *space, /* Returns 'components' pairs of values which represent */
69 	float *ptr);				/* the valid ranges of values for this space */
70     int (*domain)(i_ctx_t * i_ctx_p,		/* Returns 'components' pairs of values which represent */
71 	ref *space, float *ptr);		/* the domain over which values are valid */
72     int (*basecolorproc)(i_ctx_t * i_ctx_p,	/* convert the current color values into device space */
73 	ref *space, int base, int *stage,	/* values. 'base' is the requested base space, 0=gray */
74 	int *cont, int *stack_depth);		/* 1 = HSB, 2 = RGB, 3 = CMYK. Separation and DeviceN */
75 						/* spaces will return default values if they are not using */
76 						/* the alternate space, and will convert the components */
77 						/* into values in the alternate otherwise, by executing */
78 						/* the tint transform procedure */
79     int (*runtransformproc)(i_ctx_t *i_ctx_p,	/* executes the tint transform for this space */
80 	ref *space, int *usealternate,
81 	int *stage, int *stack_depth);
82     int (*validatecomponents)(i_ctx_t *i_ctx_p, /* Check the components supplied as an argument to setcolor */
83 	ref *space, float *values,		/* are valid */
84 	int num_comps);
85     int (*compareproc)(i_ctx_t *i_ctx_p,	/* Compare two color spaces of this type, to see if they */
86 	ref *space, ref *testspace);		/* are the same */
87     int (*initialcolorproc)(i_ctx_t *i_ctx_p,	/* Set the appropriate initial color for this space */
88 	ref *space);
89 };
90 
91 
92 /* Given a pointer to a color space (name or array), returns
93  * the appropriate instance of PS_colour_space_s from the colorProcs array
94  */
95 int get_space_object(i_ctx_t *i_ctx_p, ref *arr, PS_colour_space_t **obj);
96 
97 #endif /* zcolor_INCLUDED */
98