|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 7928 (0x1ef8) Types: TextFile Names: »pxl_open.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/crt-viewers/X/xdvi/pxl_open.c«
/* * pxl_open.c(font, font_ret, mag, mag_ret, factor, name, read_font_index) * 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 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. * *factor the ratio of the point sizes of the requested font * and the font actually found (or 1.0 if altfont is used). * *name a pointer to a string containing the file name * *read_font_index a pointer to the read_index procedure to be * used for the given font format. * * 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. In that case, the variable n_fonts_left * gives the number of open files that are left, (initially MAXINT, set * dynamically) and when it is necessary to close a file, these routines * call close_a_file() which should free up a file descriptor. * */ #include <stdio.h> #ifndef X10 #include <X11/Xos.h> /* same as below */ #else /* X10 */ #ifdef SYSV #include <string.h> #define index strchr #define rindex strrchr #else /* SYSV */ #include <strings.h> #endif /* SYSV */ #endif /* X10 */ #include <errno.h> extern int errno; /* * If you think you have to change DEFAULT_TAIL, then you haven't read the * documentation closely enough. */ #ifndef VMS #define PATH_SEP ':' #define DEFAULT_TAIL "/%f.%d%p" #else /* VMS */ #include <string.h> #define index strchr #define rindex strrchr #define PATH_SEP '/' #define DEFAULT_TAIL ":%f.%d%p" #endif /* VMS */ #ifndef OPEN_MODE #ifndef VMS #define OPEN_MODE "r" #else #define OPEN_MODE "r", "ctx=stm" #endif #endif /* OPEN_MODE */ extern int n_fonts_left; extern char *alt_font; static char *font_path; static char default_font_path[] = DEFAULT_FONT_PATH; static int *sizes, *sizend; static char default_size_list[] = DEFAULT_FONT_SIZES; /* the corresponding read_char procedures are handled in xdvi.h */ typedef void (*read_font_index_proc)(); /* struct font *fontp; */ read_font_index_proc read_GF_index, read_PK_index, read_PXL_index; #ifdef sun char *sprintf(); #endif char *malloc(), *getenv(); double atof(); #define Strcpy (void) strcpy #define Sprintf (void) sprintf 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; } } init_pxl_open() { char *size_list; int *sp, *sp1, *sp2; unsigned int n; char *p; if ((font_path = getenv("XDVIFONTS")) == NULL) font_path = default_font_path; else if (*font_path == PATH_SEP) /*concatenate default_font_path before font_path */ font_path = strcat(strcpy(malloc((unsigned) strlen(default_font_path) + strlen(font_path) + 1), default_font_path), font_path); 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 *) malloc(n * sizeof(int)); 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); } static FILE * formatted_open(path, font, pxl, mag, name) char *path, *font, *pxl; int mag; char **name; { char *p = path, nm[128], *n = nm, c; int f_used = 0; FILE *f; for (;;) { c = *p++; if (c==PATH_SEP || c=='\0') { if (f_used) break; p = DEFAULT_TAIL; continue; } if (c=='%') { c = *p++; switch (c) { case 'f': f_used=1; Strcpy(n, font); break; case 'p': Strcpy(n, pxl); break; case 'd': Sprintf(n, "%d", mag); break; default: *n++ = c; *n = '\0'; } n += strlen(n); } else *n++ = c; } *n = '\0'; f = fopen(nm, OPEN_MODE); if (f == NULL && errno == EMFILE) { n_fonts_left = 0; close_a_file(); f = fopen(nm, OPEN_MODE); } if (f != NULL) { *name = malloc((unsigned) (n - nm + 1)); Strcpy(*name, nm); } return f; } static FILE * pre_pxl_open(font, mag, mag_ret, name, read_font_index) char *font; int mag, *mag_ret; char **name; read_font_index_proc *read_font_index; { char *p; FILE *f; int *p1, *p2, pxlmag, pkmag; /* * Loop over sizes. Try closest sizes first. */ for (p2 = sizes; p2 < sizend; ++p2) if (*p2 >= mag) break; p1 = p2; for (;;) { if (p1 <= sizes) if (p2 >= sizend) return NULL; else pxlmag = *p2++; else if (p2 >= sizend || mag * mag <= p1[-1] * *p2) pxlmag = *--p1; else pxlmag = *p2++; *mag_ret = pxlmag; pkmag = (pxlmag + 2) / 5; /* * loop over paths */ for (p = font_path;;) { if (read_GF_index && (f = formatted_open(p, font, "gf", pkmag, name)) != NULL) { *read_font_index = read_GF_index; return f; } if (read_PK_index && (f = formatted_open(p, font, "pk", pkmag, name)) != NULL) { *read_font_index = read_PK_index; return f; } if (read_PXL_index && (f = formatted_open(p, font, "pxl", pxlmag, name)) != NULL) { *read_font_index = read_PXL_index; return f; } p = index(p, PATH_SEP); if (p == NULL) break; ++p; } } } FILE * pxl_open(font, font_ret, mag, mag_ret, factor, name, read_font_index) char *font, **font_ret; int mag, *mag_ret; float *factor; char **name; read_font_index_proc *read_font_index; { FILE *f; int actual_pt, low_pt, high_pt, trial_pt; char fn[50], *fnend; *factor = 1.0; f = pre_pxl_open(font, mag, mag_ret, name, read_font_index); 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_pxl_open(fn, mag * actual_pt / trial_pt, mag_ret, name, read_font_index); if (f != NULL) { *font_ret = strcpy(malloc((unsigned) strlen(fn) + 1), fn); *factor = (float) actual_pt / trial_pt; return f; } } } if (alt_font != NULL) { *font_ret = alt_font; f = pre_pxl_open(alt_font, mag, mag_ret, name, read_font_index); if (f != NULL) *font_ret = strcpy(malloc((unsigned) strlen(alt_font) + 1), alt_font); } return f; }