/* Get ColorRenderingType 1 procedures from the PostScript dictionary. */ static int zcrd1_proc_params(const gs_memory_t *mem, os_ptr op, ref_cie_render_procs * pcprocs) { int code; ref *pRT; code = dict_proc3_param(mem, op, "EncodeLMN", &pcprocs->EncodeLMN); if (code < 0) return code; code = dict_proc3_param(mem, op, "EncodeABC", &pcprocs->EncodeABC); if (code < 0) return code; code = dict_proc3_param(mem, op, "TransformPQR", &pcprocs->TransformPQR); if (code < 0) return code; if (code == 1) return gs_note_error(e_undefined); if (dict_find_string(op, "RenderTable", &pRT) > 0) { const ref *prte; int size; int i; check_read_type(*pRT, t_array); size = r_size(pRT); if (size < 5) return_error(e_rangecheck); prte = pRT->value.const_refs; for (i = 5; i < size; i++) check_proc_only(prte[i]); make_const_array(&pcprocs->RenderTableT, a_readonly | r_space(pRT), size - 5, prte + 5); } else make_null(&pcprocs->RenderTableT); return 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; }
/* * 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); }
/* * 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; }