/* Only the type of *op has been checked. */ int zcopy_dict(i_ctx_t *i_ctx_p) { os_ptr op = osp; os_ptr op1 = op - 1; int code; check_type(*op1, t_dictionary); check_dict_read(*op1); check_dict_write(*op); if (!imemory->gs_lib_ctx->dict_auto_expand && (dict_length(op) != 0 || dict_maxlength(op) < dict_length(op1)) ) return_error(e_rangecheck); code = idict_copy(op1, op); if (code < 0) return code; /* * In Level 1 systems, we must copy the access attributes too. * The only possible effect this can have is to make the * copy read-only if the original dictionary is read-only. */ if (!level2_enabled) r_copy_attrs(dict_access_ref(op), a_write, dict_access_ref(op1)); ref_assign(op1, op); pop(1); return 0; }
/* Print a ref */ void debug_print_ref(ref *pref) { unsigned size = pref->size; printf("(%x)", pref->type_attrs); switch ( r_type(pref) ) { case t_array: printf("array(%u)0x%lx", size, (ulong)pref->value.refs); break; case t_boolean: printf("boolean %x", pref->value.index); break; case t_device: printf("device 0x%lx", (ulong)pref->value.pdevice); break; case t_dictionary: printf("dict(%u/%u)0x%lx", dict_length(pref), dict_maxlength(pref), (ulong)pref->value.pdict); break; case t_file: printf("file 0x%lx", (ulong)pref->value.pfile); break; case t_integer: printf("int %ld", pref->value.intval); break; case t_mark: printf("mark"); break; case t_name: printf("name(0x%lx#%x)", (ulong)pref->value.pname, pref->value.pname->index); debug_print_string(pref->value.pname->string_bytes, pref->value.pname->string_size); break; case t_null: printf("null"); break; case t_operator: printf("op(%u)0x%lx", size, (ulong)pref->value.opproc); break; case t_packedarray: printf("packedarray(%u)0x%lx", size, (ulong)pref->value.refs); break; case t_real: printf("real %f", pref->value.realval); break; case t_string: printf("string(%u)0x%lx", size, (ulong)pref->value.bytes); break; default: printf("type 0x%x", r_type(pref)); } }
/* Print a ref */ void debug_print_full_ref(const ref *pref) { unsigned size = r_size(pref); ref nref; dprintf1("(%x)", r_type_attrs(pref)); switch ( r_type(pref) ) { case t_array: dprintf2("array(%u)0x%lx", size, (ulong)pref->value.refs); break; case t_boolean: dprintf1("boolean %x", pref->value.index); break; case t_condition: dprintf1("condition 0x%lx", (ulong)pref->value.pcond); break; case t_device: dprintf1("device 0x%lx", (ulong)pref->value.pdevice); break; case t_dictionary: dprintf3("dict(%u/%u)0x%lx", dict_length(pref), dict_maxlength(pref), (ulong)pref->value.pdict); break; case t_file: dprintf1("file 0x%lx", (ulong)pref->value.pfile); break; case t_gstate: dprintf1("gstate 0x%lx", (ulong)pref->value.pgstate); break; case t_integer: dprintf1("int %ld", pref->value.intval); break; case t_lock: dprintf1("lock 0x%lx", (ulong)pref->value.plock); break; case t_mark: dprintf("mark"); break; case t_mixedarray: dprintf2("mixed packedarray(%u)0x%lx", size, (ulong)pref->value.packed); break; case t_name: dprintf2("name(0x%lx#%x)", (ulong)pref->value.pname, name_index(pref)); debug_print_name(pref); break; case t_null: dprintf("null"); break; case t_oparray: dprintf1("op_array(0x%x)", size); name_index_ref(op_array_nx_table[size - op_def_count], &nref); debug_print_name(&nref); break; case t_operator: dprintf1("op(0x%x", size); if ( size ) dprintf1(":%s", (const char *)(op_def_table[size]->oname + 1)); dprintf1(")0x%lx", (ulong)pref->value.opproc); break; case t_real: dprintf1("real %f", pref->value.realval); break; case t_shortarray: dprintf2("short packedarray(%u)0x%lx", size, (ulong)pref->value.packed); break; case t_string: dprintf2("string(%u)0x%lx", size, (ulong)pref->value.bytes); break; default: dprintf1("type 0x%x", r_type(pref)); } }
/* <dict> maxlength <int> */ static int zmaxlength(i_ctx_t *i_ctx_p) { os_ptr op = osp; check_type(*op, t_dictionary); check_dict_read(*op); make_int(op, dict_maxlength(op)); return 0; }
/* Enter a name and value into a dictionary. */ static int i_initial_enter_name_in(i_ctx_t *i_ctx_p, ref *pdict, const char *nstr, const ref * pref) { int code = idict_put_string(pdict, nstr, pref); if (code < 0) lprintf4("initial_enter failed (%d), entering /%s in -dict:%u/%u-\n", code, nstr, dict_length(pdict), dict_maxlength(pdict)); 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; }
/* * Look up a name on the dictionary stack. * Return the pointer to the value if found, 0 if not. */ ref * dstack_find_name_by_index(dict_stack_t * pds, uint nidx) { ds_ptr pdref = pds->stack.p; /* Since we know the hash function is the identity function, */ /* there's no point in allocating a separate variable for it. */ #define hash dict_name_index_hash(nidx) ref_packed kpack = packed_name_key(nidx); do { dict *pdict = pdref->value.pdict; uint size = npairs(pdict); const gs_memory_t *mem = dict_mem(pdict); #ifdef DEBUG if (gs_debug_c('D')) { ref dnref; name_index_ref(mem, nidx, &dnref); dlputs("[D]lookup "); debug_print_name(mem, &dnref); dprintf3(" in 0x%lx(%u/%u)\n", (ulong) pdict, dict_length(pdref), dict_maxlength(pdref)); } #endif #define INCR_DEPTH(pdref)\ INCR(depth[min(MAX_STATS_DEPTH, pds->stack.p - pdref)]) if (dict_is_packed(pdict)) { packed_search_1(INCR_DEPTH(pdref), return packed_search_value_pointer, DO_NOTHING, goto miss); packed_search_2(INCR_DEPTH(pdref), return packed_search_value_pointer, DO_NOTHING, break); miss:; } else { ref *kbot = pdict->keys.value.refs; register ref *kp; int wrap = 0; /* Search the dictionary */ for (kp = kbot + dict_hash_mod(hash, size) + 2;;) { --kp; if (r_has_type(kp, t_name)) { if (name_index(mem, kp) == nidx) { INCR_DEPTH(pdref); return pdict->values.value.refs + (kp - kbot); } } else if (r_has_type(kp, t_null)) { /* Empty, deleted, or wraparound. */ /* Figure out which. */ if (!r_has_attr(kp, a_executable)) break; if (kp == kbot) { /* wrap */ if (wrap++) break; /* 2 wraps */ kp += size + 1; } } } } #undef INCR_DEPTH }