[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