rem: if (!automatic) printf("%s", sa.c_str());
context: do_file(const String &input_filename, const OpenType::Font &otf,	const DvipsEncoding &dvipsenc_in, bool dvipsenc_literal,	ErrorHandler *errh){    Cff cff(otf.table("CFF"), errh);    if (!cff.ok())	return;    Cff::Font font(&cff, PermString(), errh);    if (!font.ok())	return;    Vector<PermString> glyph_names;    font.glyph_names(glyph_names);    OpenType::debug_glyph_names = glyph_names;    // set typeface name from font family name    {	String typeface = font.dict_string(Cff::oFamilyName);	// make it reasonable for the shell	StringAccum sa;	for (int i = 0; i < typeface.length(); i++)	    if (isalnum(typeface[i]) || typeface[i] == '_' || typeface[i] == '-' || typeface[i] == '.' || typeface[i] == ',' || typeface[i] == '+')		sa << typeface[i];	set_typeface(sa.length() ? sa.take_string() : font_name, false);    }    // prepare encoding    DvipsEncoding dvipsenc;    if (dvipsenc_in)	dvipsenc = dvipsenc_in;    else if (Type1Encoding *t1e = font.type1_encoding()) {	for (int i = 0; i < 256; i++)	    dvipsenc.encode(i, (*t1e)[i]);    }        // initialize encoding    GsubEncoding encoding;    OpenType::Cmap cmap(otf.table("cmap"), errh);    assert(cmap.ok());    if (dvipsenc_literal)	dvipsenc.make_literal_gsub_encoding(encoding, &font);    else	dvipsenc.make_gsub_encoding(encoding, cmap, &font);        // maintain statistics about features    HashMap<uint32_t, int> feature_usage(0);        // apply activated GSUB features    OpenType::Gsub gsub(otf.table("GSUB"), errh);    Vector<Lookup> lookups(gsub.nlookups(), Lookup());    find_lookups(gsub.script_list(), gsub.feature_list(), lookups, errh);    Vector<OpenType::Substitution> subs;    for (int i = 0; i < lookups.size(); i++)	if (lookups[i].used) {	    OpenType::GsubLookup l = gsub.lookup(i);	    bool understood = l.unparse_automatics(gsub, subs);	    int nunderstood = 0;	    for (int j = 0; j < subs.size(); j++)		nunderstood += encoding.apply(subs[j], !dvipsenc_literal);	    encoding.apply_substitutions();	    // mark as used	    int d = (understood && nunderstood == subs.size() ? F_GSUB_ALL : (nunderstood ? F_GSUB_PART : 0)) + F_GSUB_TRY;	    for (int j = 0; j < lookups[i].features.size(); j++)		feature_usage.find_force(lookups[i].features[j].value()) |= d;	}    encoding.simplify_ligatures(false);        if (dvipsenc_literal)	encoding.cut_encoding(256);    else	encoding.shrink_encoding(256, dvipsenc_in, glyph_names, errh);        // apply activated GPOS features    OpenType::Gpos gpos(otf.table("GPOS"), errh);    lookups.assign(gpos.nlookups(), Lookup());    find_lookups(gpos.script_list(), gpos.feature_list(), lookups, errh);    Vector<OpenType::Positioning> poss;    for (int i = 0; i < lookups.size(); i++)	if (lookups[i].used) {	    OpenType::GposLookup l = gpos.lookup(i);	    bool understood = l.unparse_automatics(poss);	    int nunderstood = 0;	    for (int j = 0; j < poss.size(); j++)		nunderstood += encoding.apply(poss[j]);	    // mark as used	    int d = (understood && nunderstood == poss.size() ? F_GPOS_ALL : (nunderstood ? F_GPOS_PART : 0)) + F_GPOS_TRY;	    for (int j = 0; j < lookups[i].features.size(); j++)		feature_usage.find_force(lookups[i].features[j].value()) |= d;	}    encoding.simplify_kerns();    // apply LIGKERN commands to the result    dvipsenc.apply_ligkern(encoding, errh);    // report unused and underused features if any    report_underused_features(feature_usage, errh);    // figure out our FONTNAME    if (!font_name) {	// derive font name from OpenType font name	font_name = font.font_name();	if (encoding_file) {	    int slash = encoding_file.find_right('/') + 1;	    int dot = encoding_file.find_right('.');	    if (dot < slash)	// includes dot < 0 case		dot = encoding_file.length();	    font_name += String("--") + encoding_file.substring(slash, dot - slash);	}	if (interesting_scripts.size() != 2 || interesting_scripts[0] != OpenType::Tag("latn") || interesting_scripts[1].valid())	    for (int i = 0; i < interesting_scripts.size(); i += 2) {		font_name += String("--S") + interesting_scripts[i].text();		if (interesting_scripts[i+1].valid())		    font_name += String(".") + interesting_scripts[i+1].text();	    }	for (int i = 0; i < interesting_features.size(); i++)	    if (feature_usage[interesting_features[i].value()])		font_name += String("--F") + interesting_features[i].text();    }        // output encoding    if (dvipsenc_literal) {	out_encoding_name = dvipsenc_in.name();	out_encoding_file = dvipsenc_in.filename();    } else	output_encoding(encoding, glyph_names, errh);    // check whether virtual metrics are necessary    String metrics_suffix;    if (encoding.need_virtual())	metrics_suffix = "--base";    else	output_flags &= ~G_VMETRICS;        // output metrics    if (!(output_flags & G_METRICS))	/* do nothing */;    else if (output_flags & G_BINARY) {	String fn = getodir(O_TFM, errh) + "/" + font_name + metrics_suffix + ".tfm";	write_tfm(&font, cmap, encoding, glyph_names, fn, String(), errh);    } else {	String outfile = getodir(O_PL, errh) + "/" + font_name + metrics_suffix + ".pl";	output_pl(&font, cmap, encoding, glyph_names, false, outfile, errh);	update_odir(O_PL, outfile, errh);    }    // output virtual metrics    if (!(output_flags & G_VMETRICS))	/* do nothing */;    else if (output_flags & G_BINARY) {	String tfm = getodir(O_TFM, errh) + "/" + font_name + ".tfm";	String vf = getodir(O_VF, errh) + "/" + font_name + ".vf";	write_tfm(&font, cmap, encoding, glyph_names, tfm, vf, errh);    } else {	String outfile = getodir(O_VPL, errh) + "/" + font_name + ".vpl";	output_pl(&font, cmap, encoding, glyph_names, true, outfile, errh);	update_odir(O_VPL, outfile, errh);    }    // print DVIPS map line    if (!stdout_used && errh->nerrors() == 0) {	StringAccum sa;	sa << font_name << metrics_suffix << ' ' << font.font_name() << " \"";	if (extend)	    sa << extend << " ExtendFont ";	if (slant)	    sa << slant << " SlantFont ";	sa << out_encoding_name << " ReEncodeFont\" <[" << out_encoding_file;	if (String fn = installed_type1(input_filename, font.font_name(), (output_flags & G_TYPE1), errh))	    sa << " <" << fn;	sa << '\n';	if (!automatic)	    printf("%s", sa.c_str());	update_autofont_map(font_name + metrics_suffix, sa.take_string(), errh);    }}