Пример #1
0
int
cie_cache_joint(i_ctx_t *i_ctx_p, const ref_cie_render_procs * pcrprocs,
		const gs_cie_common *pcie, gs_state * pgs)
{
    const gs_cie_render *pcrd = gs_currentcolorrendering(pgs);
    gx_cie_joint_caches *pjc = gx_unshare_cie_caches(pgs);
    gs_ref_memory_t *imem = (gs_ref_memory_t *) gs_state_memory(pgs);
    ref pqr_procs;
    uint space;
    int code;
    int i;

    if (pcrd == 0)		/* cache is not set up yet */
	return 0;
    if (pjc == 0)		/* must already be allocated */
	return_error(e_VMerror);
    if (r_has_type(&pcrprocs->TransformPQR, t_null)) {
	/*
	 * This CRD came from a driver, not from a PostScript dictionary.
	 * Resample TransformPQR in C code.
	 */
	return gs_cie_cs_complete(pgs, true);
    }
    gs_cie_compute_points_sd(pjc, pcie, pcrd);
    code = ialloc_ref_array(&pqr_procs, a_readonly, 3 * (1 + 4 + 4 * 6),
			    "cie_cache_common");
    if (code < 0)
	return code;
    /* When we're done, deallocate the procs and complete the caches. */
    check_estack(3);
    cie_cache_push_finish(i_ctx_p, cie_tpqr_finish, imem, pgs);
    *++esp = pqr_procs;
    space = r_space(&pqr_procs);
    for (i = 0; i < 3; i++) {
	ref *p = pqr_procs.value.refs + 3 + (4 + 4 * 6) * i;
	const float *ppt = (float *)&pjc->points_sd;
	int j;

	make_array(pqr_procs.value.refs + i, a_readonly | a_executable | space,
		   4, p);
	make_array(p, a_readonly | space, 4 * 6, p + 4);
	p[1] = pcrprocs->TransformPQR.value.refs[i];
	make_oper(p + 2, 0, cie_exec_tpqr);
	make_oper(p + 3, 0, cie_post_exec_tpqr);
	for (j = 0, p += 4; j < 4 * 6; j++, p++, ppt++)
	    make_real(p, *ppt);
    }
    return cie_prepare_cache3(i_ctx_p, &pcrd->RangePQR,
			      pqr_procs.value.const_refs,
			      pjc->TransformPQR.caches,
			      pjc, imem, "Transform.PQR");
}
Пример #2
0
/*
 * Execute a quit in the case of an exit or stop with no appropriate
 * enclosing control scope (loop or stopped).  The caller has already
 * ensured two free slots on the top of the o-stack.
 */
static int
unmatched_exit(os_ptr op, op_proc_t opproc)
{
    make_oper(op - 1, 0, opproc);
    make_int(op, e_invalidexit);
    return_error(e_Quit);
}
Пример #3
0
/*
 * Convert an operator index to an operator or oparray ref.
 * This is only used for debugging and for 'get' from packed arrays,
 * so it doesn't have to be very fast.
 */
