static int ref_param_make_float(ref *pe, const void *pvalue, uint i, gs_ref_memory_t *imem) { make_tav(pe, t_real, imemory_new_mask(imem), realval, ((const gs_param_float_array *)pvalue)->data[i]); return 0; }
/* 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; }
/* 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; }
/* Note that i_ctx_p may be NULL. */ int add_FID(i_ctx_t *i_ctx_p, ref * fp /* t_dictionary */ , gs_font * pfont, gs_ref_memory_t *imem) { ref fid; make_tav(&fid, t_fontID, a_readonly | imemory_space(imem) | imemory_new_mask(imem), pstruct, (void *)pfont); return (i_ctx_p ? idict_put_string(fp, "FID", &fid) : dict_put_string(fp, "FID", &fid, NULL)); }
/* - currentdevice <device> */ int zcurrentdevice(i_ctx_t *i_ctx_p) { os_ptr op = osp; gx_device *dev = gs_currentdevice(igs); gs_ref_memory_t *mem = (gs_ref_memory_t *) dev->memory; push(1); make_tav(op, t_device, (mem == 0 ? avm_foreign : imemory_space(mem)) | a_all, pdevice, dev); return 0; }
/* <device> copydevice <newdevice> */ private int zcopydevice(register os_ptr op) { gx_device *new_dev; int code; check_read_type(*op, t_device); code = gs_copydevice(&new_dev, op->value.pdevice, imemory); if ( code < 0 ) return code; new_dev->memory = imemory; make_tav(op, t_device, icurrent_space | a_all, pdevice, new_dev); return 0; }
/* <matrix> <width> <height> <palette> <word?> makewordimagedevice <device> */ static int zmakewordimagedevice(i_ctx_t *i_ctx_p) { os_ptr op = osp; os_ptr op1 = op - 1; gs_matrix imat; gx_device *new_dev; const byte *colors; int colors_size; int code; check_int_leu(op[-3], max_uint >> 1); /* width */ check_int_leu(op[-2], max_uint >> 1); /* height */ check_type(*op, t_boolean); if (r_has_type(op1, t_null)) { /* true color */ colors = 0; colors_size = -24; /* 24-bit true color */ } else if (r_has_type(op1, t_integer)) { /* * We use if/else rather than switch because the value is long, * which is not supported as a switch value in pre-ANSI C. */ if (op1->value.intval != 16 && op1->value.intval != 24 && op1->value.intval != 32 ) return_error(e_rangecheck); colors = 0; colors_size = -op1->value.intval; } else { check_type(*op1, t_string); /* palette */ if (r_size(op1) > 3 * 256) return_error(e_rangecheck); colors = op1->value.bytes; colors_size = r_size(op1); } if ((code = read_matrix(imemory, op - 4, &imat)) < 0) return code; /* Everything OK, create device */ code = gs_makewordimagedevice(&new_dev, &imat, (int)op[-3].value.intval, (int)op[-2].value.intval, colors, colors_size, op->value.boolval, true, imemory); if (code == 0) { new_dev->memory = imemory; make_tav(op - 4, t_device, imemory_space(iimemory) | a_all, pdevice, new_dev); pop(4); } return code; }
/* - .getdefaultdevice <device> */ static int zgetdefaultdevice(i_ctx_t *i_ctx_p) { os_ptr op = osp; const gx_device *dev; dev = gs_getdefaultdevice(); if (dev == 0) /* couldn't find a default device */ return_error(e_unknownerror); push(1); make_tav(op, t_device, avm_foreign | a_readonly, pdevice, (gx_device *) dev); return 0; }
/* <device> <keep_open> .copydevice2 <newdevice> */ static int zcopydevice2(i_ctx_t *i_ctx_p) { os_ptr op = osp; gx_device *new_dev; int code; check_read_type(op[-1], t_device); check_type(*op, t_boolean); code = gs_copydevice2(&new_dev, op[-1].value.pdevice, op->value.boolval, imemory); if (code < 0) return code; new_dev->memory = imemory; make_tav(op - 1, t_device, icurrent_space | a_all, pdevice, new_dev); pop(1); return 0; }
/* <int> .getdevice <device> */ static int zgetdevice(i_ctx_t *i_ctx_p) { os_ptr op = osp; const gx_device *dev; check_type(*op, t_integer); if (op->value.intval != (int)(op->value.intval)) return_error(e_rangecheck); /* won't fit in an int */ dev = gs_getdevice((int)(op->value.intval)); if (dev == 0) /* index out of range */ return_error(e_rangecheck); /* Device prototypes are read-only; */ /* the cast is logically unnecessary. */ make_tav(op, t_device, avm_foreign | a_readonly, pdevice, (gx_device *) dev); return 0; }
/* - save <save> */ int zsave(i_ctx_t *i_ctx_p) { os_ptr op = osp; uint space = icurrent_space; vm_save_t *vmsave; ulong sid; int code; gs_state *prev; if (I_VALIDATE_BEFORE_SAVE) ivalidate_clean_spaces(i_ctx_p); ialloc_set_space(idmemory, avm_local); vmsave = ialloc_struct(vm_save_t, &st_vm_save, "zsave"); ialloc_set_space(idmemory, space); if (vmsave == 0) return_error(e_VMerror); code = alloc_save_state(idmemory, vmsave, &sid); if (code < 0) return code; if (sid == 0) { ifree_object(vmsave, "zsave"); return_error(e_VMerror); } if_debug2('u', "[u]vmsave 0x%lx, id = %lu\n", (ulong) vmsave, (ulong) sid); code = gs_gsave_for_save(igs, &prev); if (code < 0) return code; code = gs_gsave(igs); if (code < 0) return code; vmsave->gsave = prev; push(1); make_tav(op, t_save, 0, saveid, sid); if (I_VALIDATE_AFTER_SAVE) ivalidate_clean_spaces(i_ctx_p); return 0; }
/* Return 0 if OK, error code if not. */ int write_matrix_in(ref * op, const gs_matrix * pmat, gs_dual_memory_t *idmemory, gs_ref_memory_t *imem) { ref *aptr; const float *pel; int i; check_write_type(*op, t_array); if (r_size(op) != 6) return_error(e_rangecheck); aptr = op->value.refs; pel = (const float *)pmat; for (i = 5; i >= 0; i--, aptr++, pel++) { if (idmemory) { ref_save(op, aptr, "write_matrix"); make_real_new(aptr, *pel); } else { make_tav(aptr, t_real, imemory_new_mask(imem), realval, *pel); } } return 0; }
/* Resize a dictionary. */ int dict_resize(ref * pdref, uint new_size, dict_stack_t *pds) { dict *pdict = pdref->value.pdict; gs_ref_memory_t *mem = dict_memory(pdict); uint new_mask = imemory_new_mask(mem); ushort orig_attrs = r_type_attrs(&pdict->values) & (a_all | a_executable); dict dnew; ref drto; int code; if (new_size < d_length(pdict)) { if (!mem->gs_lib_ctx->dict_auto_expand) return_error(gs_error_dictfull); new_size = d_length(pdict); } make_tav(&drto, t_dictionary, r_space(pdref) | a_all | new_mask, pdict, &dnew); dnew.memory = pdict->memory; if ((code = dict_create_contents(new_size, &drto, dict_is_packed(pdict))) < 0) return code; /* * We must suppress the store check, in case we are expanding * systemdict or another global dictionary that is allowed * to reference local objects. */ r_set_space(&drto, avm_local); /* * If we are expanding a permanent dictionary, we must make sure that * dict_put doesn't think this is a second definition for any * single-definition names. This in turn requires that * dstack_dict_is_permanent must be true for the second ("to") * argument of dict_copy_elements, which requires temporarily * setting *pdref = drto. */ if (CAN_SET_PVALUE_CACHE(pds, pdref, mem)) { ref drfrom; drfrom = *pdref; *pdref = drto; dict_copy_elements(&drfrom, pdref, COPY_FOR_RESIZE, pds); *pdref = drfrom; } else { dict_copy_elements(pdref, &drto, 0, pds); } /* Save or free the old dictionary. */ if (ref_must_save_in(mem, &pdict->values)) ref_do_save_in(mem, pdref, &pdict->values, "dict_resize(values)"); else gs_free_ref_array(mem, &pdict->values, "dict_resize(old values)"); if (ref_must_save_in(mem, &pdict->keys)) ref_do_save_in(mem, pdref, &pdict->keys, "dict_resize(keys)"); else gs_free_ref_array(mem, &pdict->keys, "dict_resize(old keys)"); ref_assign(&pdict->keys, &dnew.keys); ref_assign(&pdict->values, &dnew.values); r_store_attrs(&pdict->values, a_all | a_executable, orig_attrs); ref_save_in(dict_memory(pdict), pdref, &pdict->maxlength, "dict_resize(maxlength)"); d_set_maxlength(pdict, new_size); if (pds) dstack_set_top(pds); /* just in case this is the top dict */ return 0; }