diff options
Diffstat (limited to 'Build/source/texk/kpathsea/fontmap.c')
-rw-r--r-- | Build/source/texk/kpathsea/fontmap.c | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/Build/source/texk/kpathsea/fontmap.c b/Build/source/texk/kpathsea/fontmap.c new file mode 100644 index 00000000000..8c2777404ad --- /dev/null +++ b/Build/source/texk/kpathsea/fontmap.c @@ -0,0 +1,200 @@ +/* fontmap.c: read files for additional font names. + + Copyright 2001, 2002, 2005 Olaf Weber. + Copyright 1993, 94, 95, 96, 97 Karl Berry. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include <kpathsea/config.h> + +#include <kpathsea/c-ctype.h> +#include <kpathsea/c-fopen.h> +#include <kpathsea/fontmap.h> +#include <kpathsea/hash.h> +#include <kpathsea/line.h> +#include <kpathsea/pathsearch.h> +#include <kpathsea/str-list.h> +#include <kpathsea/tex-file.h> + +/* We have one and only one fontmap, so may as well make it static + instead of passing it around. */ +static hash_table_type map; +#ifndef MAP_NAME +#define MAP_NAME "texfonts.map" +#endif +#ifndef MAP_HASH_SIZE +#define MAP_HASH_SIZE 4001 +#endif + +static const_string map_path; /* Only want to create this once. */ + +/* Return next whitespace-delimited token in STR or NULL if none. */ + +static string +token P1C(const_string, str) +{ + unsigned len; + const_string start; + string ret; + + while (*str && ISSPACE (*str)) + str++; + + start = str; + while (*str && !ISSPACE (*str)) + str++; + + len = str - start; + ret = (string)xmalloc (len + 1); + strncpy (ret, start, len); + ret[len] = 0; + + return ret; +} + +/* Open and read the mapping file MAP_FILENAME, putting its entries into + MAP. Comments begin with % and continue to the end of the line. Each + line of the file defines an entry: the first word is the real + filename (e.g., `ptmr'), the second word is the alias (e.g., + `Times-Roman'), and any subsequent words are ignored. .tfm is added + if either the filename or the alias have no extension. This is the + same order as in Dvips' psfonts.map. Perhaps someday the programs + will both read the same file. */ + +static void +map_file_parse P1C(const_string, map_filename) +{ + char *orig_l; + unsigned map_lineno = 0; + FILE *f = xfopen (map_filename, FOPEN_R_MODE); + + while ((orig_l = read_line (f)) != NULL) { + string filename; + string l = orig_l; + string comment_loc = strrchr (l, '%'); + if (!comment_loc) { + comment_loc = strstr (l, "@c"); + } + + /* Ignore anything after a % or @c. */ + if (comment_loc) + *comment_loc = 0; + + map_lineno++; + + /* Skip leading whitespace so we can use strlen below. Can't use + strtok since this routine is recursive. */ + while (*l && ISSPACE (*l)) + l++; + + /* If we don't have any filename, that's ok, the line is blank. */ + filename = token (l); + if (filename) { + string alias = token (l + strlen (filename)); + + if (STREQ (filename, "include")) { + if (alias == NULL) { + WARNING2 ("%s:%u: Filename argument for include directive missing", + map_filename, map_lineno); + } else { + string include_fname = kpse_path_search (map_path, alias, false); + if (include_fname) { + map_file_parse (include_fname); + if (include_fname != alias) + free (include_fname); + } else { + WARNING3 ("%s:%u: Can't find fontname include file `%s'", + map_filename, map_lineno, alias); + } + free (alias); + free (filename); + } + + /* But if we have a filename and no alias, something's wrong. */ + } else if (alias == NULL) { + WARNING3 ("%s:%u: Fontname alias missing for filename `%s'", + map_filename, map_lineno, filename); + free (filename); + + } else { + /* We've got everything. Insert the new entry. They were + already dynamically allocated, so don't bother with xstrdup. */ + hash_insert_normalized (&map, alias, filename); + } + } + + free (l); + } + + xfclose (f, map_filename); +} + +/* Parse the file MAP_NAME in each of the directories in PATH and + return the resulting structure. Entries in earlier files override + later files. */ + +static void +read_all_maps P1H(void) +{ + string *filenames; + + map_path = kpse_init_format (kpse_fontmap_format); + filenames = kpse_all_path_search (map_path, MAP_NAME); + + map = hash_create (MAP_HASH_SIZE); + + while (*filenames) { + map_file_parse (*filenames); + filenames++; + } +} + +/* Look up KEY in texfonts.map's; if it's not found, remove any suffix + from KEY and try again. Create the map if necessary. */ + +string * +kpse_fontmap_lookup P1C(const_string, key) +{ + string *ret; + string suffix = find_suffix (key); + + if (map.size == 0) { + read_all_maps (); + } + + ret = hash_lookup (map, key); + if (!ret) { + /* OK, the original KEY didn't work. Let's check for the KEY without + an extension -- perhaps they gave foobar.tfm, but the mapping only + defines `foobar'. */ + if (suffix) { + string base_key = remove_suffix (key); + ret = hash_lookup (map, base_key); + free (base_key); + } + } + + /* Append any original suffix. */ + if (ret && suffix) { + string *elt; + for (elt = ret; *elt; elt++) { + *elt = extend_filename (*elt, suffix); + } + } + + return ret; +} |