summaryrefslogtreecommitdiff
path: root/systems/msdos/dviware/xdvi-dos/src/font_ope.c
diff options
context:
space:
mode:
Diffstat (limited to 'systems/msdos/dviware/xdvi-dos/src/font_ope.c')
-rw-r--r--systems/msdos/dviware/xdvi-dos/src/font_ope.c887
1 files changed, 887 insertions, 0 deletions
diff --git a/systems/msdos/dviware/xdvi-dos/src/font_ope.c b/systems/msdos/dviware/xdvi-dos/src/font_ope.c
new file mode 100644
index 0000000000..78d9b412a9
--- /dev/null
+++ b/systems/msdos/dviware/xdvi-dos/src/font_ope.c
@@ -0,0 +1,887 @@
+/*
+ * font_open.c(font, font_ret, mag, mag_ret, magstepval, name)
+ * Find and open gf, pk, or pxl files in the given path, having the given
+ * name and magnification. It tries gf files first, followed by pk and pxl
+ * files. The path variable should be of the form path1:path2:...:pathn,
+ * and each of the paths will be tried successively. Strings in pathi of
+ * the form %f, %p, and %d will be replaced by the font name, "gf" or "pk"
+ * or "pxl", and the magnification, respectively. If no %f appears in a
+ * path specifier, then the string "/%f.%d%p" is added on the end. This
+ * procedure is repeated for each of the possible magnifications allowed,
+ * and if it fails then the procedure will try changing the point size
+ * as well. If all of the above fails, then alt_font will be tried.
+ *
+ * If the variable SEARCH_SUBDIRECTORIES is set, then the environment
+ * variable TEXFONTS_SUBDIR and the #define variable DEFAULT_SUBDIR_PATH
+ * will be enabled, as well as ``*'' and ``**'' specifiers. The
+ * SUBDIR_PATH things will be appended to the end of the usual path, with
+ * a `*' at the end of each component. The `*' means that subdirectories
+ * will be searched up to one level; `**' means that subdirectories
+ * will be recursively searched to any level. Neither specifier may be
+ * preceded by a `%' specifier (after the most recent colon).
+ *
+ * If the file is found, then a file pointer is returned, and the following
+ * values are set:
+ * *font_ret a pointer to a string containing the font name (if
+ * different from the font requested).
+ * *mag_ret the actual magnification found.
+ * *name a pointer to a string containing the file name
+ *
+ * If the file is not found, then the return value is NULL.
+ *
+ * Often there are so many fonts that we need to manage the number of
+ * simultaneously open files. For that reason, these routines call
+ * xfopen() instead of fopen(), which should manage the number of open
+ * font files.
+ *
+ */
+
+/*--------------------------- Msdos ---------------------------------------*/
+/* ericho */
+#ifdef __MSDOS__
+
+#define DEFAULT_FONT_PATH "/tex/fonts"
+#define DEFAULT_VF_PATH "/tex/fonts/vf"
+#define DEFAULT_FONT_SIZES "300:328.6:360:432:518.4:622:746.4"
+
+#ifdef FONTSUB
+#include <stdio.h>
+extern FILE *fontsubfile;
+extern char *subfont (FILE *,char *);
+#endif
+
+#endif
+/*--------------------------- Msdos ---------------------------------------*/
+
+#include "xdvi.h"
+#include <errno.h>
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h> /* has getenv() */
+#include <math.h> /* has atof() */
+#else
+extern char *getenv();
+#ifndef atof
+double atof();
+#endif
+#endif
+
+/*
+ * If you think you have to change DEFAULT_TAIL, then you haven't read the
+ * documentation closely enough.
+ */
+#ifndef VMS
+#define PATH_SEP ':'
+
+#ifndef __MSDOS__ /* eric ho */
+#define DEFAULT_TAIL "/%f.%d%p"
+#else
+#define DEFAULT_TAIL "/%d/%f.%p"
+#endif
+
+#define DEFAULT_VF_TAIL "/%f.vf"
+#else /* VMS */
+#define PATH_SEP '/'
+#define DEFAULT_TAIL ":%f.%d%p"
+#define DEFAULT_VF_TAIL ":%f.vf"
+#endif /* VMS */
+
+static _Xconst char *font_path;
+static _Xconst char *default_font_path = DEFAULT_FONT_PATH;
+static _Xconst char *vf_path;
+static _Xconst char *default_vf_path = DEFAULT_VF_PATH;
+#ifdef SEARCH_SUBDIRECTORIES
+static char default_subdir_path[] = DEFAULT_SUBDIR_PATH;
+#endif
+static int *sizes, *sizend;
+static char default_size_list[] = DEFAULT_FONT_SIZES;
+
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#ifdef PATH_MAX
+#define FILENAMESIZE PATH_MAX
+#endif
+#endif
+
+#ifndef FILENAMESIZE
+#define FILENAMESIZE 512
+#endif
+
+#ifdef sun
+char *sprintf();
+#endif
+
+#ifdef SEARCH_SUBDIRECTORIES
+/* We will need some system include files to deal with directories. */
+/* <sys/types.h> was included by xdvi.h. */
+
+#include <sys/stat.h>
+
+static int is_dir ();
+
+#if defined(SYSV) || defined(_POSIX_SOURCE)
+#include <dirent.h>
+typedef struct dirent *directory_entry_type;
+#else
+#include <sys/dir.h>
+typedef struct direct *directory_entry_type;
+#endif
+
+/* Declare the routine to get the current working directory. */
+
+#ifdef HAVE_GETWD
+extern char *getwd ();
+#define GETCWD(b, len) ((b) ? getwd (b) : getwd (xmalloc (len, "getwd")))
+#else
+/* POSIX says getcwd result is undefined if the pointer is NULL; at least
+ on a Convex, the result is a coredump. Hence the GETCWD macro
+ below is defined, as it works regardless of what getcwd() does
+ with a NULL pointer */
+#define GETCWD(b, len) ((b) ? getcwd (b,len) \
+ : getcwd (xmalloc (len, "getcwd"),len))
+#ifdef _POSIX_SOURCE
+#include <unistd.h> /* getcwd prototype */
+#else
+#if NeedFunctionPrototypes
+extern char *getcwd (char *, int);
+#else
+extern char *getcwd ();
+#endif /* not NeedFunctionPrototypes */
+#endif /* not _POSIX_SOURCE */
+#endif /* not HAVE_GETWD */
+
+static char *cwd;
+
+/* The following is a data structure containing the precomputed names of
+ subdirectories to be recursively searched. */
+
+static struct subdir_entry {
+ char *name; /* partial string */
+ _Xconst char *index; /* reference point in {,default_}font_path */
+ struct subdir_entry *next; /* link in list */
+}
+ *subdir_head = NULL,
+ *next_subdir;
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
+#endif
+
+
+
+/* Return true if FN is a directory or a symlink to a directory,
+ false if not. */
+
+static int
+is_dir (fn)
+ char *fn;
+{
+ struct stat stats;
+
+ return stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode);
+}
+
+/*
+ * Compute extra length of subdirectory entries, including a star for each.
+ */
+
+static int
+extra_len(str1, str2)
+ char *str1, *str2;
+{
+ int bias = 0;
+ char *p = str1;
+ char *q;
+
+ do {
+ q = index(p, PATH_SEP);
+ if (q == NULL) q = p + strlen(p);
+ if (q == p) {
+ if (str2 != NULL) {
+ bias += extra_len(str2, (char *) NULL);
+ str2 = NULL;
+ }
+ }
+ else ++bias; /* don't forget the star */
+ p = q + 1;
+ }
+ while (p[-1] != '\0');
+ return bias + p - str1;
+}
+
+/*
+ * Add the specifiers (and double stars) for the given strings (user
+ * string, plus default string) to the destination string.
+ */
+
+static void
+add_subdir_paths(dst, dst_first, src, src_default)
+ char *dst, *dst_first, *src, *src_default;
+{
+ char *q;
+
+ do {
+ q = index(src, PATH_SEP);
+ if (q == NULL) q = src + strlen(src);
+ if (q == src) {
+ if (src_default != NULL) {
+ add_subdir_paths(dst, dst_first, src_default, (char *)NULL);
+ dst += strlen(dst);
+ src_default = NULL;
+ }
+ }
+ else {
+ if (dst != dst_first) *dst++ = PATH_SEP;
+ bcopy(src, dst, q - src);
+ dst += q - src;
+ *dst++ = '*';
+ }
+ src = q + 1;
+ }
+ while (src[-1] != '\0');
+ *dst = '\0';
+}
+
+/*
+ * Make a subdirectory entry.
+ */
+
+static struct subdir_entry *
+make_subdir_entry(index, name)
+ _Xconst char *index;
+ char *name;
+{
+ struct subdir_entry *new_entry;
+ static struct subdir_entry **subdir_tail = &subdir_head;
+
+ *subdir_tail = new_entry = (struct subdir_entry *)
+ xmalloc(sizeof(struct subdir_entry), "subdirectory list entry");
+ subdir_tail = &(new_entry->next);
+ new_entry->name = strcpy(xmalloc(strlen(name) + 1,
+ "subdirectory entry string"), name);
+ new_entry->index = index;
+ new_entry->next = NULL;
+ return new_entry;
+}
+
+/*
+ * Create the subdirectory linked list for the given initial string
+ */
+
+static void
+add_subdirs(str, len, recurs)
+ _Xconst char *str;
+ int len;
+ Boolean recurs;
+{
+ int len1 = len;
+ char temp[FILENAMESIZE];
+ struct subdir_entry *next_subdir;
+ DIR *dir;
+ directory_entry_type e;
+
+ bcopy(str, temp, len);
+ if (len > 0 && temp[len - 1] != '/') temp[len1++] = '/';
+ temp[len1] = '\0';
+ next_subdir = make_subdir_entry(str, temp + len);
+ do {
+ /* By changing directories, we save a bunch of string
+ concatenations (and make the pathnames the kernel looks up
+ shorter). */
+ Strcpy(temp + len, next_subdir->name);
+ if (chdir (temp) != 0) continue;
+
+ dir = opendir (".");
+ if (dir == NULL) continue;
+
+ len1 = strlen(temp);
+ if (len1 == 0 || temp[len1 - 1] != '/') temp[len1++] = '/';
+ while ((e = readdir (dir)) != NULL) {
+ if (is_dir (e->d_name) && strcmp (e->d_name, ".") != 0
+ && strcmp (e->d_name, "..") != 0) {
+ Strcpy(temp + len1, e->d_name);
+ (void) make_subdir_entry(str, temp + len);
+ }
+ }
+ (void) closedir (dir);
+
+
+ /* Change back to the current directory, in case the path
+ contains relative directory names. */
+ if (chdir (cwd) != 0) {
+ perror (cwd);
+ exit (errno);
+ }
+ }
+ while (recurs && (next_subdir = next_subdir->next) != NULL);
+}
+
+/*
+ * Recursively figure out the subdirectory tree and precompute the
+ * list of subdirectories to search.
+ */
+
+static void
+compute_subdir_paths(fp, fp_default)
+ _Xconst char *fp;
+ _Xconst char *fp_default;
+{
+ _Xconst char *star_loc = NULL;
+ _Xconst char *endp;
+
+ do {
+ if (star_loc == NULL) {
+ star_loc = index(fp, '*');
+ if (star_loc == NULL) star_loc = fp + strlen(fp);
+ }
+ endp = index(fp, PATH_SEP);
+ if (endp == NULL) endp = fp + strlen(fp);
+ if (endp == fp) {
+ if (fp_default != NULL) {
+ compute_subdir_paths(fp_default, (char *) NULL);
+ fp_default = NULL;
+ }
+ }
+ else if (star_loc < endp) {
+ add_subdirs(fp, star_loc - fp, star_loc[1] == '*');
+ star_loc = NULL;
+ }
+ fp = endp + 1;
+ }
+ while (fp[-1] != '\0');
+}
+#endif /* SEARCH_SUBDIRECTORIES */
+
+static void
+get_sizes(size_list, spp)
+ char *size_list;
+ int **spp;
+{
+ if (*size_list == PATH_SEP) ++size_list;
+ for (;;) {
+ *(*spp)++ = atof(size_list) * 5 + 0.5;
+ size_list = index(size_list, PATH_SEP);
+ if (size_list == NULL) return;
+ ++size_list;
+ }
+}
+
+void
+init_font_open()
+{
+ char *size_list;
+ int *sp, *sp1, *sp2;
+ unsigned int n;
+ char *p;
+#ifdef SEARCH_SUBDIRECTORIES
+ char *q;
+#endif
+
+ if ((font_path = getenv("XDVIFONTS")) == NULL
+#ifndef XDVIFONTS_ONLY
+ && (font_path = getenv("PKFONTS")) == NULL
+ && (font_path = getenv("TEXFONTS")) == NULL
+#endif
+ ) {
+ font_path = default_font_path;
+ default_font_path = NULL;
+ }
+
+#ifdef SEARCH_SUBDIRECTORIES
+ p = getenv ("TEXFONTS_SUBDIR");
+ if (p == NULL) p = "";
+ q = xmalloc((unsigned) strlen(font_path)
+ + extra_len(p, default_subdir_path) + 1,
+ "initializing font searching");
+ Strcpy(q, font_path);
+ add_subdir_paths(q + strlen(q), q, p, default_subdir_path);
+ font_path = q;
+
+ /* Unfortunately, we can't look in the environment for the current
+ directory, because if we are running under a program (let's say
+ Emacs), the PWD variable might have been set by Emacs' parent
+ to the current directory at the time Emacs was invoked. This
+ is not necessarily the same directory the user expects to be
+ in. So, we must always call getcwd(3) or getwd(3), even though
+ they are slow and prone to hang in networked installations. */
+ cwd = GETCWD ((char *) NULL, FILENAMESIZE + 2);
+ if (cwd == NULL) {
+ perror ("getcwd");
+ exit (errno);
+ }
+ compute_subdir_paths(font_path, default_font_path);
+#endif
+
+ if ((vf_path = getenv("XDVIVFS")) == NULL
+#ifndef XDVIFONTS_ONLY
+ && (vf_path = getenv("VFFONTS")) == NULL
+#endif
+ ) {
+ vf_path = default_vf_path;
+ default_vf_path = NULL;
+ }
+
+ size_list = getenv("XDVISIZES");
+ n = 1; /* count number of sizes */
+ if (size_list == NULL || *size_list == PATH_SEP)
+ for (p = default_size_list; (p = index(p, PATH_SEP)) != NULL; ++p)
+ ++n;
+ if (size_list != NULL)
+ for (p = size_list; (p = index(p, PATH_SEP)) != NULL; ++p) ++n;
+ sizes = (int *) xmalloc(n * sizeof(int), "size list");
+ sizend = sizes + n;
+ sp = sizes; /* get the actual sizes */
+ if (size_list == NULL || *size_list == PATH_SEP)
+ get_sizes(default_size_list, &sp);
+ if (size_list != NULL) get_sizes(size_list, &sp);
+
+ /* bubble sort the sizes */
+ sp1 = sizend - 1; /* extent of this pass */
+ do {
+ sp2 = NULL;
+ for (sp = sizes; sp < sp1; ++sp)
+ if (*sp > sp[1]) {
+ int i = *sp;
+ *sp = sp[1];
+ sp[1] = i;
+ sp2 = sp;
+ }
+ }
+ while ((sp1 = sp2) != NULL);
+}
+
+/* eric */
+static FILE *
+formatted_open(path, font, gforpk, mag, name, first_try, tail)
+ _Xconst char *path;
+ _Xconst char *font;
+ _Xconst char *gforpk;
+ int mag;
+ char **name;
+ Boolean first_try;
+ _Xconst char *tail;
+{
+ _Xconst char *p = path;
+ char nm[FILENAMESIZE];
+ char *n = nm;
+ char c;
+ Boolean f_used = False;
+ Boolean p_used = False;
+ FILE *f;
+
+
+#ifdef SEARCH_SUBDIRECTORIES
+ if (next_subdir != NULL && next_subdir->index == p) {
+ int len = index(p, '*') - p;
+
+ bcopy(p, n, len);
+ p += len;
+ n += len;
+ Strcpy(n, next_subdir->name);
+ n += strlen(n);
+ ++p;
+ if (*p == '*') ++p;
+ if (*p != '/') *n++ = '/';
+ }
+#endif
+ for (;;) {
+ c = *p++;
+ if (c==PATH_SEP || c=='\0') {
+ if (f_used) break;
+ p = tail;
+ continue;
+ }
+ if (c=='%') {
+ c = *p++;
+ switch (c) {
+ case 'f':
+ f_used = True;
+ Strcpy(n, font);
+ break;
+ case 'p':
+ p_used = True;
+ Strcpy(n, gforpk);
+ break;
+ case 'd':
+ Sprintf(n, "%d", mag);
+ break;
+ default:
+ *n++ = c;
+ *n = '\0';
+ }
+ n += strlen(n);
+ }
+ else *n++ = c;
+ }
+ if (!p_used && !first_try) return NULL;
+ *n = '\0';
+ if (debug & DBG_OPEN) Printf("Trying font file %s\n", nm);
+
+
+ f = xfopen(nm);
+ if (f != NULL) {
+ *name = xmalloc((unsigned) (n - nm + 1), "font file name");
+ Strcpy(*name, nm);
+ }
+ return f;
+}
+
+/*
+ * Try a given size
+ */
+
+static FILE *
+try_size(font, pxlmag, name, x_font_path, x_default_font_path)
+ _Xconst char *font;
+ int pxlmag;
+ char **name;
+ _Xconst char *x_font_path;
+ _Xconst char *x_default_font_path;
+{
+ _Xconst char *p = x_font_path;
+ FILE *f;
+ int pkmag = (pxlmag + 2) / 5;
+
+#ifdef __MSDOS__
+ char *sfont, *dotptr;
+#endif
+
+ /*
+ * loop over paths
+ */
+#ifdef SEARCH_SUBDIRECTORIES
+ next_subdir = subdir_head;
+#endif
+ for (;;) {
+ if (*p == PATH_SEP || *p == '\0') {
+ if (x_default_font_path != NULL &&
+ (f = try_size(font, pxlmag, name, x_default_font_path,
+ (_Xconst char *) NULL)) != NULL)
+ return f;
+ if (*p == '\0') break;
+ }
+ else {
+
+
+
+#define FIRST_TRY True
+#ifdef USE_PK
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined(__MSDOS__) && !defined(FONTSUB)
+
+ /* I prefer this method because it'll execute a lot */
+ /* faster than looking up the font substitute file */
+
+ /* simply convert all the amXXXX font to cmXXXX */
+ dotptr = strchr (font,'a');
+ if (dotptr != (char *)NULL) {
+ *dotptr = 'c';
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+ if ((f = formatted_open(p, font, "pk", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined(__MSDOS__) && defined(FONTSUB)
+ /* look for the substitute font from file */
+ if (fontsubfile != (FILE *) NULL) {
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,(char *)font)) != (char *)NULL) {
+
+ /* try open font file again */
+ if ((f = formatted_open(p, (_Xconst char *)sfont, "pk", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#undef FIRST_TRY
+#define FIRST_TRY False
+#endif
+
+
+#ifdef USE_GF
+ if ((f = formatted_open(p, font, "gf", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined( __MSDOS__) && defined(FONTSUB)
+
+ if (fontsubfile != (FILE *) NULL) {
+ /* look for the substitute font from file */
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,font)) != (char *)NULL) {
+
+ /* try open font file again */
+ if ((f = formatted_open(p, sfont, "gf", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+
+#undef FIRST_TRY
+#define FIRST_TRY False
+#endif
+#ifdef USE_PXL
+ if ((f = formatted_open(p, font, "pxl", pxlmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+
+#if defined( __MSDOS__) && defined(FONTSUB)
+
+ if (fontsubfile != (FILE *) NULL) {
+ /* look for the substitute font from file */
+ if ((sfont = (char *)subfont((FILE *)fontsubfile,font)) != (char *)NULL) {
+ /* try open font file again */
+ if ((f = formatted_open(p, sfont, "pxl", pkmag, name, FIRST_TRY,DEFAULT_TAIL)) != NULL)
+ return f;
+ }
+ }
+#endif
+
+/* ---------------------------- MSDOS (Eric Ho) ----------------------------*/
+#endif
+
+#ifdef SEARCH_SUBDIRECTORIES
+ if (next_subdir != NULL && next_subdir->index == p) {
+ next_subdir = next_subdir->next;
+ if (next_subdir != NULL && next_subdir->index == p)
+ continue;
+ }
+#endif
+ p = index(p, PATH_SEP);
+ if (p == NULL) break;
+ }
+ ++p;
+ }
+ return NULL;
+}
+
+/*
+ * Try a virtual font
+ */
+
+static FILE *
+try_vf(font, name, x_vf_path, x_default_vf_path)
+ _Xconst char *font;
+ char **name;
+ _Xconst char *x_vf_path;
+ _Xconst char *x_default_vf_path;
+{
+ _Xconst char *p = x_vf_path;
+ FILE *f;
+
+ /*
+ * loop over paths
+ */
+ for (;;) {
+ if (*p == PATH_SEP || *p == '\0') {
+ if (x_default_vf_path != NULL &&
+ (f = try_vf(font, name, x_default_vf_path,
+ (_Xconst char *) NULL)) != NULL)
+ return f;
+ if (*p == '\0') break;
+ }
+ else {
+ if ((f = formatted_open(p, font, "vf", 0, name, True,
+ DEFAULT_VF_TAIL)) != NULL)
+ return f;
+ p = index(p, PATH_SEP);
+ if (p == NULL) break;
+ }
+ ++p;
+ }
+ return NULL;
+}
+
+#ifdef MAKEPKCMD
+#undef MAKEPK
+#define MAKEPK
+#endif
+
+#ifdef MAKEPK
+#ifndef MAKEPKCMD
+#define MAKEPKCMD "MakeTeXPK"
+#endif
+
+#define NOBUILD 29999
+#endif
+
+/*
+ * Try a given font name
+ */
+
+#ifndef MAKEPK
+#define PRE_FONT_OPEN(font, fmag, mag_ret, name, ignore) \
+ pre_font_open(font, fmag, mag_ret, name)
+#else
+#define PRE_FONT_OPEN pre_font_open
+#endif
+
+static FILE *
+PRE_FONT_OPEN(font, fmag, mag_ret, name, magstepval)
+ _Xconst char *font;
+ float fmag;
+ int *mag_ret;
+ char **name;
+#ifdef MAKEPK
+ int magstepval;
+#endif
+{
+ FILE *f;
+ int *p1, *p2;
+ int mag = 5 * fmag + 0.5;
+ int tmag;
+#ifndef VMS
+ _Xconst char *path_to_use;
+ _Xconst char *vf_path_to_use;
+#endif
+#ifdef MAKEPK
+ char mkpk[80];
+#endif
+
+ /*
+ * Loop over sizes. Try actual size first, then closest sizes.
+ If the pathname is absolutely or explicitly relative, don't
+ use the usual paths to search for it; just look for it in the
+ directory specified.
+ */
+
+#ifndef VMS
+ path_to_use = (_Xconst char *) NULL;
+ if (*font == '/') path_to_use = "/";
+ else if (*font == '.' && (*(font + 1) == '/'
+ || (*(font + 1) == '.' && *(font + 2) == '/')))
+ path_to_use = ".";
+ vf_path_to_use = path_to_use;
+ if (path_to_use == NULL) {
+ path_to_use = font_path;
+ vf_path_to_use = vf_path;
+ }
+#else /* VMS */
+#define path_to_use font_path
+#define vf_path_to_use vf_path
+#endif /* VMS */
+
+ if ((f = try_size(font, *mag_ret = mag, name, path_to_use,
+ default_font_path)) != NULL)
+ return f;
+
+ /* Try at one away from the size we just tried, to account
+ for rounding error. */
+ tmag = mag + (mag < 5 * fmag ? 1 : -1);
+ if ((f = try_size(font, tmag, name, path_to_use, default_font_path))
+ != NULL) {
+ *mag_ret = tmag;
+ return f;
+ }
+
+ /* Try a virtual font. */
+ if ((f = try_vf(font, name, vf_path_to_use, default_vf_path)) != NULL)
+ return f;
+
+#ifdef MAKEPK
+ /* Try to create the font. */
+ if (magstepval != NOBUILD) {
+ char str[24];
+ int dpi = (mag + 2) / 5;
+
+ if (magstepval == NOMAGSTP)
+ Sprintf(str, "%d+%d/%d", dpi / pixels_per_inch,
+ dpi % pixels_per_inch, pixels_per_inch);
+ else if (magstepval < 0)
+ Sprintf(str, "magstep\\(-%d%s\\)", (-magstepval) / 2,
+ magstepval % 2 ? ".5" :"");
+ else
+ Sprintf(str, "magstep\\(%d%s\\)", magstepval / 2,
+ magstepval % 2 ? ".5" :"");
+
+ Sprintf(mkpk, "%s %s %d %d %s", MAKEPKCMD, font, dpi,
+ pixels_per_inch, str);
+ Printf("- %s\n", mkpk);
+ if (system(mkpk) == 0
+ && (f = try_size(font, mag, name, path_to_use,
+ default_font_path))
+ != NULL)
+ return f;
+ }
+#endif
+
+ /* Now try at all the sizes. */
+ for (p2 = sizes; p2 < sizend; ++p2) if (*p2 >= mag) break;
+ p1 = p2;
+ for (;;) {
+ /* find another magnification */
+ if (p1 <= sizes)
+ if (p2 >= sizend) return NULL;
+ else tmag = *p2++;
+ else if (p2 >= sizend || (long) mag * mag <= (long) p1[-1] * *p2)
+ tmag = *--p1;
+ else tmag = *p2++;
+ if ((f = try_size(font, *mag_ret = tmag, name, path_to_use,
+ default_font_path)) != NULL)
+ return f;
+ }
+}
+
+/* ARGSUSED */
+FILE *
+font_open(font, font_ret, mag, mag_ret, magstepval, name)
+ _Xconst char *font;
+ char **font_ret;
+ WIDEARG(float, double) mag;
+ int *mag_ret;
+ int magstepval;
+ char **name;
+{
+ FILE *f;
+ int actual_pt, low_pt, high_pt, trial_pt;
+ char fn[50], *fnend;
+
+ f = PRE_FONT_OPEN(font, mag, mag_ret, name, magstepval);
+ if (f != NULL) {
+ *font_ret = NULL;
+ return f;
+ }
+ Strcpy(fn, font);
+ fnend = fn + strlen(fn);
+ while (fnend > fn && fnend[-1] >= '0' && fnend[-1] <= '9') --fnend;
+ actual_pt = low_pt = high_pt = atoi(fnend);
+ if (actual_pt) {
+ low_pt = actual_pt - 1;
+ high_pt = actual_pt + 1;
+ for (;;) {
+ if (2 * low_pt >= actual_pt &&
+ (low_pt * high_pt > actual_pt * actual_pt ||
+ high_pt > actual_pt + 5))
+ trial_pt = low_pt--;
+ else if (high_pt > actual_pt + 5) break;
+ else trial_pt = high_pt++;
+ Sprintf(fnend, "%d", trial_pt);
+ f = PRE_FONT_OPEN(fn, mag * actual_pt / trial_pt, mag_ret,
+ name, NOBUILD);
+ if (f != NULL) {
+ *font_ret = strcpy(xmalloc((unsigned) strlen(fn) + 1,
+ "name of font used"), fn);
+ return f;
+ }
+ }
+ }
+ if (alt_font != NULL) {
+ f = PRE_FONT_OPEN(alt_font, mag, mag_ret, name, NOBUILD);
+ if (f != NULL)
+ *font_ret = strcpy(xmalloc((unsigned) strlen(alt_font) + 1,
+ "name of font used"), alt_font);
+ }
+ return f;
+}