static int zsuperexec(i_ctx_t *i_ctx_p) { os_ptr op = osp; es_ptr ep; check_op(1); if (!r_has_attr(op, a_executable)) return 0; /* literal object just gets pushed back */ check_estack(2); ep = esp += 3; make_mark_estack(ep - 2, es_other, end_superexec); /* error case */ make_op_estack(ep - 1, end_superexec); /* normal case */ ref_assign(ep, op); esfile_check_cache(); pop(1); i_ctx_p->in_superexec++; return o_push_estack; }
/* <first> <count> <last> <proc> %for_samples - */ int zfor_samples(i_ctx_t *i_ctx_p) { os_ptr op = osp; es_ptr ep; check_type(op[-3], t_real); check_type(op[-2], t_integer); check_type(op[-1], t_real); check_proc(*op); check_estack(8); ep = esp + 7; make_mark_estack(ep - 6, es_for, no_cleanup); make_int(ep - 5, 0); memcpy(ep - 4, op - 3, 3 * sizeof(ref)); ref_assign(ep - 1, op); make_op_estack(ep, for_samples_continue); esp = ep; pop(4); return o_push_estack; }
static int zcond(i_ctx_t *i_ctx_p) { os_ptr op = osp; es_ptr ep = esp; /* Push the array on the e-stack and call the continuation. */ if (!r_is_array(op)) return_op_typecheck(op); check_execute(*op); if ((r_size(op) & 1) != 0) return_error(e_rangecheck); if (r_size(op) == 0) return zpop(i_ctx_p); check_estack(3); esp = ep += 3; ref_assign(ep - 2, op); /* the cond body */ make_op_estack(ep - 1, cond_continue); array_get(imemory, op, 0L, ep); esfile_check_cache(); pop(1); return o_push_estack; }
static int cond_continue(i_ctx_t *i_ctx_p) { os_ptr op = osp; es_ptr ep = esp; int code; /* The top element of the e-stack is the remaining tail of */ /* the cond body. The top element of the o-stack should be */ /* the (boolean) result of the test that is the first element */ /* of the tail. */ check_type(*op, t_boolean); if (op->value.boolval) { /* true */ array_get(imemory, ep, 1L, ep); esfile_check_cache(); code = o_pop_estack; } else if (r_size(ep) > 2) { /* false */ const ref_packed *elts = ep->value.packed; check_estack(2); r_dec_size(ep, 2); elts = packed_next(elts); elts = packed_next(elts); ep->value.packed = elts; array_get(imemory, ep, 0L, ep + 2); make_op_estack(ep + 1, cond_continue); esp = ep + 2; esfile_check_cache(); code = o_push_estack; } else { /* fall off end of cond */ esp = ep - 1; code = o_pop_estack; } pop(1); /* get rid of the boolean */ return code; }
static int zsethalftone5(i_ctx_t *i_ctx_p) { os_ptr op = osp; uint count; gs_halftone_component *phtc; gs_halftone_component *pc; int code = 0; int j; gs_halftone *pht; gx_device_halftone *pdht; ref sprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1]; ref tprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1]; gs_memory_t *mem; uint edepth = ref_stack_count(&e_stack); int npop = 2; int dict_enum = dict_first(op); ref rvalue[2]; int cname, colorant_number; byte * pname; uint name_size; int halftonetype, type = 0; gs_state *pgs = igs; int space_index = r_space_index(op - 1); mem = (gs_memory_t *) idmemory->spaces_indexed[space_index]; check_type(*op, t_dictionary); check_dict_read(*op); check_type(op[-1], t_dictionary); check_dict_read(op[-1]); /* * We think that Type 2 and Type 4 halftones, like * screens set by setcolorscreen, adapt automatically to * the device color space, so we need to mark them * with a different internal halftone type. */ dict_int_param(op - 1, "HalftoneType", 1, 5, 0, &type); halftonetype = (type == 2 || type == 4) ? ht_type_multiple_colorscreen : ht_type_multiple; /* Count how many components that we will actually use. */ for (count = 0; ;) { bool have_default = false; /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* * Verify that we have a valid component. We may have a * /HalfToneType entry. */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component verify that we will use it. */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; else if (colorant_number == GX_DEVICE_COLOR_MAX_COMPONENTS) { /* If here then we have the "Default" component */ if (have_default) return_error(e_rangecheck); have_default = true; } count++; /* * Check to see if we have already reached the legal number of * components. */ if (count > GS_CLIENT_COLOR_MAX_COMPONENTS + 1) { code = gs_note_error(e_rangecheck); break; } } check_estack(5); /* for sampling Type 1 screens */ refset_null(sprocs, count); refset_null(tprocs, count); rc_alloc_struct_0(pht, gs_halftone, &st_halftone, imemory, pht = 0, ".sethalftone5"); phtc = gs_alloc_struct_array(mem, count, gs_halftone_component, &st_ht_component_element, ".sethalftone5"); rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone, imemory, pdht = 0, ".sethalftone5"); if (pht == 0 || phtc == 0 || pdht == 0) { j = 0; /* Quiet the compiler: gs_note_error isn't necessarily identity, so j could be left ununitialized. */ code = gs_note_error(e_VMerror); } else { dict_enum = dict_first(op); for (j = 0, pc = phtc; ;) { int type; /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* * Verify that we have a valid component. We may have a * /HalfToneType entry. */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; /* Do not use this component */ pc->cname = cname; pc->comp_number = colorant_number; /* Now process the component dictionary */ check_dict_read(rvalue[1]); if (dict_int_param(&rvalue[1], "HalftoneType", 1, 7, 0, &type) < 0) { code = gs_note_error(e_typecheck); break; } switch (type) { default: code = gs_note_error(e_rangecheck); break; case 1: code = dict_spot_params(&rvalue[1], &pc->params.spot, sprocs + j, tprocs + j); pc->params.spot.screen.spot_function = spot1_dummy; pc->type = ht_type_spot; break; case 3: code = dict_threshold_params(&rvalue[1], &pc->params.threshold, tprocs + j); pc->type = ht_type_threshold; break; case 7: code = dict_threshold2_params(&rvalue[1], &pc->params.threshold2, tprocs + j, imemory); pc->type = ht_type_threshold2; break; } if (code < 0) break; pc++; j++; } } if (code >= 0) { pht->type = halftonetype; pht->params.multiple.components = phtc; pht->params.multiple.num_comp = j; pht->params.multiple.get_colorname_string = gs_get_colorname_string; code = gs_sethalftone_prepare(igs, pht, pdht); } if (code >= 0) { /* * Put the actual frequency and angle in the spot function component dictionaries. */ dict_enum = dict_first(op); for (pc = phtc; ; ) { /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* Verify that we have a valid component */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component and verify that we will use it. */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; if (pc->type == ht_type_spot) { code = dict_spot_results(i_ctx_p, &rvalue[1], &pc->params.spot); if (code < 0) break; } pc++; } } if (code >= 0) { /* * Schedule the sampling of any Type 1 screens, * and any (Type 1 or Type 3) TransferFunctions. * Save the stack depths in case we have to back out. */ uint odepth = ref_stack_count(&o_stack); ref odict, odict5; odict = op[-1]; odict5 = *op; pop(2); op = osp; esp += 5; make_mark_estack(esp - 4, es_other, sethalftone_cleanup); esp[-3] = odict; make_istruct(esp - 2, 0, pht); make_istruct(esp - 1, 0, pdht); make_op_estack(esp, sethalftone_finish); for (j = 0; j < count; j++) { gx_ht_order *porder = NULL; if (pdht->components == 0) porder = &pdht->order; else { /* Find the component in pdht that matches component j in the pht; gs_sethalftone_prepare() may permute these. */ int k; int comp_number = phtc[j].comp_number; for (k = 0; k < count; k++) { if (pdht->components[k].comp_number == comp_number) { porder = &pdht->components[k].corder; break; } } } switch (phtc[j].type) { case ht_type_spot: code = zscreen_enum_init(i_ctx_p, porder, &phtc[j].params.spot.screen, &sprocs[j], 0, 0, space_index); if (code < 0) break; /* falls through */ case ht_type_threshold: if (!r_has_type(tprocs + j, t__invalid)) { /* Schedule TransferFunction sampling. */ /****** check_xstack IS WRONG ******/ check_ostack(zcolor_remap_one_ostack); check_estack(zcolor_remap_one_estack); code = zcolor_remap_one(i_ctx_p, tprocs + j, porder->transfer, igs, zcolor_remap_one_finish); op = osp; } break; default: /* not possible here, but to keep */ /* the compilers happy.... */ ; } if (code < 0) { /* Restore the stack. */ ref_stack_pop_to(&o_stack, odepth); ref_stack_pop_to(&e_stack, edepth); op = osp; op[-1] = odict; *op = odict5; break; } npop = 0; } } if (code < 0) { gs_free_object(mem, pdht, ".sethalftone5"); gs_free_object(mem, phtc, ".sethalftone5"); gs_free_object(mem, pht, ".sethalftone5"); return code; } pop(npop); return (ref_stack_count(&e_stack) > edepth ? o_push_estack : 0); }
/* Finish setting up a text operator. */ int op_show_finish_setup(i_ctx_t *i_ctx_p, gs_text_enum_t * penum, int npop, op_proc_t endproc /* end procedure */ ) { gs_text_enum_t *osenum = op_show_find(i_ctx_p); es_ptr ep = esp + snumpush; gs_glyph glyph; if (gs_currentcpsimode(igs->memory)) { /* CET 14-03.PS page 2 emits rangecheck before rendering a character. Early check the text to font compatibility with decomposing the text into characters.*/ int code = gs_text_count_chars(igs, gs_get_text_params(penum), imemory); if (code < 0) return code; } /* * If we are in the procedure of a cshow for a CID font and this is * a show operator, do something special, per the Red Book. */ if (osenum && SHOW_IS_ALL_OF(osenum, TEXT_FROM_STRING | TEXT_DO_NONE | TEXT_INTERVENE) && SHOW_IS_ALL_OF(penum, TEXT_FROM_STRING | TEXT_RETURN_WIDTH) && (glyph = gs_text_current_glyph(osenum)) != gs_no_glyph && glyph >= gs_min_cid_glyph && /* According to PLRM, we don't need to raise a rangecheck error, if currentfont is changed in the proc of the operator 'cshow'. */ gs_default_same_font (gs_text_current_font(osenum), gs_text_current_font(penum), true) ) { gs_text_params_t text; if (!(penum->text.size == 1 && penum->text.data.bytes[0] == (gs_text_current_char(osenum) & 0xff)) ) return_error(e_rangecheck); text = penum->text; text.operation = (text.operation & ~(TEXT_FROM_STRING | TEXT_FROM_BYTES | TEXT_FROM_CHARS | TEXT_FROM_GLYPHS | TEXT_FROM_SINGLE_CHAR)) | TEXT_FROM_SINGLE_GLYPH; text.data.d_glyph = glyph; text.size = 1; gs_text_restart(penum, &text); } if (osenum && osenum->current_font->FontType == ft_user_defined && osenum->orig_font->FontType == ft_composite && ((const gs_font_type0 *)osenum->orig_font)->data.FMapType == fmap_CMap) { /* A special behavior defined in PLRM3 section 5.11 page 389. */ penum->outer_CID = osenum->returned.current_glyph; } if (osenum == NULL && !(penum->text.operation & (TEXT_FROM_GLYPHS | TEXT_FROM_SINGLE_GLYPH))) { int ft = igs->root_font->FontType; if ((ft >= ft_CID_encrypted && ft <= ft_CID_TrueType) || ft == ft_CID_bitmap) return_error(e_typecheck); } make_mark_estack(ep - (snumpush - 1), es_show, op_show_cleanup); if (endproc == NULL) endproc = finish_show; make_null(&esslot(ep)); make_int(&esodepth(ep), ref_stack_count_inline(&o_stack) - npop); /* Save stack depth for */ make_int(&esddepth(ep), ref_stack_count_inline(&d_stack)); /* correct interrupt processing */ make_int(&esgslevel(ep), igs->level); make_null(&essfont(ep)); make_null(&esrfont(ep)); make_op_estack(&eseproc(ep), endproc); make_istruct(ep, 0, penum); esp = ep; return 0; }
/* * Handle a scan_Comment or scan_DSC_Comment return from gs_scan_token * (scan_code) by calling out to %Process[DSC]Comment. The continuation * procedure expects the scanner state on the o-stack. */ int ztoken_handle_comment(i_ctx_t *i_ctx_p, scanner_state *sstate, const ref *ptoken, int scan_code, bool save, bool push_file, op_proc_t cont) { const char *proc_name; scanner_state *pstate; os_ptr op; ref *ppcproc; int code; switch (scan_code) { case scan_Comment: proc_name = "%ProcessComment"; break; case scan_DSC_Comment: proc_name = "%ProcessDSCComment"; break; default: return_error(e_Fatal); /* can't happen */ } /* * We can't use check_ostack here, because it returns on overflow. */ /*check_ostack(2);*/ if (ostop - osp < 2) { code = ref_stack_extend(&o_stack, 2); if (code < 0) return code; } check_estack(3); code = name_enter_string(imemory, proc_name, esp + 3); if (code < 0) return code; if (save) { pstate = (scanner_state *)ialloc_struct(scanner_state_dynamic, &st_scanner_state_dynamic, "ztoken_handle_comment"); if (pstate == 0) return_error(e_VMerror); ((scanner_state_dynamic *)pstate)->mem = imemory; *pstate = *sstate; } else pstate = sstate; /* Save the token now -- it might be on the e-stack. */ if (!pstate->s_pstack) osp[2] = *ptoken; /* * Push the continuation, scanner state, file, and callout procedure * on the e-stack. */ make_op_estack(esp + 1, cont); make_istruct(esp + 2, 0, pstate); ppcproc = dict_find_name(esp + 3); if (ppcproc == 0) { /* * This can only happen during initialization. * Pop the comment string from the o-stack if needed (see below). */ if (pstate->s_pstack) --osp; esp += 2; /* do run the continuation */ } else { /* * Push the file and comment string on the o-stack. * If we were inside { }, the comment string is already on the stack. */ if (pstate->s_pstack) { op = ++osp; *op = op[-1]; } else { op = osp += 2; /* *op = *ptoken; */ /* saved above */ } op[-1] = pstate->s_file; esp[3] = *ppcproc; esp += 3; } return o_push_estack; }
static int zsetcolorscreen(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_colorscreen_halftone cscreen; ref sprocs[4]; gs_halftone *pht; gx_device_halftone *pdht; int i; int code = 0; int space = 0; gs_memory_t *mem; for (i = 0; i < 4; i++) { os_ptr op1 = op - 9 + i * 3; int code = zscreen_params(op1, &cscreen.screens.indexed[i]); if (code < 0) return code; cscreen.screens.indexed[i].spot_function = spot_dummy; sprocs[i] = *op1; space = max(space, r_space_index(op1)); } mem = (gs_memory_t *)idmemory->spaces_indexed[space]; check_estack(8); /* for sampling screens */ rc_alloc_struct_0(pht, gs_halftone, &st_halftone, mem, pht = 0, "setcolorscreen(halftone)"); rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone, mem, pdht = 0, "setcolorscreen(device halftone)"); if (pht == 0 || pdht == 0) code = gs_note_error(e_VMerror); else { pht->type = ht_type_colorscreen; pht->params.colorscreen = cscreen; code = gs_sethalftone_prepare(igs, pht, pdht); } if (code >= 0) { /* Schedule the sampling of the screens. */ es_ptr esp0 = esp; /* for backing out */ esp += 8; make_mark_estack(esp - 7, es_other, setcolorscreen_cleanup); memcpy(esp - 6, sprocs, sizeof(ref) * 4); /* procs */ make_istruct(esp - 2, 0, pht); make_istruct(esp - 1, 0, pdht); make_op_estack(esp, setcolorscreen_finish); for (i = 0; i < 4; i++) { /* Shuffle the indices to correspond to */ /* the component order. */ code = zscreen_enum_init(i_ctx_p, &pdht->components[(i + 1) & 3].corder, &pht->params.colorscreen.screens.indexed[i], &sprocs[i], 0, 0, space); if (code < 0) { esp = esp0; break; } } } if (code < 0) { gs_free_object(mem, pdht, "setcolorscreen(device halftone)"); gs_free_object(mem, pht, "setcolorscreen(halftone)"); return code; } pop(12); return o_push_estack; }