Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "tdef.h"
2
#include "fns.h"
3
#include "ext.h"
4
 
5
#define	MAXCH NCHARS		/* maximum number of global char names */
6
char	*chnames[MAXCH];	/* chnames[n-ALPHABET] -> name of char n */
7
int	nchnames;		/* number of Cxy names currently seen */
8
 
9
#define	MAXPS	100		/* max number of point sizes */
10
int	pstab[MAXPS];		/* point sizes */
11
int	nsizes;			/* number in DESC */
12
 
13
Font	fonts[MAXFONTS+1];	/* font info + ptr to width info */
14
 
15
 
16
#define	skipline(f)	while (getc(f) != '\n')
17
 
18
#define	eq(s1, s2)	(strcmp(s1, s2) == 0)
19
 
20
getdesc(char *name)
21
{
22
	FILE *fin;
23
	char cmd[100], s[100];
24
	int i, v;
25
 
26
	if ((fin = fopen(name, "r")) == NULL)
27
		return -1;
28
	while (fscanf(fin, "%s", cmd) != EOF) {
29
		if (strcmp(cmd, "res") == 0) {
30
			fscanf(fin, "%d", &Inch);
31
		} else if (strcmp(cmd, "hor") == 0) {
32
			fscanf(fin, "%d", &Hor);
33
		} else if (strcmp(cmd, "vert") == 0) {
34
			fscanf(fin, "%d", &Vert);
35
		} else if (strcmp(cmd, "unitwidth") == 0) {
36
			fscanf(fin, "%d", &Unitwidth);
37
		} else if (strcmp(cmd, "sizes") == 0) {
38
			nsizes = 0;
39
			while (fscanf(fin, "%d", &v) != EOF && v != 0 && nsizes < MAXPS)
40
				pstab[nsizes++] = v;
41
		} else if (strcmp(cmd, "fonts") == 0) {
42
			fscanf(fin, "%d", &nfonts);
43
			for (i = 1; i <= nfonts; i++) {
44
				fscanf(fin, "%s", s);
45
				fontlab[i] = PAIR(s[0], s[1]);
46
			}
47
		} else if (strcmp(cmd, "charset") == 0) {	/* add any names */
48
			while (fscanf(fin, "%s", s) != EOF)
49
				chadd(s, Troffchar, Install);
50
			break;
51
		}
52
		/* else 
53
			just skip anything else */
54
		skipline(fin);
55
	}
56
	fclose(fin);
57
	return 1;
58
}
59
 
60
static int checkfont(char *name)
61
{		/* in case it's not really a font description file */
62
		/* really paranoid, but consider \f. */
63
	FILE *fp;
64
	char buf[300], buf2[300];
65
	int i, status = -1;
66
 
67
	if ((fp = fopen(name, "r")) == NULL)
68
		return -1;
69
	for (i = 1; i <= 10; i++) {
70
		if (fgets(buf, sizeof buf, fp) == NULL)
71
			break;
72
		sscanf(buf, "%s", buf2);
73
		if (buf2[0] == '#') {
74
			i--;
75
			continue;
76
		}
77
		if (eq(buf2, "name") || eq(buf2, "fontname") ||
78
		    eq(buf2, "special") || eq(buf2, "charset")) {
79
			status = 1;
80
			break;
81
		}
82
	}
83
	fclose(fp);
84
	return status;
85
 
86
}
87
 
