/* Initialize a Type 1 interpreter. */ static int type1_exec_init(gs_type1_state *pcis, gs_text_enum_t *penum, gs_state *pgs, gs_font_type1 *pfont1) { /* * We have to disregard penum->pis and penum->path, and render to * the current gstate and path. This is a design bug that we will * have to address someday! */ int alpha_bits = 1; gs_log2_scale_point log2_subpixels; if (color_is_pure(gs_currentdevicecolor_inline(pgs))) /* Keep consistency with alpha_buffer_bits() */ alpha_bits = (*dev_proc(pgs->device, get_alpha_bits)) (pgs->device, go_text); if (alpha_bits <= 1) { /* We render to cache device or the target device has no alpha bits. */ log2_subpixels = penum->log2_scale; } else { /* We'll render to target device through alpha buffer. */ /* Keep consistency with alpha_buffer_init() */ log2_subpixels.x = log2_subpixels.y = ilog2(alpha_bits); } return gs_type1_interp_init(pcis, (gs_imager_state *)pgs, pgs->path, &penum->log2_scale, &log2_subpixels, (penum->text.operation & TEXT_DO_ANY_CHARPATH) != 0 || penum->device_disabled_grid_fitting, pfont1->PaintType, pfont1); }
/* * Set up for parsing a Type 1 Charstring. * * Only uses the following elements of *pfont: * data.lenIV */ static void type1_next_init(gs_type1_state *pcis, const gs_glyph_data_t *pgd, gs_font_type1 *pfont) { gs_type1_interp_init(pcis, NULL, NULL, NULL, NULL, false, 0, pfont); pcis->flex_count = flex_max; pcis->ipstack[0].cs_data = *pgd; skip_iv(pcis); }
int gs_type1_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, int members, gs_glyph_info_t *info) { gs_font_type1 *const pfont = (gs_font_type1 *)font; gs_type1_data *const pdata = &pfont->data; int wmode = ((members & GLYPH_INFO_WIDTH1) != 0); int piece_members = members & (GLYPH_INFO_NUM_PIECES | GLYPH_INFO_PIECES); int width_members = (members & ((GLYPH_INFO_WIDTH0 << wmode) | (GLYPH_INFO_VVECTOR0 << wmode))); int default_members = members & ~(piece_members | GLYPH_INFO_WIDTHS | GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1 | GLYPH_INFO_OUTLINE_WIDTHS); int code = 0; gs_glyph_data_t gdata; if (default_members) { code = gs_default_glyph_info(font, glyph, pmat, default_members, info); if (code < 0) return code; } else info->members = 0; if (default_members == members) return code; /* all done */ gdata.memory = pfont->memory; if ((code = pdata->procs.glyph_data(pfont, glyph, &gdata)) < 0) return code; /* non-existent glyph */ if (piece_members) { code = gs_type1_glyph_pieces(pfont, &gdata, members, info); if (code < 0) return code; info->members |= piece_members; } if (width_members) { gx_path path; /* * Interpret the CharString until we get to the [h]sbw. */ gs_imager_state gis; gs_type1_state cis; int value; /* Initialize just enough of the imager state. */ if (pmat) gs_matrix_fixed_from_matrix(&gis.ctm, pmat); else { gs_matrix imat; gs_make_identity(&imat); gs_matrix_fixed_from_matrix(&gis.ctm, &imat); } gis.flatness = 0; code = gs_type1_interp_init(&cis, &gis, NULL /* no path needed */, NULL, NULL, true, 0, pfont); if (code < 0) return code; cis.no_grid_fitting = true; gx_path_init_bbox_accumulator(&path); cis.path = &path; code = pdata->interpret(&cis, &gdata, &value); switch (code) { case 0: /* done with no [h]sbw, error */ /* Adobe interpreters ignore the error! */ info->width[wmode].x = 0; info->width[wmode].y = 0; info->v.x = 0; info->v.y = 0; break; default: /* code < 0, error */ return code; case type1_result_callothersubr: /* unknown OtherSubr */ return_error(gs_error_rangecheck); /* can't handle it */ case type1_result_sbw: info->width[wmode].x = fixed2float(cis.width.x); info->width[wmode].y = fixed2float(cis.width.y); info->v.x = fixed2float(cis.lsb.x); info->v.y = fixed2float(cis.lsb.y); break; } info->members |= width_members | (GLYPH_INFO_VVECTOR0 << wmode); } gs_glyph_data_free(&gdata, "gs_type1_glyph_info"); return code; }