From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- dviware/dvipage/findfile.c | 503 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 503 insertions(+) create mode 100644 dviware/dvipage/findfile.c (limited to 'dviware/dvipage/findfile.c') diff --git a/dviware/dvipage/findfile.c b/dviware/dvipage/findfile.c new file mode 100644 index 0000000000..21d85cd4e1 --- /dev/null +++ b/dviware/dvipage/findfile.c @@ -0,0 +1,503 @@ +/* + * dvipage: DVI Previewer Program for Suns + * + * Neil Hunt (hunt@spar.slb.com) + * + * Copyright (c) 1988 Schlumberger Technologies, Inc 1988. + * Anyone can use this software in any manner they choose, + * including modification and redistribution, provided they make + * no charge for it, and these conditions remain unchanged. + * + * This program is distributed as is, with all faults (if any), and + * without any warranty. No author or distributor accepts responsibility + * to anyone for the consequences of using it, or for whether it serves any + * particular purpose at all, or any other reason. + * + * $Log: findfile.c,v $ + * Revision 1.1 88/11/28 18:40:44 hunt + * Initial revision + * + * Based upon `mitdrivers/findfile.c' + * Copyright 1985 Massachusetts Institute of Technology + */ + +#include +#include +#include +#include +#include /* For MAXPATHLEN */ +#include +#include "dvipage.h" + +forward bool find_file_in_path(); +forward bool find_best_file_in_path(); +forward bool scandir(); +forward bool scanpdir(); +forward int strdiff(); + + +/* + * find_file: + * Seaches for a font file in various places. + * dirpath is a colon separated list of possible pathnames. + * Returns TRUE if a usable file was found. + */ + +bool find_font_file(dir_path, fontptr) +char *dir_path; +struct font_entry *fontptr; +{ + int min_df, min_dp, min_dm; + + if(verbose & DEBUG_FONTS) + fprintf(stderr, "find_font_file(%s .%dgf or .%dpxl)\n", + fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag); + + /* + * Search for exact match. + */ + if(find_file_in_path(dir_path, fontptr)) + return TRUE; + + /* + * Search for nearest match. + */ + min_df = min_dp = min_dm = MAXINT; + if(find_best_file_in_path(dir_path, fontptr, + &min_df, &min_dp, &min_dm)) + { + message("Substituted font %s for %s.%d.", + fontptr->name, fontptr->n, fontptr->type == TYPE_PXL ? + fontptr->font_pxl_mag : fontptr->font_gf_mag); + return TRUE; + } + + return FALSE; +} + +/* + * find_file_in_path: + * Searches path for a font file. + * Returns TRUE if a suitable match has been found. + */ + +bool +find_file_in_path(dirpath, fontptr) +char *dirpath; +struct font_entry *fontptr; +{ + char *p; + char dir[MAXPATHLEN]; + + while(*dirpath) + { + /* + * Copy first/next path prefix to dir[]. + * Skip over the ':'. + */ + for(p = dir; *dirpath; ) + { + if(*dirpath == ':' || *dirpath == ';') + { + dirpath++; + break; + } + else + *p++ = *dirpath++; + } + *p = '\0'; + + if(use_pk) + { + /* + * Try flat structure. + */ + sprintf(fontptr->name, "%s/%s.%dpk", + dir, fontptr->n, fontptr->font_gf_mag); + if(access(fontptr->name, R_OK) == 0) + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; OK\n", + fontptr->name); + fontptr->type = TYPE_PK; + return TRUE; + } + else + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; No\n", + fontptr->name); + } + + /* + * Try hierarchical structure. + */ + sprintf(fontptr->name, "%s/%s/%s.%dpk", + dir, fontptr->n, fontptr->n, fontptr->font_gf_mag); + if(access(fontptr->name, R_OK) == 0) + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; OK\n", + fontptr->name); + fontptr->type = TYPE_PK; + return TRUE; + } + else + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; No\n", + fontptr->name); + } + } + + if(use_gf) + { + /* + * Try flat structure. + */ + sprintf(fontptr->name, "%s/%s.%dgf", + dir, fontptr->n, fontptr->font_gf_mag); + if(access(fontptr->name, R_OK) == 0) + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; OK\n", + fontptr->name); + fontptr->type = TYPE_GF; + return TRUE; + } + else + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; No\n", + fontptr->name); + } + + /* + * Try hierarchical structure. + */ + sprintf(fontptr->name, "%s/%s/%s.%dgf", + dir, fontptr->n, fontptr->n, fontptr->font_gf_mag); + if(access(fontptr->name, R_OK) == 0) + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; OK\n", + fontptr->name); + fontptr->type = TYPE_GF; + return TRUE; + } + else + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; No\n", + fontptr->name); + } + } + + if(use_pxl) + { + /* + * Try flat structure. + */ + sprintf(fontptr->name, "%s/%s.%dpxl", + dir, fontptr->n, fontptr->font_pxl_mag); + if(access(fontptr->name, R_OK) == 0) + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; OK\n", + fontptr->name); + fontptr->type = TYPE_PXL; + return TRUE; + } + else + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; No\n", + fontptr->name); + } + + /* + * Try hierarchical structure. + */ + sprintf(fontptr->name, "%s/%s/%s.%dpxl", + dir, fontptr->n, fontptr->n, fontptr->font_pxl_mag); + if(access(fontptr->name, R_OK) == 0) + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; OK\n", + fontptr->name); + fontptr->type = TYPE_PXL; + return TRUE; + } + else + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; No\n", + fontptr->name); + } + } + } + + return FALSE; +} + +/* + * find_best_file_in_path: + * Finds the best match to the desired font. + * Returns TRUE if a suitable match is found. + */ + +bool +find_best_file_in_path(dirpath, fontptr, p_min_df, p_min_dp, p_min_dm) +char *dirpath; +struct font_entry *fontptr; +int *p_min_df, *p_min_dp, *p_min_dm; +{ + register char *p; + char dir[MAXPATHLEN]; + bool status = FALSE; + + if(verbose & DEBUG_FONTS) + fprintf(stderr, "find_best_font_file(%s .%dgf or %dpxl)\n", + fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag); + + /* + * Scan over directories in dirpath. + */ + while(*dirpath) + { + /* + * Copy first/next path prefix to dir[]. + * Skip over the ':'. + */ + for(p = dir; *dirpath != '\0'; ) + { + if(*dirpath == ':' || *dirpath == ';') + { + dirpath++; + break; + } + else + *p++ = *dirpath++; + } + *p = '\0'; + + /* + * Scan the directory. + */ + if(scanpdir(dir, fontptr, p_min_df, p_min_dp, p_min_dm)) + status = TRUE; + + /* + * Scan any subdirectories. + */ + if(scandir(dir, fontptr, p_min_df, p_min_dp, p_min_dm)) + status = TRUE; + } + + return status; +} + +/* + * scandir: + * Scan directory looking for plausible names, + * then recurse to subdirectories for plausible point sizes. + * Returns TRUE if found a more plausible candidate than previous best. + */ + +bool +scandir(dir, fontptr, p_min_df, p_min_dp, p_min_dm) +char *dir; +struct font_entry *fontptr; +int *p_min_df, *p_min_dp, *p_min_dm; +{ + DIR *dirstream; + struct direct *dirrecord; + char pdir[MAXPATHLEN]; + bool status = FALSE; + + if(verbose & DEBUG_FONTS) + fprintf(stderr, " scandir(%s .%dgf or .%dpxl)\n", + fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag); + + if(! (dirstream = opendir(dir))) + return FALSE; + + while(dirrecord = readdir(dirstream)) + { + if(dirrecord->d_name[0] != '.') + continue; + + if(strdiff(fontptr->n, dirrecord->d_name) <= *p_min_df) + { + sprintf(pdir, "%s/%s", dir, dirrecord->d_name); + + if(scanpdir(pdir, fontptr, + p_min_df, p_min_dp, p_min_dm)) + status = TRUE; + } + } + + closedir(dirstream); + + return status; +} + +/* + * scanpdir: + * Scan directory looking for plausible names and point sizes. + * Returns TRUE if found a more plausible candidate than previous best. + */ + +bool +scanpdir(dir, fontptr, p_min_df, p_min_dp, p_min_dm) +char *dir; +struct font_entry *fontptr; +int *p_min_df, *p_min_dp, *p_min_dm; +{ + DIR *dirstream; + struct direct *dirrecord; + char qfamily[MAXPATHLEN]; + char qtype[MAXPATHLEN]; + int qpoint, qmag, df, dp, dm; + bool status = FALSE; + char family[MAXPATHLEN]; + int point; + + if(verbose & DEBUG_FONTS) + fprintf(stderr, " scanpdir(%s .%dgf or .%dpxl)\n", + fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag); + + /* + * Split out family name, point size and magnification. + */ + if(sscanf(fontptr->n, "%[^0123456789.]%d", family, &point) != 2) + { + message("Font name \"%s\" appears garbled.", fontptr->n); + return FALSE; + } + + if(! (dirstream = opendir(dir))) + return FALSE; + + while(dirrecord = readdir(dirstream)) + { + if(sscanf(dirrecord->d_name, "%[^0123456789.]%d.%d%s", + qfamily, &qpoint, &qmag, qtype) != 4) + continue; + + /* + * Is this a GF file. + */ + if(use_gf && strcmp(qtype, "gf") == 0) + { + df = strdiff(family, qfamily); + dp = abs(point - qpoint); + dm = abs(fontptr->font_gf_mag - qmag); + if((df < *p_min_df) || + (df == *p_min_df && dp < *p_min_dp) || + (df == *p_min_df && dp == *p_min_dp && + dm < *p_min_dm)) + { + *p_min_df = df; + *p_min_dp = dp; + *p_min_dm = dm; + + sprintf(fontptr->name, "%s/%s", + dir, dirrecord->d_name); + fontptr->type = TYPE_GF; + + if(verbose & DEBUG_FONTS) + fprintf(stderr, + " New best match (%d %d %d) is %s\n", + df, dp, dm, fontptr->name); + + status = TRUE; + } + } + + /* + * Is this a PXL file. + */ + if(use_pxl && strcmp(qtype, "pxl") == 0) + { + df = strdiff(family, qfamily); + dp = abs(point - qpoint); + dm = abs(fontptr->font_pxl_mag - qmag); + if((df < *p_min_df) || + (df == *p_min_df && dp < *p_min_dp) || + (df == *p_min_df && dp == *p_min_dp && + dm < *p_min_dm)) + { + *p_min_df = df; + *p_min_dp = dp; + *p_min_dm = dm; + + sprintf(fontptr->name, "%s/%s", + dir, dirrecord->d_name); + fontptr->type = TYPE_PXL; + + if(verbose & DEBUG_FONTS) + fprintf(stderr, + " New best match (%d %d %d) is %s\n", + df, dp, dm, fontptr->name); + + status = TRUE; + } + } + + /* + * Is this a PK file. + */ + if(use_pk && strcmp(qtype, "pk") == 0) + { + df = strdiff(family, qfamily); + dp = abs(point - qpoint); + dm = abs(fontptr->font_gf_mag - qmag); + if((df < *p_min_df) || + (df == *p_min_df && dp < *p_min_dp) || + (df == *p_min_df && dp == *p_min_dp && + dm < *p_min_dm)) + { + *p_min_df = df; + *p_min_dp = dp; + *p_min_dm = dm; + + sprintf(fontptr->name, "%s/%s", + dir, dirrecord->d_name); + fontptr->type = TYPE_PK; + + if(verbose & DEBUG_FONTS) + fprintf(stderr, + " New best match (%d %d %d) is %s\n", + df, dp, dm, fontptr->name); + + status = TRUE; + } + } + } + + closedir(dirstream); + + return status; +} + +/* + * strdiff: + * Quantify differences in font names. + */ + +int +strdiff(s1, s2) +char *s1, *s2; +{ + register int diff = 0; + + while(*s1 && *s2) + diff += abs(*s1++ - *s2++); + while(*s1) + diff += *s1++; + while(*s2) + diff += *s2++; + + return diff; +} -- cgit v1.2.3