/* Get the outline of a CIDFontType 0 glyph. */ static int z9_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat, gx_path *ppath, double sbw[4]) { gs_font_cid0 *const pfcid = (gs_font_cid0 *)font; ref gref; gs_glyph_data_t gdata; int code, fidx, ocode; gdata.memory = font->memory; code = pfcid->cidata.glyph_data((gs_font_base *)pfcid, glyph, &gdata, &fidx); if (code < 0) return code; glyph_ref(font->memory, glyph, &gref); ocode = zcharstring_outline(pfcid->cidata.FDArray[fidx], WMode, &gref, &gdata, pmat, ppath, sbw); gs_glyph_data_free(&gdata, "z9_glyph_outline"); return ocode; }
/* * 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); } }