void
op_index_ref(uint index, ref * pref)
{
    const op_array_table *opt;

    if (op_index_is_operator(index)) {
	make_oper(pref, index, op_index_proc(index));
	return;
    }
    opt = op_index_op_array_table(index);
    make_tasv(pref, t_oparray, opt->attrs, index,
	      const_refs, (opt->table.value.const_refs
			   + index - opt->base_index));
}
Пример #4
0
/* Get the calling operator for error reporting in %Type32BuildGlyph */
static int
zgetshowoperator(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_text_enum_t *osenum = op_show_find(i_ctx_p);
  
    push(1);
    if (osenum == NULL)
        make_null(op);
    else {
        op_proc_t proc;
        *(void **)&proc = osenum->enum_client_data;
        make_oper(op, 0, proc);
    }
    return 0;
}
Пример #5
0
/* Initialize the graphics stack. */
gs_state *
int_gstate_alloc(const gs_dual_memory_t * dmem)
{
    int_gstate *iigs;
    ref proc0;
    int_remap_color_info_t *prci;
    gs_ref_memory_t *lmem = dmem->space_local;
    gs_ref_memory_t *gmem = dmem->space_global;
    gs_state *pgs = gs_state_alloc((gs_memory_t *)lmem);

    iigs = gs_alloc_struct((gs_memory_t *)lmem, int_gstate, &st_int_gstate,
			   "int_gstate_alloc(int_gstate)");
    int_gstate_map_refs(iigs, make_null);
    make_empty_array(&iigs->dash_pattern_array, a_all);
    gs_alloc_ref_array(lmem, &proc0, a_readonly + a_executable, 2,
		       "int_gstate_alloc(proc0)");
    make_oper(proc0.value.refs, 0, zpop);
    make_real(proc0.value.refs + 1, 0.0);
    iigs->black_generation = proc0;
    iigs->undercolor_removal = proc0;
    make_false(&iigs->use_cie_color);
    /*
     * Even though the gstate itself is allocated in local VM, the
     * container for the color remapping procedure must be allocated in
     * global VM so that the gstate can be copied into global VM.
     */
    prci = gs_alloc_struct((gs_memory_t *)gmem, int_remap_color_info_t,
			   &st_int_remap_color_info,
			   "int_gstate_alloc(remap color info)");
    make_struct(&iigs->remap_color_info, imemory_space(gmem), prci);
    clear_pagedevice(iigs);
    gs_state_set_client(pgs, iigs, &istate_procs, true);
    /* PostScript code wants limit clamping enabled. */
    gs_setlimitclamp(pgs, true);
    /*
     * gsave and grestore only work properly
     * if there are always at least 2 entries on the stack.
     * We count on the PostScript initialization code to do a gsave.
     */
    return pgs;
}
Пример #6
0
/*
 * Consult Metrics2 and CDevProc, and call setcachedevice[2].  Return
 * o_push_estack if we had to call a CDevProc, or if we are skipping the
 * rendering process (only getting the metrics).
 * Returns exec_cont - a function, which must be called by caller after this function.
 */
