home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 3
/
Meeting_Pearls_III.iso
/
Pearls
/
texmf
/
source
/
driver
/
util
/
new_font.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-10
|
99KB
|
3,614 lines
/*
** This file generated by localize 2.9 (AmigaDOS 2.1) from util/new_font.c
*/
/*
************************************************************************
* *
* new_font.c 04. Mar. 90 *
* *
* A replacement for the old fontstructure-handling. (hes) *
* *
************************************************************************
*/
/*
* Zu tun:
*
* o common ueberpruefen. Wird common nicht zuviel/staendig neu angelegt?
* (-)
* o Arrays (z.B. Path) ueberpruefen, ob man es nicht per Pointer
* (strdup, stringpool? (Liste von Strings??)) machen koennte.
* (!)
* o Ueberall wo mit Arrays gearbeitet wird muss strncat strncpy ...
* verwendet werden.
* (!)
* o Fontstruktur umstellen. Es soll eine strikte Trennung zwischen DVI-File
* Daten und Fontdaten eingefuehrt werden. Dazu noch eine Struktur
* vorschalten. Alle Flags umschalten. Alles sollen Bitflags werden.
* (!!!)
* o pk Substitutionsmoeglichkeit: Es muesste moeglich sein, zu sagen
* dass falls ein 143dpi Font nicht gefunden wird, moege doch der 144dpi
* Font gesucht werden.
* (-)
* o TFM File lesen (optional), falls ein Font nicht gefunden wurde.
* (!!)
* o Die Fontsubstitutionsidee von Bernd implementieren. Falls pkdir oder
* flib definiert, dann die der Reihe nach absuchen.
* (!)
* o Per Option auswaehlbar was/nach welcher Reihenfolge die einzelnen
* Ersetzungen gemacht werden sollen:
* - Substitution durch andere Groesse
* - Black Box durch TFM File
* - cmr10 Font einsetzen
* (!)
* o Virtuelle Fonts! (der zweite Punkt sollte das schon vorbereiten)
* (!!!)
* o Zukunftsidee:
* Die Struktur so umstellen, dass mit mehreren DVI-Files *gleichzeitig*
* gearbeitet werden kann.
* Vielleicht mal die Fontverwaltung als eigenen Task implementieren
* so dass ShowDVI/DVIprint gleichzeitig darauf zugreifen koennen.
* (Oder auch andere zu portierende Treiber (Beeble, dvips, ...))
* (-)
*
*/
#include "defines.h"
#define OLDARGS /* !!!!! */
#include <stdio.h>
#ifdef AMIGA
# include <exec/types.h>
# include <dos/dos.h>
#endif
#include "globals.h"
#include "textypes.h"
#include "flmt.h"
#include "new_font.h"
#ifdef ANSI
# include <string.h>
# include <stdlib.h>
# include <stddef.h>
#endif
#include <ctype.h>
#ifdef LATTICE
# include <clib/exec_protos.h>
# include <clib/dos_protos.h>
# include <pragmas/exec_pragmas.h>
# include <pragmas/dos_pragmas.h>
extern struct DosLibrary *DOSBase;
#endif
#include "globals.i"
#include "new_font.i"
#include "loadfont.i"
#include "dvihand.i"
#ifdef SLOW
# include "bitmap.i"
#endif
#ifndef OLDARGS
# include "parsef.h"
# include "parsef.i"
#endif
#ifdef ATARI
# include <ext.h>
# include <aes.h> /* for shel_find */
# define abs(a) labs(a)
# ifdef __TURBOC__
extern int access(char *, int);
# if (__TURBOC__ < 0x200)
# define setup_lru_flib slruflib
# define setup_lru_font slrufont
# define what_lru_flib wlruflib
# define what_lru_font wlrufont
# define search_font_location sfloc
# define search_font_group sfgrp
# define is_font_in_font_list isifolist
# define is_font_in_lib_list isililist
# define is_font_in_pk_dirs isipkdirs
# define search_in_defined_libs sindelibs
# define search_in_rest_pathes sinrepathes
# define define_font def_font
# define define_flib def_flib
# endif
# endif
#endif
#ifdef AMIGA
# ifdef FONTS_IN_CHIPMEM
# include <exec/memory.h>
# include <libraries/dos.h>
char *AllocRemember();
extern struct Remember *Rem_Key; /* Memory-Management */
extern int fontmem_in_chipmem; /* soll oder soll nicht? */
# endif
#endif
#ifndef ATARI
# ifndef abs
# define abs(a) (((a) < 0) ? -(a) : (a))
# endif
#endif
#ifdef AMIGA
# define ACC_READ 4
# define B_OPEN_READ "r"
#else
# ifdef ATARI
# define ACC_READ S_IREAD
# define B_OPEN_READ "rb"
# endif
#endif
/*
* Fuer die locale-Library:
*
* Hier duerfen *nur* die MSG_#? Nummern eingebunden werden!
* Achtung:
* Es muss/sollte 'multiple-include' erlaubt sein!
*/
#include "local.i"
#undef CATCOMP_ARRAY
#undef CATCOMP_BLOCK
#undef CATCOMP_STRINGS
#define CATCOMP_NUMBERS
#include "localstr.h"
/*
************************************************************************
* *
************************************************************************
*/
/*
************************************************************************
* external variables *
************************************************************************
*/
#ifdef AMIGA
extern struct ArpBase *ArpBase;
#endif
extern long resolution; /* actual base resolution */
struct Font *cfontptr; /* pointer to the actual font */
struct FontMan *FontRoot = NULL; /* root structure */
/*
************************************************************************
* global variables for this module *
************************************************************************
*/
static char *lowmem, *charmap, *start_mem, *end_mem;
/* lowmem pointer to the first free memory cell */
/* charmap pointer to the current character */
/* start_mem pointer to the start of the fontmem */
/* end_mem pointer to the end of the fontmem */
static short mags[NRMAGS] = { 1000, 1095, 1200, 1315, 1440, 1577,
1728, 2074, 2488, 2986, 3583, 4300, 5160 };
/* mag(0) mag(0.5) mag(1) mag(1.5) mag(2) mag(2.5)
mag(3) mag(4) mag(5) mag(6) mag(7) mag(8) mag(9) */
#ifndef OLDARGS
/**=============================================================**/
struct FontMan *globarg_fnt_root;
static void __stdargs fkw_conc_dirs
Args((struct string_parse *p, char *line));
static void __stdargs fkw_parse_string
Args((struct string_parse *p, char *line, char *string));
static void __stdargs fkw_dir
Args((struct string_parse *p, char *line,
long *res, char *where));
static void __stdargs fkw_define_flib
Args((struct string_parse *p, char *line,
long *res, char *path));
static void __stdargs fkw_define_font
Args((struct string_parse *p, char *line,
char *name, long *res, char *path));
/* There should be better ways to do this, but I don't want to refer
to absolute array indices. */
#define ARG_CONC_FLIB 1
#define ARG_CONC_PK 2
#define ARG_STR_FLIB 1
#define ARG_STR_PK 2
#define ARG_STR_BASEPKD 3
#define ARG_STR_PKDIR 4
#define ARG_STR_FLIBFNT 5
#define ARG_PKDIR 1 /*don't you dare change this (see func)!*/
#define ARG_BASEPKDIR 2 /*don't you dare change this (see func)!*/
static struct string_parse font_config[] = {
{
"flibenv",
NULL,
(string_parse_function) fkw_conc_dirs,
PAF_ARGS,
ARG_CONC_FLIB
},
{
"pkenv",
NULL,
(string_parse_function) fkw_conc_dirs,
PAF_ARGS,
ARG_CONC_PK
},
{
"flib_str",
"%s",
(string_parse_function) fkw_parse_string,
PAF_1_ARG,
ARG_STR_FLIB
},
{
"pk_str",
"%s",
(string_parse_function) fkw_parse_string,
PAF_1_ARG,
ARG_STR_PK
},
{
"basepkdir_str",
"%s",
(string_parse_function) fkw_parse_string,
PAF_1_ARG,
ARG_STR_BASEPKD
},
{
"pkdir_str",
"%s",
(string_parse_function) fkw_parse_string,
PAF_1_ARG,
ARG_STR_PKDIR
},
{
"flib_fnt_str",
"%s",
(string_parse_function) fkw_parse_string,
PAF_1_ARG,
ARG_STR_FLIBFNT
},
{
"flib",
"%d %s",
(string_parse_function) fkw_define_flib,
PAF_2_ARGS
},
{
"pkdir",
"%ld %s",
(string_parse_function) fkw_dir,
PAF_2_ARGS,
ARG_PKDIR
},
{
"basepkdir",
"%ld %s",
(string_parse_function) fkw_dir,
PAF_2_ARGS,
ARG_BASEPKDIR
},
{
"font",
"%s %d %s",
(string_parse_function) fkw_define_font,
PAF_3_ARGS
},
{
NULL
}
};
#endif
/*
************************************************************************
* external functions *
************************************************************************
*
* void resetfont Args((void));
* void setup_ctfmw Args((struct Font *font));
* void SetFntNum Args((long fntnum));
* int HasBeenRead Args((long fntnum));
* void LoadFont Args((int action, 0: define only
* long fntnum, 1: load only
* char *fntname, 2: define & load
* long chksum,
* long d,
* long s,
* long fontmag,
* long fontmag5));
* int init_fontmt Args((char show)); 0: dviprint, 1: showdvi
* long alloc_char Args((ulong size)); ret = -1 -> no memory
*
*
*/
/*
************************************************************************
* local functions *
************************************************************************
*/
static void MarkFile Args((char * full_name));
#ifdef PASEIT
static int parsit Args((char *line,
char ***array));
#endif
static void setup_sealst Args((struct FontMan *fnt_root));
static int split_env_string Args((struct SeaLst *sl,
char *env_var,
char *def_value));
static long compute_vert Args((long hdpi));
static void my_sprintf Args((char buffer[],
int length,
char fmt[],
char fntname[],
long dpi,
long dpi5));
static void InitFontMan Args((char is_show));
static long test_pk_file Args((char *pk_name));
static void setup_lru_flib Args((struct LibLst *list,
struct Fnt_Lib *lib));
static void setup_lru_font Args((struct FontLst *list,
struct Font *font));
static struct Fnt_Lib *what_lru_flib Args((struct LibLst *list));
static struct Font *what_lru_font Args((struct FontLst *list));
static void close_flibs Args((struct FontMan *fnt_root));
static struct CommonFontGroups
*search_font_group Args((char *fntname,
struct FontMan *fnt_root));
static struct Font *search_font Args((char *fntname,
long magnification,
long magnification5,
struct FontMan *fnt_root));
static struct Font *search_font_location Args((char *fntname,
long dpi,
long dpi5,
struct FontMan *fnt_root));
static struct Font *is_font_in_font_list Args((char *fntname,
long dpi,
long dpi5,
struct FontLst *fnt_list,
struct FontMan *fnt_root));
static struct Font *is_font_in_lib_list Args((char *fntname,
long dpi,
long dpi5,
struct FontMan *fnt_root));
static struct Font *is_font_in_pk_dirs Args((char * fntname,
long dpi,
long dpi5,
struct FontMan *fnt_root));
static struct Font *is_font_in_pred_pk_dirs Args((char * fntname,
long dpi,
long dpi5,
struct FontMan *fnt_root,
short base));
static struct Font *define_test_pk_font Args((char *path,
char *fntname,
long dpi,
long dpi5,
char *format_str,
struct FontMan *fnt_root));
static struct Font *search_in_defined_libs Args((char *fntname,
long dpi,
long dpi5,
struct FontMan *fnt_root));
static struct Font *search_in_rest_pathes Args((char *fntname,
long dpi,
long dpi5,
struct FontMan *fnt_root));
static struct Font *find_font_in_flib Args((char *fntname,
long dpi,
long dpi5,
struct Fnt_Lib *flib,
struct FontMan *fnt_root));
static void read_font_def_file Args((struct FontMan *fnt_root,
char *file_name));
static void parse_line Args((struct FontMan *fnt_root,
char *line));
static void conc_dirs Args((char *str,
struct SeaLst *sl));
static void define_flib Args((struct FontMan *fnt_root,
long dpi,
char *path));
static void define_font Args((struct FontMan *fnt_root,
long dpi,
char *path,
char *name));
struct Font *mag_substitution Args((char *fntname,
long dpi,
struct FontMan *fnt_root));
struct Font *dpi_substitution Args((char *fntname,
long magnification,
struct FontMan *fnt_root));
static void init_mem Args((ulong size));
static long *open_charmap Args((void));
static long close_charmap Args((void));
static void adjust_mem Args((long *start,
long size));
static int do_garcol Args((void));
#ifdef AMIGA
static struct Font *read_atex_file Args((char *fntname,
long dpi,
long dpi5,
struct FontMan *fnt_root));
static int copy_file Args((char *source,
char *drain));
static int create_path Args((char *path));
#endif
/*
************************************************************************
* mark the file full_name *
************************************************************************
*/
static void MarkFile(char * full_name)
{
if (mark_fonts) {
__aligned struct FileInfoBlock fib;
char comment[80];
struct DateStamp ds;
long old;
BPTR lck = Lock(full_name, ACCESS_READ);
if (lck) {
(void)DateStamp(&ds);
Examine(lck, &fib);
if (fib.fib_Comment[0] == '\0' || sscanf(fib.fib_Comment+10, "%d", &old) != 1) {
old = 0;
}
sprintf(comment, "FontUsed: %d (%d %d %d)", old+1, ds.ds_Days, ds.ds_Minute, ds.ds_Tick);
UnLock(lck);
if (!SetComment(full_name, comment)) {
; //printf("SetComment %d fehlgeschlagen!\n", comment);
}
}
}
}
/*
************************************************************************
* release all unpacked chars *
************************************************************************
*/
void release_mem(void)
{
struct FontLst *flist;
long i,j;
if (FontRoot != NULL) {
/* release chars */
if (FontRoot->unpacked_mem > 0) {
j=0L;
for (flist = FontRoot->font_list; flist != NULL; flist = flist->next_font) {
for (i=0; i<NPXLCHARS; i++) {
if (flist->font.common->ch[i].unpacked != NULL) {
xfree(flist->font.common->ch[i].unpacked);
flist->font.common->ch[i].unpacked = NULL;
j++;
}
}
}
Logging(MSG_RELEASE_CHARS,FontRoot->unpacked_mem, j);
FontRoot->unpacked_mem = 0L;
}
}
}
/*
************************************************************************
* parse a line and returns int argc, char *argv[] *
************************************************************************
*/
#ifdef PASEIT
static int parsit(char *line,char ***array)
{
char **argv;
char *word;
char *linecp;
int i,j, num_words, longest_word;
argv = *array;
if (argv != (char **)NULL) {
for (i=0; argv[i] != (char*) NULL; i++) {
xfree(argv[i]); /* free the old array */
}
xfree((char *)argv); /* and then free the ptr itself */
}
linecp = line;
num_words = longest_word = 0;
while (1) {
for (; *linecp == ' ' || *linecp == '\t'; ++linecp) ;
if (*linecp == '\0') {
break;
}
word = linecp;
for (; *linecp != ' ' && *linecp != '\t' && *linecp != '\0'; ++linecp) ;
num_words++;
if ((i = linecp-word) > longest_word) {
longest_word = i;
}
if (*linecp == '\0') {
break;
}
}
if ((argv = (char **)xmalloc((size_t)(num_words +1) * 4)) == (char **)NULL) {
Warning(MSG_NO_MEM);
return (0);
}
if ((word = (char *)xmalloc((size_t)(longest_word+2))) == (char *)NULL) {
Warning(MSG_NO_MEM);
return (0);
}
j = i = 0;
while (1) {
for (; *line == ' ' || *line == '\t'; line++) ;
if (*line == '\0') {
break;
}
i = 0;
for (; *line != ' ' && *line != '\t' && *line != '\0'; line++) {
word[i++] = *line;
}
word[i] = '\0';
argv[j] = xmalloc((size_t)strlen(word+1));
if (argv[j] == (char *)NULL) {
xfree(word);
Warning(MSG_NO_MEM);
return (0);
}
(void)strcpy(argv[j], word);
j++;
if (*line == '\0') {
break;
}
}
argv[j] = (char *)NULL; /* NULL at end of list */
*array = argv;
xfree(word);
return (j);
}
#endif
/*
************************************************************************
* compute the vertical resolution *
************************************************************************
*/
static long compute_vert(long hdpi)
{
return ((hdpi * vconvresolution + hconvresolution/2) / hconvresolution);
}
/*
************************************************************************
* make in path a complete path-string *
************************************************************************
*/
void mk_correct_path(char *path)
{
int length = strlen(path);
#if defined(HARDDEB)
if (NULL == path) printf("mk_correct_path == NULL!\n");
#endif
if ('\n' == path[length-1]) path[--length] = '\0';
# ifdef ATARI
if (path[length-1] != ':' && path[length-1] != '\\') {
path[length] = '\\';
path[length+1] = '\0';
}
# else
if (0 < length && path[length-1] != ':' && path[length-1] != '/') {
path[length] = '/';
path[length+1] = '\0';
}
# endif
}
/*
************************************************************************
* insert dpi and fontname in fmt string *
************************************************************************
*/
static void my_sprintf(char *buffer, int buf_length, char *fmt,
char *fntname, long dpi, long dpi5)
{
char c, *t, work[16], hbuf[128];
if (buffer == NULL || fmt == NULL || fntname == NULL) {
Fatal(20, MSG_INTERNAL_ERROR_SPRINTF);
}
--buf_length; /* there has to be a '\0' char at the end ! */
while( *fmt != '\0' && buf_length > 0 ) {
if( *fmt != '%' ) { /* copy all chars up to a '%' sign */
*buffer++ = *fmt++;
--buf_length;
continue;
}
/* we have found a '%' */
fmt++;
if( *fmt == '%' ) { /* for '%%' insert one '%' */
*buffer++ = *fmt++;
--buf_length;
continue;
}
/* copy '%...X' part from `fmt' into work[] */
t = work;
*t++ = '%';
/* Zwischen % und Zeichen sind nur Zahlen+Punkt erlaubt */
while( (c = *fmt) != '\0' && strchr(".0123456789", c) != NULL
&& t < &work[16-2] )
*t++ = *fmt++;
*t = 'd'; /* 'd' is most common case, orig char is in `c' */
*(t+1) = '\0';
/* weitere Fehlerabfrage wird im default-case des switch erledigt */
if (c != '\0')
fmt++;
switch (c) {
case 'h' :
case 'd' : sprintf(hbuf, work, (int)dpi); /* insert dpi */
break;
case 'v' : sprintf(hbuf, work, (int)compute_vert(dpi));
break;
#ifdef FONT_MAG
case 'x' : { int pxl = (dpi5 * resolution * 5 + 500)/1000;
sprintf(hbuf, work, pxl); /* insert dpi*5 */
}
break;
case 'y' : { int pxl = (dpi5 * resolution * 5 + 500)/1000;
sprintf(hbuf, work, (int)compute_vert(pxl));
}
break;
case 'M' : sprintf(hbuf, work, dpi5); /* insert font mag */
break;
case 'm' : *t = 'f'; /* insert font mag/1000 */
sprintf(hbuf, work, (float)dpi5/1000.0);
break;
#else
case 'x' : sprintf(hbuf, work, (int)dpi5); /* insert dpi*5 */
break;
case 'y' : sprintf(hbuf, work, (int)compute_vert(dpi5));
break;
#endif
case 's' : *t = 's';
sprintf(hbuf, work, fntname); /* insert font name */
break;
default : Fatal(5, MSG_UNKNOWN_FORMAT_SPRINTF);
return;
}
if (strlen(hbuf) > 100) {
Fatal(20, MSG_STRING_OVERFLOW_SPRINTF);
/* NOT REACHED */
}
if (strlen(hbuf) >= buf_length)
hbuf[buf_length] = '\0'; /* Cut rest of hbuf (with warning?) */
strcpy(buffer, hbuf);
buffer += strlen(hbuf);
buf_length -= strlen(hbuf);
}
*buffer = '\0'; /* null-terminate string */
}
/* string only for logging ! */
void get_full_name(char *str, struct Font *fnt)
{
char fontname[PK_NAME_SIZE], name[PATH_SIZE+PK_NAME_SIZE];
if (fnt->common->where_is_font == WHERE_LIB) {
/* font in lib: fontname == Lib-name, name == full name of Lib */
my_sprintf(fontname, PK_NAME_SIZE,
fnt->common->location.fnt_library->format_str,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution,
fnt->common->resolution5);
strcpy(name,fnt->common->location.fnt_library->path);
mk_correct_path(name);
strcat(name,fontname);
strcat(name," [");
strcat(name,fnt->common->fnt_group->fnt_name);
strcat(name,"]");
}
else {
/* font as pk-file: fontname: full pk-name (without path) */
strcpy(name,fnt->common->location.pk_directory->path);
mk_correct_path(name);
my_sprintf(fontname, PK_NAME_SIZE,
fnt->common->location.pk_directory->format_str,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution,
fnt->common->resolution5);
strcat(name, fontname);
}
strcpy(str, name);
}
/*
************************************************************************
* split a env-string and saves it in a search-list *
************************************************************************
*/
static int split_env_string(struct SeaLst *sl, char *env_var, char *def_value)
{
char *tmp, *ptr, save[300];
int i;
char *string;
struct SeaEle *ele, *ele2;
save[0] = '\0'; /* init for strcat() */
tmp = getenv(env_var);
if (tmp != NULL) {
strcpy(save, tmp);
for (ptr = save; *ptr != '\0'; ptr++) {
if (*ptr == '!' || *ptr == ',') { /* env-seperators */
*ptr = ' ';
} /* !! no spaces in pathes of environmentstring !! */
}
strcat(save, " ");
}
if (PXLpath != NULL) { /* -a option given */
strcat(save, PXLpath);
strcat(save, " ");
}
#ifdef ALWAYS_DEFAULT
strcat(save, def_value);
#else
if (strlen(save) == 0)
strcat(save, def_value);
#endif
i = 1;
string = xmalloc(strlen(save)+1);
strcpy(string,save);
ele = xmalloc(sizeof(struct SeaEle));
sl->first_ele = ele;
ele->path = string;
ele->next_ele = NULL;
while (*string != '\0' && isspace(*string)) { string++; }
while (*string != '\0') {
while (*string != '\0' && !isspace(*string)) { string++; }
if (*string != '\0') {
*string = '\0';
string++;
while (*string != '\0' && isspace(*string)) { string++; }
if (*string != '\0') {
ele2 = xmalloc(sizeof(struct SeaEle));
ele2->path = string;
ele2->next_ele = NULL;
ele->next_ele = ele2;
ele = ele2;
i++;
}
}
}
sl->number = i;
return 0;
}
/*
************************************************************************
* setup the search list for flibs/pk-dirs *
************************************************************************
*/
static void setup_sealst(struct FontMan *fnt_root)
{
if (split_env_string(&(fnt_root->s_list_flib),ENV_FLIB_DIRS,FLIB_AREA) != 0) {
Warning(MSG_ERROR_SEARCH_LIST_LIB);
}
if (split_env_string(&(fnt_root->s_list_pkdirs),ENV_PK_DIRS,PK_AREA) != 0) {
Warning(MSG_ERROR_SEARCH_LIST_PK);
}
}
/*
************************************************************************
* is the file a pk-file, returns size of pk-file or 0 if not *
************************************************************************
*/
static long test_pk_file(char *pk_name)
{
long size;
#undef SAVETY_PK
#ifdef SAVETY_PK
char ptr[2];
FILE *fp;
fp = BINARYOPEN(pk_name);
if (fp != NULL) {
if (fread(ptr,1,2,fp) != 2) {
fclose(fp);
return 0L;
}
if (*((unsigned short *)ptr) != PK_MAGIC) {
fclose(fp);
return 0L;
}
fclose(fp);
#endif
#ifdef ATARI
{
struct stat pkstat;
if (stat(pk_name, &pkstat) == -1)
{
return(0L);
}
return(pkstat.st_size);
}
#endif
#ifdef AMIGA
{
struct FileInfoBlock *fib;
# ifdef LATTICE
BPTR lock;
# else
struct FileLock *lock;
# endif
lock = Lock(pk_name,ACCESS_READ);
if (lock == NULL) {
return 0L;
}
fib = (struct FileInfoBlock *)xmalloc(sizeof(struct FileInfoBlock));
if (Examine(lock,fib)==0) {
xfree(fib);
UnLock((BPTR)lock);
return 0L;
}
size = fib->fib_Size;
xfree(fib);
UnLock((BPTR)lock);
}
#endif
#ifdef SAVETY_PK
}
#endif
return size;
}
/*
************************************************************************
* advance the lru-count of all lib's expect lib *
************************************************************************
*/
static void setup_lru_flib (struct LibLst *list, struct Fnt_Lib *lib)
{
struct LibLst *temp;
#if 0
for (temp = list; temp != NULL; temp = temp->next_lib) {
if (&(temp->flib) == lib) {
temp->flib.lru_count = 0;
}
else {
temp->flib.lru_count++;
}
}
#else
/* (br) so sollte es klappen... und es ist schneller ;-) */
for (temp = list; temp != NULL; temp = temp->next_lib) {
temp->flib.lru_count++;
}
lib->lru_count = 0;
#endif
}
/*
************************************************************************
* advance the lru-count of all font's expect font *
************************************************************************
*/
static void setup_lru_font (struct FontLst *list, struct Font *font)
{
register struct FontLst *temp;
/* (br) dto. */
for (temp = list; temp != NULL; temp = temp->next_font) {
temp->font.common->lru_count++;
}
font->common->lru_count = 0L;
}
/*
************************************************************************
* search the lib with the highest lru-count and fileptr != NULL *
************************************************************************
*/
static struct Fnt_Lib *what_lru_flib (struct LibLst *list)
{
register struct LibLst *temp, *res = NULL;
long s = 0;
/*** used for closing older flibs ***/
for (temp = list; temp != NULL; temp = temp->next_lib) {
if (temp->flib.lru_count > s && temp->flib.lib_status == LIB_OPEND) {
s = temp->flib.lru_count;
res = temp;
}
}
if (res == NULL) {
res = list;
}
return &(res->flib);
}
/*
************************************************************************
* search the font with the highest lru-count *
************************************************************************
*/
static struct Font *what_lru_font (struct FontLst *list)
{
struct FontLst *temp, *res;
long s;
s = 0;
res = NULL;
/*** used for deleting font from the ram ***/
for (temp = list; temp != NULL; temp = temp->next_font) {
if ((temp->font.common->lru_count >= s && temp->font.common->fnt_status == FNT_OLD_LOADED) ||
(temp->font.common->lru_count >= s && temp->font.common->fnt_status == FNT_DEFINED_OLOADED) ||
(temp->font.common->lru_count > s && temp->font.common->fnt_status == FNT_LOADED)) {
s = temp->font.common->lru_count;
res = temp;
}
}
if (res == NULL) {
return NULL;
}
else {
return &(res->font);
}
}
/*
************************************************************************
* close the flibs whith highest lru-count *
************************************************************************
*/
static void close_flibs(struct FontMan *fnt_root)
{
/* close files */
short to_close = abs(fnt_root->files_left);
short cl, res=0;
struct Fnt_Lib *lib;
if (fnt_root->files_left > 0) {
return;
}
for (cl=0; cl <= to_close; cl++) {
lib = what_lru_flib(fnt_root->flib_list);
if (lib->file_ptr != NULL) {
fclose(lib->file_ptr);
lib->file_ptr = NULL;
lib->lib_status = LIB_READ_CLOSED;
res++;
}
}
fnt_root->files_left += res;
}
/*
************************************************************************ *
* setup the global fontmanagement-structure * *
************************************************************************ *
*/
static void InitFontMan(char is_show)
{
register struct FontMan *fr;
/* (br) Why not a static & initialized FontRoot ??? */
fr = (struct FontMan *)xmalloc((size_t)sizeof(struct FontMan));
FontRoot = fr;
#ifdef OLD_NOFONT
fr->noFontList = NULL;
#endif
fr->s_list_flib.number = 0L;
fr->s_list_flib.first_ele = NULL;
fr->s_list_pkdirs.number = 0L;
fr->s_list_pkdirs.first_ele = NULL;
fr->s_list_pkdpi.number = 0L;
fr->s_list_pkdpi.first_ele = NULL;
fr->s_list_base_pkdpi.number = 0L;
fr->s_list_base_pkdpi.first_ele = NULL;
fr->font_list = NULL;
fr->flib_list = NULL;
fr->group_list = NULL;
fr->files_left = MAXOPEN;
fr->unpacked_mem = 0L;
if (is_show) {
fr->driver_type = (char)DRIVER_TYPE_SHOWDVI;
}
else {
fr->driver_type = (char)DRIVER_TYPE_DVIPRINT;
}
fr->flib_fmt = strdup(FLIB_STRING);
fr->pk_fmt = strdup(PK_STRING);
fr->pkdir_fmt = strdup(PKDIR_STRING);
fr->basepkdir_fmt = strdup(BASE_PK_STRING);
fr->flib_fnt_fmt = strdup(FLIB_FNT_STRING);
if (fr->flib_fmt == NULL || fr->pk_fmt == NULL ||
fr->pkdir_fmt == NULL || fr->flib_fnt_fmt == NULL) {
Fatal(10, MSG_NO_MEM);
}
setup_sealst(fr);
read_font_def_file(fr, is_show ? SFONT_DEF_FILE : DFONT_DEF_FILE);
}
/*
* ******** global functions *******
*/
/*
************************************************************************ *
* initialize all * *
************************************************************************ *
*/
void init_fontmt(char show)
{
init_mem(fontmemsize);
InitFontMan(show); /* showdvi OR dviprint */
}
/*
************************************************************************ *
* reset the status of all fonts * *
************************************************************************ *
*/
void resetfont(void)
{
struct FontLst *fntlst;
for (fntlst = FontRoot->font_list; fntlst != NULL; fntlst = fntlst->next_font) {
if (fntlst->font.common->fnt_status == FNT_DEFINED) {
fntlst->font.common->fnt_status = FNT_FOUND;
} else if (fntlst->font.common->fnt_status == FNT_LOADED
|| fntlst->font.common->fnt_status == FNT_DEFINED_OLOADED) {
fntlst->font.common->fnt_status = FNT_OLD_LOADED;
}
fntlst->font.fnt_number = -1L;
fntlst->font.ctfmw_valid = (char)FALSE;
}
}
/*
************************************************************************ *
* setup the ctfmw[] array of the font * *
************************************************************************ *
*/
void setup_ctfmw(struct Font *font) /* dies wird auch in fast_cp.c gebraucht */
{
int i, maxchar;
maxchar = font->common->maxchars;
/* printf("setup_ctfmw(%s, %d): maxchar = %d\n", font->common->fnt_group->fnt_name, font->fnt_number, maxchar);*/
for (i = 0; i < maxchar; i++) {
font->ctfmw[i] =
scalewidth(font->common->fnt_group->tfmw[i], font->space_faktor);
}
for (; i < NPXLCHARS; i++) {
font->ctfmw[i] = 0L;
}
font->ctfmw_valid = (char)TRUE;
}
/*
************************************************************************ *
* load the font fntnum * *
************************************************************************ *
*/
void SetFntNum (long fntnum)
{
struct FontLst *fntlst;
for (fntlst = FontRoot->font_list;
fntlst != NULL && fntlst->font.fnt_number != fntnum;
fntlst = fntlst->next_font);
if (fntlst == NULL) {
Fatal(5, MSG_FONT_UNDEFINED, fntnum);
}
cfontptr = &(fntlst->font); /* this is the actual font now */
if (cfontptr->common->fnt_status == FNT_DEFINED ||
cfontptr->common->fnt_status == FNT_DEFINED_OLOADED) {
LoadFont(1,fntnum,(char *)NULL,0L,0L,0L,0L,0L); /* load font */
}
else {
setup_lru_font (FontRoot->font_list, cfontptr);
if (!cfontptr->ctfmw_valid)
setup_ctfmw(cfontptr);
}
/* nachfolgendes sollte man besser als zusaetzliche Information zum
* Font ablegen (z.B. tenquadpxl = 10 * size of font in pt als Naeherung
* fuer 1 quad; siehe Level0-Draft)
*/
{ double tenquad;
unsigned long tenquadpxl;
extern double alpha;
extern long mag;
extern int thinspace, backspace, vertsmallspace;
tenquad = ((((double)(mag * cfontptr->space_faktor))/
((double)0x100000 * 100.0)) / alpha);
tenquadpxl = (unsigned long)
(tenquad * (100 * resolution) / 7227.0 + 0.5);
#if 0
Logging("Font #%d >%s< at %ld = %ld (ss: %lx ds: %lx)",
cfontptr->fnt_number, cfontptr->common->fnt_group->fnt_name,
(long)floor(tenquad),
tenquadpxl, cfontptr->space_faktor, cfontptr->design_faktor);
#endif
vertsmallspace = 8 * tenquadpxl / 100;
thinspace = 2 * tenquadpxl / 100;
backspace = -(9 * tenquadpxl / 100);
}
}
/*
************************************************************************ *
* is this font already defined? * *
************************************************************************ *
*/
int HasBeenRead(long fntnum)
{
register struct FontLst *fntlst;
for(fntlst = FontRoot->font_list; fntlst != NULL; fntlst = fntlst->next_font)
if( fntlst->font.fnt_number == fntnum )
return TRUE;
return FALSE;
}
/*
************************************************************************
* search a font-group *
************************************************************************
*/
/*
* Search font `fntname' in group_list, if not found, make new group and
* insert it in group_list.
*/
static struct CommonFontGroups *
search_font_group(char *fntname, struct FontMan *fnt_root)
{
struct GroupLst *glst;
for (glst = fnt_root->group_list; glst != NULL; glst = glst->next_group) {
if( 0 == stricmp(fntname, glst->fnt_group.fnt_name) )
return &(glst->fnt_group);
}
/* group not found: make a new one */
/* Dirty Trick (but supported by all C-Compiler):
* struct includes "char fnt_name[1]" declaration as last(!) part,
* we have to allocate the struct and the string mem
*/
glst = (struct GroupLst *) xmalloc(sizeof(struct GroupLst) + strlen(fntname));
/**** Initialize structure: ****/
{ struct CommonFontGroups *gp;
int i;
gp = &(glst->fnt_group);
strcpy(gp->fnt_name, fntname);
/* set TFM width of all chars to ZERO */
for( i = 0; i < NPXLCHARS; i++ ) {
gp->tfmw[i] = 0L;
}
}
/* and insert new group node at the beginning of group_list */
glst->next_group = fnt_root->group_list;
fnt_root->group_list = glst;
return &(glst->fnt_group);
}
/*
************************************************************************ *
* make new fontlist and commonelement nodes for the font * *
************************************************************************ *
*/
/*
* Make new font description for `fntname' and insert it in font_list.
*/
static struct Font *
make_new_fontdesc(char *fntname, struct FontMan *fnt_root)
{
struct Font *fnt;
struct FontLst *fontlst;
fontlst = (struct FontLst *)xmalloc((size_t)sizeof(struct FontLst));
fnt = &(fontlst->font);
fnt->common = (struct CommonFontElems *)
xmalloc((size_t)sizeof(struct CommonFontElems));
/* Search for the group of this font, if none found, make a new group */
fnt->common->fnt_group = search_font_group(fntname, FontRoot);
/* Initialize... */
fnt->common->fnt_length = 0L;
fnt->common->lru_count = 0L;
fnt->common->ch_start_bm = NULL;
fnt->common->ch_len = 0L;
fnt->common->location.pk_directory = NULL;
/* search_font_group initialize the TFM width info to 0L for new group
* => it's save to set maxchars to NPXLCHARS
* (=> if this font doesn't exist, it uses the whole tfmw array)
*/
fnt->common->maxchars = NPXLCHARS;
fnt->space_faktor = 0L;
fnt->design_faktor = 0L;
fnt->chksum = 0L;
fnt->ctfmw_valid = (char)FALSE;
/* insert font at the beginning of the font-list */
fontlst->next_font = fnt_root->font_list;
fnt_root->font_list = fontlst;
return fnt;
}
/*
************************************************************************ *
* load / define a font * *
* where we must search the font? * *
* - user defs / pk-dirs / flib-dirs or * *
* - user defs / flib-dirs / pk-dirs or ...? * *
************************************************************************ *
*/
void LoadFont(int action, long fntnum, char *fntname,
long chksum, long d, long s, long fontmag, long fontmag5)
/*
* 0: define only \
* 1: load only => action
* 2: define & load /
*/
{
struct FontLst *fntlst;
struct Font *fnt;
char full_name[PATH_SIZE+FLIB_NAME_SIZE];
int i, is_subst = FALSE;
/* search font with the correct fntnum */
for (fntlst = FontRoot->font_list;
fntlst != NULL && fntlst->font.fnt_number != fntnum;
fntlst = fntlst->next_font);
if (fntlst != NULL) /* font with fntnum found -> font defined */
{
if (action != 1) /* define font, but font already defined?? */
{
Fatal(5, MSG_FONT_ALREADY_DEFINED, fntname, fntnum);
}
fnt = &(fntlst->font);
}
else /* no font with fntnum found -> font undefined */
{
if (action == 1) { /* load only, but font not defined?? */
Fatal(5, MSG_FONT_STR_UNDEFINED, fntname, fntnum);
}
/**** and now -> search the font ****/
fnt = search_font(fntname, fontmag, fontmag5, FontRoot);
}
if (fnt == NULL) {
/* Oh no, NO font */
/* Warning already printed */
fnt = make_new_fontdesc(fntname, FontRoot);
fnt->fnt_number = fntnum;
fnt->common->fnt_status = FNT_NOT_EXISTS;
fnt->common->resolution = fontmag;
fnt->common->resolution5 = fontmag5;
fnt->orig_dpi = fontmag;
fnt->space_faktor = s;
fnt->design_faktor = d;
fnt->chksum = chksum;
for (i=0; i < NPXLCHARS; i++) /* mark the chars */
{
fnt->common->ch[i].packed_data = -1L;
}
/*
* Here we can read the tfm-file of this font (if it exists).
* Currently we use the tfmw info of another font in the same font
* group for the char width info.
*/
return; /* =========>>>>> and return */
}
/* ======================================== */
/* === We know, that fnt != NULL === */
/* ======================================== */
/* here it is */
if (action != 1) { /* not ONLY load the font */
/* define the font */
/* is this font a substituted font ?? */
if (fnt->fnt_number != fntnum &&
(fnt->common->fnt_status == FNT_DEFINED ||
fnt->common->fnt_status == FNT_DEFINED_OLOADED ||
fnt->common->fnt_status == FNT_LOADED)) {
/* problem with substituted fonts -> same font with different fntnum */
struct FontLst *fontlst;
is_subst = TRUE;
fontlst = (struct FontLst *)xmalloc((size_t)sizeof(struct FontLst));
fontlst->font.common = fnt->common;
fontlst->font.orig_dpi = fontmag;
/* sort font into font-list */
fontlst->next_font = FontRoot->font_list;
FontRoot->font_list = fontlst;
fnt = &(fontlst->font); /* this is now the current font */
}
fnt->fnt_number = fntnum; /* define the font */
fnt->space_faktor = s;
fnt->design_faktor = d;
fnt->chksum = chksum;
fnt->ctfmw_valid = (char)FALSE;
#if 0 /* bin mir nicht sicher, ob das gemacht werden muss */
/* Bei den substituierten Fonts muss das ctfmw Feld wieder aufgefrischt werden! */
if (is_subst && (fnt->common->fnt_status == FNT_DEFINED_OLOADED ||
fnt->common->fnt_status == FNT_LOADED)) {
fnt->common->fnt_status = FNT_LOADED;
setup_ctfmw(fnt);
}
#endif
} /* if (action != 1) */
/* exist's the font ?? */
if (fnt->common->fnt_status == FNT_NOT_EXISTS) {
return; /* =========>>>>> and return */
}
if (action == 0) { /* only define the font */
/* FNT_LOADET ist auch moeglich (wb. Substituierung..) */
if (fnt->common->fnt_status != FNT_OLD_LOADED &&
fnt->common->fnt_status != FNT_LOADED) {
fnt->common->fnt_status = FNT_DEFINED;
} else {
fnt->common->fnt_status = FNT_DEFINED_OLOADED;
#if 0 /* bin mir nicht sicher, ob das gemacht werden muss */
setup_ctfmw(fnt);
#endif
}
return; /* =========>>>>> and return */
}
/* ================================================================= */
/* === The font is defined, it exists ... and now: load the font === */
/* ================================================================= */
if (fnt->common->fnt_status == FNT_OLD_LOADED
|| fnt->common->fnt_status == FNT_DEFINED_OLOADED
|| (is_subst && fnt->common->fnt_status == FNT_LOADED)) {
/* pk-file already loaded */
if (!is_subst) {
sprintf(m_string,GetTeXString(MSG_RELOAD_FONT),
fnt->common->fnt_group->fnt_name, fnt->common->resolution);
/** Message(m_string); reload ist auf'n Bildschirm nicht so interessant **/
sprintf(full_name,GetTeXString(MSG_FONTMEM_USED),
(long)(100L-(end_mem-lowmem)*100L/fontmemsize));
strcat(m_string,full_name);
LoggingStr(m_string);
}
setup_lru_font (FontRoot->font_list, fnt);
fnt->common->fnt_status = FNT_LOADED;
setup_ctfmw(fnt);
return; /* =========>>>>> and return */
}
/* ======================= */
/* === Load a new font === */
/* ======================= */
/* So nun sollte eigentlich der Font ins Fontmemory geladen werden. */
/* Alles ist bestens vorbereitet, ein Aufruf Load_really(fnt) taets. */
/* Aber es wird nicht gemacht! Es wird verzoegert, bis wirklich ein */
/* Zeichen aus dem Font benoetigt wird. Sprich erst wenn ein Zeichen */
/* in SetChar nicht gefunden wird. Falls der Font nur definiert ist, */
/* so wird ein Load_really() probiert. */
/* Das hat den Vorteil, wenn ein Font 'removed' wurde, die */
/* benoetigten Chars aber schon im Speicher sind, muss der Font nicht */
/* gleich wieder geladen werden, sonder eben erst, wenn ein Char */
/* auszupacken ist. (hes) */
/* printf("Load new font %s %d (was loaded %d, status %d, valid %d)\n", fnt->common->fnt_group->fnt_name, */
/* fnt->fnt_number, fnt->common->was_loadet, fnt->common->fnt_status, fnt->ctfmw_valid);*/
if (!fnt->common->was_loadet) {
/* dieser Font ist noch nie geladen worden... */
/* also lade ihn zum ersten Mal. Dabei werden */
/* auch die Chars Strukturen initialisiert. */
struct Chars *cd;
fnt->common->was_loadet = TRUE;
/* Initialisiere das ganze nur *einmal* pro Font! */
cd = fnt->common->ch;
for (i=0; i<NPXLCHARS; i++) {
cd->pixelwidth = 0;
cd->packed_data = -1; /* NIL pointer in internal memory */
cd->unpacked = NULL;
cd++;
}
Load_really(fnt); /* beim ersten Mal wird's gleich geladen! */
}
else {
setup_ctfmw(fnt); /* der Font war zwar schon mal geladen, aber ctfmw muss wieder geupdated werden */
}
}
/*
************************************************************************ *
* macht nun den letzten Schritt: Laed den Font in das fontmem * *
************************************************************************ *
*/
void Load_really(struct Font *fnt)
/* fnt_root wird *global* genommen */
{
FILE *pkfile;
char libname[FLIB_NAME_SIZE];
char full_name[PATH_SIZE+FLIB_NAME_SIZE];
long fntnum;
char *fntname;
fntnum = fnt->fnt_number;
fntname = &(fnt->common->fnt_group->fnt_name[0]);
if (fnt->common->fnt_status == FNT_LOADED) {
Fatal(5,MSG_LOAD_LOADED_FONT,fntname,fntnum);
}
Message(MSG_LOAD_FONT,fnt->common->fnt_group->fnt_name,fnt->common->resolution);
if (fnt->common->where_is_font == WHERE_LIB) {
setup_lru_flib(FontRoot->flib_list, fnt->common->location.fnt_library);
pkfile = fnt->common->location.fnt_library->file_ptr;
if (pkfile == NULL) {
if (fnt->common->location.fnt_library->lib_status == LIB_READ_CLOSED) {
my_sprintf(libname,FLIB_NAME_SIZE,fnt->common->location.fnt_library->format_str /*FontRoot->flib_fmt*/,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution,
fnt->common->resolution5);
strcpy(full_name,fnt->common->location.fnt_library->path);
mk_correct_path(full_name);
strcat(full_name,libname);
pkfile = BINARYOPEN(full_name);
if (pkfile != NULL) {
FontRoot->files_left--;
fnt->common->location.fnt_library->lib_status = LIB_OPEND;
fnt->common->location.fnt_library->file_ptr = pkfile;
MarkFile(full_name);
}
else {
Fatal(5,MSG_CANT_OPEN,full_name);
}
}
else {
Fatal(20,MSG_INTERNAL_ERROR_LIB_MISMATCH);
}
}
fseek(pkfile,fnt->common->where_in_lib,0);
}
else {
/* load pk-file */
strcpy(full_name,fnt->common->location.pk_directory->path);
mk_correct_path(full_name);
my_sprintf(libname,FLIB_NAME_SIZE,
fnt->common->location.pk_directory->format_str,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution, fnt->common->resolution5);
#ifdef UNNOETIG
if (fnt->common->where_is_font == WHERE_PKDIR) {
my_sprintf(libname,FLIB_NAME_SIZE,
fnt->common->location.pk_directory->format_str /*FontRoot->pkdir_fmt*/,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution, fnt->common->resolution5);
}
else {
my_sprintf(libname,FLIB_NAME_SIZE,
fnt->common->location.pk_directory->format_str /*FontRoot->pk_fmt*/,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution, fnt->common->resolution5);
}
#endif
strcat(full_name,libname);
if (fnt->common->fnt_status == FNT_PATH_DEFINED) { /* shouldn't occur */
fnt->common->fnt_length = test_pk_file(full_name); /* check size */
if (fnt->common->fnt_length == 0L) {
Fatal(5,MSG_CANT_OPEN,full_name);
}
}
pkfile = BINARYOPEN(full_name);
if (pkfile == NULL) {
Fatal(5,MSG_CANT_OPEN,full_name);
}
MarkFile(full_name);
}
if (pkfile == NULL) { /* unnoetig, da schon abgefragt */
FatalStr(20,"pkfile == NULL");
}
setup_lru_font(FontRoot->font_list, fnt);
fnt->common->copied = (char)FALSE;
fnt->common->ch_start_bm = open_charmap ();
loadfont(fnt, pkfile); /* NEW (laed nur pk-file, packt _nicht_ aus) */
fnt->common->ch_len = close_charmap ();
fnt->common->fnt_status = FNT_LOADED;
setup_ctfmw(fnt);
if (fnt->common->where_is_font != WHERE_LIB) {
fclose(pkfile);
}
Logging(MSG_LOAD_FONT_MEM_USED,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution,
100L-(end_mem-lowmem)*100L/fontmemsize);
if (Stats) {
if (fnt->common->where_is_font == WHERE_LIB) {
my_sprintf(full_name, PATH_SIZE+FLIB_NAME_SIZE, fnt->common->location.fnt_library->format_str,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution, fnt->common->resolution5);
Logging(MSG_FOUND_IN_LIB,
fnt->common->location.fnt_library->path, full_name);
}
else {
my_sprintf(full_name, PATH_SIZE+FLIB_NAME_SIZE, fnt->common->location.pk_directory->format_str,
fnt->common->fnt_group->fnt_name,
fnt->common->resolution, fnt->common->resolution5);
Logging(MSG_FOUND_AS_PK,
fnt->common->location.pk_directory->path, full_name);
}
}
}
/*
************************************************************************ *
* alloc the memory for a character * *
************************************************************************ *
*/
long alloc_char (size)
ulong size;
{
char *memstart;
#if 0
size += (4 - (size % 4)); /* if size%4 == 0, add 4 ???? */
#else
size = (size + 3) & ~3L; /* long alignment */
#endif
while (size > (long)(end_mem - lowmem)) {
if( do_garcol() != 0 )
return (-1L); /* no memory */
}
memstart = lowmem;
#if 0
lowmem = (char *)((ulong)lowmem + size);
#else
lowmem += size;
#endif
if (lowmem < start_mem || charmap < start_mem ||
lowmem > end_mem || charmap > end_mem ) {
Fatal(10,MSG_MEMORY_ERROR);
}
return (long)((memstart - charmap)/sizeof(long)); /* / bytesperlong */
}
/* (br)
* Substitution von Fonts sollte man noch verbessern, z.B. ist es
* manchmal im Previewer wuenschenswert, wenn man kurz auf eine hoehere
* Magnification gehen kann und trotzdem noch die meisten Fonts gefunden
* werden (wenn man Fonts komplett in allen maghalf-Steps hat).
*
* Nachfolgend ist ein Ansatz, wie man dies machen kann.
*
* Um nicht zu grosse Rundungsfehler zu haben, sollte die Resolution, DPI
* bzw. DPI5 (oder Magnification bzgl. DPI) eines Fonts besser mit einem
* Faktor zwischen 2^8 und 2^16 multipliziert im Font-Struct abgelegt werden.
* (Danach muss man jedoch auf Overflows achten !)
*/
/*
************************************************************************
* try to substitute a font within magscale list *
************************************************************************
*/
struct Font *mag_substitution(fntname, dpi, fnt_root)
char *fntname;
long dpi;
struct FontMan *fnt_root;
{
struct Font *fnt;
int i, nr;
long diff, temp, new_dpi, new_dpi5;
diff = 1L<<30; /* max diff */
nr = 0;
for ( i = 0; i < NRMAGS; i++ ) {
/** new_dpi = ((long)resolution * mags[nr] + 500L) / 1000L; **/
new_dpi = ((long)resolution * mags[i] + 500L) / 1000L;
temp = abs(dpi - new_dpi);
/* subst. Font sollte nicht groesser als 5% ueber tatsaechlichem sein */
/* (Heuristik) */
if (temp < diff && (new_dpi <= dpi || temp <= (resolution * 5)/100) ) {
nr = i;
diff = temp;
}
}
fnt = NULL;
while (nr >= 0 && fnt == NULL) {
new_dpi = ((long)resolution * mags[nr] + 500L) / 1000L;
#ifdef FONT_MAG
new_dpi5 = mags[nr];
#else
new_dpi5 = ((long)resolution * 5 * mags[nr] + 500L) / 1000L;
#endif
if (new_dpi != dpi) {
fnt = search_font_location(fntname, new_dpi, new_dpi5, fnt_root);
}
if (fnt == NULL) {
nr--;
if (fnt_root->files_left <= 0) {
close_flibs(fnt_root);
}
}
}
if (nr >= 0) {
/* substitute font */
Logging(MSG_SUBSTITUTE_FONT,fntname,dpi,new_dpi);
Message(MSG_SUBSTITUTE_FONT,fntname,dpi,new_dpi);
}
else {
#ifdef OLD_NOFONT
/* no font found */
struct noFont *nf;
/* Dirty Trick (string alloc) */
nf = (struct noFont *)xmalloc(sizeof(struct noFont) + strlen(fntname));
strcpy(nf->fnt_name, fntname);
nf->resolution = dpi;
nf->next = fnt_root->noFontList;
fnt_root->noFontList = nf;
#endif
if (hconvresolution == vconvresolution) {
Warning(MSG_FONT_NOT_FOUND, fntname, dpi);
}
else {
Warning(MSG_FONT_XY_NOT_FOUND, fntname, dpi, compute_vert(dpi));
}
}
return fnt;
}
/*
************************************************************************
* try to substitute a font with defined fonts/flibs *
************************************************************************
*/
#if 0 /* dass muss ich mir erst mal spaeter in Ruhe ansehen (hes) */
struct Font *dpi_substitution(fntname, magnification, fnt_root)
char *fntname;
long magnification;
struct FontMan *fnt_root;
{
struct Font *fnt;
struct LibLst *lp;
long diff, ndiff, dpi, best_dpi = 0L;
diff = 1L << 30;
for(lp = fnt_root->flib_list; lp != NULL; lp = lp->next_lib) {
if( lp->flib.lib_status == LIB_NONE
|| lp->flib.lib_status == LIB_NOT_EXISTS )
continue;
dpi = lp->flib.resolution;
ndiff = abs(magnification - dpi);
/* subst. Font sollte nicht groesser als 5% ueber tatsaechlichem sein */
if( ndiff < diff && (dpi <= magnification || ndiff <= 5*resolution/100) ) {
diff = ndiff;
best_dpi = dpi;
}
}
Logging(MSG_TRY_SUBSTITUTE,fntname, magnification, best_dpi);
fnt = NULL;
if( best_dpi > 0L ) { /* wir haben was gefunden */
long dpi5;
/* Oouch, this could be totally buggy! */
#ifdef FONT_MAG
dpi5 = (best_dpi * 1000 + resolution/2) / resolution;
#else
dpi5 = best_dpi * 5;
#endif
fnt = search_font_location(fntname, best_dpi, dpi5, fnt_root);
}
if( fnt != NULL ) {
/* substitute font */
Logging(MSG_SUBSTITUTE_FONT,fntname, magnification, best_dpi);
Message(MSG_SUBSTITUTE_FONT,fntname, magnification, best_dpi);
}
return fnt;
}
#endif
/*
************************************************************************
* search a font, substitute fonts if necessary *
************************************************************************
*/
static struct Font *search_font(fntname, magnification, magnification5, fnt_root)
char *fntname;
long magnification;
long magnification5;
struct FontMan *fnt_root;
{
struct Font *fnt;
fnt = search_font_location(fntname, magnification, magnification5, fnt_root);
#ifdef AMIGA
if (fnt == NULL) {
char pkname[PK_NAME_SIZE];
char pkdir[PATH_SIZE];
char *format;
struct SeaEleDpi *dele;
short found;
found = FALSE;
for (dele = FontRoot->s_list_base_pkdpi.first_ele; dele != NULL && !found; dele = dele->next_ele) {
if (dele->hdpi == hconvresolution && dele->vdpi == vconvresolution) {
strcpy(pkdir, dele->path);
mk_correct_path(pkdir);
format = dele->format_str;
found = TRUE;
}
}
if (!found) {
strcpy(pkdir, "TeX:pk/");
format = fnt_root->pk_fmt;
}
my_sprintf(pkname, PK_NAME_SIZE, format, fntname, magnification, magnification5);
if (call_mf(fntname, magnification, hconvresolution, vconvresolution,
(long)fnt_root->driver_type, pkname, pkdir)) { /* call metafont */
fnt = search_font_location(fntname, magnification, magnification5,
fnt_root);
}
}
#endif /* AMIGA */
if (fnt == NULL) {
/* not found => try to substitute, find first matching magstep */
fnt = mag_substitution(fntname, magnification, fnt_root);
}
#if 0 /* das geh ich erst spaeter an... (hes) */
if (fnt == NULL) {
/* search dpi-list of defined flibs, pk's etc. for a possible subst */
fnt = dpi_substitution(fntname, magnification, fnt_root);
}
#endif
if (fnt != NULL) {
/* font found => set lru counter */
setup_lru_font(fnt_root->font_list, fnt);
}
if (fnt_root->files_left <= 0) {
/* close files */
close_flibs(fnt_root);
}
return (fnt);
}
/*
************************************************************************
* where is the font? *
************************************************************************
*/
static struct Font *search_font_location(fntname, dpi, dpi5, fnt_root)
char *fntname;
long dpi, dpi5;
struct FontMan *fnt_root;
{
/* search only for the location of the font. */
/* Returns NULL if the font cannot be found. */
/* return: */
/* font structure with fnt_name/fnt_status/where_is_font/resol. */
struct Font *fnt;
/* Ist der Font einzeln definiert? --------------------*/
fnt = is_font_in_font_list(fntname, dpi, dpi5, fnt_root->font_list, fnt_root);
if (fnt == NULL) {
/* Ist eine passende Library einzeln oder per ENV definiert? -------------------*/
fnt = is_font_in_lib_list(fntname, dpi, dpi5, fnt_root);
if (fnt == NULL) {
/* Ist der Font in einem vordefinierten Base-DPI Verzeichnis? ----------------*/
fnt = is_font_in_pred_pk_dirs(fntname, dpi, dpi5, fnt_root, (short)1);
if (fnt == NULL) {
/* Ist der Font in einem PK-Dir, definiert in der ENV Variable? ------------*/
fnt = is_font_in_pk_dirs(fntname, dpi, dpi5, fnt_root);
if (fnt == NULL) {
/* Ist der Font in einem fuer eine bestimmte DPI ausgelegten Directory? --*/
/* Diese Moeglichkeit ist mehr zum Fontsubstituieren gedacht, */
/* deshalb wird dies erst nach dem Durchsuchen der ENV Pfade gemacht. */
fnt = is_font_in_pred_pk_dirs(fntname, dpi, dpi5, fnt_root, (short)0);
#ifdef AMIGA
if (fnt == NULL) {
/* Ist der Font ueber das TeX:pk/fontvols File zu finden? --------------*/
fnt = read_atex_file(fntname, dpi, dpi5, fnt_root);
}
#endif
}
}
}
}
return (fnt);
}
/*
************************************************************************
* is the font in the font list *
************************************************************************
*/
static struct Font *is_font_in_font_list(fntname, dpi, dpi5, fnt_list, fnt_root)
char *fntname;
long dpi, dpi5;
struct FontLst *fnt_list;
struct FontMan *fnt_root;
{
/* easy function. Looks only in the list of the defined fonts */
/* ^^^^ naja (rbs) */
/* this function doesn't define a NEW font! */
/* only changes the status of a font */
struct FontLst *lst;
char pkname[PK_NAME_SIZE], full_name[PATH_SIZE+FLIB_NAME_SIZE];
long size;
lst = fnt_list;
if (lst == NULL)
return NULL;
do {
if (lst->font.common->resolution == dpi
&& stricmp(lst->font.common->fnt_group->fnt_name, fntname) == 0) {
if (lst->font.common->fnt_status == FNT_FOUND
|| lst->font.common->fnt_status == FNT_DEFINED
|| lst->font.common->fnt_status == FNT_LOADED
|| lst->font.common->fnt_status == FNT_DEFINED_OLOADED
|| lst->font.common->fnt_status == FNT_OLD_LOADED) {
return &(lst->font);
}
if (lst->font.common->fnt_status == FNT_PATH_DEFINED) {
if (lst->font.common->where_is_font == WHERE_LIB) {
Fatal(10,MSG_PREDEF_FONT_IN_LIB);
/* NOT REACHED */
}
my_sprintf(pkname, PK_NAME_SIZE,
lst->font.common->location.pk_directory->format_str /*fnt_root->pk_fmt*/,
fntname, dpi, dpi5);
strcpy(full_name, lst->font.common->location.pk_directory->path);
mk_correct_path(full_name);
strcat(full_name,pkname);
size = test_pk_file(full_name);
if (size != 0L) {
lst->font.common->fnt_status = FNT_FOUND;
lst->font.common->fnt_length = size;
return &(lst->font);
}
/* (size == 0L) */
lst->font.common->fnt_status = FNT_NOT_EXISTS;
Logging(MSG_PREDEF_FONT_NOT_FOUND,fntname,dpi);
}
}
} while( (lst = lst->next_font) != NULL );
return NULL;
}
/*
************************************************************************
* is the font in a fontlibrary *
************************************************************************
*/
static struct Font *is_font_in_lib_list(fntname, dpi, dpi5, fnt_root)
char *fntname;
long dpi, dpi5;
struct FontMan *fnt_root;
{
/* this function looks in all directories for the fontlibraries */
/* then it looks if the fontlib in this directory is already opened */
/* if this is successful, then define a new font and a new fontlibrary */
struct Font *font;
/**** search in the list of predefined libs ****/
font = search_in_defined_libs(fntname, dpi, dpi5, fnt_root);
if (font == NULL) {
/**** font not in a predefined lib => search in the rest of the pathes ****/
font = search_in_rest_pathes(fntname, dpi, dpi5, fnt_root);
}
return (font);
}
/*
************************************************************************
* is the font in a pk-directory (not predefined) *
************************************************************************
*/
static struct Font *is_font_in_pk_dirs(fntname, dpi, dpi5, fnt_root)
char *fntname;
long dpi, dpi5;
struct FontMan *fnt_root;
{
struct Font *font;
struct SeaEle *ele;
ele = fnt_root->s_list_pkdirs.first_ele;
font = NULL;
while (font == NULL && ele != NULL) {
font = define_test_pk_font(ele->path, fntname, dpi, dpi5,
fnt_root->pk_fmt, fnt_root);
ele = ele->next_ele;
}
return (font);
}
/*
************************************************************************
* is the font in a pk-directory (defined in *.fnt) *
************************************************************************
*/
static struct Font *is_font_in_pred_pk_dirs(fntname, dpi, dpi5, fnt_root, base)
char *fntname;
long dpi, dpi5;
struct FontMan *fnt_root;
short base; /* search in base pk-dirs or in normal pk-dirs? */
{
struct Font *font;
struct SeaEleDpi *ele;
if (base) {
ele = fnt_root->s_list_base_pkdpi.first_ele;
}
else {
ele = fnt_root->s_list_pkdpi.first_ele;
}
font = NULL;
while (font == NULL && ele != NULL) {
/* printf("base: %ld, ele->dpi: %ld, dpi: %ld, hc: %ld\n", base, ele->dpi, dpi, hconvresolution); */
/* stimmt die Base-Dpi? */
if ((base && ele->hdpi == hconvresolution && ele->vdpi == vconvresolution) ||
(!base && ele->hdpi == dpi && ele->vdpi == compute_vert(dpi))) {
font = define_test_pk_font(ele->path, fntname, dpi, dpi5,
ele->format_str, fnt_root);
if (font != NULL) {
font->common->where_is_font = WHERE_PKDIR;
}
}
ele = ele->next_ele;
}
return (font);
}
/*
************************************************************************
* test a pk-file and define the font if the pk-file exists *
************************************************************************
*/
static struct Font *define_test_pk_font(path, fntname, dpi, dpi5, format_str, fnt_root)
char *path;
char *fntname;
long dpi, dpi5;
char *format_str;
struct FontMan *fnt_root;
{
char whole_name[PATH_SIZE+FONT_NAME_SIZE];
char pkname[PK_NAME_SIZE];
struct Font *font;
long size; /* size in bytes of pk-file */
BPTR lck;
if (format_str == NULL) Fatal(20, MSG_INTERNAL_ERROR_FMT_STR);
my_sprintf(pkname, PK_NAME_SIZE, format_str, fntname, dpi, dpi5);
strcpy(whole_name,path);
mk_correct_path(whole_name);
strcat(whole_name,pkname);
lck = Lock(whole_name, ACCESS_READ); /* read access ? */
if (!lck) return NULL;
UnLock(lck);
lck = NULL;
/* font is found, now define the font-structure */
size = test_pk_file(whole_name);
if (size == 0L)
return (struct Font *)NULL;
font = make_new_fontdesc(fntname, fnt_root);
font->fnt_number = -1L;
font->common->fnt_status = FNT_FOUND;
font->common->where_is_font = WHERE_PK;
font->common->where_in_lib = 0L;
font->common->fnt_length = size;
font->common->resolution = dpi;
font->common->resolution5 = dpi5;
font->orig_dpi = dpi;
font->common->location.pk_directory =
(struct PK_Dir *)xmalloc((size_t)sizeof(struct PK_Dir));
strcpy(font->common->location.pk_directory->path, path);
font->common->location.pk_directory->format_str = format_str;
return font;
}
/*
************************************************************************
* search a font in the list of fontlibraries *
************************************************************************
*/
static struct Font *search_in_defined_libs(fntname, dpi, dpi5, fnt_root)
char *fntname;
long dpi, dpi5;
struct FontMan *fnt_root;
{
int ret;
struct LibLst *liblist;
FILE *file;
struct Font *font;
char libname[FLIB_NAME_SIZE];
char full_name[PATH_SIZE+FLIB_NAME_SIZE];
int version;
/**** search in the list of predefined libs ****/
for(liblist = fnt_root->flib_list; liblist != NULL;
liblist = liblist->next_lib) {
if (liblist->flib.resolution == dpi) {
/* here is already a lib defined */
if (liblist->flib.lib_status == LIB_PATH_DEFINED) {
/* open the lib and read the directory */
my_sprintf(libname, FLIB_NAME_SIZE, liblist->flib.format_str, fntname, dpi, dpi5);
strcpy(full_name,liblist->flib.path);
mk_correct_path(full_name);
strcat(full_name,libname);
file = open_flib(full_name, B_OPEN_READ, &version, (short)0);
liblist->flib.directory.version = version;
if (file != NULL) {
/* here is really a flib */
ret = read_dir(file,&(liblist->flib.directory));
if (ret) { /* all ok */
fnt_root->files_left--;
liblist->flib.lib_status = LIB_OPEND;
liblist->flib.file_ptr = file;
setup_lru_flib(fnt_root->flib_list,&(liblist->flib));
}
else { /* corrupted file ? */
fclose(file);
liblist->flib.lib_status = LIB_NOT_EXISTS;
}
}
else { /* can't open the file */
liblist->flib.lib_status = LIB_NOT_EXISTS;
}
}
if (liblist->flib.lib_status == LIB_OPEND ||
liblist->flib.lib_status == LIB_READ_CLOSED) {
/* the directoy of the lib is already in the ram */
font = find_font_in_flib(fntname, dpi, dpi5, &(liblist->flib), fnt_root);
if (font != NULL)
return font; /* ======>>>>> found it */
}
}
}
return (struct Font *)NULL;
}
/*
************************************************************************
* search in this places, where no lib is found *
************************************************************************
*/
static struct Font *search_in_rest_pathes(fntname, dpi, dpi5, fnt_root)
char *fntname;
long dpi, dpi5;
struct FontMan *fnt_root;
{
int ret;
char *path, libname[FLIB_NAME_SIZE];
char full_name[PATH_SIZE+FLIB_NAME_SIZE];
struct LibLst *liblist;
FILE *file;
struct Font *font;
struct SeaEle *ele;
int version;
/**** font not in a predefined lib => search in the rest of the pathes ****/
my_sprintf(libname, FLIB_NAME_SIZE, fnt_root->flib_fmt, fntname, dpi, dpi5);
ele = fnt_root->s_list_flib.first_ele;
while (ele != NULL) {
path = ele->path;
ele = ele->next_ele;
/* is this flib (whith this path) already defined?? */
for (liblist = fnt_root->flib_list;
liblist != NULL && (liblist->flib.resolution != dpi ||
(stricmp(liblist->flib.path,path) != 0));
liblist = liblist->next_lib);
if (liblist == NULL) { /* no, nix defined */
/* this path is a new path */
liblist = (struct LibLst *)xmalloc((size_t)sizeof(struct LibLst));
strcpy(full_name,path);
mk_correct_path(full_name);
strcat(full_name,libname);
file = open_flib(full_name, B_OPEN_READ, &version, (short)0);
liblist->flib.directory.version = version;
/* and now, sort the flib into the flib-list */
liblist->next_lib = fnt_root->flib_list;
fnt_root->flib_list = liblist;
liblist->flib.resolution = dpi;
liblist->flib.lru_count = 0;
liblist->flib.format_str = fnt_root->flib_fmt;
strcpy(liblist->flib.path, path);
if (file != NULL) {
/* here is really a flib */
ret = read_dir(file,&(liblist->flib.directory));
if (ret) {
/* define a new fontlibrary */
fnt_root->files_left--;
liblist->flib.file_ptr = file;
liblist->flib.lib_status = LIB_OPEND;
setup_lru_flib(fnt_root->flib_list,&(liblist->flib));
font = find_font_in_flib(fntname, dpi, dpi5, &(liblist->flib), fnt_root);
if (font != NULL)
return font;
}
else {
fclose(file);
liblist->flib.file_ptr = NULL;
liblist->flib.lib_status = LIB_NOT_EXISTS;
}
}
else { /* can't open flib */
liblist->flib.file_ptr = NULL;
liblist->flib.lib_status = LIB_NOT_EXISTS;
}
}
}
return (struct Font *)NULL;
}
/*
************************************************************************
* search-define a font in a fontlibrary *
************************************************************************
*/
static struct Font *find_font_in_flib(fntname, dpi, dpi5, flib, fnt_root)
char *fntname;
long dpi, dpi5;
struct Fnt_Lib *flib;
struct FontMan *fnt_root;
{
/* this function search in a flib a font and if it is found, the font */
/* would be defined and in the font-list inserted. */
char name[FONT_NAME_SIZE];
struct dirlist *dirlist;
struct Font *font;
my_sprintf(name, FONT_NAME_SIZE, fnt_root->flib_fnt_fmt, fntname, dpi, dpi5);
dirlist = findmod(&(flib->directory),name);
if (dirlist == NULL)
return (struct Font *)NULL;
/* font found, now define the font-structure */
font = make_new_fontdesc(fntname, fnt_root);
font->fnt_number = -1L;
font->common->fnt_status = FNT_FOUND;
font->common->where_is_font = WHERE_LIB;
font->common->where_in_lib = dirlist->dirent.where;
font->common->fnt_length = dirlist->dirent.size;
font->common->resolution = dpi;
font->common->resolution5 = dpi5;
font->orig_dpi = dpi;
font->common->location.fnt_library = flib;
return (font);
}
/*
* writes font definitions into log (!) file (by AbortRun if Stats)
*/
void write_font_def_file(void)
{
struct LibLst *llist;
struct FontLst *flist;
struct SeaEle *ele;
struct SeaEleDpi *dele;
long i, j;
char *last_format;
if (FontRoot != NULL)
{
j=0L;
for (flist = FontRoot->font_list; flist != NULL; flist = flist->next_font) {
for (i=0; i<NPXLCHARS; i++) {
if (flist->font.common->ch[i].unpacked != NULL) {
j++;
}
}
}
LoggingStr("");
Logging(MSG_BYTES_USED_FOR_CHARS,FontRoot->unpacked_mem,j);
LoggingStr("");
Logging(MSG_SEARCHPATH_LIB_ENTRIES_NR,FontRoot->s_list_flib.number);
strcpy(m_string,"\t");
for (ele = FontRoot->s_list_flib.first_ele; ele != NULL; ele = ele->next_ele) {
strcat(m_string,ele->path);
if (ele->next_ele != NULL) {
strcat(m_string,", ");
}
}
LoggingStr(m_string);
LoggingStr("");
Logging(MSG_SEARCHPATH_PK_ENTRIES_NR,FontRoot->s_list_pkdirs.number);
strcpy(m_string,"\t");
for (ele = FontRoot->s_list_pkdirs.first_ele; ele != NULL; ele = ele->next_ele) {
strcat(m_string,ele->path);
if (ele->next_ele != NULL) {
strcat(m_string,", ");
}
}
LoggingStr(m_string);
last_format = FontRoot->flib_fmt;
LoggingStr("");
LoggingStr("");
Logging(MSG_LOG_FONTDEF_START);
for (llist=FontRoot->flib_list; llist != NULL; llist = llist->next_lib)
{
if (stricmp(llist->flib.format_str, last_format) != 0) {
last_format = llist->flib.format_str;
LoggingStr("flib_str\t%s", last_format);
}
switch (llist->flib.lib_status)
{
case LIB_READ_CLOSED:
case LIB_OPEND:
Logging(MSG_LOG_FONTDEF_LIB_FOUND,
llist->flib.resolution,
llist->flib.path);
break;
case LIB_PATH_DEFINED:
Logging(MSG_LOG_FONTDEF_LIB_DEF,
llist->flib.resolution,
llist->flib.path);
break;
case LIB_NOT_EXISTS:
Logging(MSG_LOG_FONTDEF_LIB_NOT_FOUND,
llist->flib.resolution,
llist->flib.path);
break;
default:
break;
}
}
if (stricmp(FontRoot->flib_fmt, last_format) != 0) {
LoggingStr("flib_str\t%s", FontRoot->flib_fmt);
}
for (flist = FontRoot->font_list; flist != NULL; flist = flist->next_font) {
flist->font.common->copied = (char)FALSE;
}
last_format = FontRoot->pk_fmt;
for (flist=FontRoot->font_list; flist != NULL; flist = flist->next_font)
{
if (flist->font.common->copied == (char)FALSE)
{
flist->font.common->copied = (char)TRUE;
if (flist->font.common->where_is_font != WHERE_LIB)
{
if (flist->font.common->location.pk_directory != NULL)
{
if (stricmp(flist->font.common->location.pk_directory->format_str,
last_format) != 0) {
last_format = flist->font.common->location.pk_directory->format_str;
LoggingStr("pk_str\t\t%s", last_format);
}
}
switch (flist->font.common->fnt_status)
{
case FNT_FOUND:
case FNT_LOADED:
case FNT_OLD_LOADED:
Logging(MSG_LOG_FONTDEF_PK_FOUND,
flist->font.common->fnt_group->fnt_name,
flist->font.common->resolution,
flist->font.common->location.pk_directory->path);
break;
case FNT_PATH_DEFINED:
Logging(MSG_LOG_FONTDEF_PK_PREDEF,
flist->font.common->fnt_group->fnt_name,
flist->font.common->resolution,
flist->font.common->location.pk_directory->path);
break;
case FNT_NOT_EXISTS:
{
struct PK_Dir *dir;
dir = flist->font.common->location.pk_directory;
if (dir != NULL)
{
Logging(MSG_LOG_FONTDEF_PK_PREDEF_NOT_FOUND,
flist->font.common->fnt_group->fnt_name,
flist->font.common->resolution,
flist->font.common->location.pk_directory->path);
}
break;
}
default:
break;
}
}
}
}
for (flist = FontRoot->font_list; flist != NULL; flist = flist->next_font)
{
flist->font.common->copied = (char)FALSE;
}
if (stricmp(FontRoot->pk_fmt, last_format) != 0) {
LoggingStr("pk_str\t\t%s", FontRoot->pk_fmt);
}
/**** logge die base-pk-directories zu einer bestimmten Grundaufloesung***/
last_format = FontRoot->basepkdir_fmt;
if (FontRoot->s_list_base_pkdpi.number > 0) {
LoggingStr("");
Logging(MSG_LOG_FONTDEF_NR_BASE_PK_DIRS_PREDEF, FontRoot->s_list_base_pkdpi.number);
for (dele = FontRoot->s_list_base_pkdpi.first_ele; dele != NULL; dele = dele->next_ele) {
if (stricmp(dele->format_str, last_format) != 0) {
last_format = dele->format_str;
LoggingStr("basepkdir_str\t%s", last_format);
}
LoggingStr("basepkdir\t%ld\t%ld\t%s", dele->hdpi, dele->vdpi, dele->path);
}
/** das wird hier nicht benoetigt, da ja keine Eintraege dynamisch hinzukommen!
if (stricmp(FontRoot->basepkdir_fmt, last_format) != 0) {
LoggingStr("basepkdir_str\t%s", FontRoot->basepkdir_fmt);
}
**/
}
/**** logge die pk-directories zu einer bestimmten Aufloesung***/
last_format = FontRoot->pkdir_fmt;
if (FontRoot->s_list_pkdpi.number > 0) {
LoggingStr("");
Logging(MSG_LOG_FONTDEF_NO_PK_DIRS_PREDEF, FontRoot->s_list_pkdpi.number);
for (dele = FontRoot->s_list_pkdpi.first_ele; dele != NULL; dele = dele->next_ele) {
if (stricmp(dele->format_str, last_format) != 0) {
last_format = dele->format_str;
LoggingStr("pkdir_str\t%s", last_format);
}
LoggingStr("pkdir\t\t%ld\t%ld\t%s", dele->hdpi, dele->vdpi, dele->path);
}
/** das wird hier nicht benoetigt, da ja keine Eintraege dynamisch hinzukommen!
if (stricmp(FontRoot->pkdir_fmt, last_format) != 0) {
LoggingStr("pkdir_str\t%s", FontRoot->pkdir_fmt);
}
**/
}
Logging(MSG_LOG_FONTDEF_END);
LoggingStr("");
}
}
/*
************************************************************************
* read font definition file *
************************************************************************
*/
static void read_font_def_file(fnt_root, file_name)
struct FontMan *fnt_root;
char *file_name;
{
FILE *f;
#ifndef AMIGA
char def_file[PATH_SIZE], *d;
#endif
#ifdef AMIGA
f = OpenConfigFile(file_name, MODE_READ);
#else
d = getenv(ENV_DEFAULT_PATH);
if (d == NULL) { /** no environment var defined **/
strcpy(def_file,DEFAULT_PATH);
}
else { /** take the defined path **/
strcpy(def_file,d);
}
mk_correct_path(def_file);
strcat(def_file,file_name);
f = fopen(def_file,"r");
#endif
if (f == NULL)
{
#ifdef ATARI
strcpy(def_file, file_name);
if (shel_find(def_file)==0)
{
char *shenv;
Logging("*** Can't open font/flib configuration file \"%s\"!",file_name);
Logging(" Font/flib configuration file has been searched in following pathes:");
if (d != NULL)
{
Logging(" - via environment variable \"%s\" ('%s')",
ENV_DEFAULT_PATH, d);
}
else
{
Logging(" - via default path ('%s')",
DEFAULT_PATH);
}
shel_envrn(&shenv,"PATH=");
strcpy(def_file, (shenv==NULL) ? "" : shenv);
Logging(" - via system environment variable \"PATH=\" ('%s')", def_file);
return;
}
f = fopen(def_file,"r");
if (f == NULL)
{
Logging("*** Can't open font/flib configuration file \"%s\"!",def_file);
return;
}
#else
Logging(MSG_CANT_OPEN_FONT_CONFIG,file_name);
return;
#endif
}
Logging(MSG_LOAD_FONT_CONFIG,file_name);
#ifdef OLDARGS
{ char line[256], *s;
line[255] = '\0';
while(fgets(line,255,f) != NULL) {
s = strrchr(line,'\n');
if (s != NULL) *s = '\0';
s = strchr(line,';');
if (s != NULL) *s = '\0'; /* skip comment */
parse_line(fnt_root,line);
}
}
#else
globarg_fnt_root = fnt_root;
parse_file(font_config,f, 0); /* ignore unknown keywords */
#endif
fclose(f);
}
#ifdef OLDARGS
/*
************************************************************************
* read a line of a font-def-file *
************************************************************************
*/
static void parse_line(fnt_root,line)
struct FontMan *fnt_root;
char *line;
{
char key[20], arg1[100], arg2[100], arg3[100];
long number_dpi;
short mark;
for (; (*line == ' ' || *line == '\t') && *line != '\0'; line++);
if (*line == '\0') { /* empty line */
return;
}
#ifndef ATARI
if (sscanf(line,"%19s %99s %99s %99s",key,arg1,arg2,arg3) < 2) {
Warning(MSG_CANT_PARSE_FONT_CONFIG_LINE,line);
}
#else
if (sscanf(line,"%20s %100s",key,arg1) < 2) {
Warning("Can't parse line \"%s\"!",line);
}
#endif
/*** FLIBENV *******************************************************/
if (stricmp("flibenv",key) == 0) {
if (*arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "flibenv");
}
else {
conc_dirs(line, &(fnt_root->s_list_flib));
}
return;
}
/*** PKENV *******************************************************/
if (stricmp("pkenv",key) == 0) {
if (*arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "pkenv");
}
else {
conc_dirs(line, &(fnt_root->s_list_pkdirs));
}
return;
}
/*** FLIB_STR *******************************************************/
if (stricmp("flib_str",key) == 0) {
if (*arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "flib_str");
}
else {
if ((fnt_root->flib_fmt = strdup(arg1)) == NULL) {
Fatal(10, MSG_NO_MEM);
}
}
return;
}
/*** PK_STR *******************************************************/
if (stricmp("pk_str",key) == 0) {
if (*arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "pk_str");
}
else {
if ((fnt_root->pk_fmt = strdup(arg1)) == NULL) {
Fatal(10, MSG_NO_MEM);
}
}
return;
}
/*** BASEPKDIR_STR *******************************************************/
if (stricmp("basepkdir_str",key) == 0) {
if (*arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "basepkdir_str");
}
else {
if ((fnt_root->basepkdir_fmt = strdup(arg1)) == NULL) {
Fatal(10, MSG_NO_MEM);
}
}
return;
}
/*** PKDIR_STR *******************************************************/
if (stricmp("pkdir_str",key) == 0) {
if (*arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "pkdir_str");
}
else {
if ((fnt_root->pkdir_fmt = strdup(arg1)) == NULL) {
Fatal(10, MSG_NO_MEM);
}
}
return;
}
/*** FLIB_FNT_STR *******************************************************/
if (stricmp("flib_fnt_str",key) == 0) {
if (*arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "flib_fnt_str");
}
else {
if ((fnt_root->flib_fnt_fmt = strdup(arg1)) == NULL) {
Fatal(10, MSG_NO_MEM);
}
}
return;
}
#ifdef ATARI
if (sscanf(line,"%20s %100s %100s",key,arg1,arg2) < 3) {
Warning("Can't parse line \"%s\"!",line);
}
#endif
/*** FLIB *******************************************************/
if (stricmp("flib",key) == 0) {
if (*arg2 == '\0' || *arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "flib");
}
else {
long dpi;
sscanf(arg1,"%ld",&dpi);
define_flib(fnt_root,dpi,arg2);
}
return;
}
/*** PKDIR -- BASEPKDIR *********************************************/
mark = 0;
if (stricmp("pkdir",key) == 0) {
mark = 1;
}
if (stricmp("basepkdir",key) == 0) {
mark = 2;
}
if (mark != 0) {
struct SeaEleDpi *ele, *new;
char *larg;
if (*arg2 == '\0' || *arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, (mark == 1) ? "pkdir" : "basepkdir");
return;
}
/* arg1 == dpi, arg2 == vdpi, arg2/3 (larg) == path */
new = xmalloc(sizeof(struct SeaEleDpi));
if (sscanf(arg1, "%ld",&(new->hdpi)) != 1) {
xfree(new);
Warning(MSG_NOT_A_VALID_INT,arg1);
return; /* ** weg ** */
}
if (isdigit(*arg2)) {
if (sscanf(arg2, "%ld",&(new->vdpi)) != 1) {
xfree(new);
Warning(MSG_NOT_A_VALID_INT,arg1);
return; /* ** weg ** */
}
larg = &(arg3[0]);
if (*larg == '\0') {
xfree(new);
Warning(MSG_TOO_FEW_ARGS, (mark == 1) ? "pkdir" : "basepkdir");
return; /* ** weg ** */
}
}
else {
new->vdpi = new->hdpi;
larg = &(arg2[0]);
}
new->path = strdup(larg);
if (new->path == NULL) {
xfree(new);
return; /* ** weg ** */
}
if (mark == 1) {
new->format_str = strdup(fnt_root->pkdir_fmt);
}
else {
new->format_str = strdup(fnt_root->basepkdir_fmt);
}
if (new->format_str == NULL) {
xfree(new->path);
xfree(new);
return; /* ** weg ** */
}
new->next_ele = NULL;
if (mark == 1) {
fnt_root->s_list_pkdpi.number++;
ele = fnt_root->s_list_pkdpi.first_ele;
if (ele == NULL) {
fnt_root->s_list_pkdpi.first_ele = new;
}
else {
for (; ele->next_ele != NULL; ele = ele->next_ele);
ele->next_ele = new;
}
}
else {
fnt_root->s_list_base_pkdpi.number++;
ele = fnt_root->s_list_base_pkdpi.first_ele;
if (ele == NULL) {
fnt_root->s_list_base_pkdpi.first_ele = new;
}
else {
for (; ele->next_ele != NULL; ele = ele->next_ele);
ele->next_ele = new;
}
}
return;
}
#ifdef ATARI
if (sscanf(line,"%20s %100s %100s %100s",key,arg1,arg2,arg3) < 4) {
Warning("Can't parse line \"%s\"!",line);
}
#endif
/*** FONT *******************************************************/
if (stricmp("font",key) == 0) {
if (*arg3 == '\0' || *arg2 == '\0' || *arg1 == '\0') {
Warning(MSG_TOO_FEW_ARGS, "font");
}
else {
if (sscanf(arg2,"%ld",&number_dpi) == 1) {
define_font(fnt_root,number_dpi,arg3,arg1);
}
else {
Warning(MSG_CANT_READ_DPI_FONT_COMM);
}
}
return;
}
Warning(MSG_UNKNOWN_KEYWORD_IN_CONFIG,key);
}
#else /* OLDARGS */
/* fkw_conc_dirs
*
* Called when a list of directories needs to be parsed.
*/
static void __stdargs fkw_conc_dirs
(struct string_parse *p, char *line)
{
struct SeaLst *sl;
switch (p->paf_userdata) {
case ARG_CONC_FLIB:
sl = &globarg_fnt_root->s_list_flib;
break;
case ARG_CONC_PK:
sl = &globarg_fnt_root->s_list_pkdirs;
break;
#if defined(HARDDEB)
default: Fatal(20,"fkw_conc_dirs() : illegal switch!");
#endif
}
conc_dirs(line, sl);
}
/* fkw_parse_string
*
* Called when a full string needs to be parsed.
*/
static void __stdargs fkw_parse_string
(struct string_parse *p, char *line, char *string)
{
char **s;
switch(p->paf_userdata) {
case ARG_STR_FLIB:
s=&globarg_fnt_root->flib_fmt;
break;
case ARG_STR_PK:
s=&globarg_fnt_root->pk_fmt;
break;
case ARG_STR_BASEPKD:
s=&globarg_fnt_root->basepkdir_fmt;
break;
case ARG_STR_PKDIR:
s=&globarg_fnt_root->pkdir_fmt;
break;
case ARG_STR_FLIBFNT:
s=&globarg_fnt_root->flib_fnt_fmt;
break;
#if defined(HARDDEB)
default: Fatal(20,"fkw_parse_string(): Illegal switch!");
#endif
}
if (NULL == (*s = strdup(string)))
Fatal(10,"Not enough memory!");
}
/* fkw_dir
*
* Called through 'pkdir'and 'basepkdir' keywords
*/
static void __stdargs fkw_dir
(struct string_parse *p, char *line, long *dpi, char *path)
{
int mark = p->paf_userdata;
struct SeaEleDpi *ele, *new;
new = xmalloc(sizeof(struct SeaEleDpi));
new->dpi = *dpi;
new->path = xmalloc(strlen(path)+1);
if (mark == 1) { /* pkdir */
new->format_str = strdup(globarg_fnt_root->pkdir_fmt);
}
else { /* basepkdir */
new->format_str = strdup(globarg_fnt_root->basepkdir_fmt);
}
if (new->format_str == NULL) {
xfree(new);
}
else {
strcpy(new->path, path);
new->next_ele = NULL;
if (mark == 1) {
globarg_fnt_root->s_list_pkdpi.number++;
ele = globarg_fnt_root->s_list_pkdpi.first_ele;
if (ele == NULL) {
globarg_fnt_root->s_list_pkdpi.first_ele = new;
}
else {
for (; ele->next_ele != NULL; ele = ele->next_ele);
ele->next_ele = new;
}
}
else {
globarg_fnt_root->s_list_base_pkdpi.number++;
ele = globarg_fnt_root->s_list_base_pkdpi.first_ele;
if (ele == NULL) {
globarg_fnt_root->s_list_base_pkdpi.first_ele = new;
}
else {
for (; ele->next_ele != NULL; ele = ele->next_ele);
ele->next_ele = new;
}
}
}
}
static void __stdargs fkw_define_flib
(struct string_parse *p, char *line, long *dpi, char *path)
{
define_flib(globarg_fnt_root, *dpi, path);
}
static void __stdargs fkw_define_font
(struct string_parse *p, char *line, char *name, long *dpi, char *where)
{
define_font(globarg_fnt_root, *dpi, where, name);
}
#endif /* OLDARGS */
/*
************************************************************************
* parse string and append the entries to the search list *
************************************************************************
*/
static void conc_dirs(char *str, struct SeaLst *sl)
{
short nr = 0;
char *token;
struct SeaEle *se, *nse, *lse;
for (se = sl->first_ele;
se != NULL && se->next_ele != NULL && se->next_ele->next_ele != NULL;
se = se->next_ele);
/* last ele should be last ele */
if (se != NULL) { /* no ele ? */
if (se->next_ele == NULL) { /* only one ele ? */
lse = se;
se = NULL;
}
else {
lse = se->next_ele;
}
}
(void) strtok(str, " ,\t"); /* skip key word */
do {
token = strtok(NULL, " ,\t");
if (token != NULL) {
if ((nse = xmalloc(sizeof(struct SeaEle))) == NULL) {
sl->number += nr;
return;
}
if ((nse->path = strdup(token)) == NULL) {
xfree(nse);
sl->number += nr;
return;
}
nse->next_ele = lse; /* next ele is every time the last ele */
if (se == NULL) {
sl->first_ele = nse;
}
else {
se->next_ele = nse;
}
nr++;
se = nse;
}
} while (token != NULL);
sl->number += nr;
}
/*
************************************************************************
* define a flib *
************************************************************************
*/
static void define_flib (fnt_root, dpi, path)
struct FontMan *fnt_root;
long dpi;
char *path;
{
struct LibLst *entry;
entry = (struct LibLst *)xmalloc((size_t)sizeof(struct LibLst));
entry->flib.lib_status = LIB_PATH_DEFINED;
strcpy(entry->flib.path,path);
entry->flib.resolution = dpi;
entry->flib.format_str = fnt_root->flib_fmt;
entry->flib.lru_count = 0;
entry->next_lib = fnt_root->flib_list;
fnt_root->flib_list = entry;
}
/*
************************************************************************
* define a pk-font *
************************************************************************
*/
static void define_font (fnt_root, dpi, path, name)
struct FontMan *fnt_root;
long dpi;
char *path;
char *name;
{
struct Font *entry;
struct PK_Dir *p;
/* Huch.... warum wird hier eigentlich auf jeden Fall ein neues font-common angelegt ??? */
/* (br) soll es oder soll es nicht ??? */
/* (hes) wuesste nicht warum ? */
entry = make_new_fontdesc(name, fnt_root);
p = (struct PK_Dir *)xmalloc(sizeof(struct PK_Dir));
strcpy(p->path, path);
p->format_str = fnt_root->pk_fmt;
entry->fnt_number = -1L;
entry->common->fnt_status = FNT_PATH_DEFINED;
entry->common->location.pk_directory = p;
entry->common->resolution = dpi;
entry->common->resolution5 = dpi * 5; /* not exactely */
entry->common->where_is_font = WHERE_PK;
entry->orig_dpi = dpi;
}
/*---------------------------------------------*/
/*
************************************************************************
* initialize the memory-pool for the fonts *
************************************************************************
*/
static void init_mem (ulong size)
{
if (size % 2) size++; /* byte alignment */
lowmem = xmalloc((unsigned)size);
start_mem = lowmem;
#if 0
/* wrong !! compiler/machine-dependent (unsigned long) != (char *) */
end_mem = (char *)((unsigned long)lowmem + (unsigned long)size);
#else
end_mem = lowmem + size;
#endif
}
static long *open_charmap (void)
{
charmap = lowmem;
return ((long *)charmap);
}
static long close_charmap (void)
{
#if 0
return (((long)lowmem - (long)charmap) >> 2); /* length in long's */
#else
return (long)((lowmem - charmap)/sizeof(long)); /* length in long's */
#endif
}
/* verschiebe Bereich von (start + size*4 ... lowmem)
* nach (start ... lowmem - size*4)
* d.h. Bereich (start ... start + size*4 - 1) wird "geloescht"
*/
static void adjust_mem (long *start,long size)
{
long len;
long *copy;
copy = start + size; /* first source-adr */
len = (long)((lowmem - (char *)copy) / sizeof(long)); /* len in byte's */
#if 0
lowmem = (char *) ((long *)lowmem - size);
#else
lowmem = lowmem - (size * sizeof(long));
#endif
while (len-- > 0)
*start++ = *copy++;
#ifdef MYDEBUG
/* After copying: start == lowmem !! */
if( (char *)start != lowmem ) {
LoggingStr("ERROR: adjust_mem() start: 0x%x lowmem: 0x%x size: 0x%x",
start, lowmem, size);
}
#endif
}
static int do_garcol(void)
{
struct Font *rmFont;
struct FontLst *flist;
long size; /* size of deleted font in long's */
/* find font to remove */
rmFont = what_lru_font(FontRoot->font_list);
if (rmFont == NULL) return (TRUE);
/* remove font `rmFont' */
size = rmFont->common->ch_len; /* len in long's */
adjust_mem(rmFont->common->ch_start_bm, size);
/* don't forget to change bm_pointer of fonts in moved area */
for (flist = FontRoot->font_list; flist != NULL; flist = flist->next_font) {
flist->font.common->copied = (char)FALSE;
}
for (flist = FontRoot->font_list; flist != NULL; flist = flist->next_font) {
if (flist->font.common->ch_start_bm != NULL
&& flist->font.common->ch_start_bm > rmFont->common->ch_start_bm
&& flist->font.common->copied == (char)FALSE) {
flist->font.common->ch_start_bm -= size;
flist->font.common->copied = (char)TRUE;
}
}
charmap = charmap - size * sizeof(long);
rmFont->common->ch_start_bm = NULL;
rmFont->common->ch_len = 0;
if (rmFont->common->fnt_status == FNT_LOADED ||
rmFont->common->fnt_status == FNT_DEFINED_OLOADED) {
rmFont->common->fnt_status = FNT_DEFINED;
}
else {
rmFont->common->fnt_status = FNT_FOUND;
}
Message(MSG_FONT_REMOVED,
rmFont->common->fnt_group->fnt_name, rmFont->common->resolution);
Logging(MSG_FONT_REMOVED_USED,
rmFont->common->fnt_group->fnt_name, rmFont->common->resolution,
100L-(end_mem-lowmem)*100L/fontmemsize);
return (FALSE);
}
#ifdef AMIGA
/*
************************************************************************
* read the AmigaTeX "fontvols" file and search a pk-font *
************************************************************************
*/
static struct Font *read_atex_file(char *fntname,
long dpi, long dpi5,
struct FontMan *fnt_root)
{
FILE *fontvols;
struct Font *fnt = NULL;
char *s, *t, *ptr, c;
long d_entry, d_v_entry, read_dpi, read_v_dpi;
int end, linenr;
char *memory, *line, *path, *pkname, *source_name, *dest_name;
/**
Allociere die Arrays per malloc, damit 4kB Stack ausreichen!!
char line[256], path[PATH_SIZE], pkname[PK_NAME_SIZE];
char source_name[PATH_SIZE+FONT_NAME_SIZE], dest_name[PATH_SIZE+FONT_NAME_SIZE],
**/
memory = xmalloc(256+PATH_SIZE+PK_NAME_SIZE+2*(PATH_SIZE+FONT_NAME_SIZE));
line = memory;
path = line+256;
pkname = path+PATH_SIZE;
source_name = pkname+PK_NAME_SIZE;
dest_name = source_name+PATH_SIZE+FONT_NAME_SIZE;
/* suche erst im TEXCONFIG Pfad */
fontvols = OpenConfigFile("fontvols", MODE_READ);
if (fontvols == NULL) {
fontvols = fopen("TeX:pk/fontvols", "r");
}
if (fontvols != NULL) {
line[255] = '\0';
linenr = 0;
while(fnt == NULL && fgets(line,255,fontvols) != NULL) {
d_entry = d_v_entry = 0;
linenr++;
t = strrchr(&(line[0]), '\n'); /* skip trailing Return */
if (t != NULL) *t = '\0';
t = strchr(&(line[0]), ';'); /* skip trailing comment */
if (t != NULL) *t = '\0';
t = &(line[0]); /* skip leading blanks */
while (*t != '\0' && isspace(*t)) t++;
if (*t == '\0') continue; /* skip blank line */
s = strchr(line,'=');
if (s == NULL) {
Warning(MSG_ERROR_IN_FONTVOLS, "`='", linenr);
}
else {
*s++ = '\0';
t = strchr(s, 'd');
if (t != NULL) {
if (sscanf(s, "%ldx%ld", &d_entry, &d_v_entry) != 2) {
d_v_entry = d_entry; /* kein ddxdd entry */
}
s = t+1; /* setze s auf eins nach 'd', sollte ein '.' sein */
}
end = FALSE;
if (t == NULL || *s != '.') {
Warning(MSG_ERROR_IN_FONTVOLS,
(t == NULL) ? "`d' key" : GetTeXString(MSG_FONTVOLS_FIRST_DOT), linenr);
end = TRUE;
}
/* hier wird noch getestet, ob die Zeile auch zur richtigen Aufloesung gehoert */
end = end || (d_entry != 0 && d_entry != hconvresolution && d_v_entry != vconvresolution);
/**
printf("d: %ld, vd: %ld, hc: %ld, vc: %ld, end: %ld, &t: %x, *s: %c\n",
d_entry, d_v_entry, hconvresolution, vconvresolution, end, t, *s);
**/
s++; /* skip point */
while (fnt == NULL && !end) {
/* now read entry */
for (t=s; *t != '\0' && *t != '.' && *t != '\n'; t++);
if (*t == '\n' || *t == '\0') { end = TRUE; }
*t = c = '\0';
if (sscanf(s,"%ld%c", &read_dpi, &c) > 0) {
if (c == 'x') {
ptr = strchr(s, c); /* da sollte nun wirklich nie NULL rauskommen */
if (ptr == NULL || sscanf(ptr+1, "%ld", &read_v_dpi) != 1) {
read_v_dpi = read_dpi; /* da nehmen wir quadratisch an... */
}
}
else {
read_v_dpi = read_dpi;
}
/* teste auf x und y resolution */
if (read_dpi == dpi && read_v_dpi == compute_vert(dpi)) {
char *dest_path;
struct SeaEleDpi *ele;
strcpy(path,line);
strcat(path,":");
/* falls basepkdir definiert wird dieses als Ziel verwendet */
ele = fnt_root->s_list_base_pkdpi.first_ele;
/* suche passendes Dir... */
while (ele != NULL && (ele->hdpi != hconvresolution || ele->vdpi != vconvresolution)) {
ele = ele->next_ele;
}
/* wenn ein basepkdir gefunden, nimm den Formatstring davon */
fnt = define_test_pk_font(path, fntname, dpi, dpi5,
(ele == NULL) ? fnt_root->pk_fmt : ele->format_str, fnt_root);
if (fnt != NULL) {
my_sprintf(pkname, PK_NAME_SIZE, fnt->common->location.pk_directory->format_str, fntname, dpi, dpi5);
strcpy(source_name,path);
mk_correct_path(source_name);
strcat(source_name,pkname);
/* hier wird nun path[] zu dem Zielpfad */
if (ele != NULL) {
/* BasePKDir gefunden */
my_sprintf(pkname, PK_NAME_SIZE, ele->format_str, fntname, dpi, dpi5);
strncpy(dest_name, ele->path, PATH_SIZE);
strncpy(path, ele->path, PATH_SIZE);
mk_correct_path(dest_name);
strncat(dest_name, pkname, PATH_SIZE+FONT_NAME_SIZE);
dest_path = ele->path;
}
else {
/* ansonsten nimm default 'TeX:pk' */
my_sprintf(pkname, PK_NAME_SIZE, fnt_root->pk_fmt, fntname, dpi, dpi5);
strcpy(dest_name, PK_AREA); /* keine Ueberpruefung noetig! */
strcpy(path, PK_AREA);
mk_correct_path(dest_name);
strncat(dest_name, pkname, PATH_SIZE+FONT_NAME_SIZE);
dest_path = PK_AREA;
}
Logging(MSG_COPY_FONT_TO_CACHE,fntname,dpi,dest_path);
Message(MSG_COPY_FONT_TO_CACHE,fntname,dpi,dest_path);
/** fnt_root->files_left =-2; CRASH **/
/** close_flibs(fnt_root); CRASH **/
if (!copy_file(source_name,dest_name)) {
Warning(MSG_CANT_COPY_FONT_TO_CACHE);
}
else {
/* Wenn der Font kopiert...dann setze den Pfad auf die Kopie */
/* damit die Diskette nicht mehr benoetigt wird! */
strncpy(fnt->common->location.pk_directory->path, path, PK_NAME_SIZE);
}
/** fnt_root->files_left =+2; CRASH **/
}
}
}
s = t+1;
} /* end while */
}
}
fclose(fontvols);
}
xfree(memory);
return fnt;
}
/*
************************************************************************
* copy the file source to the file drain (make directory) *
************************************************************************
*/
static int copy_file(char *source, char *drain)
{
FILE *sf, *df;
long len;
char *buffer;
/* erzeuge alle noetigen Unterdirectories */
if (!create_path(drain)) {
return FALSE;
}
/* xmalloc() liefert nie NULL */
buffer = xmalloc(CPBUFSIZE*sizeof(char));
if ((sf = fopen(source,"r")) == NULL) {
xfree(buffer);
return FALSE;
}
if ((df = fopen(drain,"w")) == NULL) {
fclose(sf);
xfree(buffer);
return FALSE;
}
while ((len = fread(buffer,sizeof(char),CPBUFSIZE,sf)) == CPBUFSIZE) {
if (fwrite(buffer,sizeof(char),CPBUFSIZE,df) != CPBUFSIZE) {
fclose(sf);
fclose(df);
xfree(buffer);
return FALSE;
}
}
if (len > 0) {
if (fwrite(buffer,sizeof(char),len,df) != len) {
fclose(sf);
fclose(df);
xfree(buffer);
return FALSE;
}
}
fclose(sf);
fclose(df);
xfree(buffer);
return TRUE;
}
static int create_path(char *path)
{
char *dir, *ptr;
BPTR lock;
ptr = path;
while ((dir = strchr(ptr,'/')) != NULL) {
*dir = '\0';
lock = Lock(path,ACCESS_READ);
if (lock == NULL) {
lock = CreateDir(path);
if (lock == NULL) {
return FALSE;
}
}
UnLock((BPTR)lock);
*dir = '/';
ptr = dir+1;
}
return TRUE;
}
#endif