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