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