diff options
Diffstat (limited to 'devices/vector/gdevpsdp.c')
-rw-r--r-- | devices/vector/gdevpsdp.c | 93 |
1 files changed, 86 insertions, 7 deletions
diff --git a/devices/vector/gdevpsdp.c b/devices/vector/gdevpsdp.c index bda3fe2a..c8a48ee5 100644 --- a/devices/vector/gdevpsdp.c +++ b/devices/vector/gdevpsdp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2019 Artifex Software, Inc. +/* Copyright (C) 2001-2020 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -232,7 +232,7 @@ static const gs_param_item_t psdf_param_items[] = { /* (DefaultRenderingIntent) */ pi("DetectBlends", gs_param_type_bool, DetectBlends), pi("DoThumbnails", gs_param_type_bool, DoThumbnails), - pi("ImageMemory", gs_param_type_long, ImageMemory), + pi("ImageMemory", gs_param_type_size_t, ImageMemory), /* (LockDistillerParams) */ pi("LZWEncodePages", gs_param_type_bool, LZWEncodePages), pi("OPM", gs_param_type_int, OPM), @@ -625,6 +625,10 @@ gdev_psdf_get_params(gx_device * dev, gs_param_list * plist) if (code < 0) return code; + code = param_write_string_array(plist, "PSPageOptions", &pdev->params.PSPageOptions); + if (code < 0) + return code; + code = psdf_write_name(plist, "CannotEmbedFontPolicy", CannotEmbedFontPolicy_names[(int)pdev->params.CannotEmbedFontPolicy]); @@ -1040,6 +1044,65 @@ psdf_put_image_params(const gx_device_psdf * pdev, gs_param_list * plist, return ecode; } +/* This is a convenience routine. There doesn't seem to be any way to have a param_string_array + * enumerated for garbage collection, and we have (currently) three members of the psdf_distiller_params + * structure which store param_string_array. If the interpreter is using garbage collection then there + * is the potential for the array, or its contents, to be relocated or freed while we are still + * maintaining pointers to them, unless we enumerate the pointers. + * Instead, we'll copy the string data from the interpreter, make our own param_string_array, and + * manage the memory ourselves. This allows us to move the data into non-GC memory which is preferable + * anyway. + */ +static int psdf_copy_param_string_array(gs_memory_t *mem, gs_param_list * plist, gs_param_string_array *sa, gs_param_string_array *da) +{ + int code; + + if (sa->size > 0) { + int ix; + byte **dest; + + if (da->data != NULL) { + for (ix = 0; ix < da->size;ix++) + gs_free_object(mem->non_gc_memory, (byte *)da->data[ix].data, "freeing old string array copy"); + gs_free_object(mem->non_gc_memory, (byte *)da->data, "freeing old string array"); + } + da->data = (const gs_param_string *)gs_alloc_bytes(mem->non_gc_memory, sa->size * sizeof(gs_param_string), "allocate new string array"); + if (da->data == NULL) + return_error(gs_note_error(gs_error_VMerror)); + memset((byte *)da->data, 0x00, sa->size * sizeof(gs_param_string)); + da->size = sa->size; + da->persistent = false; + + for(ix=0;ix < sa->size;ix++) { + ((gs_param_string *)&da->data[ix])->data = gs_alloc_bytes(mem->non_gc_memory, sa->data[ix].size, "allocate new strings"); + if (da->data[ix].data == NULL) + return_error(gs_note_error(gs_error_VMerror)); + memcpy((byte *)(da->data[ix].data), sa->data[ix].data, sa->data[ix].size); + ((gs_param_string *)&da->data[ix])->size = sa->data[ix].size; + ((gs_param_string *)&da->data[ix])->persistent = false; + } + gs_free_object(plist->memory, (byte *)sa->data, "freeing temporary param string array"); + sa->data = NULL; + sa->size = 0; + } + return 0; +} + +static int psdf_read_copy_param_string_array(gs_memory_t *mem, gs_param_list * plist, char *Key, gs_param_string_array *da) +{ + gs_param_string_array sa; + int code; + + code = param_read_embed_array(plist, Key, &sa); + if (code < 0) + return code; + + if(sa.size) + code = psdf_copy_param_string_array(mem, plist, &sa, da); + + return code; +} + /* Put parameters. */ int gdev_psdf_put_params(gx_device * dev, gs_param_list * plist) @@ -1076,6 +1139,8 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist) params.MonoImage.ACSDict = params.MonoImage.Dict = 0; params.AlwaysEmbed.data = params.NeverEmbed.data = 0; params.AlwaysEmbed.size = params.AlwaysEmbed.persistent = params.NeverEmbed.size = params.NeverEmbed.persistent = 0; + params.PSPageOptions.data = NULL; + params.PSPageOptions.size = 0; } /* General parameters. */ @@ -1184,6 +1249,7 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist) ¶ms.AlwaysEmbed, mem, ecode); ecode = psdf_put_embed_param(plist, "~NeverEmbed", ".NeverEmbed", ¶ms.NeverEmbed, mem, ecode); + params.CannotEmbedFontPolicy = (enum psdf_cannot_embed_font_policy) psdf_put_enum(plist, "CannotEmbedFontPolicy", (int)params.CannotEmbedFontPolicy, @@ -1199,7 +1265,7 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist) if (code < 0) goto exit; - code = param_read_embed_array(plist, "PSPageOptions", ¶ms.PSPageOptions); + code = psdf_read_copy_param_string_array(pdev->memory, plist, "PSPageOptions", ¶ms.PSPageOptions); if (code < 0) goto exit; @@ -1208,6 +1274,14 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist) exit: if (!(pdev->params.LockDistillerParams && params.LockDistillerParams)) { /* Only update the device paramters if there was no error */ + /* If we have any copied param_string_arrays, start by freeing them */ + if (pdev->params.PSPageOptions.size && params.PSPageOptions.size) { + int ix; + + for (ix = 0; ix < pdev->params.PSPageOptions.size;ix++) + gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data[ix].data, "freeing old string array copy"); + gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data, "freeing old string array"); + } pdev->params = params; } else { /* We read a bunch of parameters and are now throwing them away. Either because there @@ -1216,10 +1290,15 @@ exit: */ gs_memory_t *stable_mem = gs_memory_stable(mem); - if (params.NeverEmbed.data != 0) - gs_free_object(stable_mem, (void *)params.NeverEmbed.data, "free dummy param NeverEmbed"); - if (params.AlwaysEmbed.data != 0) - gs_free_object(stable_mem, (void *)params.AlwaysEmbed.data, "free dummy param AlwaysEmbed"); + if (params.PSPageOptions.data != NULL) { + int ix; + + for (ix = 0; ix < pdev->params.PSPageOptions.size;ix++) + gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data[ix].data, "freeing dummy PSPageOptions"); + gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data, "freeing dummy PSPageOptions"); + params.PSPageOptions.data = NULL; + params.PSPageOptions.size = 0; + } if (params.CalCMYKProfile.data != 0) gs_free_string(stable_mem, (void *)params.CalCMYKProfile.data, params.CalCMYKProfile.size, "free dummy param CalCMYKProfile"); if (params.CalGrayProfile.data != 0) |