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; }
/* 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)); }
/* Note that this is now internal, since it only handles "new" arrays. */ static int array_new_indexed_param_write(iparam_list * iplist, const ref * pkey, const ref * pvalue) { const ref *const arr = &((dict_param_list *)iplist)->dict; ref *eltp; if (!r_has_type(pkey, t_integer)) return_error(e_typecheck); check_int_ltu(*pkey, r_size(arr)); store_check_dest(arr, pvalue); eltp = arr->value.refs + pkey->value.intval; /* ref_assign_new(eltp, pvalue); */ ref_assign(eltp, pvalue); r_set_attrs(eltp, imemory_new_mask(iplist->ref_memory)); 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; }
/* 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; }
/* 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; }
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; }
/* 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; }