예제 #1
0
파일: zchar.c 프로젝트: ststeiger/ghostsvg
/* 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;
}
예제 #2
0
/* <obj1> ... <objn> <int> copy <obj1> ... <objn> <obj1> ... <objn> */
static int
zcopy_integer(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    int count, i;
    int code;

    if ((uint) op->value.intval > (uint)(op - osbot)) {
	/* There might be enough elements in other blocks. */
	check_type(*op, t_integer);
        if (op->value.intval >= (int)ref_stack_count(&o_stack)) 
            return_error(e_stackunderflow);
        if (op->value.intval < 0) 
            return_error(e_rangecheck);
        check_int_ltu(*op, ref_stack_count(&o_stack));
	count = op->value.intval;
    } else if (op1 + (count = op->value.intval) <= ostop) {
	/* Fast case. */
	memcpy((char *)op, (char *)(op - count), count * sizeof(ref));
	push(count - 1);
	return 0;
    }
    /* Do it the slow, general way. */
    code = ref_stack_push(&o_stack, count - 1);
    if (code < 0)
	return code;
    for (i = 0; i < count; i++)
	*ref_stack_index(&o_stack, i) =
	    *ref_stack_index(&o_stack, i + count);
    return 0;
}
예제 #3
0
int
ztoken(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    switch (r_type(op)) {
        default:
            return_op_typecheck(op);
        case t_file: {
            stream *s;
            scanner_state state;

            check_read_file(i_ctx_p, s, op);
            check_ostack(1);
            gs_scanner_init(&state, op);
            return token_continue(i_ctx_p, &state, true);
        }
        case t_string: {
            ref token;
            /* -1 is to remove the string operand in case of error. */
            int orig_ostack_depth = ref_stack_count(&o_stack) - 1;
            int code;

            /* Don't pop the operand in case of invalidaccess. */
            if (!r_has_attr(op, a_read))
                return_error(e_invalidaccess);
            code = gs_scan_string_token(i_ctx_p, op, &token);
            switch (code) {
            case scan_EOF:      /* no tokens */
                make_false(op);
                return 0;
            default:
                if (code < 0) {
                    /*
                     * Clear anything that may have been left on the ostack,
                     * including the string operand.
                     */
                    if (orig_ostack_depth < ref_stack_count(&o_stack))
                        pop(ref_stack_count(&o_stack)- orig_ostack_depth);
                    return code;
                }
            }
            push(2);
            op[-1] = token;
            make_true(op);
            return 0;
        }
    }
}
예제 #4
0
/* <key> load <value> */
static int
zload(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref *pvalue;

    switch (r_type(op)) {
	case t_name:
	    /* Use the fast lookup. */
	    if ((pvalue = dict_find_name(op)) == 0)
		return_error(e_undefined);
	    ref_assign(op, pvalue);
	    return 0;
	case t_null:
	    return_error(e_typecheck);
	case t__invalid:
	    return_error(e_stackunderflow);
	default: {
		/* Use an explicit loop. */
		uint size = ref_stack_count(&d_stack);
		uint i;

		for (i = 0; i < size; i++) {
		    ref *dp = ref_stack_index(&d_stack, i);

		    check_dict_read(*dp);
		    if (dict_find(dp, op, &pvalue) > 0) {
			ref_assign(op, pvalue);
			return 0;
		    }
		}
		return_error(e_undefined);
	    }
    }
}
예제 #5
0
파일: zchar.c 프로젝트: ststeiger/ghostsvg
/*
 * Restore state after finishing, or unwinding from an error within, a show
 * operation.  Note that we assume op == osp, and may reset osp.
 */
