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 /* graphics state definition */
18 
19 #ifndef gxistate_INCLUDED
20 #  define gxistate_INCLUDED
21 
22 #include "gscsel.h"
23 #include "gsrefct.h"
24 #include "gsropt.h"
25 #include "gstparam.h"
26 #include "gxcvalue.h"
27 #include "gxcmap.h"
28 #include "gxfixed.h"
29 #include "gxline.h"
30 #include "gxmatrix.h"
31 #include "gxtmap.h"
32 #include "gscspace.h"
33 #include "gstrans.h"
34 #include "gsnamecl.h"
35 #include "gscms.h"
36 #include "gscpm.h"
37 #include "gscspace.h"
38 #include "gxdcolor.h"
39 #include "gxstate.h"
40 #include "gsfont.h"
41 #include "gxpath.h"
42 #include "gsccolor.h"
43 #include "gsht1.h"
44 #include "gxclipsr.h"
45 
46 
47 /*
48  * Define the color rendering state information.
49  * This should be a separate object (or at least a substructure),
50  * but making this change would require editing too much code.
51  */
52 
53 /*
54  * We need some special memory management for the components of a
55  * c.r. state, as indicated by the following notations on the elements:
56  *      (RC) means the element is reference-counted.
57  *      (Shared) means the element is shared among an arbitrary number of
58  *        c.r. states and is never freed.
59  *      (Owned) means exactly one c.r. state references the element,
60  *        and it is guaranteed that no references to it will outlive
61  *        the c.r. state itself.
62  */
63 
64 /* Define the interior structure of a transfer function. */
65 typedef struct gx_transfer_s {
66     int red_component_num;
67     gx_transfer_map *red;		/* (RC) */
68     int green_component_num;
69     gx_transfer_map *green;		/* (RC) */
70     int blue_component_num;
71     gx_transfer_map *blue;		/* (RC) */
72     int gray_component_num;
73     gx_transfer_map *gray;		/* (RC) */
74 } gx_transfer;
75 
76 #define gs_color_rendering_state_common\
77 \
78                 /* Halftone screen: */\
79 \
80         gs_halftone *halftone;			/* (RC) */\
81         gs_int_point screen_phase[gs_color_select_count];\
82                 /* dev_ht depends on halftone and device resolution. */\
83         gx_device_halftone *dev_ht;		/* (RC) */\
84 \
85                 /* Color (device-dependent): */\
86 \
87         struct gs_cie_render_s *cie_render;	/* (RC) may be 0 */\
88         bool cie_to_xyz;			/* flag for conversion to XYZ, no CRD req'd */\
89         gx_transfer_map *black_generation;	/* (RC) may be 0 */\
90         gx_transfer_map *undercolor_removal;	/* (RC) may be 0 */\
91                 /* set_transfer holds the transfer functions specified by */\
92                 /* set[color]transfer; effective_transfer includes the */\
93                 /* effects of overrides by TransferFunctions in halftone */\
94                 /* dictionaries.  (In Level 1 systems, set_transfer and */\
95                 /* effective_transfer are always the same.) */\
96         gx_transfer set_transfer;		/* members are (RC) */\
97         int effective_transfer_non_identity_count;\
98         gx_transfer_map *effective_transfer[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* see below */\
99 \
100                 /* Color caches: */\
101 \
102                 /* cie_joint_caches depend on cie_render and */\
103                 /* the color space. */\
104         struct gx_cie_joint_caches_s *cie_joint_caches;		/* (RC) */\
105                 /* cmap_procs depend on the device's color_info. */\
106         const struct gx_color_map_procs_s *cmap_procs;		/* static */\
107                 /* DeviceN component map for current color space */\
108         gs_devicen_color_map color_component_map;\
109                 /* The contents of pattern_cache depend on the */\
110                 /* the color space and the device's color_info and */\
111                 /* resolution. */\
112         struct gx_pattern_cache_s *pattern_cache;	/* (Shared) by all gstates */\
113 \
114         /* Simple color spaces, stored here for easy access from */ 	\
115         /* gx_concrete_space_CIE */ \
116         gs_color_space *devicergb_cs;\
117         gs_color_space *devicecmyk_cs;\
118 \
119         /* Stores for cached values which correspond to whichever */\
120         /* color isn't in force at the moment */\
121         struct gx_cie_joint_caches_s *cie_joint_caches_alt;\
122         gs_devicen_color_map          color_component_map_alt
123 
124 
125 /* Current colors (non-stroking, and stroking) */
126 typedef struct gs_gstate_color_s {
127     gs_color_space *color_space; /* after substitution */
128     gs_client_color *ccolor;
129     gx_device_color *dev_color;
130     bool effective_opm;
131 } gs_gstate_color;
132 
133 /*
134  * Enumerate the reference-counted pointers in a c.r. state.  Note that
135  * effective_transfer doesn't contribute to the reference count: it points
136  * either to the same objects as set_transfer, or to objects in a halftone
137  * structure that someone else worries about.
138  */
139 #define gs_cr_state_do_rc_ptrs(m)\
140   m(halftone) \
141   m(dev_ht) \
142   m(cie_render) \
143   m(black_generation) \
144   m(undercolor_removal) \
145   m(set_transfer.red) \
146   m(set_transfer.green) \
147   m(set_transfer.blue) \
148   m(set_transfer.gray) \
149   m(cie_joint_caches) \
150   m(devicergb_cs) \
151   m(devicecmyk_cs)\
152   m(cie_joint_caches_alt)
153 
154 /* Enumerate the pointers in a c.r. state. */
155 #define gs_cr_state_do_ptrs(m)\
156   m(0,halftone) \
157   m(1,dev_ht) \
158   m(2,cie_render) \
159   m(3,black_generation) \
160   m(4,undercolor_removal) \
161   m(5,set_transfer.red) \
162   m(6,set_transfer.green) \
163   m(7,set_transfer.blue) \
164   m(8,set_transfer.gray)\
165   m(9,cie_joint_caches) \
166   m(10,pattern_cache) \
167   m(11,devicergb_cs) \
168   m(12,devicecmyk_cs)\
169   m(13,cie_joint_caches_alt)
170   /*
171    * We handle effective_transfer specially in gsistate.c since its pointers
172    * are not enumerated for garbage collection but they are are relocated.
173    */
174 /*
175  * This count does not include the effective_transfer pointers since they
176  * are not enumerated for GC.
177  */
178 #define st_cr_state_num_ptrs 14
179 
180 struct gs_devicen_color_map_s {
181     bool use_alt_cspace;
182     separation_type sep_type;
183     uint num_components;	/* Input - Duplicate of value in gs_device_n_params */
184     uint num_colorants;		/* Number of colorants - output */
185     gs_id cspace_id;		/* Used to verify color space and map match */
186     int color_map[GS_CLIENT_COLOR_MAX_COMPONENTS];
187 };
188 
189 
190 /* These flags are used to keep track of qQ
191    combinations surrounding a graphic state
192    change that includes a softmask setting.
193    The transparency compositor must be notified
194    when a Q event occurs following a softmask */
195 
196 typedef struct gs_xstate_trans_flags {
197     bool xstate_pending;
198     bool xstate_change;
199 } gs_xstate_trans_flags_t;
200 
201 #define gs_currentdevicecolor_inline(pgs) ((pgs)->color[0].dev_color)
202 #define gs_currentcolor_inline(pgs)       ((pgs)->color[0].ccolor)
203 #define gs_currentcolorspace_inline(pgs)  ((pgs)->color[0].color_space)
204 #define gs_altdevicecolor_inline(pgs)     ((pgs)->color[1].dev_color)
205 #define gs_currentcolor_eopm(pgs)         ((pgs)->color[0].effective_opm)
206 
207 #define char_tm_only(pgs) *(gs_matrix *)&(pgs)->char_tm
208 
209 #undef gs_currentdevice_inline /* remove definition in gsdevice.h?? */
210 #define gs_currentdevice_inline(pgs) ((pgs)->device)
211 
212 #define gs_gstate_client_data(pgs) ((pgs)->client_data)
213 
214 /* Define the graphics state structure itself. */
215 /*
216  * Note that the ctm member is a gs_matrix_fixed.  As such, it cannot be
217  * used directly as the argument for procedures like gs_point_transform.
218  * Instead, one must use the ctm_only macro, e.g., &ctm_only(pgs) rather
219  * than &pgs->ctm.
220  */
221 
222 /* Access macros */
223 #define ctm_only(pgs) (*(const gs_matrix *)&(pgs)->ctm)
224 #define ctm_only_writable(pgs) (*(gs_matrix *)&(pgs)->ctm)
225 #define set_ctm_only(pgs, mat) (*(gs_matrix *)&(pgs)->ctm = (mat))
226 #define gs_init_rop(pgs) ((pgs)->log_op = lop_default)
227 #define gs_currentflat_inline(pgs) ((pgs)->flatness)
228 #define gs_currentlineparams_inline(pgs) (&(pgs)->line_params)
229 #define gs_current_logical_op_inline(pgs) ((pgs)->log_op)
230 #define gs_set_logical_op_inline(pgs, lop) ((pgs)->log_op = (lop))
231 
232 struct gs_gstate_s {
233     gs_memory_t *memory;
234     void *client_data;
235     gx_line_params line_params;
236     bool hpgl_path_mode;
237     gs_matrix_fixed ctm;
238     bool current_point_valid;
239     gs_point current_point;
240     gs_point subpath_start;
241     bool clamp_coordinates;
242     gs_logical_operation_t log_op;
243     gx_color_value alpha;
244     gs_blend_mode_t blend_mode;
245     gs_transparency_source_t opacity, shape;
246     gs_xstate_trans_flags_t trans_flags;
247     gs_id soft_mask_id;
248     bool text_knockout;
249     uint text_rendering_mode;
250     bool has_transparency;   /* used to keep from doing shading fills in device color space */
251     gx_device *trans_device;  /* trans device has all mappings to group color space */
252     bool overprint;
253     int overprint_mode;
254     bool stroke_overprint;
255     float flatness;
256     gs_fixed_point fill_adjust; /* A path expansion for fill; -1 = dropout prevention*/
257     bool stroke_adjust;
258     bool accurate_curves;
259     bool have_pattern_streams;
260     float smoothness;
261     int renderingintent; /* See gsstate.c */
262     bool blackptcomp;
263     gsicc_manager_t *icc_manager; /* ICC color manager, profile */
264     gsicc_link_cache_t *icc_link_cache; /* ICC linked transforms */
265     gsicc_profile_cache_t *icc_profile_cache;  /* ICC profiles from PS. */
266     CUSTOM_COLOR_PTR        /* Pointer to custom color callback struct */
267     const gx_color_map_procs *
268       (*get_cmap_procs)(const gs_gstate *, const gx_device *);
269     gs_color_rendering_state_common;
270 
271     gs_gstate *saved;	        /* previous state from gsave */
272 
273     /* Transformation: */
274     gs_matrix ctm_inverse;
275     bool ctm_inverse_valid;     /* true if ctm_inverse = ctm^-1 */
276     gs_matrix ctm_default;
277     bool ctm_default_set;       /* if true, use ctm_default; */
278                                 /* if false, ask device */
279     /* Paths: */
280 
281     gx_path *path;
282     gx_clip_path *clip_path;
283     gx_clip_stack_t *clip_stack;  /* (LanguageLevel 3 only) */
284     gx_clip_path *view_clip;	  /* (may be 0, or have rule = 0) */
285 
286     /* Effective clip path cache */
287     gs_id effective_clip_id;            /* (key) clip path id */
288     gs_id effective_view_clip_id;	/* (key) view clip path id */
289     gx_clip_path *effective_clip_path;	/* (value) effective clip path, */
290                                 /* possibly = clip_path or view_clip */
291     bool effective_clip_shared;	/* true iff e.c.p. = c.p. or v.c. */
292 
293     /* PDF graphics state parameters */
294     float strokeconstantalpha, fillconstantalpha;
295                                 /* *SMask is stored in int_gstate as its a ref object */
296     bool alphaisshape;
297     float textspacing;
298     float textleading;
299     float textrise;
300     float wordspacing;
301     float texthscaling;
302     float PDFfontsize;
303     gs_matrix textlinematrix;
304     gs_matrix textmatrix;
305     /* Current colors (non-stroking, and stroking) */
306     gs_gstate_color color[2];
307     int is_fill_color;
308     /* Font: */
309     gs_font *font;
310     gs_font *root_font;
311     gs_matrix_fixed char_tm;     /* font matrix * ctm */
312     bool char_tm_valid;	         /* true if char_tm is valid */
313     gs_in_cache_device_t in_cachedevice;    /* (see gscpm.h) */
314     gs_char_path_mode in_charpath;          /* (see gscpm.h) */
315     gs_gstate *show_gstate;      /* gstate when show was invoked */
316                                 /* (so charpath can append to path) */
317     /* Other stuff: */
318     int level;			/* incremented by 1 per gsave */
319     gx_device *device;
320     gs_gstate_client_procs client_procs;
321 };
322 
323 /* Initialization for gs_gstate */
324 #define gs_gstate_initial(scale)\
325   0, 0, { gx_line_params_initial }, 0,\
326    { (float)(scale), 0.0, 0.0, (float)(-(scale)), 0.0, 0.0 },\
327   false, {0, 0}, {0, 0}, false, \
328   lop_default, gx_max_color_value, BLEND_MODE_Compatible,\
329 { 1.0 }, { 1.0 }, {0, 0}, 0, 0/*false*/, 0, 0/*false*/, 0, 0/*false*/, 0, 0/*false*/, 1.0,  \
330    { fixed_half, fixed_half }, 0/*false*/, 1/*true*/, 0/*false*/, 1.0,\
331   1, 1/* bpt true */, 0, 0, 0, INIT_CUSTOM_COLOR_PTR	/* 'Custom color' callback pointer */  \
332   gx_default_get_cmap_procs
333 
334 #define GS_STATE_INIT_VALUES(s, scale) \
335   do { \
336     static const struct gs_gstate_s __state_init = {gs_gstate_initial(scale)}; \
337     s->memory = __state_init.memory; \
338     s->client_data = __state_init.client_data; \
339     s->line_params = __state_init.line_params; \
340     s->hpgl_path_mode = __state_init.hpgl_path_mode; \
341     s->ctm = __state_init.ctm; \
342     s->current_point_valid = __state_init.current_point_valid; \
343     s->current_point = __state_init.current_point; \
344     s->subpath_start = __state_init.subpath_start; \
345     s->clamp_coordinates = __state_init.clamp_coordinates; \
346     s->log_op = __state_init.log_op; \
347     s->alpha = __state_init.alpha; \
348     s->blend_mode = __state_init.blend_mode; \
349     s->opacity = __state_init.opacity; \
350     s->shape = __state_init.shape; \
351     s->trans_flags = __state_init.trans_flags; \
352     s->soft_mask_id = __state_init.soft_mask_id; \
353     s->text_knockout = __state_init.text_knockout; \
354     s->text_rendering_mode = __state_init.text_rendering_mode; \
355     s->has_transparency = __state_init.has_transparency; \
356     s->trans_device = __state_init.trans_device; \
357     s->overprint = __state_init.overprint; \
358     s->overprint_mode = __state_init.overprint_mode; \
359     s->stroke_overprint = __state_init.stroke_overprint; \
360     s->flatness = __state_init.flatness; \
361     s->fill_adjust = __state_init.fill_adjust; \
362     s->stroke_adjust = __state_init.stroke_adjust; \
363     s->accurate_curves = __state_init.accurate_curves; \
364     s->have_pattern_streams = __state_init.have_pattern_streams; \
365     s->smoothness = __state_init.smoothness; \
366     s->renderingintent = __state_init.renderingintent; \
367     s->blackptcomp = __state_init.blackptcomp; \
368     s->icc_manager = __state_init.icc_manager; \
369     s->icc_link_cache = __state_init.icc_link_cache; \
370     s->icc_profile_cache = __state_init.icc_profile_cache; \
371     s->get_cmap_procs = __state_init.get_cmap_procs; \
372     s->show_gstate = NULL; \
373     s->is_fill_color = 1; \
374   } while (0)
375 
376 struct_proc_finalize(gs_gstate_finalize);
377 #define public_st_gs_gstate()	/* in gsstate.c */\
378   gs_public_st_composite_use_final(st_gs_gstate, gs_gstate, "gs_gstate",\
379     gs_gstate_enum_ptrs, gs_gstate_reloc_ptrs, gs_gstate_finalize)
380 
381 /*
382  * Enumerate the pointers in a graphics state
383  * except device which must
384  * be handled specially.
385  */
386 #define gs_gstate_do_ptrs(m)\
387   m(0,  client_data) \
388   m(1,  trans_device) \
389   m(2,  icc_manager) \
390   m(3,  icc_link_cache) \
391   m(4,  icc_profile_cache) \
392   m(5,  saved) \
393   m(6,  path) \
394   m(7,  clip_path) \
395   m(8,  clip_stack) \
396   m(9,  view_clip) \
397   m(10, effective_clip_path) \
398   m(11, color[0].color_space) \
399   m(12, color[0].ccolor) \
400   m(13, color[0].dev_color) \
401   m(14, color[1].color_space) \
402   m(15, color[1].ccolor) \
403   m(16, color[1].dev_color)\
404   m(17, font) \
405   m(18, root_font) \
406   m(19, show_gstate)
407 
408 #define gs_gstate_num_ptrs 20
409 
410 /* The '+1' in the following is because gs_gstate.device
411  * is handled specially
412  */
413 #define st_gs_gstate_num_ptrs\
414   (st_line_params_num_ptrs + st_cr_state_num_ptrs + gs_gstate_num_ptrs + 1)
415 
416 /* Initialize an graphics state, other than the parts covered by */
417 /* gs_gstate_initial. */
418 int gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem);
419 
420 /* Make a temporary copy of a gs_gstate.  Note that this does not */
421 /* do all the necessary reference counting, etc. */
422 gs_gstate * gs_gstate_copy_temp(const gs_gstate * pgs, gs_memory_t * mem);
423 
424 /* Increment reference counts to note that a graphics state has been copied. */
425 void gs_gstate_copied(gs_gstate * pgs);
426 
427 /* Adjust reference counts before assigning one gs_gstate to another. */
428 void gs_gstate_pre_assign(gs_gstate *to, const gs_gstate *from);
429 
430 /* Release an gs_gstate. */
431 void gs_gstate_release(gs_gstate * pgs);
432 int gs_currentscreenphase_pgs(const gs_gstate *, gs_int_point *, gs_color_select_t);
433 
434 
435 /* The following macro is used for development purpose for designating places
436    where current point is changed. Clients must not use it. */
437 #define gx_setcurrentpoint(pgs, xx, yy)\
438     (pgs)->current_point.x = xx;\
439     (pgs)->current_point.y = yy;
440 
441 /* The const is a lie. The swapcolors stuff is a bit of a hack; a late
442  * addition to the graphics library, which has to be used in many places
443  * where the device interface only has a const gs_gstate available to it
444  * rather than a non-const one. In all these cases, we flip the colors
445  * during a call to a function, then swap it back again before we leave,
446  * so the net effect of the call remains that the gstate is not changed.
447  * Rather than breaking const at every single callsite, we move the const
448  * breaking into the function itself. */
449 void gs_swapcolors_quick(const gs_gstate *);
450 
451 /* Set the graphics_type_tag iff the requested tag bit is not set in the dev_color and	*/
452 /* unset the dev_color so that gx_set_dev_color will remap (encode) with the new tag.	*/
453 /* Also make sure the tag is set in the device so the two remain in sync.               */
ensure_tag_is_set(gs_gstate * pgs,gx_device * dev,gs_graphics_type_tag_t tag)454 static inline void ensure_tag_is_set(gs_gstate *pgs, gx_device *dev, gs_graphics_type_tag_t tag)
455 {
456     if ((dev->graphics_type_tag & tag) == 0)
457         dev_proc(dev, set_graphics_type_tag)(dev, tag);
458     if (device_encodes_tags(dev)) {
459         if ((pgs->color[0].dev_color->tag & tag) == 0) {
460             gx_unset_dev_color(pgs);	/* current dev_color needs update to new tag */
461             pgs->color[0].dev_color->tag = tag;	/* after unset, now set it */
462         }
463     }
464 }
465 
466 
467 #endif /* gxistate_INCLUDED */
468