コード例 #1
0
ファイル: idict.c プロジェクト: computersforpeace/ghostpdl
/* Create a dictionary using the given allocator. */
int
dict_alloc(gs_ref_memory_t * mem, uint size, ref * pdref)
{
    ref arr;
    int code =
        gs_alloc_ref_array(mem, &arr, a_all, sizeof(dict) / sizeof(ref),
                           "dict_alloc");
    dict *pdict;
    ref dref;

    if (code < 0)
        return code;
    pdict = (dict *) arr.value.refs;
    make_tav(&dref, t_dictionary,
             r_space(&arr) | imemory_new_mask(mem) | a_all,
             pdict, pdict);
    make_struct(&pdict->memory, avm_foreign, mem);
    code = dict_create_contents(size, &dref, dict_default_pack);
    if (code < 0) {
        gs_free_ref_array(mem, &arr, "dict_alloc");
        return code;
    }
    *pdref = dref;
    return 0;
}
コード例 #2
0
ファイル: idict.c プロジェクト: computersforpeace/ghostpdl
/* the VM space where the dictionary is allocated. */
static int
dict_create_contents(uint size, const ref * pdref, bool pack)
{
    dict *pdict = pdref->value.pdict;
    gs_ref_memory_t *mem = dict_memory(pdict);
    uint new_mask = imemory_new_mask(mem);
    uint asize = dict_round_size((size == 0 ? 1 : size));
    int code;
    register uint i;

    if (asize == 0 || asize > max_array_size - 1)	/* too large */
        return_error(gs_error_limitcheck);
    asize++;			/* allow room for wraparound entry */
    code = gs_alloc_ref_array(mem, &pdict->values, a_all, asize,
                              "dict_create_contents(values)");
    if (code < 0)
        return code;
    r_set_attrs(&pdict->values, new_mask);
    refset_null_new(pdict->values.value.refs, asize, new_mask);
    if (pack) {
        uint ksize = (asize + packed_per_ref - 1) / packed_per_ref;
        ref arr;
        ref_packed *pkp;
        ref_packed *pzp;

        code = gs_alloc_ref_array(mem, &arr, a_all, ksize,
                                  "dict_create_contents(packed keys)");
        if (code < 0)
            return code;
        pkp = (ref_packed *) arr.value.refs;
        make_tasv(&pdict->keys, t_shortarray,
                  r_space(&arr) | a_all | new_mask,
                  asize, packed, pkp);
        for (pzp = pkp, i = 0; i < asize || i % packed_per_ref; pzp++, i++)
            *pzp = packed_key_empty;
        *pkp = packed_key_deleted;	/* wraparound entry */
    } else {			/* not packed */
        int code = dict_create_unpacked_keys(asize, pdref);

        if (code < 0)
            return code;
    }
    make_tav(&pdict->count, t_integer, new_mask, intval, 0);
    make_tav(&pdict->maxlength, t_integer, new_mask, intval, size);
    return 0;
}
コード例 #3
0
/* Return <0 on error, 0 if not wanted, 1 if wanted. */
static int
ref_array_param_requested(const iparam_list *iplist, gs_param_name pkey,
			  ref *pvalue, uint size, client_name_t cname)
{
    int code;

    if (!ref_param_requested((const gs_param_list *)iplist, pkey))
	return 0;
    code = gs_alloc_ref_array(iplist->ref_memory, pvalue, a_all, size, cname);
    return (code < 0 ? code : 1);
}
コード例 #4
0
ファイル: idict.c プロジェクト: computersforpeace/ghostpdl
/* The keys are allocated using the same allocator as the dictionary. */
static int
dict_create_unpacked_keys(uint asize, const ref * pdref)
{
    dict *pdict = pdref->value.pdict;
    gs_ref_memory_t *mem = dict_memory(pdict);
    int code;

    code = gs_alloc_ref_array(mem, &pdict->keys, a_all, asize,
                              "dict_create_unpacked_keys");
    if (code >= 0) {
        uint new_mask = imemory_new_mask(mem);
        ref *kp = pdict->keys.value.refs;

        r_set_attrs(&pdict->keys, new_mask);
        refset_null_new(kp, asize, new_mask);
        r_set_attrs(kp, a_executable);	/* wraparound entry */
    }
    return code;
}
コード例 #5
0
/* Initialize the graphics stack. */
gs_state *
int_gstate_alloc(const gs_dual_memory_t * dmem)
{
    int_gstate *iigs;
    ref proc0;
    int_remap_color_info_t *prci;
    gs_ref_memory_t *lmem = dmem->space_local;
    gs_ref_memory_t *gmem = dmem->space_global;
    gs_state *pgs = gs_state_alloc((gs_memory_t *)lmem);

    iigs = gs_alloc_struct((gs_memory_t *)lmem, int_gstate, &st_int_gstate,
			   "int_gstate_alloc(int_gstate)");
    int_gstate_map_refs(iigs, make_null);
    make_empty_array(&iigs->dash_pattern_array, a_all);
    gs_alloc_ref_array(lmem, &proc0, a_readonly + a_executable, 2,
		       "int_gstate_alloc(proc0)");
    make_oper(proc0.value.refs, 0, zpop);
    make_real(proc0.value.refs + 1, 0.0);
    iigs->black_generation = proc0;
    iigs->undercolor_removal = proc0;
    make_false(&iigs->use_cie_color);
    /*
     * Even though the gstate itself is allocated in local VM, the
     * container for the color remapping procedure must be allocated in
     * global VM so that the gstate can be copied into global VM.
     */
    prci = gs_alloc_struct((gs_memory_t *)gmem, int_remap_color_info_t,
			   &st_int_remap_color_info,
			   "int_gstate_alloc(remap color info)");
    make_struct(&iigs->remap_color_info, imemory_space(gmem), prci);
    clear_pagedevice(iigs);
    gs_state_set_client(pgs, iigs, &istate_procs, true);
    /* PostScript code wants limit clamping enabled. */
    gs_setlimitclamp(pgs, true);
    /*
     * gsave and grestore only work properly
     * if there are always at least 2 entries on the stack.
     * We count on the PostScript initialization code to do a gsave.
     */
    return pgs;
}
コード例 #6
0
ファイル: idparam.c プロジェクト: BorodaZizitopa/ghostscript
/* 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;
}
コード例 #7
0
static int
ref_param_begin_write_collection(gs_param_list * plist, gs_param_name pkey,
				 gs_param_dict * pvalue,
				 gs_param_collection_type_t coll_type)
{
    iparam_list *const iplist = (iparam_list *) plist;
    gs_ref_memory_t *imem = iplist->ref_memory;
    dict_param_list *dlist = (dict_param_list *)
	gs_alloc_bytes(plist->memory, size_of(dict_param_list),
		       "ref_param_begin_write_collection");
    int code;

    if (dlist == 0)
	return_error(e_VMerror);
    if (coll_type != gs_param_collection_array) {
	ref dref;

	code = dict_alloc(imem, pvalue->size, &dref);
	if (code >= 0) {
	    code = dict_param_list_write(dlist, &dref, NULL, imem);
	    dlist->int_keys = coll_type == gs_param_collection_dict_int_keys;
	}
    } else {
	ref aref;

	code = gs_alloc_ref_array(imem, &aref, a_all, pvalue->size,
				  "ref_param_begin_write_collection");
	if (code >= 0)
	    code = array_new_indexed_plist_write(dlist, &aref, NULL, imem);
    }
    if (code < 0)
	gs_free_object(plist->memory, dlist, "ref_param_begin_write_collection");
    else
	pvalue->list = (gs_param_list *) dlist;
    return code;
}
コード例 #8
0
/* ensuring that refs in mixed arrays are properly aligned. */
#undef idmemory			/****** NOTA BENE ******/
int
make_packed_array(ref * parr, ref_stack_t * pstack, uint size,
		  gs_dual_memory_t *idmemory, client_name_t cname)
{
    uint i;
    const ref *pref;
    uint idest = 0, ishort = 0;
    ref_packed *pbody;
    ref_packed *pdest;
    ref_packed *pshort;		/* points to start of */
				/* last run of short elements */
    gs_ref_memory_t *imem = idmemory->current;
    uint space = imemory_space(imem);
    int skip = 0, pad;
    ref rtemp;
    int code;

    /* Do a first pass to calculate the size of the array, */
    /* and to detect local-into-global stores. */

    for (i = size; i != 0; i--) {
	pref = ref_stack_index(pstack, i - 1);
	switch (r_btype(pref)) {	/* not r_type, opers are special */
	    case t_name:
	      if (name_index(imem, pref) >= packed_name_max_index)
		    break;	/* can't pack */
		idest++;
		continue;
	    case t_integer:
		if (pref->value.intval < packed_min_intval ||
		    pref->value.intval > packed_max_intval
		    )
		    break;
		idest++;
		continue;
	    case t_oparray:
		/* Check for local-into-global store. */
		store_check_space(space, pref);
		/* falls through */
	    case t_operator:
		{
		    uint oidx;

		    if (!r_has_attr(pref, a_executable))
			break;
		    oidx = op_index(pref);
		    if (oidx == 0 || oidx > packed_int_mask)
			break;
		}
		idest++;
		continue;
	    default:
		/* Check for local-into-global store. */
		store_check_space(space, pref);
	}
	/* Can't pack this element, use a full ref. */
	/* We may have to unpack up to align_packed_per_ref - 1 */
	/* preceding short elements. */
	/* If we are at the beginning of the array, however, */
	/* we can just move the elements up. */
	{
	    int i = (idest - ishort) & (align_packed_per_ref - 1);

	    if (ishort == 0)	/* first time */
		idest += skip = -i & (align_packed_per_ref - 1);
	    else
		idest += (packed_per_ref - 1) * i;
	}
	ishort = idest += packed_per_ref;
    }
    pad = -(int)idest & (packed_per_ref - 1);	/* padding at end */

    /* Now we can allocate the array. */

    code = gs_alloc_ref_array(imem, &rtemp, 0, (idest + pad) / packed_per_ref,
			      cname);
    if (code < 0)
	return code;
    pbody = (ref_packed *) rtemp.value.refs;

    /* Make sure any initial skipped elements contain legal packed */
    /* refs, so that the garbage collector can scan storage. */

    pshort = pbody;
    for (; skip; skip--)
	*pbody++ = pt_tag(pt_integer);
    pdest = pbody;

    for (i = size; i != 0; i--) {
	pref = ref_stack_index(pstack, i - 1);
	switch (r_btype(pref)) {	/* not r_type, opers are special */
	    case t_name:
		{
		    uint nidx = name_index(imem, pref);

		    if (nidx >= packed_name_max_index)
			break;	/* can't pack */
		    *pdest++ = nidx +
			(r_has_attr(pref, a_executable) ?
			 pt_tag(pt_executable_name) :
			 pt_tag(pt_literal_name));
		}
		continue;
	    case t_integer:
		if (pref->value.intval < packed_min_intval ||
		    pref->value.intval > packed_max_intval
		    )
		    break;
		*pdest++ = pt_tag(pt_integer) +
		    ((short)pref->value.intval - packed_min_intval);
		continue;
	    case t_oparray:
	    case t_operator:
		{
		    uint oidx;

		    if (!r_has_attr(pref, a_executable))
			break;
		    oidx = op_index(pref);
		    if (oidx == 0 || oidx > packed_int_mask)
			break;
		    *pdest++ = pt_tag(pt_executable_operator) + oidx;
		}
		continue;
	}
	/* Can't pack this element, use a full ref. */
	/* We may have to unpack up to align_packed_per_ref - 1 */
	/* preceding short elements. */
	/* Note that if we are at the beginning of the array, */
	/* 'skip' already ensures that we don't need to do this. */
	{
	    int i = (pdest - pshort) & (align_packed_per_ref - 1);
	    const ref_packed *psrc = pdest;
	    ref *pmove =
	    (ref *) (pdest += (packed_per_ref - 1) * i);

	    ref_assign_new(pmove, pref);
	    while (--i >= 0) {
		--psrc;
		--pmove;
		packed_get(imem->non_gc_memory, psrc, pmove);
	    }
	}
	pshort = pdest += packed_per_ref;
    }

    {
	int atype =
	(pdest == pbody + size ? t_shortarray : t_mixedarray);

	/* Pad with legal packed refs so that the garbage collector */
	/* can scan storage. */

	for (; pad; pad--)
	    *pdest++ = pt_tag(pt_integer);

	/* Finally, make the array. */

	ref_stack_pop(pstack, size);
	make_tasv_new(parr, atype, a_readonly | space, size,
		      packed, pbody + skip);
    }
    return 0;
}
コード例 #9
0
ファイル: zfont.c プロジェクト: jonathan-mui/ruby-ghostscript
int
zdefault_make_font(gs_font_dir * pdir, const gs_font * oldfont,
                   const gs_matrix * pmat, gs_font ** ppfont)
{
    gs_font *newfont = *ppfont;
    gs_memory_t *mem = newfont->memory;
    /* HACK: we know this font was allocated by the interpreter. */
    gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
    ref *fp = pfont_dict(oldfont);
    font_data *pdata;
    ref newdict, newmat, scalemat;
    uint dlen = dict_maxlength(fp);
    uint mlen = dict_length(fp) + 3;	/* FontID, OrigFont, ScaleMatrix */
    int code;

    if (dlen < mlen)
        dlen = mlen;
    if ((pdata = gs_alloc_struct(mem, font_data, &st_font_data,
                                 "make_font(font_data)")) == 0
        )
        return_error(e_VMerror);
    /*
     * This dictionary is newly created: it's safe to pass NULL as the
     * dstack pointer to dict_copy and dict_put_string.
     */
    if ((code = dict_alloc(imem, dlen, &newdict)) < 0 ||
        (code = dict_copy(fp, &newdict, NULL)) < 0 ||
        (code = gs_alloc_ref_array(imem, &newmat, a_all, 12,
                                   "make_font(matrices)")) < 0
        )
        return code;
    refset_null_new(newmat.value.refs, 12, imemory_new_mask(imem));
    ref_assign(&scalemat, &newmat);
    r_set_size(&scalemat, 6);
    scalemat.value.refs += 6;
    /*
     * Create the scaling matrix.  We could do this several different
     * ways: by "dividing" the new FontMatrix by the base FontMatrix, by
     * multiplying the current scaling matrix by a ScaleMatrix kept in
     * the gs_font, or by multiplying the current scaling matrix by the
     * ScaleMatrix from the font dictionary.  We opt for the last of
     * these.
     */
    {
        gs_matrix scale, prev_scale;
        ref *ppsm;

        if (!(dict_find_string(fp, "ScaleMatrix", &ppsm) > 0 &&
              read_matrix(mem, ppsm, &prev_scale) >= 0 &&
              gs_matrix_multiply(pmat, &prev_scale, &scale) >= 0)
            )
            scale = *pmat;
        write_matrix_new(&scalemat, &scale, imem);
    }
    r_clear_attrs(&scalemat, a_write);
    r_set_size(&newmat, 6);
    write_matrix_new(&newmat, &newfont->FontMatrix, imem);
    r_clear_attrs(&newmat, a_write);
    if ((code = dict_put_string(&newdict, "FontMatrix", &newmat, NULL)) < 0 ||
        (code = dict_put_string(&newdict, "OrigFont", pfont_dict(oldfont->base), NULL)) < 0 ||
        (code = dict_put_string(&newdict, "ScaleMatrix", &scalemat, NULL)) < 0 ||
        (code = add_FID(NULL, &newdict, newfont, imem)) < 0
        )
        return code;
    newfont->client_data = pdata;
    *pdata = *pfont_data(oldfont);
    pdata->dict = newdict;
    r_clear_attrs(dict_access_ref(&newdict), a_write);
    return 0;
}