static int
op_show_restore(i_ctx_t *i_ctx_p, bool for_error)
{
    register es_ptr ep = esp + snumpush;
    gs_text_enum_t *penum = esenum(ep);
    int saved_level = esgslevel(ep).value.intval;
    int code = 0;

    if (for_error) {
#if 0 /* Disabled for CPSI compatibility for 13-12-4. 
         CPSI doesn't remove cshow, kshow proc operands. */
	uint saved_count = esodepth(ep).value.intval;
	uint count = ref_stack_count(&o_stack);

	if (count > saved_count)	/* if <, we're in trouble */
	    ref_stack_pop(&o_stack, count - saved_count);
#endif
	if (ep[1].value.opproc == op_show_continue && penum->enum_client_data != NULL) {
	    /* Replace the continuation operaton on estack with the right operator : */
	    op_proc_t proc;

	    *(void **)&proc = penum->enum_client_data;
	    make_op_estack(ep + 1, proc);
	}
    }
    if (SHOW_IS_STRINGWIDTH(penum) && igs->text_rendering_mode != 3) {	
	/* stringwidth does an extra gsave */
	--saved_level;
    }
    if (penum->text.operation & TEXT_REPLACE_WIDTHS) {
	gs_free_const_object(penum->memory, penum->text.y_widths, "y_widths");
	if (penum->text.x_widths != penum->text.y_widths)
	    gs_free_const_object(penum->memory, penum->text.x_widths, "x_widths");
    }
    /*
     * We might have been inside a cshow, in which case currentfont was
     * reset temporarily, as though we were inside a BuildChar/ BuildGlyph
     * procedure.  To handle this case, set currentfont back to its original
     * state.  NOTE: this code previously used fstack[0] in the enumerator
     * for the root font: we aren't sure that this change is correct.
     */
    gs_set_currentfont(igs, penum->orig_font);
    while (igs->level > saved_level && code >= 0) {
	if (igs->saved == 0 || igs->saved->saved == 0) {
	    /*
	     * Bad news: we got an error inside a save inside a BuildChar or
	     * BuildGlyph.  Don't attempt to recover.
	     */
	    code = gs_note_error(e_Fatal);
	} else
	    code = gs_grestore(igs);
    }
    gs_text_release(penum, "op_show_restore");
    return code;
}
예제 #6
0
/* - countdictstack <int> */
static int
zcountdictstack(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint count = ref_stack_count(&d_stack);

    push(1);
    if (!level2_enabled)
	count--;		/* see dstack.h */
    make_int(op, count);
    return 0;
}
예제 #7
0
파일: zfsample.c 프로젝트: hackqiang/gs
/*
 * Set up to collect the data for the sampled function.  This is used for
 * those alternate tint transforms that cannot be converted into a
 * type 4 function.
 */
static int
sampled_data_setup(i_ctx_t *i_ctx_p, gs_function_t *pfn,
        const ref * pproc, int (*finish_proc)(i_ctx_t *), gs_memory_t * mem)
{
    os_ptr op = osp;
    gs_sampled_data_enum *penum;
    int i;
    gs_function_Sd_params_t * params = (gs_function_Sd_params_t *)&pfn->params;

    check_estack(estack_storage + 1);		/* Verify space on estack */
    check_ostack(params->m + O_STACK_PAD);	/* and the operand stack */
    check_ostack(params->n + O_STACK_PAD);

    /*
     * Allocate space for the enumerator data structure.
     */
    penum = gs_sampled_data_enum_alloc(imemory, "zbuildsampledfuntion(params)");
    if (penum == NULL)
        return_error(e_VMerror);

    /* Initialize data in the enumeration structure */

    penum->pfn = pfn;
    for(i=0; i< params->m; i++)
        penum->indexes[i] = 0;
    /*
     * Save stack depth for checking the correct number of values on stack
     * after the function, which is being sampled, is called.
     */
    penum->o_stack_depth = ref_stack_count(&o_stack);
    /*
     * Note:  As previously mentioned, we are putting some spare (unused) stack
     * space under the input values in case the function unbalances the stack.
     * It is possible for the function to pop or change values on the stack
     * outside of the input values.  (This has been found to happen with some
     * proc sets from Adobe.)
     */
    push(O_STACK_PAD);
    for (i = 0; i < O_STACK_PAD; i++) 		/* Set space = null */
        make_null(op - i);

    /* Push everything on the estack */

    esp += estack_storage;
    make_op_estack(esp - 2, finish_proc);	/* Finish proc onto estack */
    sample_proc = *pproc;			/* Save function to be sampled */
    make_istruct(esp, 0, penum);		/* Color cube enumeration structure */
    push_op_estack(sampled_data_sample);	/* Start sampling data */
    return o_push_estack;
}
예제 #8
0
/*
 * Count the number of elements on the exec stack, with or without
 * the normally invisible elements (*op is a Boolean that indicates this).
 */
