[gs-cvs] rev 9596 - in trunk/gs: Resource/Init base
ken at ghostscript.com
ken at ghostscript.com
Thu Mar 26 06:46:30 PDT 2009
Author: ken
Date: 2009-03-26 06:46:29 -0700 (Thu, 26 Mar 2009)
New Revision: 9596
Modified:
trunk/gs/Resource/Init/gs_pdfwr.ps
trunk/gs/base/gdevpsdp.c
Log:
Fix (pdfwrite) : NeverEmbed/AlwaysEmbed not working properly.
DETAILS :
Patch and Log supplied by Leonardo.
Bug 689610 "Possible /NeverEmbed vs /AlwaysEmbed problem"
The root of the problem is that (1) empty arrays did not work,
and (2) existing values of the parameters (before setdistillerparams)
were not properly accounted for in setdistillerparams.
In the old code, PS and C parts of "embed" parameters implementation
are inconsistent each to another and to the documentation. Replacing both with the
right logic defined in the Adobe Distiller Parameters specification.
The comment in gdevpsdp.c line 81 is kept as the basic interface definition.
Note: in the old code param_read_embed_array could not distinguish empty array from
no array, but it is important for the Adobe logic.
Also psdf_put_embed_param parameters did not correspond to the documentation in
gdevpsdp.c ln 81.
ref# leo2073.
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/Resource/Init/gs_pdfwr.ps
===================================================================
--- trunk/gs/Resource/Init/gs_pdfwr.ps 2009-03-25 13:00:06 UTC (rev 9595)
+++ trunk/gs/Resource/Init/gs_pdfwr.ps 2009-03-26 13:46:29 UTC (rev 9596)
@@ -665,18 +665,28 @@
/MonoImageResolution { }
% Font embedding parameters
/AlwaysEmbed
- { dup length 0 gt
- { dup 0 get false eq
+ { dup length 0 gt
+ { dup 0 get type /booleantype eq } { false } ifelse
+ { dup 0 get
+ { dup length 1 sub 1 exch getinterval
+ }
{ dup length 1 sub 1 exch getinterval exch pop /~AlwaysEmbed exch
- } if
- } if
+ } ifelse
+ }
+ { exch pop /.AlwaysEmbed exch
+ } ifelse
}
/NeverEmbed
- { dup length 0 gt
- { dup 0 get false eq
- { dup length 1 sub 1 exch getinterval exch pop /~NeverEmbed exch
- } if
- } if
+ { dup length 0 gt
+ { dup 0 get type /booleantype eq } { false } ifelse
+ { dup 0 get
+ { dup length 1 sub 1 exch getinterval
+ }
+ { dup length 1 sub 1 exch getinterval exch pop /~NeverEmbed exch
+ } ifelse
+ }
+ { exch pop /.NeverEmbed exch
+ } ifelse
}
/CannotEmbedFontPolicy { }
/EmbedAllFonts { }
Modified: trunk/gs/base/gdevpsdp.c
===================================================================
--- trunk/gs/base/gdevpsdp.c 2009-03-25 13:00:06 UTC (rev 9595)
+++ trunk/gs/base/gdevpsdp.c 2009-03-26 13:46:29 UTC (rev 9596)
@@ -487,22 +487,22 @@
}
/* Put [~](Always|Never)Embed parameters. */
+/* Returns 0 = OK, 1 = no paramewter specified, <0 = error. */
static int
param_read_embed_array(gs_param_list * plist, gs_param_name pname,
- gs_param_string_array * psa, int ecode)
+ gs_param_string_array * psa)
{
int code;
psa->data = 0, psa->size = 0;
switch (code = param_read_name_array(plist, pname, psa)) {
default:
- ecode = code;
- param_signal_error(plist, pname, ecode);
+ param_signal_error(plist, pname, code);
case 0:
case 1:
break;
}
- return ecode;
+ return code;
}
static bool
param_string_eq(const gs_param_string *ps1, const gs_param_string *ps2)
@@ -563,88 +563,83 @@
}
prsa->size = count;
}
+static int merge_embed(gs_param_string_array * psa, gs_param_string_array * asa,
+ gs_memory_t *mem)
+{
+ gs_param_string_array rsa;
+ gs_param_string *rdata;
+ int code;
+
+ rdata = gs_alloc_struct_array(mem, psa->size + asa->size,
+ gs_param_string,
+ &st_param_string_element,
+ "psdf_put_embed_param(update)");
+ if (rdata == 0)
+ return_error(gs_error_VMerror);
+ memcpy(rdata, psa->data, psa->size * sizeof(*psa->data));
+ rsa.data = rdata;
+ rsa.size = psa->size;
+ rsa.persistent = false;
+ code = add_embed(&rsa, asa, mem);
+ if (code < 0) {
+ gs_free_object(mem, rdata, "psdf_put_embed_param(update)");
+ return code;
+ }
+ gs_free_const_object(mem, psa->data, "psdf_put_embed_param(free)");
+ *psa = rsa;
+ return 0;
+}
+
static int
psdf_put_embed_param(gs_param_list * plist, gs_param_name notpname,
- gs_param_name allpname, gs_param_string_array * psa,
+ gs_param_name pname, gs_param_string_array * psa,
gs_memory_t *mem, int ecode)
{
- gs_param_name pname = notpname + 1;
+ gs_param_name allpname = pname + 1;
gs_param_string_array sa, nsa, asa;
- bool replace;
- gs_param_string *rdata;
- gs_param_string_array rsa;
- int code = 0;
+ int code;
mem = gs_memory_stable(mem);
- ecode = param_read_embed_array(plist, pname, &sa, ecode);
- ecode = param_read_embed_array(plist, notpname, &nsa, ecode);
- ecode = param_read_embed_array(plist, allpname, &asa, ecode);
- if (ecode < 0)
- return ecode;
- /*
- * Figure out whether we're replacing (sa == asa or asa and no sa,
- * no nsa) or updating (all other cases).
- */
- if (asa.data == 0 || nsa.data != 0)
- replace = false;
- else if (sa.data == 0)
- replace = true;
- else if (sa.size != asa.size)
- replace = false;
- else {
- /* Test whether sa == asa. */
- uint i;
+ code = param_read_embed_array(plist, pname, &sa);
+ if (code < 0)
+ return code;
+ if (code == 0) {
+ /* Optimize for sa == *psa. */
+ int i;
- replace = true;
- for (i = 0; i < sa.size; ++i)
- if (!param_string_eq(&sa.data[i], &asa.data[i])) {
- replace = false;
- break;
- }
- if (replace)
- return 0; /* no-op */
- }
- if (replace) {
- /* Wholesale replacement, only asa is relevant. */
- rdata = gs_alloc_struct_array(mem, asa.size, gs_param_string,
- &st_param_string_element,
- "psdf_put_embed_param(replace)");
- if (rdata == 0)
- return_error(gs_error_VMerror);
- rsa.data = rdata;
- rsa.size = 0;
- if ((code = add_embed(&rsa, &asa, mem)) < 0) {
- gs_free_object(mem, rdata, "psdf_put_embed_param(replace)");
- ecode = code;
+ if (sa.size == psa->size) {
+ for (i = 0; i < sa.size; ++i) {
+ if (!param_string_eq(&sa.data[i], &psa->data[i]))
+ break;
+ }
} else
- delete_embed(psa, psa, mem);
- } else if (sa.data || nsa.data) {
- /* Incremental update, sa and nsa are relevant, asa is not. */
- rdata = gs_alloc_struct_array(mem, psa->size + sa.size,
- gs_param_string,
- &st_param_string_element,
- "psdf_put_embed_param(update)");
- if (rdata == 0)
- return_error(gs_error_VMerror);
- memcpy(rdata, psa->data, psa->size * sizeof(*psa->data));
- rsa.data = rdata;
- rsa.size = psa->size;
- if ((code = add_embed(&rsa, &sa, mem)) < 0) {
- gs_free_object(mem, rdata, "psdf_put_embed_param(update)");
- ecode = code;
+ i = -1;
+ if (i == sa.size) {
+ /* equal, no-op. */
} else {
- delete_embed(&rsa, &nsa, mem);
- rsa.data = gs_resize_object(mem, rdata, rsa.size,
- "psdf_put_embed_param(resize)");
+ delete_embed(psa, psa, mem);
+ code = merge_embed(psa, &sa, mem);
+ if (code < 0)
+ return code;
}
- } else
- return 0; /* no-op */
- if (code >= 0) {
- gs_free_const_object(mem, psa->data, "psdf_put_embed_param(free)");
- rsa.persistent = false;
- *psa = rsa;
}
- return ecode;
+ code = param_read_embed_array(plist, notpname, &nsa);
+ if (code < 0)
+ return code;
+ if (nsa.data != 0)
+ delete_embed(psa, &nsa, mem);
+ code = param_read_embed_array(plist, allpname, &asa);
+ if (code < 0)
+ return code;
+ if (asa.data != 0) {
+ code = merge_embed(psa, &asa, mem);
+ if (code < 0)
+ return code;
+ }
+ if (psa->data)
+ psa->data = gs_resize_object(mem, (gs_param_string *)psa->data, psa->size,
+ "psdf_put_embed_param(resize)");
+ return 0;
}
/* Put an image Dict parameter. */
More information about the gs-cvs
mailing list