88
getfont(char *name, int pos)	/* create width tab for font */
89
{
90
	FILE *fin;
91
	Font *ftemp = &fonts[pos];
92
	Chwid chtemp[MAXCH];
93
	static Chwid chinit;
94
	int i, nw, n, wid, kern, code, type;
95
	char buf[100], ch[100], s1[100], s2[100], s3[100], cmd[300];
96
 
97
	/* fprintf(stderr, "read font %s onto %d\n", name, pos); */
98
	if (checkfont(name) == -1)
99
		return -1;
100
	if ((fin = fopen(name, "r")) == NULL)
101
		return -1;
102
	for (i = 0; i < ALPHABET; i++)
103
		chtemp[i] = chinit;	/* zero out to begin with */
104
	ftemp->specfont = ftemp->ligfont = 0;
105
	ftemp->defaultwidth = ftemp->spacewidth = Inch * Unitwidth / 72 / 3; /* should be rounded */
106
	nw = code = 0;
107
	while (fscanf(fin, "%s", cmd) != EOF) {
108
		if (strcmp(cmd, "name") == 0)
109
			fscanf(fin, "%s", ftemp->longname);
110
		else if (strcmp(cmd, "special") == 0)
111
			ftemp->specfont = 1;
112
		else if (strcmp(cmd, "ligatures") == 0) {
113
			ftemp->ligfont = getlig(fin);
114
		} else if (strcmp(cmd, "spacewidth") == 0) {
115
			fscanf(fin, "%d", &ftemp->spacewidth);
116
		} else if (strcmp(cmd, "defaultwidth") == 0) {
117
			fscanf(fin, "%d", &ftemp->defaultwidth);
118
		} else if (strcmp(cmd, "charset") == 0) {
119
			wchar_t wc;
120
			skipline(fin);
121
			nw = ALPHABET;
122
			while (fgets(buf, sizeof buf, fin) != NULL) {
123
				sscanf(buf, "%s %s %s %s", ch, s1, s2, s3);
124
				if (s1[0] != '"') {	/* genuine new character */
125
					sscanf(s1, "%d", &wid);
126
					sscanf(s2, "%d", &kern);
127
					code = strtol(s3, 0, 0);	/* dec/oct/hex */
128
				}
129
				/* otherwise it's a synonym for prev character, */
130
				/* so leave previous values intact */
131
 
132
 
133
				/* decide what kind of alphabet it might come from here */
134
 
135
 
136
				if (strlen(ch) == 1) {	/* it's ascii */
137
					n = ch[0];	/* origin includes non-graphics */
138
					chtemp[n].num = ch[0];
139
				} else if (ch[0] == '\\' && ch[1] == '0') {
140
					n = strtol(ch+1, 0, 0);	/* \0octal or \0xhex */
141
					chtemp[n].num = n;
142
#ifdef UNICODE
143
				} else if (mbtowc(&wc, ch, strlen(ch)) > 1) {
144
					chtemp[nw].num = chadd(ch,  MBchar, Install);
145
					n = nw;
146
					nw++;
147
#endif	/*UNICODE*/
148
				} else {
149
					if (strcmp(ch, "---") == 0) { /* no name */
150
						sprintf(ch, "%d", code);
151
						type = Number;
152
					} else
153
						type = Troffchar;
154
					chtemp[nw].num = chadd(ch, type, Install);
155
					n = nw;
156
					nw++;
157
				}
158
				chtemp[n].wid = wid;
159
				chtemp[n].kern = kern;
160
				chtemp[n].code = code;
161
				/*fprintf(stderr, "font %2.2s char %4.4s num %3d wid %2d code %3d\n",
162
					ftemp->longname, ch, n, wid, code);
163
				*/
164
			}
165
			break;
166
		}
167
		skipline(fin);
168
	}
169
	fclose(fin);
170
	chtemp[' '].wid = ftemp->spacewidth;	/* width of space on this font */
171
	ftemp->nchars = nw;
172
	if (ftemp->wp)
173
		free(ftemp->wp);	/* god help us if this wasn't allocated */
174
	ftemp->wp = (Chwid *) malloc(nw * sizeof(Chwid));
175
	if (ftemp->wp == NULL)
176
		return -1;
177
	for (i = 0; i < nw; i++)
178
		ftemp->wp[i] = chtemp[i];
179
/*
180
 *	printf("%d chars: ", nw);
181
 *	for (i = 0; i < nw; i++)
182
 *		if (ftemp->wp[i].num > 0 && ftemp->wp[i].num < ALPHABET) {
183
 *			printf("%c %d ", ftemp->wp[i].num, ftemp->wp[i].wid);
184
 *		else if (i >= ALPHABET)
185
 *			printf("%d (%s) %d ", ftemp->wp[i].num,
186
 *				chnames[ftemp->wp[i].num-ALPHABET], ftemp->wp[i].wid);
187
 *	}
188
 *	printf("\n");
189
 */
190
	return 1;
191
}
192
 
193
chadd(char *s, int type, int install)	/* add s to global character name table; */
194
{					/* or just look it up */
195
 
196
	/* a temporary kludge:  store the "type" as the first character */
197
	/* of the string, so we can remember from whence it came */
198
 
199
	char *p;
200
	int i;
201
 
202
/* fprintf(stderr, "into chadd %s %c %c\n", s, type, install); /* */
203
	for (i = 0; i < nchnames; i++)
204
		if (type == chnames[i][0] && eq(s, chnames[i]+1)) /* +1 since type at front */
205
			break;
206
/* fprintf(stderr, "i %d, nchnames %d\n", i, nchnames); /* */
207
	if (i < nchnames)		/* found same type and bytes at position i */
208
		return ALPHABET + i;
209
	else if (install == Lookup)	/* not found, and we were just looking */
210
		return -1;
211
 
212
	chnames[nchnames] = p = (char *) malloc(strlen(s)+1+1);	/* type + \0 */
213
	if (p == NULL) {
214
		ERROR "out of space adding character %s", s WARN;
215
		return LEFTHAND;
216
	}
217
	if (nchnames >= NCHARS - ALPHABET) {
218
		ERROR "out of table space adding character %s", s WARN;
219
		return LEFTHAND;
220
	}
221
	strcpy(chnames[nchnames]+1, s);
222
	chnames[nchnames][0] = type;
223
/* fprintf(stderr, "installed %c%s at %d\n", type, s, nchnames); /* */
224
	return nchnames++ + ALPHABET;
225
}
226
 
227
char *chname(int n)	/* return string for char with index n */
228
{			/* includes type char at front, to be peeled off elsewhere */
229
	if (n >= ALPHABET && n < nchnames + ALPHABET)
230
		return chnames[n-ALPHABET];
231
	else
232
		return "";
233
}
234
 
235
getlig(FILE *fin)	/* pick up ligature list */
236
{
237
	int lig;
238
	char temp[200];
239
 
240
	lig = 0;
241
	while (fscanf(fin, "%s", temp) != EOF && strcmp(temp, "0") != 0) {
242
		if (strcmp(temp, "fi") == 0)
243
			lig |= LFI;
244
		else if (strcmp(temp, "fl") == 0)
245
			lig |= LFL;
246
		else if (strcmp(temp, "ff") == 0)
247
			lig |= LFF;
248
		else if (strcmp(temp, "ffi") == 0)
249
			lig |= LFFI;
250
		else if (strcmp(temp, "ffl") == 0)
251
			lig |= LFFL;
252
		else
253
			fprintf(stderr, "illegal ligature %s ignored\n", temp);
254
	}
255
	return lig;
256
}