Beispiel #1
0
/* <string|int> .checkpassword <0|1|2> */
static int
zcheckpassword(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref params[2];
    array_param_list list;
    gs_param_list *const plist = (gs_param_list *)&list;
    int result = 0;
    int code = name_ref(imemory, (const byte *)"Password", 8, &params[0], 0);
    password pass;

    if (code < 0)
        return code;
    params[1] = *op;
    array_param_list_read(&list, params, 2, NULL, false, iimemory);
    if (dict_read_password(&pass, systemdict, "StartJobPassword") >= 0 &&
        param_check_password(plist, &pass) == 0
        )
        result = 1;
    if (dict_read_password(&pass, systemdict, "SystemParamsPassword") >= 0 &&
        param_check_password(plist, &pass) == 0
        )
        result = 2;
    iparam_list_release(&list);
    make_int(op, result);
    return 0;
}
Beispiel #2
0
/* <obj> <typenames> .type <name> */
static int
ztype(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref tnref;
    int code = array_get(imemory, op, (long)r_btype(op - 1), &tnref);

    if (code < 0)
	return code;
    if (!r_has_type(&tnref, t_name)) {
	/* Must be either a stack underflow or a t_[a]struct. */
	check_op(2);
	{			/* Get the type name from the structure. */
	    const char *sname =
		gs_struct_type_name_string(gs_object_type(imemory,
							  op[-1].value.pstruct));
	    int code = name_ref(imemory, (const byte *)sname, strlen(sname),
				(ref *) (op - 1), 0);

	    if (code < 0)
		return code;
	}
	r_set_attrs(op - 1, a_executable);
    } else {
	ref_assign(op - 1, &tnref);
    }
    pop(1);
    return 0;
}
Beispiel #3
0
/* Remove a name from systemdict. */
void
i_initial_remove_name(i_ctx_t *i_ctx_p, const char *nstr)
{
    ref nref;

    if (name_ref(imemory, (const byte *)nstr, strlen(nstr), &nref, -1) >= 0)
	idict_undef(systemdict, &nref);
}
Beispiel #4
0
/* Get a global glyph code.  */
static int
zfont_global_glyph_code(const gs_memory_t *mem, gs_const_string *gstr, gs_glyph *pglyph)
{
    ref v;
    int code = name_ref(mem, gstr->data, gstr->size, &v, 0);

    if (code < 0)
        return code;
    *pglyph = (gs_glyph)name_index(mem, &v);
    return 0;
}
Beispiel #5
0
/* Convert a key to a ref. */
static int
ref_param_key(const iparam_list * plist, gs_param_name pkey, ref * pkref)
{
    if (plist->int_keys) {
	long key;

	if (sscanf(pkey, "%ld", &key) != 1)
	    return_error(e_rangecheck);
	make_int(pkref, key);
	return 0;
    } else
        return name_ref(plist->memory, (const byte *)pkey, strlen(pkey), pkref, 0);
}
Beispiel #6
0
/*
 * Enter a key-value pair where the key is a (constant) C string.
 */
