386BSD 0.1 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Tue, 7 Apr 1992 21:24:00 +0000 (13:24 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Tue, 7 Apr 1992 21:24:00 +0000 (13:24 -0800)
Work on file usr/othersrc/public/ghostscript-2.4.1/zprops.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.1

usr/othersrc/public/ghostscript-2.4.1/zprops.c [new file with mode: 0644]

diff --git a/usr/othersrc/public/ghostscript-2.4.1/zprops.c b/usr/othersrc/public/ghostscript-2.4.1/zprops.c
new file mode 100644 (file)
index 0000000..5b77ae5
--- /dev/null
@@ -0,0 +1,258 @@
+/* Copyright (C) 1991, 1992 Aladdin Enterprises.  All rights reserved.
+   Distributed by Free Software Foundation, Inc.
+
+This file is part of Ghostscript.
+
+Ghostscript is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
+to anyone for the consequences of using it or for whether it serves any
+particular purpose or works at all, unless he says so in writing.  Refer
+to the Ghostscript General Public License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+Ghostscript, but only under the conditions described in the Ghostscript
+General Public License.  A copy of this license is supposed to have been
+given to you along with Ghostscript so you can know your rights and
+responsibilities.  It should be in a file named COPYING.  Among other
+things, the copyright notice and this notice must be preserved on all
+copies.  */
+
+/* zprops.c */
+/* Device property operators */
+#include "memory_.h"
+#include "ghost.h"
+#include "alloc.h"
+#include "dict.h"
+#include "errors.h"
+#include "oper.h"
+#include "name.h"
+#include "store.h"
+#include "gsprops.h"
+#include "gsmatrix.h"                  /* for gxdevice.h */
+#include "gxdevice.h"
+
+/* Imported procedures */
+extern int array_get(P3(ref *, long, ref *));
+
+/* Forward references */
+private int props_to_stack(P3(gs_prop_item *, os_ptr, int));
+private int props_from_stack(P3(gs_prop_item *, os_ptr, int));
+
+/* getdeviceprops */
+int
+zgetdeviceprops(os_ptr op)
+{      gx_device *dev;
+       gs_prop_item *plist;
+       int count;
+       int code;
+       check_type(*op, t_device);
+       dev = op->value.pdevice;
+       count = (*dev->procs->get_props)(dev, NULL);
+       plist = (gs_prop_item *)alloc(count, sizeof(gs_prop_item), "getdeviceprops");
+       if ( plist == 0 ) return_error(e_VMerror);
+       (*dev->procs->get_props)(dev, plist);
+       code = props_to_stack(plist, op + 1, count);
+       alloc_free((char *)plist, count, sizeof(gs_prop_item), "getdeviceprops");
+       if ( code >= 0 )
+          {    make_mark(op);
+               push(code);
+               code = 0;
+          }
+       return code;
+}
+
+/* putdeviceprops */
+int
+zputdeviceprops(os_ptr op)
+{      gx_device *dev;
+       gs_prop_item *plist;
+       os_ptr mp;
+       int count, acount = 0;
+       int code;
+       check_type(*op, t_device);
+       dev = op->value.pdevice;
+       for ( mp = op - 1; !r_has_type(mp, t_mark); mp-- )
+          {    if ( mp <= osbot ) return e_unmatchedmark;
+               switch ( r_type(mp) )
+                  {
+               case t_array:
+               case t_mixedarray:
+               case t_shortarray:
+                       acount += r_size(mp);
+                  }
+          }
+       count = op - mp - 1;
+       if ( count & 1 ) return e_rangecheck;
+       count >>= 1;
+       plist = (gs_prop_item *)alloc(count + acount, sizeof(gs_prop_item), "putdeviceprops");
+       if ( plist == 0 ) return_error(e_VMerror);
+       code = props_from_stack(plist, mp + 1, count);
+       if ( code >= 0 )
+               code = (*dev->procs->put_props)(dev, plist, count + acount);
+       alloc_free((char *)plist, count + acount, sizeof(gs_prop_item), "putdeviceprops");
+       if ( code >= 0 )
+          {    *mp = *op;
+               osp = op = mp;
+          }
+       return code;
+}
+
+/* ------ Initialization procedure ------ */
+
+op_def zprops_op_defs[] = {
+       {"1getdeviceprops", zgetdeviceprops},
+       {"2putdeviceprops", zputdeviceprops},
+       op_def_end(0)
+};
+
+/* ------ Internal routines ------ */
+
+/* Get properties from a property list to the stack. */
+private int
+props_to_stack(gs_prop_item *plist, os_ptr op0, int count)
+{      gs_prop_item *pi;
+       os_ptr op;
+       int i;
+       int code;
+       for ( op = op0, pi = plist, i = count; i != 0; pi++, i-- )
+          {    ref value;
+               const char *nstr = pi->pname;
+               int nlen = pi->name_size;
+               if ( nstr == 0 ) continue;      /* no name, skip */
+               if ( ostop - op < 2 ) return e_stackoverflow;
+               if ( nlen < 0 ) nlen = strlen(nstr);
+               code = name_ref((const byte *)nstr, nlen, op, 0);
+               if ( code < 0 ) return code;
+               switch ( pi->type )
+                  {
+               case (int)prt_int:
+                       make_int(&value, pi->value.i);
+                       break;
+               case (int)prt_float:
+                       make_real(&value, pi->value.f);
+                       break;
+               case (int)prt_bool:
+                       make_bool(&value, pi->value.b);
+                       break;
+               case (int)prt_string:
+                  {    ushort size = pi->value.a.size;
+                       char *str;
+                       if ( size == (ushort)(-1) )
+                               size = strlen(pi->value.a.p.s);
+                       str = alloc(size, 1, "props_to_stack(string)");
+                       if ( str == 0 ) return e_VMerror;
+                       memcpy(str, pi->value.a.p.s, size);
+                       make_tasv(&value, t_string, a_all, size, bytes, (byte *)str);
+                  }    break;
+               case (int)prt_int_array:
+               case (int)prt_float_array:
+                  {    uint size = pi->value.a.size;
+                       ref *arefs = alloc_refs(size, "props_to_stack(array)");
+                       uint j;
+                       gs_prop_item *pv = pi->value.a.p.v;
+                       if ( arefs == 0 ) return e_VMerror;
+                       make_tasv_new(&value, t_array, a_all, size, refs, arefs);
+                       for ( j = 0; j < size; j++, arefs++, pv++ )
+                         if ( pi->type == prt_int_array )
+                               make_int_new(arefs, pv->value.i);
+                         else
+                               make_real_new(arefs, pv->value.f);
+                  }    break;
+               default:
+                       return e_typecheck;
+                  }
+               ref_assign(op + 1, &value);
+               op += 2;
+          }
+       return op - op0;
+}
+
+/* Set properties from the stack. */
+/* Returns the number of elements copied. */
+/* Entries with non-name keys are not copied; */
+/* entries with invalid values are copied with status = pv_typecheck. */
+private int
+props_from_stack(gs_prop_item *plist /* [count + acount] */, os_ptr op0,
+  int count)
+{      gs_prop_item *pi = plist;
+       gs_prop_item *pai = plist + count;
+       os_ptr op = op0 + 1;
+       for ( ; count; op += 2, count-- )
+          {    ref sref;
+               if ( !r_has_type(op - 1, t_name) ) return e_typecheck;
+               name_string_ref(op - 1, &sref);
+               pi->pname = (char *)sref.value.bytes;
+               pi->name_size = r_size(&sref);
+               pi->status = pv_set;
+               switch ( r_type(op) )
+                  {
+               case t_null:
+                       pi->type = prt_null;
+                       break;
+               case t_integer:
+                       pi->type = prt_int;
+                       pi->value.i = op->value.intval;
+                       break;
+               case t_real:
+                       pi->type = prt_float;
+                       pi->value.f = op->value.realval;
+                       break;
+               case t_boolean:
+                       pi->type = prt_bool;
+                       pi->value.b = op->value.index;
+                       break;
+               case t_name:
+                       name_string_ref(op, &sref);
+                       goto nst;
+               case t_string:
+                       ref_assign(&sref, op);
+                       pi->type = prt_string;
+                       pi->value.a.p.s = (char *)op->value.bytes;
+nst:                   pi->value.a.size = r_size(&sref);
+                       break;
+               case t_array:
+               case t_mixedarray:
+               case t_shortarray:
+                  {    uint size = r_size(op);
+                       uint i;
+                       gs_prop_item *pv;
+                       gs_prop_type tv = prt_int;
+                       pi->type = prt_int_array;
+                       pi->value.a.p.v = pai;
+                       pi->value.a.size = size;
+top:                   pv = pai;
+                       for ( i = 0; i < size; i++ )
+                          {    ref rnum;
+                               array_get(op, (long)i, &rnum);
+                               pv->pname = 0;
+                               pv->type = tv;
+                               switch ( r_type(&rnum) )
+                                  {
+                               case t_real:
+                                       if ( tv == prt_int )
+                                          {    tv = prt_float;
+                                               pi->type = prt_float_array;
+                                               goto top;
+                                          }
+                                       pv++->value.f = rnum.value.realval;
+                                       break;
+                               case t_integer:
+                                       if ( tv == prt_int )
+                                         pv++->value.i = rnum.value.intval;
+                                       else
+                                         pv++->value.f = rnum.value.intval;
+                                       break;
+                               default:
+                                       pi->status = pv_typecheck;
+                                  }
+                          }
+
+                       pai = pv;
+                  }    break;
+               default:
+                       pi->status = pv_typecheck;
+                  }
+               pi++;
+          }
+       return 0;
+}