summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gdevdflt.c')
-rw-r--r--base/gdevdflt.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/base/gdevdflt.c b/base/gdevdflt.c
index f93e968d..df85e1f9 100644
--- a/base/gdevdflt.c
+++ b/base/gdevdflt.c
@@ -729,6 +729,7 @@ gx_device_fill_in_procs(register gx_device * dev)
fill_dev_proc(dev, process_page, gx_default_process_page);
fill_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region);
fill_dev_proc(dev, fill_stroke_path, gx_default_fill_stroke_path);
+ fill_dev_proc(dev, lock_pattern, gx_default_lock_pattern);
}
@@ -1260,6 +1261,7 @@ int gx_copy_device_procs(gx_device *dest, const gx_device *src, const gx_device
set_dev_proc(dest, process_page, dev_proc(&prototype, process_page));
set_dev_proc(dest, transform_pixel_region, dev_proc(&prototype, transform_pixel_region));
set_dev_proc(dest, fill_stroke_path, dev_proc(&prototype, fill_stroke_path));
+ set_dev_proc(dest, lock_pattern, dev_proc(&prototype, lock_pattern));
/*
* We absolutely must set the 'set_graphics_type_tag' to the default subclass one
@@ -1346,6 +1348,9 @@ int gx_device_subclass(gx_device *dev_to_subclass, gx_device *new_prototype, uns
child_dev->stype = a_std;
child_dev->stype_is_dynamic = 1;
+ /* At this point, the only counted reference to the child is from its parent, and we need it to use the right allocator */
+ rc_init(child_dev, dev_to_subclass->memory->stable_memory, 1);
+
psubclass_data = (void *)gs_alloc_bytes(dev_to_subclass->memory->non_gc_memory, private_data_size, "subclass memory for subclassing device");
if (psubclass_data == 0){
gs_free_const_object(dev_to_subclass->memory->non_gc_memory, b_std, "gs_device_subclass(stype)");
@@ -1431,12 +1436,15 @@ void gx_device_unsubclass(gx_device *dev)
gx_device *parent, *child;
gs_memory_struct_type_t *a_std = 0, *b_std = 0;
int dynamic, ref_count;
+ gs_memory_t *rcmem;
/* This should not happen... */
if (!dev)
return;
ref_count = dev->rc.ref_count;
+ rcmem = dev->rc.memory;
+
child = dev->child;
psubclass_data = (generic_subclass_data *)dev->subclass_data;
parent = dev->parent;
@@ -1483,6 +1491,7 @@ void gx_device_unsubclass(gx_device *dev)
* when we copy back the subclassed device.
*/
dev->rc.ref_count = ref_count;
+ dev->rc.memory = rcmem;
/* If we have a chain of devices, make sure the chain beyond the
* device we're unsubclassing doesn't get broken, we need to
@@ -1501,12 +1510,6 @@ void gx_device_unsubclass(gx_device *dev)
* devices it's possible that their child pointer can then be NULL.
*/
if (child) {
- if (child->icc_struct)
- rc_decrement(child->icc_struct, "gx_device_unsubclass, icc_struct");
- if (child->PageList)
- rc_decrement(child->PageList, "gx_device_unsubclass, PageList");
- if (child->NupControl)
- rc_decrement(child->NupControl, "gx_device_unsubclass, NupControl");
/* We cannot afford to free the child device if its stype is not
* dynamic because we can't 'null' the finalise routine, and we
* cannot permit the device to be finalised because we have copied
@@ -1519,8 +1522,7 @@ void gx_device_unsubclass(gx_device *dev)
* just security here. */
child->parent = NULL;
child->child = NULL;
- /* Make certain the memory will be freed, zap the reference count */
- child->rc.ref_count = 0;
+
/* We *don't* want to run the finalize routine. This would free
* the stype and properly handle the icc_struct and PageList,
* but for devices with a custom finalize (eg psdcmyk) it might
@@ -1529,22 +1531,27 @@ void gx_device_unsubclass(gx_device *dev)
* variable is just to get rid of const warnings.
*/
b_std = (gs_memory_struct_type_t *)child->stype;
- b_std->finalize = NULL;
- /* Having patched the stype, we need to make sure the memory
+ gs_free_const_object(dev->memory->non_gc_memory, b_std, "gs_device_unsubclass(stype)");
+ /* Make this into a generic device */
+ child->stype = &st_device;
+ child->stype_is_dynamic = false;
+
+ /* We can't simply discard the child device, because there may be references to it elsewhere,
+ but equally, we really don't want it doing anything, so set the procs so actions are just discarded.
+ */
+ gx_copy_device_procs(child, (gx_device *)&gs_null_device, (gx_device *)&gs_null_device);
+
+ /* Having changed the stype, we need to make sure the memory
* manager uses it. It keeps a copy in its own data structure,
* and would use that copy, which would mean it would call the
* finalize routine that we just patched out.
*/
- gs_set_object_type(dev->memory->stable_memory, child, b_std);
+ gs_set_object_type(dev->memory->stable_memory, child, child->stype);
+ child->finalize = NULL;
/* Now (finally) free the child memory */
- gs_free_object(dev->memory->stable_memory, child, "gx_device_unsubclass(device)");
- /* And the stype for it */
- gs_free_const_object(dev->memory->non_gc_memory, b_std, "gs_device_unsubclass(stype)");
- child = 0;
+ rc_decrement(child, "gx_device_unsubclass(device)");
}
}
- if(child)
- child->parent = dev;
dev->parent = parent;
/* If this device has a dynamic stype, we wnt to keep using it, but we copied