static uint
count_exec_stack(i_ctx_t *i_ctx_p, bool include_marks)
{
    uint count = ref_stack_count(&e_stack);

    if (!include_marks) {
        uint i;

        for (i = count; i--;)
            if (r_has_type_attrs(ref_stack_index(&e_stack, (long)i),
                                 t_null, a_executable))
                --count;
    }
    return count;
}
예제 #9
0
/* <array> dictstack <subarray> */
static int
zdictstack(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint count = ref_stack_count(&d_stack);

    if (!level2_enabled)
	count--;		/* see dstack.h */
    if (!r_is_array(op))
	return_op_typecheck(op);
    if (r_size(op) < count)
        return_error(e_rangecheck);
    if (!r_has_type_attrs(op, t_array, a_write)) 
        return_error(e_invalidaccess);
    return ref_stack_store(&d_stack, op, count, 0, 0, true, idmemory,
			   "dictstack");
}
예제 #10
0
파일: idstack.c 프로젝트: 99years/plan9
/* Check whether a dictionary is one of the permanent ones on the d-stack. */
bool
dstack_dict_is_permanent(const dict_stack_t * pds, const ref * pdref)
{
    dict *pdict = pdref->value.pdict;
    int i;

    if (pds->stack.extension_size == 0) {	/* Only one block of d-stack. */
	for (i = 0; i < pds->min_size; ++i)
	    if (pds->stack.bot[i].value.pdict == pdict)
		return true;
    } else {			/* More than one block of d-stack. */
	uint count = ref_stack_count(&pds->stack);

	for (i = count - pds->min_size; i < count; ++i)
	    if (ref_stack_index(&pds->stack, i)->value.pdict == pdict)
		return true;
    }
    return false;
}
예제 #11
0
/* <obj_0> ... <obj_n-1> <n> packedarray <packedarray> */
int
zpackedarray(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;
    ref parr;

    check_type(*op, t_integer);
    if (op->value.intval < 0)
	return_error(e_rangecheck);
    if (op->value.intval > op - osbot &&
	op->value.intval >= ref_stack_count(&o_stack)
	)
	return_error(e_stackunderflow);
    osp--;
    code = make_packed_array(&parr, &o_stack, (uint) op->value.intval,
			     idmemory, "packedarray");
    osp++;
    if (code >= 0)
	*osp = parr;
    return code;
}
예제 #12
0
/* <obj_0> ... <obj_n-1> <array> astore <array> */
static int
zastore(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint size;
    int code;

    if (!r_is_array(op))
        return_op_typecheck(op);
    size = r_size(op);
    /* Amazingly, the following is valid: 0 array noaccess astore */
    if (size == 0)
        return 0;
    if (!r_has_type_attrs(op, t_array, a_write))
        return_error(gs_error_invalidaccess);
    if (size > op - osbot) {
        /* The store operation might involve other stack segments. */
        ref arr;

        if (size >= ref_stack_count(&o_stack))
            return_error(gs_error_stackunderflow);
        arr = *op;
        code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
                               "astore");
        if (code < 0)
            return code;
        ref_stack_pop(&o_stack, size);
        *ref_stack_index(&o_stack, 0) = arr;
    } else {
        code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
        if (code < 0)
            return code;
        op[-(int)size] = *op;
        pop(size);
    }
    return 0;
}
예제 #13
0
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);
}
예제 #14
0
파일: zfsample.c 프로젝트: hackqiang/gs
/*
 * Continuation procedure for processing sampled values.
 */