int
zchar_set_cache(i_ctx_t *i_ctx_p, const gs_font_base * pbfont,
                const ref * pcnref, const double psb[2],
                const double pwidth[2], const gs_rect * pbbox,
                op_proc_t cont, op_proc_t *exec_cont,
                const double Metrics2_sbw_default[4])
{
    os_ptr op = osp;
    ref *pcdevproc, *valueref;
    int have_cdevproc;
    ref rpop;
    ref cid, *cidptr;
    bool metrics2;
    bool metrics2_use_default = false;
    double w2[10];
    gs_text_enum_t *penum = op_show_find(i_ctx_p);

    w2[0] = pwidth[0], w2[1] = pwidth[1];

    /* Adjust the bounding box for stroking if needed. */

    w2[2] = pbbox->p.x, w2[3] = pbbox->p.y;
    w2[4] = pbbox->q.x, w2[5] = pbbox->q.y;
    if (pbfont->PaintType != 0) {
        double expand = max(1.415, gs_currentmiterlimit(igs)) *
        gs_currentlinewidth(igs) / 2;

        w2[2] -= expand, w2[3] -= expand;
        w2[4] += expand, w2[5] += expand;
    }

    /* Check for Metrics2. */

    {
        int code = zchar_get_metrics2(pbfont, pcnref, w2 + 6);

        if (code < 0)
            return code;
        metrics2 = code > 0;
    }

    /*
     * For FontType 9 and 11, if Metrics2 is missing, the caller provides
     * default Metrics2 values derived from the FontBBox.
     */
    if (!metrics2 && Metrics2_sbw_default != NULL) {
        w2[6] = Metrics2_sbw_default[2];
        w2[7] = Metrics2_sbw_default[3];
        w2[8] = Metrics2_sbw_default[0];
        w2[9] = Metrics2_sbw_default[1];
        metrics2 = true;
        metrics2_use_default = true;
    }

    /* Check for CDevProc or "short-circuiting". */

    have_cdevproc = zchar_get_CDevProc(pbfont, &pcdevproc);

    /* Obscure test. The CDevProc is supposed to be called with the original CID but what we get passed
     * here is the TT GID. So the CDevProc won't do the right thing. We need to extract the CID from the
     * enumerator, and use that instead.
     */
    cidptr = (ref *)pcnref;
    if (pbfont->FontType == ft_CID_TrueType && dict_find_string(&pfont_data(gs_font_parent(pbfont))->dict, "File", &valueref) > 0) {
        if (pbfont->key_name.size != pbfont->font_name.size ||
            strncmp((const char *)pbfont->key_name.chars, (const char *)pbfont->font_name.chars, pbfont->key_name.size)) {

            if (penum->returned.current_glyph >= GS_MIN_CID_GLYPH) {
                make_int(&cid, penum->returned.current_glyph - GS_MIN_CID_GLYPH);
            }
            else {
                make_int(&cid, penum->returned.current_glyph);
            }
            cidptr = &cid;
        }
    }
    if (have_cdevproc || zchar_show_width_only(penum)) {
        int i;
        op_proc_t zsetc;
        int nparams;

        if (have_cdevproc) {
            check_proc_only(*pcdevproc);
            zsetc = zsetcachedevice2;

            /* If we have cdevproc and the font type is CID type 0,
               we'll throw away Metrics2_sbw_default that is calculated
               from FontBBox. */
            if (!metrics2
                || (penum->current_font->FontType == ft_CID_encrypted
                    && metrics2_use_default)) {
                w2[6] = w2[0], w2[7] = w2[1];
                w2[8] = w2[9] = 0;
            }
            nparams = 10;
        } else {
            make_oper(&rpop, 0, zpop);
            pcdevproc = &rpop;
            if (metrics2)
                zsetc = zsetcachedevice2, nparams = 10;
            else
                zsetc = zsetcachedevice, nparams = 6;
        }
        check_estack(3);
        /* Push the l.s.b. for .type1addpath if necessary. */
        if (psb != 0) {
            push(nparams + 3);
            make_real(op - (nparams + 2), psb[0]);
            make_real(op - (nparams + 1), psb[1]);
        } else {
            push(nparams + 1);
        }
        for (i = 0; i < nparams; ++i)
            make_real(op - nparams + i, w2[i]);
        ref_assign(op, cidptr);
        push_op_estack(cont);
        push_op_estack(zsetc);
        ++esp;
        ref_assign(esp, pcdevproc);
        return o_push_estack;
    } {
        int code =
            (metrics2 ? gs_text_setcachedevice2(penum, w2) :
             gs_text_setcachedevice(penum, w2));

        if (code < 0)
            return code;
    }

    /* No metrics modification, do the stroke or fill now. */

    /* Push the l.s.b. for .type1addpath if necessary. */
    if (psb != 0) {
        push(2);
        make_real(op - 1, psb[0]);
        make_real(op, psb[1]);
    }
    *exec_cont = cont;
    return 0;
}
Пример #7
0
/*
 * Consult Metrics2 and CDevProc, and call setcachedevice[2].  Return
 * o_push_estack if we had to call a CDevProc, or if we are skipping the
 * rendering process (only getting the metrics).
 */
