1 /* Copyright (C) 1998, 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: gxshade.h,v 1.12 2005/01/31 03:08:43 igor Exp $ */ 18 /* Internal definitions for shading rendering */ 19 20 #ifndef gxshade_INCLUDED 21 # define gxshade_INCLUDED 22 23 #include "gsshade.h" 24 #include "gxfixed.h" /* for gxmatrix.h */ 25 #include "gxmatrix.h" /* for gs_matrix_fixed */ 26 #include "stream.h" 27 28 /* 29 All shadings are defined with respect to some parameter that varies 30 continuously over some range; the shading defines a mapping from the 31 parameter values to colors and user space coordinates. Here are the 32 mappings for the 7 currently defined shading types: 33 34 Type Param space Param => color Param => User space 35 ---- ----------- -------------- ------------------- 36 1 2-D Domain Function Matrix 37 2 1-D Domain Function + Extend perp. to Coords 38 3 1-D Domain Function + Extend circles per Coords 39 4,5 triangle x Gouraud interp. on Gouraud interp. on 40 2-D in tri. Decode => corner triangle corners 41 values => Function 42 6 patch x (u,v) Decode => bilinear Sc + Sd - Sb on each patch 43 in patch interp. on corner 44 values => Function 45 7 see 6 see 6 Sum(i) Sum(j) Pij*Bi(u)*Bj(v) 46 47 To be able to render a portion of a shading usefully, we must be able to 48 do two things: 49 50 - Determine what range of parameter values is sufficient to cover 51 the region being filled; 52 53 - Evaluate the color at enough points to fill the region (in 54 device space). 55 56 Note that the latter may be implemented by a mix of evaluation and 57 interpolation, especially for types 3, 6, and 7 where an exact mapping 58 may be prohibitively expensive. 59 60 Except for type 3, where circles turn into ellipses, the CTM can get 61 folded into the parameter => user space mapping, since in all other 62 cases, the mapping space is closed under linear transformations of 63 the output. 64 */ 65 66 /* Define types and rendering procedures for the individual shadings. */ 67 typedef struct gs_shading_Fb_s { 68 gs_shading_head_t head; 69 gs_shading_Fb_params_t params; 70 } gs_shading_Fb_t; 71 SHADING_FILL_RECTANGLE_PROC(gs_shading_Fb_fill_rectangle); 72 73 typedef struct gs_shading_A_s { 74 gs_shading_head_t head; 75 gs_shading_A_params_t params; 76 } gs_shading_A_t; 77 SHADING_FILL_RECTANGLE_PROC(gs_shading_A_fill_rectangle); 78 79 typedef struct gs_shading_R_s { 80 gs_shading_head_t head; 81 gs_shading_R_params_t params; 82 } gs_shading_R_t; 83 SHADING_FILL_RECTANGLE_PROC(gs_shading_R_fill_rectangle); 84 85 typedef struct gs_shading_FfGt_s { 86 gs_shading_head_t head; 87 gs_shading_FfGt_params_t params; 88 } gs_shading_FfGt_t; 89 SHADING_FILL_RECTANGLE_PROC(gs_shading_FfGt_fill_rectangle); 90 91 typedef struct gs_shading_LfGt_s { 92 gs_shading_head_t head; 93 gs_shading_LfGt_params_t params; 94 } gs_shading_LfGt_t; 95 SHADING_FILL_RECTANGLE_PROC(gs_shading_LfGt_fill_rectangle); 96 97 typedef struct gs_shading_Cp_s { 98 gs_shading_head_t head; 99 gs_shading_Cp_params_t params; 100 } gs_shading_Cp_t; 101 SHADING_FILL_RECTANGLE_PROC(gs_shading_Cp_fill_rectangle); 102 103 typedef struct gs_shading_Tpp_s { 104 gs_shading_head_t head; 105 gs_shading_Tpp_params_t params; 106 } gs_shading_Tpp_t; 107 SHADING_FILL_RECTANGLE_PROC(gs_shading_Tpp_fill_rectangle); 108 109 /* Define a stream for decoding packed coordinate values. */ 110 typedef struct shade_coord_stream_s shade_coord_stream_t; 111 struct shade_coord_stream_s { 112 stream ds; /* stream if DataSource isn't one already -- */ 113 /* first for GC-ability (maybe unneeded?) */ 114 stream *s; /* DataSource or &ds */ 115 uint bits; /* shifted bits of current byte */ 116 int left; /* # of bits left in bits */ 117 bool ds_EOF; /* The 'ds' stream reached EOF. */ 118 const gs_shading_mesh_params_t *params; 119 const gs_matrix_fixed *pctm; 120 int (*get_value)(shade_coord_stream_t *cs, int num_bits, uint *pvalue); 121 int (*get_decoded)(shade_coord_stream_t *cs, int num_bits, 122 const float decode[2], float *pvalue); 123 bool (*is_eod)(const shade_coord_stream_t *cs); 124 }; 125 126 /* Define one vertex of a mesh. */ 127 typedef struct mesh_vertex_s { 128 gs_fixed_point p; 129 float cc[GS_CLIENT_COLOR_MAX_COMPONENTS]; 130 } mesh_vertex_t; 131 132 /* Define a structure for mesh or patch vertex. */ 133 typedef struct shading_vertex_s shading_vertex_t; 134 135 /* Initialize a packed value stream. */ 136 void shade_next_init(shade_coord_stream_t * cs, 137 const gs_shading_mesh_params_t * params, 138 const gs_imager_state * pis); 139 140 /* Get the next flag value. */ 141 int shade_next_flag(shade_coord_stream_t * cs, int BitsPerFlag); 142 143 /* Get one or more coordinate pairs. */ 144 int shade_next_coords(shade_coord_stream_t * cs, gs_fixed_point * ppt, 145 int num_points); 146 147 /* Get a color. Currently all this does is look up Indexed colors. */ 148 int shade_next_color(shade_coord_stream_t * cs, float *pc); 149 150 /* Get the next vertex for a mesh element. */ 151 int shade_next_vertex(shade_coord_stream_t * cs, shading_vertex_t * vertex); 152 153 /* 154 Currently, all shading fill procedures follow the same algorithm: 155 156 - Conservatively inverse-transform the rectangle being filled to a linear 157 or rectangular range of values in the parameter space. 158 159 - Compute the color values at the extrema of the range. 160 161 - If possible, compute the parameter range corresponding to a single 162 device pixel. 163 164 - Recursively do the following, passing the parameter range and extremal 165 color values as the recursion arguments: 166 167 - If the color values are equal to within the tolerance given by the 168 smoothness in the graphics state, or if the range of parameters maps 169 to a single device pixel, fill the range with the (0) or (0,0) color. 170 171 - Otherwise, subdivide and recurse. If the parameter range is 2-D, 172 subdivide the axis with the largest color difference. 173 174 For shadings based on a function, if the function is not monotonic, the 175 smoothness test must only be applied when the parameter range extrema are 176 all interpolated from the same entries in the Function. (We don't 177 currently do this.) 178 179 */ 180 181 /* 182 * Define the common structure for recursive subdivision. 183 * 184 * direct_space is the same as the original ColorSpace unless the 185 * original space is an Indexed space, in which case direct_space is the 186 * base space of the original space. This is the space in which color 187 * computations are done. 188 */ 189 #define shading_fill_state_common\ 190 gx_device *dev;\ 191 gs_imager_state *pis;\ 192 const gs_color_space *direct_space;\ 193 int num_components; /* # of color components in direct_space */\ 194 float cc_max_error[GS_CLIENT_COLOR_MAX_COMPONENTS] 195 typedef struct shading_fill_state_s { 196 shading_fill_state_common; 197 } shading_fill_state_t; 198 199 /* Initialize the common parts of the recursion state. */ 200 void shade_init_fill_state(shading_fill_state_t * pfs, 201 const gs_shading_t * psh, gx_device * dev, 202 gs_imager_state * pis); 203 204 /* Fill one piece of a shading. */ 205 #ifndef gx_device_color_DEFINED 206 # define gx_device_color_DEFINED 207 typedef struct gx_device_color_s gx_device_color; 208 #endif 209 int shade_fill_path(const shading_fill_state_t * pfs, gx_path * ppath, 210 gx_device_color * pdevc, const gs_fixed_point *fill_adjust); 211 212 #endif /* gxshade_INCLUDED */ 213