static int
sampled_data_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_sampled_data_enum *penum = senum;
    gs_function_Sd_params_t * params =
            (gs_function_Sd_params_t *)&penum->pfn->params;
    int i, j, num_out = params->n;
    int code = 0;
    byte * data_ptr;
    double sampled_data_value_max = (double)((1 << params->BitsPerSample) - 1);
    int bps = bits2bytes(params->BitsPerSample), stack_depth_adjust = 0;

    /*
     * Check to make sure that the procedure produced the correct number of
     * values.  If not, move the stack back to where it belongs and abort
     */
    if (num_out + O_STACK_PAD + penum->o_stack_depth != ref_stack_count(&o_stack)) {
        stack_depth_adjust = ref_stack_count(&o_stack) - penum->o_stack_depth;

        if (stack_depth_adjust < 0) {
            /*
             * If we get to here then there were major problems.  The function
             * removed too many items off of the stack.  We had placed extra
             * (unused) stack stack space to allow for this but the function
             * exceeded even that.  Data on the stack may have been lost.
             * The only thing that we can do is move the stack pointer back and
             * hope.  (We have not seen real Postscript files that have this
             * problem.)
             */
            push(-stack_depth_adjust);
            ifree_object(penum->pfn, "sampled_data_continue(pfn)");
            ifree_object(penum, "sampled_data_continue((enum)");
            return_error(e_undefinedresult);
        }
    }

    /* Save data from the given function */
    data_ptr = cube_ptr_from_index(params, penum->indexes);
    for (i=0; i < num_out; i++) {
        ulong cv;
        double value;
        double rmin = params->Range[2 * i];
        double rmax = params->Range[2 * i + 1];

        code = real_param(op + i - num_out + 1, &value);
        if (code < 0)
            return code;
        if (value < rmin)
            value = rmin;
        else if (value > rmax)
            value = rmax;
        value = (value - rmin) / (rmax - rmin);		/* Convert to 0 to 1.0 */
        cv = (int) (value * sampled_data_value_max + 0.5);
        for (j = 0; j < bps; j++)
            data_ptr[bps * i + j] = (byte)(cv >> ((bps - 1 - j) * 8));	/* MSB first */
    }
    pop(num_out);		    /* Move op to base of result values */

    /* Check if we are done collecting data. */

    if (increment_cube_indexes(params, penum->indexes)) {
        if (stack_depth_adjust == 0)
            pop(O_STACK_PAD);	    /* Remove spare stack space */
        else
            pop(stack_depth_adjust - num_out);
        /* Execute the closing procedure, if given */
        code = 0;
        if (esp_finish_proc != 0)
            code = esp_finish_proc(i_ctx_p);

        return code;
    } else {
        if (stack_depth_adjust) {
            stack_depth_adjust -= num_out;
            push(O_STACK_PAD - stack_depth_adjust);
            for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++)
                make_null(op - i);
        }
    }

    /* Now get the data for the next location */

    return sampled_data_sample(i_ctx_p);
}
예제 #15
0
파일: zchar.c 프로젝트: ststeiger/ghostsvg
/*
 * Note that op_show_continue_dispatch sets osp = op explicitly iff the
 * dispatch succeeds.  This is so that the show operators don't pop anything
 * from the o-stack if they don't succeed.  Note also that if it returns an
 * error, it has freed the enumerator.
 */
