home *** CD-ROM | disk | FTP | other *** search
- /* fontmap.c: read a file for additional font names.
-
- Copyright (C) 1993 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 2, 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "config.h"
-
- #include "c-pathmx.h"
- #include "fontmap.h"
-
- #ifdef RISCOS
- extern boolean riscos_readable(string name);
- #endif
-
- /* 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)
- 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");
-
- #ifdef RISCOS
- if (riscos_readaccess(filename))
- #else
- if (access (filename, R_OK) == 0)
- #endif
- map_file_parse (map, filename);
-
- dir_list++;
- }
- return map;
- }
-