int
zchar_set_cache(os_ptr op, const gs_font_base *pbfont, const ref *pcnref,
  const float psb[2], const float pwidth[2], const gs_rect *pbbox,
  int (*cont_fill)(P1(os_ptr)), int (*cont_stroke)(P1(os_ptr)))
{	const ref *pfdict = &pfont_data(pbfont)->dict;
	ref *pmdict;
	ref *pcdevproc;
	int have_cdevproc;
	ref rpop;
	bool metrics2 = false;
	int (*cont)(P1(os_ptr));
	float w2[10];
	gs_show_enum *penum = op_show_find();

	w2[0] = pwidth[0], w2[1] = pwidth[1];

	/* Adjust the bounding box for stroking if needed. */

	w2[2] = pbbox->p.x, w2[3] = pbbox->p.y;
	w2[4] = pbbox->q.x, w2[5] = pbbox->q.y;
	if ( pbfont->PaintType == 0 )
		cont = cont_fill;
	else
	{	double expand = max(1.415, gs_currentmiterlimit(igs)) *
		  gs_currentlinewidth(igs) / 2;

		w2[2] -= expand, w2[3] -= expand;
		w2[4] += expand, w2[5] += expand;
		cont = cont_stroke;
	}

	/* Check for Metrics2. */

	if ( dict_find_string(pfdict, "Metrics2", &pmdict) > 0 )
	{	ref *pmvalue;
		check_type_only(*pmdict, t_dictionary);
		check_dict_read(*pmdict);
		if ( dict_find(pmdict, pcnref, &pmvalue) > 0 )
		{	check_read_type_only(*pmvalue, t_array);
			if ( r_size(pmvalue) == 4 )
			{	int code = num_params(pmvalue->value.refs + 3,
						      4, w2 + 6);
				if ( code < 0 )
				  return code;
				metrics2 = true;
			}
		}
	}

	/* Check for CDevProc or "short-circuiting". */

	have_cdevproc = dict_find_string(pfdict, "CDevProc", &pcdevproc) > 0;
	if ( have_cdevproc || gs_show_width_only(penum) )
	{	int i;
		int (*zsetc)(P1(os_ptr));
		int nparams;

		if ( have_cdevproc )
		  { check_proc_only(*pcdevproc);
		    zsetc = zsetcachedevice2;
		    if ( !metrics2 )
		      { w2[6] = w2[0], w2[7] = w2[1];
			w2[8] = w2[9] = 0;
		      }
		    nparams = 10;
		  }
		else
		  { make_oper(&rpop, 0, zpop);
		    pcdevproc = &rpop;
		    if ( metrics2 )
		      zsetc = zsetcachedevice2, nparams = 10;
		    else
		      zsetc = zsetcachedevice, nparams = 6;
		  }
		check_estack(3);
		/* Push the l.s.b. for .type1addpath if necessary. */
		if ( psb != 0 )
		  { push(nparams + 3);
		    make_real(op - (nparams + 2), psb[0]);
		    make_real(op - (nparams + 1), psb[1]);
		  }
		else
		  { push(nparams + 1);
		  }
		for ( i = 0; i < nparams; ++i )
		  make_real(op - nparams + i, w2[i]);
		ref_assign(op, pcnref);
		push_op_estack(cont);
		push_op_estack(zsetc);
		++esp;
		ref_assign(esp, pcdevproc);
		return o_push_estack;
	}
	{ int code =
		(metrics2 ? gs_setcachedevice2(penum, igs, w2) :
		 gs_setcachedevice(penum, igs, w2));
	  if ( code < 0 )
	    return code;
	}

	/* No metrics modification, do the stroke or fill now. */

	/* Push the l.s.b. for .type1addpath if necessary. */
	if ( psb != 0 )
	  { push(2);
	    make_real(op - 1, psb[0]);
	    make_real(op, psb[1]);
	  }
	return cont(op);
}
Пример #8
0
/*
 * Consult Metrics2 and CDevProc, and call setcachedevice[2].  Return
 * o_push_estack if we had to call a CDevProc, or if we are skipping the
 * rendering process (only getting the metrics).
 * Returns exec_cont - a function, which must be called by caller after this function.
 */