int
op_show_continue_dispatch(i_ctx_t *i_ctx_p, int npop, int code)
{
    os_ptr op = osp - npop;
    gs_text_enum_t *penum = senum;

    switch (code) {
	case 0: {		/* all done */
	    os_ptr save_osp = osp;

	    osp = op;
	    code = (*real_opproc(&seproc)) (i_ctx_p);
	    op_show_free(i_ctx_p, code);
	    if (code < 0) {
		osp = save_osp;
		return code;
	    }
	    return o_pop_estack;
	}
	case TEXT_PROCESS_INTERVENE: {
	    ref *pslot = &sslot; /* only used for kshow */

	    push(2);
	    make_int(op - 1, gs_text_current_char(penum)); /* previous char */
	    make_int(op, gs_text_next_char(penum));
	    push_op_estack(op_show_continue);	/* continue after kerning */
	    *++esp = *pslot;	/* kerning procedure */
	    return o_push_estack;
	}
	case TEXT_PROCESS_RENDER: {
	    gs_font *pfont = gs_currentfont(igs);
	    font_data *pfdata = pfont_data(pfont);
	    gs_char chr = gs_text_current_char(penum);
	    gs_glyph glyph = gs_text_current_glyph(penum);

	    push(2);
	    op[-1] = pfdata->dict;	/* push the font */
	    /*
	     * For Type 1 and Type 4 fonts, prefer BuildChar to BuildGlyph
	     * if there is no glyph, or if there is both a character and a
	     * glyph and the glyph is the one that corresponds to the
	     * character in the Encoding, so that PostScript procedures
	     * appearing in the CharStrings dictionary will receive the
	     * character code rather than the character name; for Type 3
	     * fonts, prefer BuildGlyph to BuildChar.  For other font types
	     * (such as CID fonts), only BuildGlyph will be present.
	     */
	    if (pfont->FontType == ft_user_defined) {
		/* Type 3 font, prefer BuildGlyph. */
		if (level2_enabled &&
		    !r_has_type(&pfdata->BuildGlyph, t_null) &&
		    glyph != gs_no_glyph
		    ) {
		    glyph_ref(imemory, glyph, op);
		    esp[2] = pfdata->BuildGlyph;
		} else if (r_has_type(&pfdata->BuildChar, t_null))
		    goto err;
		else if (chr == gs_no_char) {
		    /* glyphshow, reverse map the character */
		    /* through the Encoding */
		    ref gref;
		    const ref *pencoding = &pfdata->Encoding;

		    glyph_ref(imemory, glyph, &gref);
		    if (!map_glyph_to_char(imemory, &gref, pencoding,
					   (ref *) op)
			) {	/* Not found, try .notdef */
		        name_enter_string(imemory, ".notdef", &gref);
			if (!map_glyph_to_char(imemory, &gref,
					       pencoding,
					       (ref *) op)
			    )
			    goto err;
		    }
		    esp[2] = pfdata->BuildChar;
		} else {
		    make_int(op, chr & 0xff);
		    esp[2] = pfdata->BuildChar;
		}
	    } else {
		/*
		 * For a Type 1 or Type 4 font, prefer BuildChar or
		 * BuildGlyph as described above: we know that both
		 * BuildChar and BuildGlyph are present.  For other font
		 * types, only BuildGlyph is available.
		 */
		ref eref, gref;

		if (chr != gs_no_char &&
		    !r_has_type(&pfdata->BuildChar, t_null) &&
		    (glyph == gs_no_glyph ||
		     (!r_has_type(&pfdata->Encoding, t_null) &&
		       array_get(imemory, &pfdata->Encoding, (long)(chr & 0xff), &eref) >= 0 &&
		      (glyph_ref(imemory, glyph, &gref), obj_eq(imemory, &gref, &eref))))
		    ) {
		    make_int(op, chr & 0xff);
		    esp[2] = pfdata->BuildChar;
		} else {
		    /* We might not have a glyph: substitute 0. **HACK** */
		    if (glyph == gs_no_glyph)
			make_int(op, 0);
		    else
		        glyph_ref(imemory, glyph, op);
		    esp[2] = pfdata->BuildGlyph;
		}
	    }
	    /* Save the stack depths in case we bail out. */
	    sodepth.value.intval = ref_stack_count(&o_stack) - 2;
	    sddepth.value.intval = ref_stack_count(&d_stack);
	    push_op_estack(op_show_continue);
	    ++esp;		/* skip BuildChar or BuildGlyph proc */
	    return o_push_estack;
	}
	case TEXT_PROCESS_CDEVPROC:
	    {   gs_font *pfont = penum->current_font;
		ref cnref;
		op_proc_t cont = op_show_continue, exec_cont = 0;
		gs_glyph glyph = penum->returned.current_glyph;
		int code;
    
		pop(npop);
		op = osp;
		glyph_ref(imemory, glyph, &cnref);
		if (pfont->FontType == ft_CID_TrueType) {
		    gs_font_type42 *pfont42 = (gs_font_type42 *)pfont;
		    uint glyph_index = pfont42->data.get_glyph_index(pfont42, glyph);

		    code = zchar42_set_cache(i_ctx_p, (gs_font_base *)pfont42, 
				    &cnref, glyph_index, cont, &exec_cont);
		} else if (pfont->FontType == ft_CID_encrypted)
		    code = z1_set_cache(i_ctx_p, (gs_font_base *)pfont, 
				    &cnref, glyph, cont, &exec_cont);
		else
		    return_error(e_unregistered); /* Unimplemented. */
		if (exec_cont != 0)
		    return_error(e_unregistered); /* Must not happen. */
		return code;
	    }
	default:		/* error */
err:
	    if (code >= 0)
		code = gs_note_error(e_invalidfont);
	    return op_show_free(i_ctx_p, code);
    }
}
예제 #16
0
static int
set_language_level(i_ctx_t *i_ctx_p, int new_level)
{
    int old_level = LANGUAGE_LEVEL;
    ref *pgdict =		/* globaldict, if present */
	ref_stack_index(&d_stack, ref_stack_count(&d_stack) - 2);
    ref *level2dict;
    int code = 0;

    if (new_level < 1 ||
	new_level >
	(dict_find_string(systemdict, "ll3dict", &level2dict) > 0 ? 3 : 2)
	)
	return_error(e_rangecheck);
    if (dict_find_string(systemdict, "level2dict", &level2dict) <= 0)
	return_error(e_undefined);
    /*
     * As noted in dstack.h, we allocate the extra d-stack entry for
     * globaldict even in Level 1 mode; in Level 1 mode, this entry
     * holds an extra copy of systemdict, and [count]dictstack omit the
     * very bottommost entry.
     */
    while (new_level != old_level) {
	switch (old_level) {
	    case 1: {		/* 1 => 2 or 3 */
				/* Put globaldict in the dictionary stack. */
		ref *pdict;

		/*
		 * This might be called so early in initialization that
		 * globaldict hasn't been defined yet.  If so, just skip
		 * this step.
		 */
		code = dict_find_string(level2dict, "globaldict", &pdict);
		if (code > 0) {
		    if (!r_has_type(pdict, t_dictionary))
			return_error(e_typecheck);
		    *pgdict = *pdict;
		}
		/* Set other flags for Level 2 operation. */
		imemory->gs_lib_ctx->dict_auto_expand = true;
		}
		code = swap_level_dict(i_ctx_p, "level2dict");
		if (code < 0)
		    return code;
		++old_level;
		continue;
	    case 3:		/* 3 => 1 or 2 */
		code = swap_level_dict(i_ctx_p, "ll3dict");
		if (code < 0)
		    return code;
		--old_level;
		continue;
	    default:		/* 2 => 1 or 3 */
		break;
	}
	switch (new_level) {
	    case 1: {		/* 2 => 1 */
		/*
		 * Clear the cached definition pointers of all names defined
		 * in globaldict.  This will slow down future lookups, but
		 * we don't care.
		 */
		int index = dict_first(pgdict);
		ref elt[2];

		while ((index = dict_next(pgdict, index, &elt[0])) >= 0)
		    if (r_has_type(&elt[0], t_name))
		        name_invalidate_value_cache(imemory, &elt[0]);
		/* Overwrite globaldict in the dictionary stack. */
		*pgdict = *systemdict;
		/* Set other flags for Level 1 operation. */
		imemory->gs_lib_ctx->dict_auto_expand = false;
		}
		code = swap_level_dict(i_ctx_p, "level2dict");
		break;
	    case 3:		/* 2 => 3 */
		code = swap_level_dict(i_ctx_p, "ll3dict");
		break;
	    default:		/* not possible */
		return_error(e_Fatal);
	}
	break;
    }
    dict_set_top();		/* reload dict stack cache */
    return code;
}
예제 #17
0
int seticc(i_ctx_t * i_ctx_p, int ncomps, ref *ICCdict, float *range_buff)
{
    os_ptr                  op = osp;
    int edepth = ref_stack_count(&e_stack);
    int                     code, reuse_op = 0;
    gs_color_space *        pcs;
    gs_color_space *  palt_cs;
    int                     i;
    gs_cie_icc *            picc_info;
    ref *                   pstrmval;
    stream *                s = 0L;

    palt_cs = gs_currentcolorspace(igs);
    /* verify the DataSource entry */
    if (dict_find_string(ICCdict, "DataSource", &pstrmval) <= 0)
        return_error(e_undefined);
    check_read_file(s, pstrmval);

    /* build the color space object */
    code = gs_cspace_build_CIEICC(&pcs, NULL, gs_state_memory(igs));
    if (code < 0)
        return code;
    picc_info = pcs->params.icc.picc_info;
    picc_info->num_components = ncomps;
    picc_info->instrp = s;
    picc_info->file_id = (s->read_id | s->write_id);
    for (i = 0; i < ncomps; i++) {
        picc_info->Range.ranges[i].rmin = range_buff[2 * i];
        picc_info->Range.ranges[i].rmax = range_buff[2 * i + 1];

    }

    /* record the current space as the alternative color space */
    pcs->base_space = palt_cs;
    rc_increment(palt_cs);

    code = gx_load_icc_profile(picc_info);
    if (code < 0)
	return code;

    /* If the input space to this profile is CIELAB, then we need to adjust the limits */
    /* See ICC spec ICC.1:2004-10 Section 6.3.4.2 and 6.4 */
    if(picc_info->plu->e_inSpace == icSigLabData)
    {
        picc_info->Range.ranges[0].rmin = 0.0;
        picc_info->Range.ranges[0].rmax = 100.0;

        picc_info->Range.ranges[1].rmin = -128.0;
        picc_info->Range.ranges[1].rmax = 127.0;

        picc_info->Range.ranges[2].rmin = -128.0;
        picc_info->Range.ranges[2].rmax = 127.0;

    } 
    /* If the input space is icSigXYZData, then we should do the limits based upon the white point of the profile.  */
    if(picc_info->plu->e_inSpace == icSigXYZData)
    {
	for (i = 0; i < 3; i++) 
	{
	    picc_info->Range.ranges[i].rmin = 0;
	}

	picc_info->Range.ranges[0].rmax = picc_info->common.points.WhitePoint.u;
	picc_info->Range.ranges[1].rmax = picc_info->common.points.WhitePoint.v;
    	picc_info->Range.ranges[2].rmax = picc_info->common.points.WhitePoint.w;
    }

    code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs,
			   (gs_cie_common *)picc_info, igs);
    if (code < 0)
	return code;

    return cie_set_finish( i_ctx_p,
                           pcs,
                           &istate->colorspace.procs.cie,
                           edepth,
                           code );
}
예제 #18
0
/* This opens %statementedit% or %lineedit% and is also the 
 * continuation proc for callouts.
 * Input:
 *  string is the statement/line buffer, 
 *  int is the write index into string
 *  bool is true if %statementedit%
 *  file is stdin
 * Output:
 *  file is a string based stream
 * We store the line being read in a PostScript string.
 * This limits the size to max_string_size (64k).
 * This could be increased by storing the input line in something 
 * other than a PostScript string.
 */
