# fontmap.c: read a file for additional font names. # # Copyright (C) 1993, 2011 Free Software Foundation, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #include "config.h" #include "c-pathmx.h" #include "fontmap.h" /* Fontname mapping. We use a straightforward hash table. */ #define MAP_SIZE 199 /* The hash function. We go for simplicity here. */ static unsigned map_hash (key) char *key; { unsigned n = 0; /* There are very few font names which are anagrams of each other (I think), so no point in weighting the characters. */ while (*key != 0) n += *key++; n %= MAP_SIZE; return n; } /* Look up STR in MAP. Return the corresponding `value' or NULL. */ static char * map_lookup_str (map, key) map_type map; char *key; { map_element_type *p; unsigned n = map_hash (key); for (p = map[n]; p != NULL; p = p->next) if (STREQ (key, p->key)) return p->value; return NULL; } /* Look up KEY in MAP; if it's not found, remove any suffix from KEY and try again. */ char * map_lookup (map, key) map_type map; char *key; { extern string extend_filename (); string suffix = find_suffix (key); string ret = map_lookup_str (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 = map_lookup_str (map, base_key); free (base_key); } } /* Append the same suffix we took off, if necessary. */ if (ret && suffix) ret = extend_filename (ret, suffix); return ret; } /* If KEY is not already in MAP, insert it and VALUE. */ static void map_insert (map, key, value) map_type map; char *key; char *value; { unsigned n = map_hash (key); map_element_type **p = &map[n]; map_element_type ***trailer = &p; while (*p != NULL && !STREQ (key, (*p)->key)) { *p = (*p)->next; trailer = &p; } if (*p == NULL) { **trailer = XTALLOC (MAP_SIZE, map_element_type); (**trailer)->key = xstrdup (key); (**trailer)->value = xstrdup (value); (**trailer)->next = NULL; } } /* Open and read the mapping file 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; unfortunately, we can't have TeX read that same file, since most of the real filenames start with an `r', because of the virtual fonts Dvips uses. */ static void map_file_parse (map, map_filename) map_type map; char *map_filename; { extern FILE *xfopen (); /* In xfopen.c. */ extern char *read_line (); /* In line.c. */ char *l; unsigned map_lineno = 0; FILE *f = xfopen (map_filename, FOPEN_R_MODE); while ((l = read_line (f)) != NULL) { string filename; string comment_loc = strrchr (l, '%'); map_lineno++; /* Ignore anything after a %. */ if (comment_loc) *comment_loc = 0; /* If we don't have any filename, that's ok, the line is blank. */ filename = strtok (l, " \t"); if (filename) { string alias = strtok (NULL, " \t"); /* But if we have a filename and no alias, something's wrong. */ if (alias == NULL || *alias == 0) fprintf (stderr, "%s:%u: Alias missing for filename `%s'.\n", map_filename, map_lineno, filename); else { /* We've got everything. Insert the new entry. */ map_insert (map, alias, filename); } } free (l); } xfclose (f, map_filename); } /* Look for the file `texfonts.map' in each of the directories in DIR_LIST. Entries in earlier files override later files. */ map_type map_create (dir_list) string *dir_list; { map_type map = (map_type) xcalloc (MAP_SIZE, sizeof (map_element_type *)); while (*dir_list) { char filename[PATH_MAX]; /* We don't bother with the filename truncation that `readable' in `pathsrch.c' does, since we ourselves are giving the filename, and I don't think it's worth worrying about too-long intermediate directory names in the path. */ strcpy (filename, *dir_list); strcat (filename, "texfonts.map"); if (access (filename, R_OK) == 0) map_file_parse (map, filename); dir_list++; } return map; }