Beispiel #1
0
/* width for an xfont character. */
static int
op_show_return_width(i_ctx_t *i_ctx_p, uint npop, double *pwidth)
{
    uint index = op_show_find_index(i_ctx_p);
    es_ptr ep = (es_ptr) ref_stack_index(&e_stack, index - (snumpush - 1));
    int code = gs_text_setcharwidth(esenum(ep), pwidth);
    uint ocount, dsaved, dcount;

    if (code < 0)
	return code;
    /* Restore the operand and dictionary stacks. */
    ocount = ref_stack_count(&o_stack) - (uint) esodepth(ep).value.intval;
    if (ocount < npop)
	return_error(e_stackunderflow);
    dsaved = (uint) esddepth(ep).value.intval;
    dcount = ref_stack_count(&d_stack);
    if (dcount < dsaved)
	return_error(e_dictstackunderflow);
    while (dcount > dsaved) {
	code = zend(i_ctx_p);
	if (code < 0)
	    return code;
	dcount--;
    }
    ref_stack_pop(&o_stack, ocount);
    /* We don't want to pop the mark or the continuation */
    /* procedure (op_show_continue or cshow_continue). */
    pop_estack(i_ctx_p, index - snumpush);
    return o_pop_estack;
}
/* <result> <mask> .stop - */
static int
zzstop(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint count;

    check_type(*op, t_integer);
    count = count_to_stopped(i_ctx_p, op->value.intval);
    if (count) {
        /*
         * If there are any t_oparrays on the e-stack, they will pop
         * any new items from the o-stack.  Wait to push the result
         * until we have run all the unwind procedures.
         */
        ref save_result;

        check_op(2);
        save_result = op[-1];
        pop(2);
        pop_estack(i_ctx_p, count);
        op = osp;
        push(1);
        *op = save_result;
        return o_pop_estack;
    }
    /* No mark, quit.  (per Adobe documentation) */
    return unmatched_exit(op, zzstop);
}
/* - exit - */
static int
zexit(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref_stack_enum_t rsenum;
    uint scanned = 0;

    ref_stack_enum_begin(&rsenum, &e_stack);
    do {
        uint used = rsenum.size;
        es_ptr ep = rsenum.ptr + used - 1;
        uint count = used;

        for (; count; count--, ep--)
            if (r_is_estack_mark(ep))
                switch (estack_mark_index(ep)) {
                    case es_for:
                        pop_estack(i_ctx_p, scanned + (used - count + 1));
                        return o_pop_estack;
                    case es_stopped:
                        return_error(e_invalidexit);	/* not a loop */
                }
        scanned += used;
    } while (ref_stack_enum_next(&rsenum));
    /* No mark, quit.  (per Adobe documentation) */
    push(2);
    return unmatched_exit(op, zexit);
}
/* the stacks would get restored in case of an error. */
static int
zstop(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint count = count_to_stopped(i_ctx_p, 1L);

    if (count) {
        /*
         * If there are any t_oparrays on the e-stack, they will pop
         * any new items from the o-stack.  Wait to push the 'true'
         * until we have run all the unwind procedures.
         */
        check_ostack(2);
        pop_estack(i_ctx_p, count);
        op = osp;
        push(1);
        make_true(op);
        return o_pop_estack;
    }
    /* No mark, quit.  (per Adobe documentation) */
    push(2);
    return unmatched_exit(op, zstop);
}