int
zfilelineedit(i_ctx_t *i_ctx_p)
{
    uint count = 0;
    bool in_eol = false;
    int code;
    os_ptr op = osp;
    bool statement;
    stream *s;
    stream *ins;
    gs_string str;
    uint initial_buf_size;
    const char *filename;
    /*
     * buf exists only for stylistic parallelism: all occurrences of
     * buf-> could just as well be str. .
     */
    gs_string *const buf = &str;

    check_type(*op, t_string);		/* line assembled so far */
    buf->data = op->value.bytes;
    buf->size = op->tas.rsize;
    check_type(*(op-1), t_integer);	/* index */
    count = (op-1)->value.intval;
    check_type(*(op-2), t_boolean);	/* statementedit/lineedit */
    statement = (op-2)->value.boolval;
    check_read_file(ins, op - 3);	/* %stdin */

    /* extend string */
    initial_buf_size = statement ? STATEMENTEDIT_BUF_SIZE : LINEEDIT_BUF_SIZE;
    if (initial_buf_size > max_string_size)
	return_error(e_limitcheck);
    if (!buf->data || (buf->size < initial_buf_size)) {
	count = 0;
	buf->data = gs_alloc_string(imemory_system, initial_buf_size, 
	    "zfilelineedit(buffer)");
	if (buf->data == 0)
	    return_error(e_VMerror);
        op->value.bytes = buf->data;
	op->tas.rsize = buf->size = initial_buf_size;
    }

rd:
    code = zreadline_from(ins, buf, imemory_system, &count, &in_eol);
    if (buf->size > max_string_size) {
	/* zreadline_from reallocated the buffer larger than
	 * is valid for a PostScript string.
	 * Return an error, but first realloc the buffer
	 * back to a legal size.
	 */
	byte *nbuf = gs_resize_string(imemory_system, buf->data, buf->size, 
		max_string_size, "zfilelineedit(shrink buffer)");
	if (nbuf == 0)
	    return_error(e_VMerror);
	op->value.bytes = buf->data = nbuf;
	op->tas.rsize = buf->size = max_string_size;
	return_error(e_limitcheck);
    }

    op->value.bytes = buf->data; /* zreadline_from sometimes resizes the buffer. */
    op->tas.rsize = buf->size;

    switch (code) {
	case EOFC:
	    code = gs_note_error(e_undefinedfilename);
	    /* falls through */
	case 0:
	    break;
	default:
	    code = gs_note_error(e_ioerror);
	    break;
	case CALLC:
	    {
		ref rfile;
		(op-1)->value.intval = count;
		/* callout is for stdin */
		make_file(&rfile, a_readonly | avm_system, ins->read_id, ins);
		code = s_handle_read_exception(i_ctx_p, code, &rfile,  
		    NULL, 0, zfilelineedit);
	    }
	    break;
	case 1:		/* filled buffer */
	    {
		uint nsize = buf->size;
		byte *nbuf;

		if (nsize >= max_string_size) {
		    code = gs_note_error(e_limitcheck);
		    break;
		}
		else if (nsize >= max_string_size / 2)
		    nsize= max_string_size;
		else
		    nsize = buf->size * 2;
		nbuf = gs_resize_string(imemory_system, buf->data, buf->size, nsize,
					"zfilelineedit(grow buffer)");
		if (nbuf == 0) {
		    code = gs_note_error(e_VMerror);
		    break;
		}
		op->value.bytes = buf->data = nbuf;
		op->tas.rsize = buf->size = nsize;
		goto rd;
	    }
    }
    if (code != 0)
	return code;
    if (statement) {
	/* If we don't have a complete token, keep going. */
	stream st;
	stream *ts = &st;
	scanner_state state;
	ref ignore_value;
	uint depth = ref_stack_count(&o_stack);
	int code;

	/* Add a terminating EOL. */
	if (count + 1 > buf->size) {
	    uint nsize;
	    byte *nbuf;

	    nsize = buf->size + 1;
	    if (nsize > max_string_size) {
		return_error(gs_note_error(e_limitcheck));
	    }
	    else {
		nbuf = gs_resize_string(imemory_system, buf->data, buf->size, nsize,
					"zfilelineedit(grow buffer)");
		if (nbuf == 0) {
		    code = gs_note_error(e_VMerror);
		    return_error(code);
		}
		op->value.bytes = buf->data = nbuf;
		op->tas.rsize = buf->size = nsize;
	    }
	}
	buf->data[count++] = char_EOL;
	s_init(ts, NULL);
	sread_string(ts, buf->data, count);
sc:
	scanner_init_stream_options(&state, ts, SCAN_CHECK_ONLY);
	code = scan_token(i_ctx_p, &ignore_value, &state);
	ref_stack_pop_to(&o_stack, depth);
	if (code < 0)
	    code = scan_EOF;	/* stop on scanner error */
	switch (code) {
	    case 0:		/* read a token */
	    case scan_BOS:
		goto sc;	/* keep going until we run out of data */
	    case scan_Refill:
		goto rd;
	    case scan_EOF:
		break;
	    default:		/* error */
		return code;
	}
    }
    buf->data = gs_resize_string(imemory_system, buf->data, buf->size, count,
			   "zfilelineedit(resize buffer)");
    if (buf->data == 0)
	return_error(e_VMerror);
    op->value.bytes = buf->data;
    op->tas.rsize = buf->size;

    s = file_alloc_stream(imemory_system, "zfilelineedit(stream)");
    if (s == 0)
	return_error(e_VMerror);

    sread_string(s, buf->data, count);
    s->save_close = s->procs.close;
    s->procs.close = file_close_disable;

    filename = statement ? gs_iodev_statementedit.dname
	: gs_iodev_lineedit.dname;
    code = ssetfilename(s, (const byte *)filename, strlen(filename)+1);
    if (code < 0) {
	sclose(s);
	return_error(e_VMerror);
    }

    pop(3);
    make_stream_file(osp, s, "r");

    return code;
}