1 /* Copyright (C) 2001-2019 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, 8 modified or distributed except as expressly authorized under the terms 9 of the license contained in the file LICENSE in this distribution. 10 11 Refer to licensing information at http://www.artifex.com or contact 12 Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, 13 CA 94945, U.S.A., +1(415)492-9861, for further information. 14 */ 15 16 17 /* Internal definitions for shading rendering */ 18 19 #ifndef gxshade_INCLUDED 20 # define gxshade_INCLUDED 21 22 #include "gsshade.h" 23 #include "gxfixed.h" /* for gxmatrix.h */ 24 #include "gxmatrix.h" /* for gs_matrix_fixed */ 25 #include "stream.h" 26 #include "gsdcolor.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 void (*align)(shade_coord_stream_t *cs, int radix); 124 bool (*is_eod)(const shade_coord_stream_t *cs); 125 }; 126 127 /* Define one vertex of a mesh. */ 128 typedef struct mesh_vertex_s { 129 gs_fixed_point p; 130 float cc[GS_CLIENT_COLOR_MAX_COMPONENTS]; 131 } mesh_vertex_t; 132 133 /* Define a structure for mesh or patch vertex. */ 134 typedef struct shading_vertex_s shading_vertex_t; 135 136 typedef struct patch_color_s patch_color_t; 137 138 /* Initialize a packed value stream. */ 139 void shade_next_init(shade_coord_stream_t * cs, 140 const gs_shading_mesh_params_t * params, 141 const gs_gstate * pgs); 142 143 /* Get the next flag value. */ 144 int shade_next_flag(shade_coord_stream_t * cs, int BitsPerFlag); 145 146 /* Get one or more coordinate pairs. */ 147 int shade_next_coords(shade_coord_stream_t * cs, gs_fixed_point * ppt, 148 int num_points); 149 150 /* Get a color. Currently all this does is look up Indexed colors. */ 151 int shade_next_color(shade_coord_stream_t * cs, float *pc); 152 153 /* Get the next vertex for a mesh element. */ 154 int shade_next_vertex(shade_coord_stream_t * cs, shading_vertex_t * vertex, 155 patch_color_t *c); 156 157 /* 158 Currently, all shading fill procedures follow the same algorithm: 159 160 - Conservatively inverse-transform the rectangle being filled to a linear 161 or rectangular range of values in the parameter space. 162 163 - Compute the color values at the extrema of the range. 164 165 - If possible, compute the parameter range corresponding to a single 166 device pixel. 167 168 - Recursively do the following, passing the parameter range and extremal 169 color values as the recursion arguments: 170 171 - If the color values are equal to within the tolerance given by the 172 smoothness in the graphics state, or if the range of parameters maps 173 to a single device pixel, fill the range with the (0) or (0,0) color. 174 175 - Otherwise, subdivide and recurse. If the parameter range is 2-D, 176 subdivide the axis with the largest color difference. 177 178 For shadings based on a function, if the function is not monotonic, the 179 smoothness test must only be applied when the parameter range extrema are 180 all interpolated from the same entries in the Function. (We don't 181 currently do this.) 182 183 */ 184 185 /* 186 * Define the common structure for recursive subdivision. 187 * 188 * direct_space is the same as the original ColorSpace unless the 189 * original space is an Indexed space, in which case direct_space is the 190 * base space of the original space. This is the space in which color 191 * computations are done. 192 */ 193 #define shading_fill_state_common\ 194 gx_device *dev;\ 195 gs_gstate *pgs;\ 196 const gs_color_space *direct_space;\ 197 int num_components; /* # of color components in direct_space */\ 198 float cc_max_error[GS_CLIENT_COLOR_MAX_COMPONENTS];\ 199 gx_device *trans_device;\ 200 gsicc_link_t *icclink;\ 201 bool cs_always_linear 202 203 typedef struct shading_fill_state_s { 204 shading_fill_state_common; 205 } shading_fill_state_t; 206 207 /* Initialize the common parts of the recursion state. */ 208 int shade_init_fill_state(shading_fill_state_t * pfs, 209 const gs_shading_t * psh, gx_device * dev, 210 gs_gstate * pgs); 211 212 /* Fill one piece of a shading. */ 213 int shade_fill_path(const shading_fill_state_t * pfs, gx_path * ppath, 214 gx_device_color * pdevc, const gs_fixed_point *fill_adjust); 215 216 #endif /* gxshade_INCLUDED */ 217