static string try_fontmap P4C(string *, fontname_ptr, unsigned, dpi, kpse_file_format_type, format, kpse_glyph_file_type *, glyph_file) { string *mapped_names; string fontname = *fontname_ptr; string ret = NULL; mapped_names = kpse_fontmap_lookup (fontname); if (mapped_names) { string mapped_name; string first_name = *mapped_names; while (!ret && (mapped_name = *mapped_names++)) { xputenv ("KPATHSEA_NAME", mapped_name); ret = try_resolution (mapped_name, dpi, format, glyph_file); } if (ret) { /* If some alias succeeeded, return that alias. */ *fontname_ptr = xstrdup (mapped_name); /* Return first alias name, unless that itself is an alias, in which case do nothing. */ } else if (!kpse_fontmap_lookup (first_name)) { *fontname_ptr = xstrdup (first_name); } } return ret; }
static string try_fontmap P4C(const_string, font_name, unsigned, dpi, string *, glyph_paths, kpse_font_file_type *, font_file) { static hash_table_type fontmap; string *mapped_names; string ret = NULL; if (fontmap.size == 0) { /* If we wanted to complicate our lives, we could handle separate maps for GF and PK ones. I don't see that this has any practical utility, though, because if someone wants an alias, most likely the alias should apply to non-glyphs as well as glyphs (let alone to only GF format or PK format). */ const_string map_path = KPSE_GLYPH_PATH (); fontmap = map_create (map_path); } mapped_names = map_lookup (fontmap, font_name); if (mapped_names) { string mapped_name; while ((mapped_name = *mapped_names++) && !ret) { xputenv ("KPATHSEA_NAME", mapped_name); ret = try_resolution (mapped_name, dpi, glyph_paths, font_file); } } return ret; }
string kpse_find_glyph P4C(const_string, passed_fontname, unsigned, dpi, kpse_file_format_type, format, kpse_glyph_file_type *, glyph_file) { string ret; kpse_glyph_source_type source; string fontname = (string) passed_fontname; /* discard const */ /* Start the search: try the name we're given. */ source = kpse_glyph_source_normal; xputenv ("KPATHSEA_NAME", fontname); ret = try_resolution (fontname, dpi, format, glyph_file); /* Try all the various possibilities in order of preference. */ if (!ret) { /* Maybe FONTNAME was an alias. */ source = kpse_glyph_source_alias; ret = try_fontmap (&fontname, dpi, format, glyph_file); /* If not an alias, try creating it on the fly with mktexpk, unless FONTNAME is absolute or explicitly relative. */ if (!ret && !kpse_absolute_p (fontname, true)) { source = kpse_glyph_source_maketex; /* `try_resolution' leaves the envvar set randomly. */ xputenv_int ("KPATHSEA_DPI", dpi); ret = kpse_make_tex (format, fontname); } /* If mktex... succeeded, set return struct. Doesn't make sense for `kpse_make_tex' to set it, since it can only succeed or fail, unlike the other routines. */ if (ret) { KPSE_GLYPH_FILE_DPI (*glyph_file) = dpi; KPSE_GLYPH_FILE_NAME (*glyph_file) = fontname; } /* If mktex... failed, try any fallback resolutions. */ else { if (kpse_fallback_resolutions) ret = try_fallback_resolutions (fontname, dpi, format, glyph_file); /* We're down to the font of last resort. */ if (!ret && kpse_fallback_font) { const_string name = kpse_fallback_font; source = kpse_glyph_source_fallback; xputenv ("KPATHSEA_NAME", name); /* As before, first try it at the given size. */ ret = try_resolution (name, dpi, format, glyph_file); /* The fallback font at the fallback resolutions. */ if (!ret && kpse_fallback_resolutions) ret = try_fallback_resolutions (name, dpi, format, glyph_file); } } } /* If RET is null, then the caller is not supposed to look at GLYPH_FILE, so it doesn't matter if we assign something incorrect. */ KPSE_GLYPH_FILE_SOURCE (*glyph_file) = source; /* FIXME: fontname may have been allocated, but (worse) it may also have been assigned to struct that's passed out of this function. if (fontname != passed_fontname) free (fontname); */ return ret; }
static string try_fallback_resolutions P4C(const_string, fontname, unsigned, dpi, kpse_file_format_type, format, kpse_glyph_file_type *, glyph_file) { unsigned s; int loc, max_loc; int lower_loc, upper_loc; unsigned lower_diff, upper_diff; unsigned closest_diff = UINT_MAX; string ret = NULL; /* In case the only fallback resolution is DPI. */ /* First find the fallback size closest to DPI, even including DPI. */ for (s = 0; kpse_fallback_resolutions[s] != 0; s++) { unsigned this_diff = abs (kpse_fallback_resolutions[s] - dpi); if (this_diff < closest_diff) { closest_diff = this_diff; loc = s; } } if (s == 0) return ret; /* If nothing in list, quit now. */ max_loc = s; lower_loc = loc - 1; upper_loc = loc + 1; for (;;) { unsigned fallback = kpse_fallback_resolutions[loc]; /* Don't bother to try DPI itself again. */ if (fallback != dpi) { ret = try_resolution (fontname, fallback, format, glyph_file); if (ret) break; } /* That didn't work. How far away are the locs above or below? */ lower_diff = lower_loc > -1 ? dpi - kpse_fallback_resolutions[lower_loc] : INT_MAX; upper_diff = upper_loc < max_loc ? kpse_fallback_resolutions[upper_loc] - dpi : INT_MAX; /* But if we're at the end in both directions, quit. */ if (lower_diff == INT_MAX && upper_diff == INT_MAX) break; /* Go in whichever direction is closest. */ if (lower_diff < upper_diff) { loc = lower_loc; lower_loc--; } else { loc = upper_loc; upper_loc++; } } return ret; }
string kpse_find_glyph_format P4C(const_string, font_name, unsigned, dpi, kpse_file_format_type, format, kpse_font_file_type *, font_file) { string glyph_paths[kpse_any_glyph_format]; string ret; kpse_source_type source; /* Initialize the path strings for the glyph formats we will try. */ glyph_paths[kpse_gf_format] = format == kpse_any_glyph_format || format == kpse_gf_format ? KPSE_GF_PATH () : NULL; glyph_paths[kpse_pk_format] = format == kpse_any_glyph_format || format == kpse_pk_format ? KPSE_PK_PATH () : NULL; /* Start the search: try the name we're given. */ source = kpse_source_normal; xputenv ("KPATHSEA_NAME", font_name); ret = try_resolution (font_name, dpi, glyph_paths, font_file); /* Sorry for the spaghetti logic. How to improve? */ if (!ret) { /* Maybe FONT_NAME was an alias. */ source = kpse_source_alias; ret = try_fontmap (font_name, dpi, glyph_paths, font_file); /* OK, maybe we can create it on the fly with MakeTeXPK. */ if (!ret) { source = kpse_source_maketex; /* `try_resolution' leaves the envvar set randomly. */ xputenv_int ("KPATHSEA_DPI", dpi); ret = kpse_make_tex (format, font_name); } /* If MakeTeX... succeeded, set return struct. (Doesn't make sense for `kpse_make_tex' to set it, since it can only succeed or fail, unlike the other routines.) */ if (ret) { KPSE_FONT_FILE_DPI (*font_file) = dpi; /* Discarding const here. */ KPSE_FONT_FILE_NAME (*font_file) = (string) font_name; } /* If MakeTeX... failed, try any fallback resolutions. */ else { if (kpse_fallback_resolutions) ret = try_fallback_resolutions (font_name, dpi, glyph_paths, font_file); /* We're down to the font of last resort. */ if (!ret && kpse_fallback_font) { /* As before, first try it at the given size. */ source = kpse_source_fallback; xputenv ("KPATHSEA_NAME", kpse_fallback_font); ret = try_resolution (kpse_fallback_font, dpi, glyph_paths, font_file); /* The fallback font at the fallback resolutions. */ if (!ret && kpse_fallback_resolutions) ret = try_fallback_resolutions (kpse_fallback_font, dpi, glyph_paths, font_file); } } } /* If RET is null, then the caller must not look at FONT_FILE, so it doesn't matter if we assign something incorrect to it. */ KPSE_FONT_FILE_SOURCE (*font_file) = source; return ret; }