xref: /plan9/sys/src/cmd/gs/src/gxshade.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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