/* 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; }
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; }