[gs-cvs] rev 6947 - trunk/gs/src
lpd at ghostscript.com
lpd at ghostscript.com
Tue Aug 1 21:35:46 PDT 2006
Author: lpd
Date: 2006-08-01 21:35:45 -0700 (Tue, 01 Aug 2006)
New Revision: 6947
Modified:
trunk/gs/src/zupath.c
Log:
Pops arguments off the stack if an error occurs while interpreting a user
path (for Adobe compatibility); enforces the user path order requirements
(ucache must come first if at all, setbbox must come first or immediately
after ucache, setbbox is required).
Modified: trunk/gs/src/zupath.c
===================================================================
--- trunk/gs/src/zupath.c 2006-08-02 01:14:35 UTC (rev 6946)
+++ trunk/gs/src/zupath.c 2006-08-02 04:35:45 UTC (rev 6947)
@@ -272,10 +272,35 @@
upath_op_ucache = 11
} upath_op;
+/* User path interpretation states */
+typedef enum {
+ UPS_INITIAL = 1,
+ UPS_UCACHE = 2,
+ UPS_PATH = 4
+} upath_state;
+
+typedef struct up_data_s {
+ byte num_args;
+ byte states_before;
+ byte state_after;
+} up_data_t;
+#define UP_DATA_PATH(n) {n, UPS_PATH, UPS_PATH}
+
#define UPATH_MAX_OP 11
#define UPATH_REPEAT 32
-static const byte up_nargs[UPATH_MAX_OP + 1] = {
- 4, 2, 2, 2, 2, 6, 6, 5, 5, 5, 0, 0
+static const up_data_t up_data[UPATH_MAX_OP + 1] = {
+ {4, UPS_INITIAL | UPS_UCACHE, UPS_PATH}, /* setbbox */
+ UP_DATA_PATH(2),
+ UP_DATA_PATH(2),
+ UP_DATA_PATH(2),
+ UP_DATA_PATH(2),
+ UP_DATA_PATH(6),
+ UP_DATA_PATH(6),
+ UP_DATA_PATH(5),
+ UP_DATA_PATH(5),
+ UP_DATA_PATH(5),
+ UP_DATA_PATH(0),
+ {0, UPS_INITIAL, UPS_UCACHE} /* ucache */
};
/* Declare operator procedures not declared in opextern.h. */
@@ -522,9 +547,11 @@
/* Append a user path to the current path. */
private inline int
-upath_append_aux(os_ptr oppath, i_ctx_t *i_ctx_p)
+upath_append_aux(os_ptr oppath, i_ctx_t *i_ctx_p, int *pnargs)
{
+ upath_state ups = UPS_INITIAL;
ref opcodes;
+
check_read(*oppath);
gs_newpath(igs);
/****** ROUND tx AND ty ******/
@@ -556,9 +583,15 @@
else if (opx > UPATH_MAX_OP)
return_error(e_rangecheck);
else { /* operator */
+ const up_data_t data = up_data[opx];
+
+ *pnargs = data.num_args; /* in case of error */
+ if (!(ups & data.states_before))
+ return_error(e_typecheck);
+ ups = data.state_after;
do {
os_ptr op = osp;
- byte opargs = up_nargs[opx];
+ byte opargs = data.num_args;
while (opargs--) {
push(1);
@@ -594,7 +627,9 @@
ref rup;
ref *defp;
os_ptr op = osp;
+ up_data_t data;
+ *pnargs = argcount;
array_get(imemory, arp, index, &rup);
switch (r_type(&rup)) {
case t_integer:
@@ -619,8 +654,14 @@
for (opx = 0; opx <= UPATH_MAX_OP; opx++)
if (oproc == up_ops[opx])
break;
- if (opx > UPATH_MAX_OP || argcount != up_nargs[opx])
+ if (opx > UPATH_MAX_OP)
return_error(e_typecheck);
+ data = up_data[opx];
+ if (argcount != data.num_args)
+ return_error(e_typecheck);
+ if (!(ups & data.states_before))
+ return_error(e_typecheck);
+ ups = data.state_after;
code = (*oproc)(i_ctx_p);
if (code < 0)
return code;
@@ -638,10 +679,14 @@
private int
upath_append(os_ptr oppath, i_ctx_t *i_ctx_p)
{
- int code = upath_append_aux(oppath, i_ctx_p);
+ int nargs = 0;
+ int code = upath_append_aux(oppath, i_ctx_p, &nargs);
- if (code < 0)
+ if (code < 0) {
+ /* Pop args on error, to match Adobe interpreters. */
+ pop(nargs);
return code;
+ }
igs->current_point.x = fixed2float(igs->path->position.x);
igs->current_point.y = fixed2float(igs->path->position.y);
return 0;
More information about the gs-cvs
mailing list