/* Get the information from a CIDSystemInfo dictionary. */ int cid_system_info_param(gs_cid_system_info_t *pcidsi, const ref *prcidsi) { ref *pregistry; ref *pordering; int code; if (!r_has_type(prcidsi, t_dictionary)) return_error(e_typecheck); if (dict_find_string(prcidsi, "Registry", &pregistry) <= 0 || dict_find_string(prcidsi, "Ordering", &pordering) <= 0 ) return_error(e_rangecheck); check_read_type_only(*pregistry, t_string); check_read_type_only(*pordering, t_string); pcidsi->Registry.data = pregistry->value.const_bytes; pcidsi->Registry.size = r_size(pregistry); pcidsi->Ordering.data = pordering->value.const_bytes; pcidsi->Ordering.size = r_size(pordering); code = dict_int_param(prcidsi, "Supplement", 0, max_int, -1, &pcidsi->Supplement); return (code < 0 ? code : 0); }
/* * Get the metrics for a character from the Metrics dictionary of a base * font. If present, store the l.s.b. in psbw[0,1] and the width in * psbw[2,3]. */ int /*metrics_present*/ zchar_get_metrics(const gs_font_base *pbfont, const ref *pcnref, float psbw[4]) { const ref *pfdict = &pfont_data(pbfont)->dict; ref *pmdict; if ( dict_find_string(pfdict, "Metrics", &pmdict) > 0 ) { ref *pmvalue; check_type_only(*pmdict, t_dictionary); check_dict_read(*pmdict); if ( dict_find(pmdict, pcnref, &pmvalue) > 0 ) { if ( num_params(pmvalue, 1, psbw + 2) >= 0 ) { /* <wx> only */ psbw[3] = 0; return metricsWidthOnly; } else { int code; check_read_type_only(*pmvalue, t_array); switch ( r_size(pmvalue) ) { case 2: /* [<sbx> <wx>] */ code = num_params(pmvalue->value.refs + 1, 2, psbw); psbw[2] = psbw[1]; psbw[1] = psbw[3] = 0; break; case 4: /* [<sbx> <sby> <wx> <wy>] */ code = num_params(pmvalue->value.refs + 3, 4, psbw); break; default: return_error(e_rangecheck); } if ( code < 0 ) return code; return metricsSideBearingAndWidth; } } } return metricsNone; }
/* Extract threshold common parameters + Thresholds. */ static int dict_threshold_params(const ref * pdict, gs_threshold_halftone * ptp, ref * ptproc) { ref *tstring; int code = dict_threshold_common_params(pdict, (gs_threshold_halftone_common *)ptp, &tstring, ptproc); if (code < 0) return code; check_read_type_only(*tstring, t_string); if (r_size(tstring) != (long)ptp->width * ptp->height) return_error(e_rangecheck); ptp->thresholds.data = tstring->value.const_bytes; ptp->thresholds.size = r_size(tstring); ptp->transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_mapped_transfer); return 0; }
/* Get the vertical metrics for a character from Metrics2, if present. */ int zchar_get_metrics2(const gs_font_base * pbfont, const ref * pcnref, double pwv[4]) { const ref *pfdict = &pfont_data(gs_font_parent(pbfont))->dict; ref *pmdict; 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, pwv); return (code < 0 ? code : metricsSideBearingAndWidth); } } } return metricsNone; }
/* * 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); }