int
zchar_set_cache(i_ctx_t *i_ctx_p, const gs_font_base * pbfont,
		const ref * pcnref, const double psb[2],
		const double pwidth[2], const gs_rect * pbbox,
		op_proc_t cont, op_proc_t *exec_cont,
		const double Metrics2_sbw_default[4])
{
    os_ptr op = osp;
    ref *pcdevproc;
    int have_cdevproc;
    ref rpop;
    bool metrics2;
    bool metrics2_use_default = false;
    double w2[10];
    gs_text_enum_t *penum = op_show_find(i_ctx_p);

    w2[0] = pwidth[0], w2[1] = pwidth[1];

    /* Adjust the bounding box for stroking if needed. */

    w2[2] = pbbox->p.x, w2[3] = pbbox->p.y;
    w2[4] = pbbox->q.x, w2[5] = pbbox->q.y;
    if (pbfont->PaintType != 0) {
	double expand = max(1.415, gs_currentmiterlimit(igs)) *
	gs_currentlinewidth(igs) / 2;

	w2[2] -= expand, w2[3] -= expand;
	w2[4] += expand, w2[5] += expand;
    }

    /* Check for Metrics2. */

    {
	int code = zchar_get_metrics2(pbfont, pcnref, w2 + 6);

	if (code < 0)
	    return code;
	metrics2 = code > 0;
    }

    /*
     * For FontType 9 and 11, if Metrics2 is missing, the caller provides
     * default Metrics2 values derived from the FontBBox.
     */
    if (!metrics2 && Metrics2_sbw_default != NULL) {
        w2[6] = Metrics2_sbw_default[2];
        w2[7] = Metrics2_sbw_default[3];
        w2[8] = Metrics2_sbw_default[0];
        w2[9] = Metrics2_sbw_default[1];
	metrics2 = true;
	metrics2_use_default = true;
    }

    /* Check for CDevProc or "short-circuiting". */

    have_cdevproc = zchar_get_CDevProc(pbfont, &pcdevproc);
    if (have_cdevproc || zchar_show_width_only(penum)) {
	int i;
	op_proc_t zsetc;
	int nparams;

	if (have_cdevproc) {
	    check_proc_only(*pcdevproc);
	    zsetc = zsetcachedevice2;
	    
	    /* If we have cdevproc and the font type is CID type 0,
	       we'll throw away Metrics2_sbw_default that is calculated 
	       from FontBBox. */
	    if (!metrics2 
		|| (penum->current_font->FontType == ft_CID_encrypted
		    && metrics2_use_default)) {
		w2[6] = w2[0], w2[7] = w2[1];
		w2[8] = w2[9] = 0;
	    }
	    nparams = 10;
	} else {
	    make_oper(&rpop, 0, zpop);
	    pcdevproc = &rpop;
	    if (metrics2)
		zsetc = zsetcachedevice2, nparams = 10;
	    else
		zsetc = zsetcachedevice, nparams = 6;
	}
	check_estack(3);
	/* Push the l.s.b. for .type1addpath if necessary. */
	if (psb != 0) {
	    push(nparams + 3);
	    make_real(op - (nparams + 2), psb[0]);
	    make_real(op - (nparams + 1), psb[1]);
	} else {
	    push(nparams + 1);
	}
	for (i = 0; i < nparams; ++i)
	    make_real(op - nparams + i, w2[i]);
	ref_assign(op, pcnref);
	push_op_estack(cont);
	push_op_estack(zsetc);
	++esp;
	ref_assign(esp, pcdevproc);
	return o_push_estack;
    } {
	int code =
	    (metrics2 ? gs_text_setcachedevice2(penum, w2) :
	     gs_text_setcachedevice(penum, w2));

	if (code < 0)
	    return code;
    }

    /* No metrics modification, do the stroke or fill now. */

    /* Push the l.s.b. for .type1addpath if necessary. */
    if (psb != 0) {
	push(2);
	make_real(op - 1, psb[0]);
	make_real(op, psb[1]);
    }
    *exec_cont = cont;
    return 0;
}