summaryrefslogtreecommitdiff
path: root/gs/base/gsistate.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/base/gsistate.c')
-rw-r--r--gs/base/gsistate.c222
1 files changed, 222 insertions, 0 deletions
diff --git a/gs/base/gsistate.c b/gs/base/gsistate.c
new file mode 100644
index 000000000..0c7562656
--- /dev/null
+++ b/gs/base/gsistate.c
@@ -0,0 +1,222 @@
+/* Copyright (C) 2001-2006 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 that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* $Id$ */
+/* Imager state housekeeping */
+#include "gx.h"
+#include "gserrors.h"
+#include "gscspace.h"
+#include "gscie.h"
+#include "gsstruct.h"
+#include "gsutil.h" /* for gs_next_ids */
+#include "gxbitmap.h"
+#include "gxcmap.h"
+#include "gxdht.h"
+#include "gxistate.h"
+#include "gzht.h"
+#include "gzline.h"
+#include "gxfmap.h"
+
+/******************************************************************************
+ * See gsstate.c for a discussion of graphics/imager state memory management. *
+ ******************************************************************************/
+
+/* Imported values */
+/* The following should include a 'const', but for some reason */
+/* the Watcom compiler won't accept it, even though it happily accepts */
+/* the same construct everywhere else. */
+extern /*const*/ gx_color_map_procs *const cmap_procs_default;
+
+/* GC procedures for gx_line_params */
+static
+ENUM_PTRS_WITH(line_params_enum_ptrs, gx_line_params *plp) return 0;
+ case 0: return ENUM_OBJ((plp->dash.pattern_size == 0 ?
+ NULL : plp->dash.pattern));
+ENUM_PTRS_END
+static RELOC_PTRS_WITH(line_params_reloc_ptrs, gx_line_params *plp)
+{
+ if (plp->dash.pattern_size)
+ RELOC_VAR(plp->dash.pattern);
+} RELOC_PTRS_END
+private_st_line_params();
+
+/*
+ * GC procedures for gs_imager_state
+ *
+ * See comments in gixstate.h before the definition of gs_cr_state_do_rc and
+ * st_cr_state_num_ptrs for an explanation about why the effective_transfer
+ * pointers are handled in this manner.
+ */
+public_st_imager_state();
+static
+ENUM_PTRS_BEGIN(imager_state_enum_ptrs)
+ ENUM_SUPER(gs_imager_state, st_line_params, line_params, st_imager_state_num_ptrs - st_line_params_num_ptrs);
+ ENUM_PTR(0, gs_imager_state, client_data);
+ ENUM_PTR(1, gs_imager_state, transparency_stack);
+#define E1(i,elt) ENUM_PTR(i+2,gs_imager_state,elt);
+ gs_cr_state_do_ptrs(E1)
+#undef E1
+ENUM_PTRS_END
+static RELOC_PTRS_BEGIN(imager_state_reloc_ptrs)
+{
+ RELOC_SUPER(gs_imager_state, st_line_params, line_params);
+ RELOC_PTR(gs_imager_state, client_data);
+ RELOC_PTR(gs_imager_state, transparency_stack);
+#define R1(i,elt) RELOC_PTR(gs_imager_state,elt);
+ gs_cr_state_do_ptrs(R1)
+#undef R1
+ {
+ int i = GX_DEVICE_COLOR_MAX_COMPONENTS - 1;
+
+ for (; i >= 0; i--)
+ RELOC_PTR(gs_imager_state, effective_transfer[i]);
+ }
+} RELOC_PTRS_END
+
+
+/* Initialize an imager state, other than the parts covered by */
+/* gs_imager_state_initial. */
+int
+gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem)
+{
+ int i;
+ pis->memory = mem;
+ pis->client_data = 0;
+ pis->transparency_stack = 0;
+ /* Color rendering state */
+ pis->halftone = 0;
+ {
+ int i;
+
+ for (i = 0; i < gs_color_select_count; ++i)
+ pis->screen_phase[i].x = pis->screen_phase[i].y = 0;
+ }
+ pis->dev_ht = 0;
+ pis->cie_render = 0;
+ pis->cie_to_xyz = false;
+ pis->black_generation = 0;
+ pis->undercolor_removal = 0;
+ /* Allocate an initial transfer map. */
+ rc_alloc_struct_n(pis->set_transfer.gray,
+ gx_transfer_map, &st_transfer_map,
+ mem, return_error(gs_error_VMerror),
+ "gs_imager_state_init(transfer)", 1);
+ pis->set_transfer.gray->proc = gs_identity_transfer;
+ pis->set_transfer.gray->id = gs_next_ids(pis->memory, 1);
+ pis->set_transfer.gray->values[0] = frac_0;
+ pis->set_transfer.red =
+ pis->set_transfer.green =
+ pis->set_transfer.blue = NULL;
+ for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
+ pis->effective_transfer[i] = pis->set_transfer.gray;
+ pis->cie_joint_caches = NULL;
+ pis->cmap_procs = cmap_procs_default;
+ pis->pattern_cache = NULL;
+ pis->have_pattern_streams = false;
+ pis->devicergb_cs = gs_cspace_new_DeviceRGB(mem);
+ pis->devicecmyk_cs = gs_cspace_new_DeviceCMYK(mem);
+ return 0;
+}
+
+/*
+ * Make a temporary copy of a gs_imager_state. Note that this does not
+ * do all the necessary reference counting, etc. However, it does
+ * clear out the transparency stack in the destination.
+ */
+gs_imager_state *
+gs_imager_state_copy(const gs_imager_state * pis, gs_memory_t * mem)
+{
+ gs_imager_state *pis_copy =
+ gs_alloc_struct(mem, gs_imager_state, &st_imager_state,
+ "gs_imager_state_copy");
+
+ if (pis_copy) {
+ *pis_copy = *pis;
+ pis_copy->transparency_stack = 0;
+ }
+ return pis_copy;
+}
+
+/* Increment reference counts to note that an imager state has been copied. */
+void
+gs_imager_state_copied(gs_imager_state * pis)
+{
+ rc_increment(pis->halftone);
+ rc_increment(pis->dev_ht);
+ rc_increment(pis->cie_render);
+ rc_increment(pis->black_generation);
+ rc_increment(pis->undercolor_removal);
+ rc_increment(pis->set_transfer.gray);
+ rc_increment(pis->set_transfer.red);
+ rc_increment(pis->set_transfer.green);
+ rc_increment(pis->set_transfer.blue);
+ rc_increment(pis->cie_joint_caches);
+ rc_increment(pis->devicergb_cs);
+ rc_increment(pis->devicecmyk_cs);
+}
+
+/* Adjust reference counts before assigning one imager state to another. */
+void
+gs_imager_state_pre_assign(gs_imager_state *pto, const gs_imager_state *pfrom)
+{
+ const char *const cname = "gs_imager_state_pre_assign";
+
+#define RCCOPY(element)\
+ rc_pre_assign(pto->element, pfrom->element, cname)
+
+ RCCOPY(cie_joint_caches);
+ RCCOPY(set_transfer.blue);
+ RCCOPY(set_transfer.green);
+ RCCOPY(set_transfer.red);
+ RCCOPY(set_transfer.gray);
+ RCCOPY(undercolor_removal);
+ RCCOPY(black_generation);
+ RCCOPY(cie_render);
+ RCCOPY(dev_ht);
+ RCCOPY(halftone);
+ RCCOPY(devicergb_cs);
+ RCCOPY(devicecmyk_cs);
+#undef RCCOPY
+}
+
+/* Release an imager state. */
+void
+gs_imager_state_release(gs_imager_state * pis)
+{
+ const char *const cname = "gs_imager_state_release";
+ gx_device_halftone *pdht = pis->dev_ht;
+
+#define RCDECR(element)\
+ rc_decrement(pis->element, cname)
+
+ RCDECR(cie_joint_caches);
+ RCDECR(set_transfer.gray);
+ RCDECR(set_transfer.blue);
+ RCDECR(set_transfer.green);
+ RCDECR(set_transfer.red);
+ RCDECR(undercolor_removal);
+ RCDECR(black_generation);
+ RCDECR(cie_render);
+ /*
+ * If we're going to free the device halftone, make sure we free the
+ * dependent structures as well.
+ */
+ if (pdht != 0 && pdht->rc.ref_count == 1) {
+ gx_device_halftone_release(pdht, pdht->rc.memory);
+ }
+ RCDECR(dev_ht);
+ RCDECR(halftone);
+ RCDECR(devicergb_cs);
+ RCDECR(devicecmyk_cs);
+#undef RCDECR
+}