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