int
dict_put_string(ref * pdref, const char *kstr, const ref * pvalue,
                dict_stack_t *pds)
{
    int code;
    ref kname;
    dict *pdict = pdref->value.pdict;

    if ((code = name_ref(dict_mem(pdict),
                         (const byte *)kstr, strlen(kstr), &kname, 0)) < 0)
        return code;
    return dict_put(pdref, &kname, pvalue, pds);
}
Beispiel #7
0
/* Convert strings to executable names for build_proc_refs. */
int
build_proc_name_refs(const gs_memory_t *mem, build_proc_refs * pbuild,
                     const char *bcstr, const char *bgstr)
{
    int code;

    if (!bcstr)
        make_null(&pbuild->BuildChar);
    else {
        if ((code = name_ref(mem, (const byte *)bcstr,
                             strlen(bcstr), &pbuild->BuildChar, 0)) < 0)
            return code;
        r_set_attrs(&pbuild->BuildChar, a_executable);
    }
    if (!bgstr)
        make_null(&pbuild->BuildGlyph);
    else {
        if ((code = name_ref(mem, (const byte *)bgstr,
                             strlen(bgstr), &pbuild->BuildGlyph, 0)) < 0)
            return code;
        r_set_attrs(&pbuild->BuildGlyph, a_executable);
    }
    return 0;
}
Beispiel #8
0
/*
 * Files created with .tempfile permit some operations even if the 
 * temp directory is not explicitly named on the PermitFile... path 
 * The names 'SAFETY' and 'tempfiles' are defined by gs_init.ps
*/
static bool
file_is_tempfile(i_ctx_t *i_ctx_p, const uchar *fname, int len)
{
    ref *SAFETY;
    ref *tempfiles;
    ref kname;

    if (dict_find_string(systemdict, "SAFETY", &SAFETY) <= 0 ||
	    dict_find_string(SAFETY, "tempfiles", &tempfiles) <= 0)
	return false;
    if (name_ref(imemory, fname, len, &kname, -1) < 0 ||
	    dict_find(tempfiles, &kname, &SAFETY) <= 0)
	return false;
    return true;
}
Beispiel #9
0
/* - .wrapfont - */
static int
zwrapfont(i_ctx_t *i_ctx_p)
{
    gs_font *font = gs_currentfont(igs);
    gs_font_type0 *font0;
    int wmode = 0;
    int code;

    switch (font->FontType) {
    case ft_TrueType:
	code = gs_font_type0_from_type42(&font0, (gs_font_type42 *)font, wmode,
					 true, font->memory);
	if (code < 0)
	    return code;
	/*
	 * Patch up BuildChar and CIDMap.  This isn't necessary for
	 * TrueType fonts in general, only for Type 42 fonts whose
	 * BuildChar is implemented in PostScript code.
	 */
	{
	    font_data *pdata = pfont_data(font);
	    const char *bgstr = "%Type11BuildGlyph";
	    ref temp;

	    make_int(&temp, 0);
	    ref_assign(&pdata->u.type42.CIDMap, &temp);
	    code = name_ref((const byte *)bgstr, strlen(bgstr), &temp, 1);
	    if (code < 0)
		return code;
	    r_set_attrs(&temp, a_executable);
	    ref_assign(&pdata->BuildGlyph, &temp);
	}
	break;
    case ft_CID_encrypted:
    case ft_CID_user_defined:
    case ft_CID_TrueType:
	code = gs_font_type0_from_cidfont(&font0, font, wmode, NULL,
					  font->memory);
	break;
    default:
	return_error(e_rangecheck);
    }
    if (code < 0)
	return code;
    gs_setfont(igs, (gs_font *)font0);
    return 0;
}
Beispiel #10
0
/*
 * Look up a (constant) C string in a dictionary.
 * Return 1 if found, <= 0 if not.
 */
