summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gxgstate.h')
-rw-r--r--base/gxgstate.h459
1 files changed, 459 insertions, 0 deletions
diff --git a/base/gxgstate.h b/base/gxgstate.h
new file mode 100644
index 00000000..4f243165
--- /dev/null
+++ b/base/gxgstate.h
@@ -0,0 +1,459 @@
+/* Copyright (C) 2001-2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+/* graphics state definition */
+
+#ifndef gxistate_INCLUDED
+# define gxistate_INCLUDED
+
+#include "gscsel.h"
+#include "gsrefct.h"
+#include "gsropt.h"
+#include "gstparam.h"
+#include "gxcvalue.h"
+#include "gxcmap.h"
+#include "gxfixed.h"
+#include "gxline.h"
+#include "gxmatrix.h"
+#include "gxtmap.h"
+#include "gscspace.h"
+#include "gstrans.h"
+#include "gsnamecl.h"
+#include "gscms.h"
+#include "gscpm.h"
+#include "gscspace.h"
+#include "gxdcolor.h"
+#include "gxstate.h"
+#include "gsfont.h"
+#include "gxpath.h"
+#include "gsccolor.h"
+#include "gsht1.h"
+#include "gxclipsr.h"
+
+
+/*
+ * Define the color rendering state information.
+ * This should be a separate object (or at least a substructure),
+ * but making this change would require editing too much code.
+ */
+
+/*
+ * We need some special memory management for the components of a
+ * c.r. state, as indicated by the following notations on the elements:
+ * (RC) means the element is reference-counted.
+ * (Shared) means the element is shared among an arbitrary number of
+ * c.r. states and is never freed.
+ * (Owned) means exactly one c.r. state references the element,
+ * and it is guaranteed that no references to it will outlive
+ * the c.r. state itself.
+ */
+
+/* Define the interior structure of a transfer function. */
+typedef struct gx_transfer_s {
+ int red_component_num;
+ gx_transfer_map *red; /* (RC) */
+ int green_component_num;
+ gx_transfer_map *green; /* (RC) */
+ int blue_component_num;
+ gx_transfer_map *blue; /* (RC) */
+ int gray_component_num;
+ gx_transfer_map *gray; /* (RC) */
+} gx_transfer;
+
+#define gs_color_rendering_state_common\
+\
+ /* Halftone screen: */\
+\
+ gs_halftone *halftone; /* (RC) */\
+ gs_int_point screen_phase[gs_color_select_count];\
+ /* dev_ht depends on halftone and device resolution. */\
+ gx_device_halftone *dev_ht; /* (RC) */\
+\
+ /* Color (device-dependent): */\
+\
+ struct gs_cie_render_s *cie_render; /* (RC) may be 0 */\
+ bool cie_to_xyz; /* flag for conversion to XYZ, no CRD req'd */\
+ gx_transfer_map *black_generation; /* (RC) may be 0 */\
+ gx_transfer_map *undercolor_removal; /* (RC) may be 0 */\
+ /* set_transfer holds the transfer functions specified by */\
+ /* set[color]transfer; effective_transfer includes the */\
+ /* effects of overrides by TransferFunctions in halftone */\
+ /* dictionaries. (In Level 1 systems, set_transfer and */\
+ /* effective_transfer are always the same.) */\
+ gx_transfer set_transfer; /* members are (RC) */\
+ int effective_transfer_non_identity_count;\
+ gx_transfer_map *effective_transfer[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* see below */\
+\
+ /* Color caches: */\
+\
+ /* cie_joint_caches depend on cie_render and */\
+ /* the color space. */\
+ struct gx_cie_joint_caches_s *cie_joint_caches; /* (RC) */\
+ /* cmap_procs depend on the device's color_info. */\
+ const struct gx_color_map_procs_s *cmap_procs; /* static */\
+ /* DeviceN component map for current color space */\
+ gs_devicen_color_map color_component_map;\
+ /* The contents of pattern_cache depend on the */\
+ /* the color space and the device's color_info and */\
+ /* resolution. */\
+ struct gx_pattern_cache_s *pattern_cache; /* (Shared) by all gstates */\
+\
+ /* Simple color spaces, stored here for easy access from */ \
+ /* gx_concrete_space_CIE */ \
+ gs_color_space *devicergb_cs;\
+ gs_color_space *devicecmyk_cs;\
+\
+ /* Stores for cached values which correspond to whichever */\
+ /* color isn't in force at the moment */\
+ struct gx_cie_joint_caches_s *cie_joint_caches_alt;\
+ gs_devicen_color_map color_component_map_alt
+
+
+/* Current colors (non-stroking, and stroking) */
+typedef struct gs_gstate_color_s {
+ gs_color_space *color_space; /* after substitution */
+ gs_client_color *ccolor;
+ gx_device_color *dev_color;
+} gs_gstate_color;
+
+/*
+ * Enumerate the reference-counted pointers in a c.r. state. Note that
+ * effective_transfer doesn't contribute to the reference count: it points
+ * either to the same objects as set_transfer, or to objects in a halftone
+ * structure that someone else worries about.
+ */
+#define gs_cr_state_do_rc_ptrs(m)\
+ m(halftone) \
+ m(dev_ht) \
+ m(cie_render) \
+ m(black_generation) \
+ m(undercolor_removal) \
+ m(set_transfer.red) \
+ m(set_transfer.green) \
+ m(set_transfer.blue) \
+ m(set_transfer.gray) \
+ m(cie_joint_caches) \
+ m(devicergb_cs) \
+ m(devicecmyk_cs)\
+ m(cie_joint_caches_alt)
+
+/* Enumerate the pointers in a c.r. state. */
+#define gs_cr_state_do_ptrs(m)\
+ m(0,halftone) \
+ m(1,dev_ht) \
+ m(2,cie_render) \
+ m(3,black_generation) \
+ m(4,undercolor_removal) \
+ m(5,set_transfer.red) \
+ m(6,set_transfer.green) \
+ m(7,set_transfer.blue) \
+ m(8,set_transfer.gray)\
+ m(9,cie_joint_caches) \
+ m(10,pattern_cache) \
+ m(11,devicergb_cs) \
+ m(12,devicecmyk_cs)\
+ m(13,cie_joint_caches_alt)
+ /*
+ * We handle effective_transfer specially in gsistate.c since its pointers
+ * are not enumerated for garbage collection but they are are relocated.
+ */
+/*
+ * This count does not include the effective_transfer pointers since they
+ * are not enumerated for GC.
+ */
+#define st_cr_state_num_ptrs 14
+
+struct gs_devicen_color_map_s {
+ bool use_alt_cspace;
+ separation_type sep_type;
+ uint num_components; /* Input - Duplicate of value in gs_device_n_params */
+ uint num_colorants; /* Number of colorants - output */
+ gs_id cspace_id; /* Used to verify color space and map match */
+ int color_map[GS_CLIENT_COLOR_MAX_COMPONENTS];
+};
+
+
+/* These flags are used to keep track of qQ
+ combinations surrounding a graphic state
+ change that includes a softmask setting.
+ The transparency compositor must be notified
+ when a Q event occurs following a softmask */
+
+typedef struct gs_xstate_trans_flags {
+ bool xstate_pending;
+ bool xstate_change;
+} gs_xstate_trans_flags_t;
+
+#define gs_currentdevicecolor_inline(pgs) ((pgs)->color[0].dev_color)
+#define gs_currentcolor_inline(pgs) ((pgs)->color[0].ccolor)
+#define gs_currentcolorspace_inline(pgs) ((pgs)->color[0].color_space)
+#define gs_altdevicecolor_inline(pgs) ((pgs)->color[1].dev_color)
+
+#define char_tm_only(pgs) *(gs_matrix *)&(pgs)->char_tm
+
+#undef gs_currentdevice_inline /* remove definition in gsdevice.h?? */
+#define gs_currentdevice_inline(pgs) ((pgs)->device)
+
+#define gs_gstate_client_data(pgs) ((pgs)->client_data)
+
+/* Define the graphics state structure itself. */
+/*
+ * Note that the ctm member is a gs_matrix_fixed. As such, it cannot be
+ * used directly as the argument for procedures like gs_point_transform.
+ * Instead, one must use the ctm_only macro, e.g., &ctm_only(pgs) rather
+ * than &pgs->ctm.
+ */
+
+/* Access macros */
+#define ctm_only(pgs) (*(const gs_matrix *)&(pgs)->ctm)
+#define ctm_only_writable(pgs) (*(gs_matrix *)&(pgs)->ctm)
+#define set_ctm_only(pgs, mat) (*(gs_matrix *)&(pgs)->ctm = (mat))
+#define gs_init_rop(pgs) ((pgs)->log_op = lop_default)
+#define gs_currentflat_inline(pgs) ((pgs)->flatness)
+#define gs_currentlineparams_inline(pgs) (&(pgs)->line_params)
+#define gs_current_logical_op_inline(pgs) ((pgs)->log_op)
+#define gs_set_logical_op_inline(pgs, lop) ((pgs)->log_op = (lop))
+
+struct gs_gstate_s {
+ gs_memory_t *memory;
+ void *client_data;
+ gx_line_params line_params;
+ bool hpgl_path_mode;
+ gs_matrix_fixed ctm;
+ bool current_point_valid;
+ gs_point current_point;
+ gs_point subpath_start;
+ bool clamp_coordinates;
+ gs_logical_operation_t log_op;
+ gx_color_value alpha;
+ gs_blend_mode_t blend_mode;
+ gs_transparency_source_t opacity, shape;
+ gs_xstate_trans_flags_t trans_flags;
+ gs_id soft_mask_id;
+ bool text_knockout;
+ uint text_rendering_mode;
+ bool has_transparency; /* used to keep from doing shading fills in device color space */
+ gx_device *trans_device; /* trans device has all mappings to group color space */
+ bool overprint;
+ int overprint_mode;
+ int effective_overprint_mode;
+ bool stroke_overprint;
+ float flatness;
+ gs_fixed_point fill_adjust; /* A path expansion for fill; -1 = dropout prevention*/
+ bool stroke_adjust;
+ bool accurate_curves;
+ bool have_pattern_streams;
+ float smoothness;
+ int renderingintent; /* See gsstate.c */
+ bool blackptcomp;
+ gsicc_manager_t *icc_manager; /* ICC color manager, profile */
+ gsicc_link_cache_t *icc_link_cache; /* ICC linked transforms */
+ gsicc_profile_cache_t *icc_profile_cache; /* ICC profiles from PS. */
+ CUSTOM_COLOR_PTR /* Pointer to custom color callback struct */
+ const gx_color_map_procs *
+ (*get_cmap_procs)(const gs_gstate *, const gx_device *);
+ gs_color_rendering_state_common;
+
+ gs_gstate *saved; /* previous state from gsave */
+
+ /* Transformation: */
+ gs_matrix ctm_inverse;
+ bool ctm_inverse_valid; /* true if ctm_inverse = ctm^-1 */
+ gs_matrix ctm_default;
+ bool ctm_default_set; /* if true, use ctm_default; */
+ /* if false, ask device */
+ /* Paths: */
+
+ gx_path *path;
+ gx_clip_path *clip_path;
+ gx_clip_stack_t *clip_stack; /* (LanguageLevel 3 only) */
+ gx_clip_path *view_clip; /* (may be 0, or have rule = 0) */
+
+ /* Effective clip path cache */
+ gs_id effective_clip_id; /* (key) clip path id */
+ gs_id effective_view_clip_id; /* (key) view clip path id */
+ gx_clip_path *effective_clip_path; /* (value) effective clip path, */
+ /* possibly = clip_path or view_clip */
+ bool effective_clip_shared; /* true iff e.c.p. = c.p. or v.c. */
+
+ /* PDF graphics state parameters */
+ float strokeconstantalpha, fillconstantalpha;
+ /* *SMask is stored in int_gstate as its a ref object */
+ bool alphaisshape;
+ float textspacing;
+ float textleading;
+ float textrise;
+ float wordspacing;
+ float texthscaling;
+ float PDFfontsize;
+ gs_matrix textlinematrix;
+ gs_matrix textmatrix;
+ /* Current colors (non-stroking, and stroking) */
+ gs_gstate_color color[2];
+
+ /* Font: */
+ gs_font *font;
+ gs_font *root_font;
+ gs_matrix_fixed char_tm; /* font matrix * ctm */
+ bool char_tm_valid; /* true if char_tm is valid */
+ gs_in_cache_device_t in_cachedevice; /* (see gscpm.h) */
+ gs_char_path_mode in_charpath; /* (see gscpm.h) */
+ gs_gstate *show_gstate; /* gstate when show was invoked */
+ /* (so charpath can append to path) */
+ /* Other stuff: */
+ int level; /* incremented by 1 per gsave */
+ gx_device *device;
+ gs_gstate_client_procs client_procs;
+};
+
+/* Initialization for gs_gstate */
+#define gs_gstate_initial(scale)\
+ 0, 0, { gx_line_params_initial }, 0,\
+ { (float)(scale), 0.0, 0.0, (float)(-(scale)), 0.0, 0.0 },\
+ false, {0, 0}, {0, 0}, false, \
+ lop_default, gx_max_color_value, BLEND_MODE_Compatible,\
+{ 1.0 }, { 1.0 }, {0, 0}, 0, 0/*false*/, 0, 0/*false*/, 0, 0/*false*/, 0, 0, 0/*false*/, 1.0, \
+ { fixed_half, fixed_half }, 0/*false*/, 1/*true*/, 0/*false*/, 1.0,\
+ 1, 1/* bpt true */, 0, 0, 0, INIT_CUSTOM_COLOR_PTR /* 'Custom color' callback pointer */ \
+ gx_default_get_cmap_procs
+
+#define GS_STATE_INIT_VALUES(s, scale) \
+ do { \
+ static const struct gs_gstate_s __state_init = {gs_gstate_initial(scale)}; \
+ s->memory = __state_init.memory; \
+ s->client_data = __state_init.client_data; \
+ s->line_params = __state_init.line_params; \
+ s->hpgl_path_mode = __state_init.hpgl_path_mode; \
+ s->ctm = __state_init.ctm; \
+ s->current_point_valid = __state_init.current_point_valid; \
+ s->current_point = __state_init.current_point; \
+ s->subpath_start = __state_init.subpath_start; \
+ s->clamp_coordinates = __state_init.clamp_coordinates; \
+ s->log_op = __state_init.log_op; \
+ s->alpha = __state_init.alpha; \
+ s->blend_mode = __state_init.blend_mode; \
+ s->opacity = __state_init.opacity; \
+ s->shape = __state_init.shape; \
+ s->trans_flags = __state_init.trans_flags; \
+ s->soft_mask_id = __state_init.soft_mask_id; \
+ s->text_knockout = __state_init.text_knockout; \
+ s->text_rendering_mode = __state_init.text_rendering_mode; \
+ s->has_transparency = __state_init.has_transparency; \
+ s->trans_device = __state_init.trans_device; \
+ s->overprint = __state_init.overprint; \
+ s->overprint_mode = __state_init.overprint_mode; \
+ s->effective_overprint_mode = __state_init.effective_overprint_mode; \
+ s->stroke_overprint = __state_init.stroke_overprint; \
+ s->flatness = __state_init.flatness; \
+ s->fill_adjust = __state_init.fill_adjust; \
+ s->stroke_adjust = __state_init.stroke_adjust; \
+ s->accurate_curves = __state_init.accurate_curves; \
+ s->have_pattern_streams = __state_init.have_pattern_streams; \
+ s->smoothness = __state_init.smoothness; \
+ s->renderingintent = __state_init.renderingintent; \
+ s->blackptcomp = __state_init.blackptcomp; \
+ s->icc_manager = __state_init.icc_manager; \
+ s->icc_link_cache = __state_init.icc_link_cache; \
+ s->icc_profile_cache = __state_init.icc_profile_cache; \
+ s->get_cmap_procs = __state_init.get_cmap_procs; \
+ s->show_gstate = NULL; \
+ } while (0)
+
+struct_proc_finalize(gs_gstate_finalize);
+#define public_st_gs_gstate() /* in gsstate.c */\
+ gs_public_st_composite_use_final(st_gs_gstate, gs_gstate, "gs_gstate",\
+ gs_gstate_enum_ptrs, gs_gstate_reloc_ptrs, gs_gstate_finalize)
+
+/*
+ * Enumerate the pointers in a graphics state
+ * except device which must
+ * be handled specially.
+ */
+#define gs_gstate_do_ptrs(m)\
+ m(0, client_data) \
+ m(1, trans_device) \
+ m(2, icc_manager) \
+ m(3, icc_link_cache) \
+ m(4, icc_profile_cache) \
+ m(5, saved) \
+ m(6, path) \
+ m(7, clip_path) \
+ m(8, clip_stack) \
+ m(9, view_clip) \
+ m(10, effective_clip_path) \
+ m(11, color[0].color_space) \
+ m(12, color[0].ccolor) \
+ m(13, color[0].dev_color) \
+ m(14, color[1].color_space) \
+ m(15, color[1].ccolor) \
+ m(16, color[1].dev_color)\
+ m(17, font) \
+ m(18, root_font) \
+ m(19, show_gstate)
+
+#define gs_gstate_num_ptrs 20
+
+/* The '+1' in the following is because gs_gstate.device
+ * is handled specially
+ */
+#define st_gs_gstate_num_ptrs\
+ (st_line_params_num_ptrs + st_cr_state_num_ptrs + gs_gstate_num_ptrs + 1)
+
+/* Initialize an graphics state, other than the parts covered by */
+/* gs_gstate_initial. */
+int gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem);
+
+/* Make a temporary copy of a gs_gstate. Note that this does not */
+/* do all the necessary reference counting, etc. */
+gs_gstate * gs_gstate_copy_temp(const gs_gstate * pgs, gs_memory_t * mem);
+
+/* Increment reference counts to note that a graphics state has been copied. */
+void gs_gstate_copied(gs_gstate * pgs);
+
+/* Adjust reference counts before assigning one gs_gstate to another. */
+void gs_gstate_pre_assign(gs_gstate *to, const gs_gstate *from);
+
+/* Release an gs_gstate. */
+void gs_gstate_release(gs_gstate * pgs);
+int gs_currentscreenphase_pgs(const gs_gstate *, gs_int_point *, gs_color_select_t);
+
+
+/* The following macro is used for development purpose for designating places
+ where current point is changed. Clients must not use it. */
+#define gx_setcurrentpoint(pgs, xx, yy)\
+ (pgs)->current_point.x = xx;\
+ (pgs)->current_point.y = yy;
+
+int gs_swapcolors(gs_gstate *);
+void gs_swapcolors_quick(gs_gstate *);
+
+/* Set the graphics_type_tag iff the requested tag bit is not set in the dev_color and */
+/* unset the dev_color so that gx_set_dev_color will remap (encode) with the new tag. */
+/* Also make sure the tag is set in the device so the two remain in sync. */
+static inline void ensure_tag_is_set(gs_gstate *pgs, gx_device *dev, gs_graphics_type_tag_t tag)
+{
+ if ((dev->graphics_type_tag & tag) == 0)
+ dev_proc(dev, set_graphics_type_tag)(dev, tag);
+ if (device_encodes_tags(dev)) {
+ if ((pgs->color[0].dev_color->tag & tag) == 0) {
+ gx_unset_dev_color(pgs); /* current dev_color needs update to new tag */
+ pgs->color[0].dev_color->tag = tag; /* after unset, now set it */
+ }
+ }
+}
+
+
+#endif /* gxistate_INCLUDED */