int
dict_find_string(const ref * pdref, const char *kstr, ref ** ppvalue)
{
    int code;
    ref kname;
    if ( pdref != 0 ) {
        dict *pdict = pdref->value.pdict;

        if ((code = name_ref(dict_mem(pdict),
                             (const byte *)kstr, strlen(kstr), &kname, -1)) < 0)
            return code;
        code = dict_find(pdref, &kname, ppvalue);
        if (code == gs_error_dictfull)
            return_error(gs_error_undefined);
        return code;
    }
    return 0;
}
Beispiel #11
0
/* Encode a character. */
gs_glyph
zfont_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t gspace)
{
    font_data *pdata = pfont_data(pfont);
    const ref *pencoding = &pdata->Encoding;
    ulong index = chr;	/* work around VAX widening bug */
    ref cname;
    int code = array_get(pfont->memory, pencoding, (long)index, &cname);

    if (code < 0 || !r_has_type(&cname, t_name))
        return gs_no_glyph;
    if (pfont->FontType == ft_user_defined && r_type(&pdata->BuildGlyph) == t_null) {
        ref nsref, tname;

        name_string_ref(pfont->memory, &cname, &nsref);
        if (r_size(&nsref) == 7 &&
            !memcmp(nsref.value.const_bytes, ".notdef", r_size(&nsref))) {
            /* A special support for high level devices.
               They need a glyph name but the font doesn't provide one
               due to an instandard BuildChar.
               Such fonts don't conform to PLRM section 5.3.7,
               but we've got real examples that we want to handle (Bug 686982).
               Construct a name here.
               Low level devices don't pass here, because regular PS interpretation
               doesn't need such names.
            */
            char buf[20];
            int code;

            if (gspace == GLYPH_SPACE_NOGEN)
                return gs_no_glyph;
            sprintf(buf, "j%ld", chr); /* 'j' is arbutrary. */
            code = name_ref(pfont->memory, (const byte *)buf, strlen(buf), &tname, 1);
            if (code < 0) {
                /* Can't propagate the error due to interface limitation,
                   return with .notdef */
            } else
                cname = tname;
        }
    }
    return (gs_glyph)name_index(pfont->memory, &cname);
}
Beispiel #12
0
/* Get the name of a glyph. */
static int
zfont_glyph_name(gs_font *font, gs_glyph index, gs_const_string *pstr)
{
    ref nref, sref;

    if (index >= gs_min_cid_glyph) {	/* Fabricate a numeric name. */
        char cid_name[sizeof(gs_glyph) * 3 + 1];
        int code;

        sprintf(cid_name, "%lu", (ulong) index);
        code = name_ref(font->memory, (const byte *)cid_name, strlen(cid_name),
                        &nref, 1);
        if (code < 0)
            return code;
    } else
        name_index_ref(font->memory, index, &nref);
    name_string_ref(font->memory, &nref, &sref);
    pstr->data = sref.value.const_bytes;
    pstr->size = r_size(&sref);
    return 0;
}
Beispiel #13
0
/* Create and store [/key any] array in $error.errorinfo.
 * The key must be a permanently allocated C string.
 * This routine is here because it is often used with parameter dictionaries.
 */
int
gs_errorinfo_put_pair(i_ctx_t *i_ctx_p, const char *key, int len, const ref *any)
{
    int code;
    ref pair, *aptr, key_name, *pderror;

    code = name_ref(imemory_local, (const byte *)key, len, &key_name, 0);
    if (code < 0)
        return code;
    code = gs_alloc_ref_array(iimemory_local, &pair, a_readonly, 2, "gs_errorinfo_put_pair");
    if (code < 0)
        return code;
    aptr = pair.value.refs;
    ref_assign_new(aptr, &key_name);
    ref_assign_new(aptr+1, any);
    if (dict_find_string(systemdict, "$error", &pderror) <= 0 ||
        !r_has_type(pderror, t_dictionary) ||
        idict_put_string(pderror, "errorinfo", &pair) < 0
        )
        return_error(e_Fatal);
    return 0;
}
Beispiel #14
0
/* or a negative error code. */
int
build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype,
              gs_memory_type_ptr_t pstype, const build_proc_refs * pbuild,
              build_font_options_t options)
{
    ref kname;			/* t_string */
    ref *pftype;
    ref *pencoding = 0;
    bool bitmapwidths;
    int exactsize, inbetweensize, transformedchar;
    int wmode;
    int code;
    gs_font *pfont;
    ref *pfid;
    ref *aop = dict_access_ref(op);
    bool cpsi_mode = gs_currentcpsimode(imemory);

    get_font_name(imemory, &kname, op - 1);
    if (dict_find_string(op, "FontType", &pftype) <= 0 ||
        !r_has_type(pftype, t_integer) ||
        pftype->value.intval != (int)ftype
        )
        return_error(e_invalidfont);
    if (dict_find_string(op, "Encoding", &pencoding) <= 0) {
        if (!(options & bf_Encoding_optional))
            return_error(e_invalidfont);
        pencoding = 0;
    } else {
        if (!r_is_array(pencoding))
            return_error(e_invalidfont);
    }
    if (pencoding) {   /* observed Adobe behavior */
        int count = r_size(pencoding);
        int type = ftype ? t_name : t_integer;
        bool fixit = false;

        while (count--) {
           ref r;
           if ((code = array_get(imemory, pencoding, count, &r)) < 0 ||
             !(r_has_type(&r, type) || r_has_type(&r, t_null))) {
               if (!cpsi_mode && ftype == ft_user_defined) {
                   if (code < 0 || r_has_type(&r, t_null)) {
                       return_error(e_typecheck);
                   }
                   fixit = true;
                   break;
               }
               else {
                   return_error(e_typecheck);
               }
           }
        }

        /* For at least Type 3 fonts, Adobe Distiller will "fix" an Encoding array, as in, for example
         * Bug 692681 where the arrays contain integers rather than names. Once the font is instantiated
         * the integers have been converted to names.
         * It is preferable to to this manipulation here, rather than in Postscript, because we are less
         * restricted by read-only attributes and VM save levels.
         */
        if (fixit) {
            ref penc;
            uint size = 0;
            char buf[32], *bptr;
            avm_space curglob = ialloc_space(idmemory);
            avm_space useglob = r_is_local(pencoding) ? avm_local : avm_global;

            ialloc_set_space(idmemory, useglob);
            
            count = r_size(pencoding);
            if ((code = ialloc_ref_array(&penc, (r_type_attrs(pencoding) & a_readonly), count, "build_gs_font")) < 0)
                 return code;
            
            while (count--) {
               ref r;
               if (array_get(imemory, pencoding, count, &r) < 0){
                   return_error(e_typecheck);
               }
               /* For type 3, we know the Encoding entries must be names */
               if (r_has_type(&r, t_name)){
                   ref_assign(&(penc.value.refs[count]), &r);
               }
               else {
               
                   if ((code = obj_cvs(imemory, &r, (byte *)buf, 32, &size, (const byte **)(&bptr))) < 0) {
                       return(code);
                   }
                   if ((code = name_ref(imemory, (const byte *)bptr, size, &r, true)) < 0)
                        return code;
                   ref_assign(&(penc.value.refs[count]), &r);
               }
            }
            
            if ((code = dict_put_string(osp, "Encoding", &penc, NULL)) < 0)
               return code;
            ialloc_set_space(idmemory, curglob);
        }
    }
    if ((code = dict_int_param(op, "WMode", 0, 1, 0, &wmode)) < 0 ||
        (code = dict_bool_param(op, "BitmapWidths", false, &bitmapwidths)) < 0 ||
        (code = dict_int_param(op, "ExactSize", 0, 2, fbit_use_bitmaps, &exactsize)) < 0 ||
        (code = dict_int_param(op, "InBetweenSize", 0, 2, fbit_use_outlines, &inbetweensize)) < 0 ||
        (code = dict_int_param(op, "TransformedChar", 0, 2, fbit_use_outlines, &transformedchar)) < 0
        )
        return code;
    code = dict_find_string(op, "FID", &pfid);
    if (code > 0 && r_has_type(pfid, t_fontID)) { /* silently ignore invalid FID per CET 13-05.ps */
        /*
         * If this font has a FID entry already, it might be a scaled font
         * made by makefont or scalefont; in a Level 2 environment, it might
         * be an existing font being registered under a second name, or a
         * re-encoded font (which was invalid in Level 1, but dvips did it
         * anyway).
         */
        pfont = r_ptr(pfid, gs_font);
        /*
         * If the following condition is false this is a re-encoded font,
         * or some other questionable situation in which the FID
         * was preserved.  Pretend the FID wasn't there.
         */
        if (obj_eq(pfont->memory, pfont_dict(pfont), op)) {
            if (pfont->base == pfont) {	/* original font */
                if (!level2_enabled)
                    return_error(e_invalidfont);
                *ppfont = pfont;
                return 1;
            } else {		/* This was made by makefont or scalefont. */
                /* Just insert the new name. */
                gs_matrix mat;
                ref fname;			/* t_string */

                code = sub_font_params(imemory, op, &mat, NULL, &fname);
                if (code < 0)
                    return code;
                code = 1;
                copy_font_name(&pfont->font_name, &fname);
                goto set_name;
            }
        }
    }
    /* This is a new font. */
    if (!r_has_attr(aop, a_write))
        return_error(e_invalidaccess);
    {
        ref encoding;

        /*
         * Since add_FID may resize the dictionary and cause
         * pencoding to become invalid, save the Encoding.
         */
        if (pencoding) {
            encoding = *pencoding;
            pencoding = &encoding;
        }
        code = build_gs_sub_font(i_ctx_p, op, &pfont, ftype, pstype,
                                 pbuild, pencoding, op);
        if (code < 0)
            return code;
    }
    pfont->BitmapWidths = bitmapwidths;
    pfont->ExactSize = (fbit_type)exactsize;
    pfont->InBetweenSize = (fbit_type)inbetweensize;
    pfont->TransformedChar = (fbit_type)transformedchar;
    pfont->WMode = wmode;
    pfont->procs.font_info = zfont_info;
    code = 0;
set_name:
    copy_font_name(&pfont->key_name, &kname);
    *ppfont = pfont;
    return code;
}
Beispiel #15
0
/* Initialize the operator table. */
int
op_init(i_ctx_t *i_ctx_p)
{
    const op_def *const *tptr;
    int code;

    /* Enter each operator into the appropriate dictionary. */

    for (tptr = op_defs_all; *tptr != 0; tptr++) {
	ref *pdict = systemdict;
	const op_def *def;
	const char *nstr;

	for (def = *tptr; (nstr = def->oname) != 0; def++)
	    if (op_def_is_begin_dict(def)) {
		ref nref;

		code = name_ref(imemory, (const byte *)nstr, strlen(nstr), &nref, -1);
		if (code < 0)
		    return code;
		if (!dict_find(systemdict, &nref, &pdict))
		    return_error(e_Fatal);
		if (!r_has_type(pdict, t_dictionary))
		    return_error(e_Fatal);
	    } else {
		ref oper;
		uint index_in_table = def - *tptr;
		uint opidx = (tptr - op_defs_all) * OP_DEFS_MAX_SIZE +
		    index_in_table;

		if (index_in_table >= OP_DEFS_MAX_SIZE) {
		    lprintf1("opdef overrun! %s\n", def->oname);
		    return_error(e_Fatal);
		}
		gs_interp_make_oper(&oper, def->proc, opidx);
		/* The first character of the name is a digit */
		/* giving the minimum acceptable number of operands. */
		/* Check to make sure it's within bounds. */
		if (*nstr - '0' > gs_interp_max_op_num_args)
		    return_error(e_Fatal);
		nstr++;
		/*
		 * Skip internal operators, and the second occurrence of
		 * operators with special indices.
		 */
		if (*nstr != '%' && r_size(&oper) == opidx) {
		    code =
			i_initial_enter_name_in(i_ctx_p, pdict, nstr, &oper);
		    if (code < 0)
			return code;
		}
	    }
    }
    /* Allocate the tables for `operator' procedures. */
    /* Make one of them local so we can have local operators. */

    if ((code = alloc_op_array_table(i_ctx_p, OP_ARRAY_TABLE_GLOBAL_SIZE,
				     avm_global, &op_array_table_global) < 0))
	return code;
    op_array_table_global.base_index = op_def_count;
    if ((code = gs_register_ref_root(imemory, NULL,
				     (void **)&op_array_table_global.root_p,
				     "op_array_table(global)")) < 0 ||
	(code = gs_register_struct_root(imemory, NULL,
				(void **)&op_array_table_global.nx_table,
					"op_array nx_table(global)")) < 0 ||
	(code = alloc_op_array_table(i_ctx_p, OP_ARRAY_TABLE_LOCAL_SIZE,
				     avm_local, &op_array_table_local) < 0)
	)
	return code;
    op_array_table_local.base_index =
	op_array_table_global.base_index +
	r_size(&op_array_table_global.table);
    if ((code = gs_register_ref_root(imemory, NULL,
				     (void **)&op_array_table_local.root_p,
				     "op_array_table(local)")) < 0 ||
	(code = gs_register_struct_root(imemory, NULL,
				(void **)&op_array_table_local.nx_table,
					"op_array nx_table(local)")) < 0
	)
	return code;

    return 0;
}
Beispiel #16
0
/*
 * Look up a key in a dictionary.  Store a pointer to the value slot
 * where found, or to the (value) slot for inserting.
 * See idict.h for the possible return values.
 */
int
dict_find(const ref * pdref, const ref * pkey,
          ref ** ppvalue /* result is stored here */ )
{
    dict *pdict = pdref->value.pdict;
    uint size = npairs(pdict);
    register int etype;
    uint nidx;
    ref_packed kpack;
    uint hash;
    int ktype;
    const gs_memory_t *mem = dict_mem(pdict);

    /* Compute hash.  The only types we bother with are strings, */
    /* names, and (unlikely, but worth checking for) integers. */
    switch (r_type(pkey)) {
    case t_name:
        nidx = name_index(mem, pkey);
    nh:
        hash = dict_name_index_hash(nidx);
        kpack = packed_name_key(nidx);
        ktype = t_name;
        break;
    case t_string:		/* convert to a name first */
        {
            ref nref;
            int code;

            if (!r_has_attr(pkey, a_read))
                return_error(gs_error_invalidaccess);
            code = name_ref(mem, pkey->value.bytes, r_size(pkey), &nref, 1);
            if (code < 0)
                return code;
            nidx = name_index(mem, &nref);
        }
        goto nh;
    case t_real:
        /*
         * Make sure that equal reals and integers hash the same.
         */
        {
            int expt, i;
            double mant = frexp(pkey->value.realval, &expt);
            /*
             * The value is mant * 2^expt, where 0.5 <= mant < 1,
             * or else expt == mant == 0.
             */

            if (expt < sizeof(long) * 8 || pkey->value.realval == min_long)
                i = (int)pkey->value.realval;
            else
                i = (int)(mant * min_long); /* MSVC 6.00.8168.0 cannot compile this */
            hash = (uint)i * 30503;         /*   with -O2 as a single expression    */
        }
        goto ih;
    case t_integer:
        hash = (uint)pkey->value.intval * 30503;
    ih:
        kpack = packed_key_impossible;
        ktype = -1;
        nidx = 0;		/* only to pacify gcc */
        break;
    case t_null:		/* not allowed as a key */
        return_error(gs_error_typecheck);
    default:
        hash = r_btype(pkey) * 99;	/* yech */
        kpack = packed_key_impossible;
        ktype = -1;
        nidx = 0;		/* only to pacify gcc */
    }
    /* Search the dictionary */
    if (dict_is_packed(pdict)) {
        const ref_packed *pslot = 0;

#	define found *ppvalue = packed_search_value_pointer; return 1
#	define deleted if (pslot == 0) pslot = kp
#	define missing goto miss
#	include "idicttpl.h"
#	undef missing
#	undef deleted
#	undef found
        /*
         * Double wraparound, dict is full.
         * Note that even if there was an empty slot (pslot != 0),
         * we must return dictfull if length = maxlength.
         */
        if (pslot == 0 || d_length(pdict) == d_maxlength(pdict))
            return_error(gs_error_dictfull);
        *ppvalue = pdict->values.value.refs + (pslot - kbot);
        return 0;
      miss:			/* Key is missing, not double wrap.  See above re dictfull. */
        if (d_length(pdict) == d_maxlength(pdict))
            return_error(gs_error_dictfull);
        if (pslot == 0)
            pslot = kp;
        *ppvalue = pdict->values.value.refs + (pslot - kbot);
        return 0;
    } else {
        ref *kbot = pdict->keys.value.refs;
        register ref *kp;
        ref *pslot = 0;
        int wrap = 0;

        for (kp = kbot + dict_hash_mod(hash, size) + 2;;) {
            --kp;
            if ((etype = r_type(kp)) == ktype) {	/* Fast comparison if both keys are names */
                if (name_index(mem, kp) == nidx) {
                    *ppvalue = pdict->values.value.refs + (kp - kbot);
                    return 1;
                }
            } else if (etype == t_null) {	/* Empty, deleted, or wraparound. */
                /* Figure out which. */
                if (kp == kbot) {	/* wrap */
                    if (wrap++) {	/* wrapped twice */
                        if (pslot == 0)
                            return_error(gs_error_dictfull);
                        break;
                    }
                    kp += size + 1;
                } else if (r_has_attr(kp, a_executable)) {	/* Deleted entry, save the slot. */
                    if (pslot == 0)
                        pslot = kp;
                } else		/* key not found */
                    break;
            } else {
                if (obj_eq(mem, kp, pkey)) {
                    *ppvalue = pdict->values.value.refs + (kp - kbot);
                    return 1;
                }
            }
        }
        if (d_length(pdict) == d_maxlength(pdict))
            return_error(gs_error_dictfull);
        *ppvalue = pdict->values.value.refs +
            ((pslot != 0 ? pslot : kp) - kbot);
        return 0;
    }
}
Beispiel #17
0
/* The current color space is the alternate space for the separation space. */
static int
zsetseparationspace(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const ref *pcsa;
    gs_color_space *pcs;
    gs_color_space * pacs;
    ref_colorspace cspace_old;
    ref sname, name_none, name_all;
    gs_function_t *pfn = NULL;
    separation_type sep_type;
    int code;
    const gs_memory_t * mem = imemory;

    /* Verify that we have an array as our input parameter */
    check_read_type(*op, t_array);
    if (r_size(op) != 4)
	return_error(e_rangecheck);

    /* The alternate color space has been selected as the current color space */
    pacs = gs_currentcolorspace(igs);
    if (!pacs->type->can_be_alt_space)
	return_error(e_rangecheck);

    /*
     * pcsa is a pointer to element 1 (2nd element)  in the Separation colorspace
     * description array.  Thus pcsa[2] is element #3 (4th element) which is the
     * tint transform.
     */
    pcsa = op->value.const_refs + 1;
    sname = *pcsa;
    switch (r_type(&sname)) {
	default:
	    return_error(e_typecheck);
	case t_string:
	    code = name_from_string(mem, &sname, &sname);
	    if (code < 0)
		return code;
	    /* falls through */
	case t_name:
	    break;
    }

    if ((code = name_ref(mem, (const byte *)"All", 3, &name_all, 0)) < 0)
	return code;
    if ((code = name_ref(mem, (const byte *)"None", 4, &name_none, 0)) < 0)
	return code;
    sep_type = ( name_eq(&sname, &name_all) ? SEP_ALL :
	         name_eq(&sname, &name_none) ? SEP_NONE : SEP_OTHER);

    /* Check tint transform procedure. */
    /* See comment above about psca */
    check_proc(pcsa[2]);
    pfn = ref_function(pcsa + 2);
    if (pfn == NULL)
	return_error(e_rangecheck);

    cspace_old = istate->colorspace;
    /* Now set the current color space as Separation */
    code = gs_cspace_new_Separation(&pcs, pacs, imemory);
    if (code < 0)
	return code;
    pcs->params.separation.sep_type = sep_type;
    pcs->params.separation.sep_name = name_index(mem, &sname);
    pcs->params.separation.get_colorname_string = gs_get_colorname_string;
    istate->colorspace.procs.special.separation.layer_name = pcsa[0];
    istate->colorspace.procs.special.separation.tint_transform = pcsa[2];
    if (code >= 0)
        code = gs_cspace_set_sepr_function(pcs, pfn);
    if (code >= 0)
	code = gs_setcolorspace(igs, pcs);
    /* release reference from construction */
    rc_decrement_only(pcs, "zsetseparationspace");
    if (code < 0) {
	istate->colorspace = cspace_old;
	return code;
    }
    pop(1);
    return 0;
}
Beispiel #18
0
/* Prepare to write a name value. */
static int
ref_param_write_name_value(const gs_memory_t *mem, ref * pref, const gs_param_string * pvalue)
{
    return name_ref(mem, pvalue->data, pvalue->size, pref,
		    (pvalue->persistent ? 0 : 1));
}