1 #ifndef lint
2 static char sccsid[] = "@(#)dumpdev.c	1.2 (CWI) 85/10/24";
3 #endif lint
4 
5 /*
6  * inverse of makethev, dump de information of the (binary) device information
7  * will also dump the font info of standard (default) mounted fonts.
8  *
9  * Usage:
10  * dumpdev [flags] device
11  *
12  * flags:
13  *	-f name;	take info from dir name instead of default dir
14  *	-Tdevice;	device for wich the dump is made;
15  *	-D;		dump only the device info, not the font info
16  *	-F F1 F2 ...;	dump only the named fonts info
17  *	-d;		give extra debug info on error output
18  *
19  * Author: jaap akkerhuis, Mathematisch Centrum, Oc 1982
20  *
21  */
22 
23 # include "../dev.h"
24 # include <stdio.h>
25 
26 # define BMASK	0377
27 # define FATAL	1
28 
29 struct dev	dev;
30 struct Font	font;
31 
32 char *fontdir	= "/usr/local/lib/ditroff/font";
33 char *devname	= "har";	/* devicename */
34 
35 int	nfonts;
36 int	nsizes;
37 int	nchtab;
38 
39 # define NSIZE	100	/* maximum number of sizes */
40 
41 # define NCH	256	/* maximum number of characters with funny names */
42 
43 # define FSIZE	200	/* size of physical font */
44 
45 # define NFONT	10	/* Maximum number of default fonts */
46 
47 int	dbg;
48 int 	Dflag;
49 int	Fflag;
50 
51 main(argc, argv)
52 int	argc;	char *argv[];
53 {	FILE *fp;
54 
55 	while (argc > 1 && argv[1][0] == '-') {
56 		switch (argv[1][1]) {
57 		case 'f':
58 			fontdir = argv[2];
59 			argv++;
60 			argc--;
61 			break;
62 		case 'd':
63 			dbg ++;
64 			break;
65 		case 'T':
66 			devname = &argv[1][2];
67 			break;
68 		case 'D':
69 			Dflag++;
70 			break;
71 		case 'F':
72 			Fflag++;
73 			break;
74 		default:
75 			fprintf( stderr, "Unknown option %c\n", argv[1][1]);
76 			break;
77 		}
78 		argv++;
79 		argc--;
80 	}
81 
82 	if(devname == NULL)
83 		error(FATAL,"No device specified");
84 
85 	getdesc();
86 
87 	if(Dflag)
88 		exit(0);
89 
90 	if( Fflag)
91 		while ( argc > 1) {
92 			getfont( argv[1] );
93 			argv++;
94 			argc--;
95 		}
96 }
97 
98 error(f, s, a1, a2, a3, a4, a5, a6, a7) {
99 	fprintf(stderr, "dumpdev: ");
100 	fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
101 	fprintf(stderr, "\n");
102 	if (f)
103 		exit(1);
104 }
105 
106 /*
107  * structure of a device file.
108  *
109  * the first part consists of the structure dev.
110  *
111  * Notes: dev.filesize contains the size of the file minus the strcture dev
112  * 	dev.nchtab contains the nimber of funny charnames +1
113  *
114  * then follows a list of sizes (shorts), ended with a zero.
115  *
116  * then follows a table of dev.nchtab pointers ( shorts  ),
117  * 	these will point to the strings with all the funnynames.
118  *	this is called chtab.
119  *
120  * after this is the table of funny names (chname) which is dev.lnchname
121  *	bytes big.
122  *
123  * So up uo here the device charactistics are read.
124  *
125  * Then follows the default mounted font info, dev.nfont times (max NFONT).
126  *
127  * first the font structure.
128  *
129  * font.nwfonts is the amount of widths of the font, so it will be used
130  * as the amount of characters in the font as well.
131  *
132  * so now will follow:
133  *	the widthtable (font.nwfonts bytes) containg the widths info
134  *	the kerntable (font.nwfonts bytes) containing the de- & ascender info
135  *	the codetable (font.nwfonts bytes) containing the codes for the chars
136  *	the fitable (dev.nchtab+128-32 bytes) containing indexes to the
137  *		previous three tables.
138  *
139  *	if font.fonttab == 1
140  *		will also follow the fcodetable (font.nwfonts (sizeof(short))
141  *		containing the physical font numbers ( see also the comment
142  *		added by jna in makedev.c)
143  *
144  * for info about the use of this tables, see the comment at dumpfont.
145  *
146  */
147 
148 char *chname;
149 short *chtab;
150 
151 getdesc()
152 {
153 	char *malloc(), *filebase, *p;
154 	struct	Font	*fontbase[NFONT];
155 	short *pstab, *p1;
156 	int i, fin, nw;
157 	char temp[60];
158 
159 	sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname);
160 
161 	if((fin = open(temp, 0)) < 0)
162 		error(FATAL, "can't open DESC.out for %s\n", temp);
163 
164 	printf("# Dump of device %s (%s)\n", devname, temp);
165 
166 	if((read(fin, &dev, sizeof(struct dev))) != sizeof(struct dev))
167 		error(FATAL, "read error reading devstruct %s", temp);
168 	nfonts = dev.nfonts;
169 	nsizes = dev.nsizes;
170 	nchtab = dev.nchtab;
171 	if(nfonts > NFONT)
172 		error(!FATAL,"More (%d) fonts then possible (%d)",
173 			nfonts, NFONT);
174 	if(nsizes > NSIZE)
175 		error(!FATAL,"More (%d) sizes then possible (%d)",
176 			nsizes, NSIZE);
177 	if(nchtab > NCH)
178 		error(!FATAL,"More (%d) names then possible (%d)",
179 			nchtab, NCH);
180 	if(dbg) {
181 		fprintf(stderr,
182 	"filesize %d, default fonts %d, sizes %d, funny names %d lchname %d\n",
183 		dev.filesize, dev.nfonts, dev.nsizes, dev.nchtab, dev.lchname);
184 		fprintf(stderr,
185 	"sizescale %d, paperwidth %d, paperlenght %d, spare1 %d, spare2 %d\n",
186 		dev.sizescale, dev.paperwidth, dev.paperlength, dev.spare1,
187 		dev.spare2);
188 	}
189 
190 	printf("res %d\nhor %d\nvert %d\nunitwidth %d\n",
191 			dev.res, dev.hor, dev.vert, dev.unitwidth);
192 	if( dev.sizescale)
193 		printf("sizescale %d\n", dev.sizescale);
194 	if(dev.paperwidth)
195 		printf("paperwidth %d\n", dev.paperwidth);
196 	if(dev.paperlength)
197 		printf("paperlength %d\n", dev.paperlength);
198 	if(dev.spare1)
199 		printf("spare1 %d\n", dev.spare1);
200 	if(dev.spare2)
201 		printf("spare2 %d\n", dev.spare2);
202 
203 	filebase = malloc(dev.filesize);	/* enough room for whole file */
204 	if((read(fin, filebase, dev.filesize)) != dev.filesize)	/* all at once */
205 		error(FATAL, "read error reading fontinfo %s", temp);
206 	pstab = (short *) filebase;
207 
208 	printf("sizes ");
209 	i = 0;
210 	for( p1 = pstab; *p1; p1++) {
211 		i++;
212 		printf("%d ",*p1);
213 	}
214 	printf("\n");
215 	if ( i != nsizes)
216 		error(!FATAL, "%s sizes (%d) then expected (%d)\n",
217 			i > nsizes ? "More" : "Less", i, nsizes);
218 
219 	chtab = pstab + nsizes + 1;	/* table of indexes in chname */
220 	chname = (char *) (chtab + dev.nchtab);	/* start of name table */
221 	p = chname + dev.lchname;	/* beginning of first font */
222 
223 	for ( i = 0; i < nfonts; i++) {	/* pickup the font names */
224 		fontbase[i] = (struct Font *) p;
225 		nw = *p & BMASK;	/* first thing is width count */
226 		p += sizeof(struct Font);
227 		p += 3 * nw + dev.nchtab + 128 - 32;
228 		if(fontbase[i]->fonttab == 1)
229 			p += nw * sizeof( short );
230 	}
231 	printf("fonts %d", nfonts);
232 	for ( i = 0; i < nfonts; i++)
233 		printf(" %s",fontbase[i]->namefont);
234 	printf("\n");
235 
236 	if(dbg) {
237 		fprintf(stderr, "Indexes:");
238 		p1 = chtab;
239 		i = 0;
240 		for( p1 = chtab; p1 < chtab + dev.nchtab - 1; p1++) {
241 			i++;
242 			fprintf(stderr, " %d", *p1);
243 			if( i == 16) {
244 				fprintf(stderr,"\n");
245 				i = 0;
246 			}
247 		}
248 		if( i != 0)
249 			fprintf(stderr, "\n");
250 	}
251 
252 	printf("charset\n");
253 	i = 0;
254 	for( p1 = chtab; p1 < chtab + dev.nchtab -1; p1++) {
255 		int i2;
256 		i++;
257 		printf("  %s", chname + *p1);
258 		if( i == 16 || (i2 == 0 & i == 4)) {
259 			printf("\n");
260 			i = 0;
261 			if( i2 == 0)
262 				i2++;
263 		}
264 	}
265 	if( i != 0)
266 		printf("\n");
267 
268 	if( !Dflag)
269 		if ( !Fflag)
270 			for( i = 0; i < nfonts ; i++ )
271 				dumpfont( fontbase[i]);
272 	close( fin );
273 }
274 
275 /*
276  * How to use the tables
277  *
278  * the fitable (font index table) contains indexes to the information about
279  * all the characters of a device that can be printed.
280  * The device is supposed to have all (128-32) printable ascii chars.
281  * We rely on thus idea
282  * There are also an unknown numer (den.nchtab -1) funny chars.
283  * So this make it clear why fitab is device dependent and not font dependent.
284  *
285  * For ascii characters you get your information by:
286  *	fitab[inputchar-32] will have the index in the tables,
287  *	if the index is 0, the char doesn't exist on this font
288  *		so f.i. codetab[fitab[inputchar-32]] will give you the
289  *		outputcode.
290  *
291  * For funny chars:
292  * 	Compare the string of the funny char with strings in nchname table
293  *	if the nth string are the same, you can find the index by
294  *	fitab[n + 128-32]
295  *	if the index is 0, the char doesn't exist on this font
296  *	and the kerning info f.i. by
297  *	kerntab[fitab[n + 128-32]]
298  *	if font.fonttab == 1
299  *		There will also be a font code table, this is found by
300  *		the same ways.
301  *	if n >= dev.nchtab, the funny name was illegal.
302  *
303  * Note:
304  *	Width[0] contains the spacesize, set by or the spacesize command
305  *	while constructing the font file, or the default spacesize.
306  *
307  */
308 
309 dumpfont( font )
310 struct Font *font;
311 {	char *p;
312 	int nw;
313 	int i, c;
314 	char *kerntab, *fitab, *widthtab, *codetab;
315 	short *fcode;
316 
317 	p = (char *) font;
318 
319 	nw = *p & BMASK;
320 
321 	p += sizeof(struct Font);
322 
323 	widthtab = p;
324 	p += nw;
325 	kerntab = p;
326 	p += nw;
327 	codetab = p;
328 	p += nw;
329 	fitab = p;
330 	if( font->fonttab == 1) {	/* the fcode tab is here */
331 		p += nchtab + 128 -32;
332 		fcode = (short *) p;
333 	}
334 
335 	printf("# Fontinfo for %s\n", devname);
336 	printf("name %s\n", font->namefont);
337 	printf("internalname %s\n", font->intname);
338 	if( font->specfont )
339 		printf("special\n");
340 	mklig( font->ligfont );
341 	if( font->fonttab )
342 		printf("fonttab\n");
343 	if( font->slant )
344 		printf("slant %d\n", font-> slant);
345 	if( *widthtab )	/* widthtab[0] contains the spacewidth */
346 		printf( "spacewidth %d\n", *widthtab & BMASK);
347 
348 	/* now print the contents of this font */
349 
350 	/* first the ascii chars */
351 	for( c = 0; c < 128 - 32; c++) {
352 		i = fitab[c];
353 		if( i ) {
354 			printf("%c\t%d\t%o\t0%o",
355 			  (c + 32) & BMASK, widthtab[i] & BMASK,
356 			   kerntab[i] & BMASK, codetab[i] & BMASK);
357 			if(font->fonttab == 1)
358 				printf("\t%d\n", fcode[i]);
359 			else
360 				printf("\n");
361 		}
362 	}
363 
364 	/* and now the special ones */
365 	for( c = 0; c < nchtab; c++) {
366 		i = (unsigned char)fitab[c + 128 - 32];
367 		if(i) {
368 			printf("%s\t%d\t%o\t0%o",
369 			  &chname[chtab[c]], widthtab[i] & BMASK,
370 			   kerntab[i] & BMASK, codetab[i] & BMASK);
371 			if(font->fonttab == 1)
372 				printf("\t%d\n", fcode[i]);
373 			else
374 				printf("\n");
375 		}
376 	}
377 }
378 
379 
380 mklig( c )
381 char c;
382 {
383 	if( !c )
384 		return;
385 
386 	printf("ligatures");
387 
388 	if( c & LFF)
389 		printf(" ff");
390 	if( c & LFI)
391 		printf(" fi");
392 	if( c & LFL)
393 		printf(" fl");
394 	if( c & LFFI)
395 		printf(" ffi");
396 	if( c & LFFL)
397 		printf(" ffl");
398 	printf(" 0\n");
399 }
400 
401 getfont( fname )
402 char *fname;
403 {	char *malloc(), *p;
404 	int fin, size;
405 	char temp[60];
406 
407 	sprintf(temp,"%s/dev%s/%s.out", fontdir, devname, fname);
408 
409 	if((fin = open(temp, 0)) < 0)
410 		error(FATAL, "can't open %s\n", temp);
411 
412 	printf("# Dump of font %s (%s)\n", fname, temp);
413 
414 	size = lseek(fin, 0L, 2);	/*get size of file*/
415 	if(dbg)
416 		fprintf(stderr, "Size of font %s: %d\n", temp, size);
417 
418 	lseek(fin, 0L, 0);
419 
420 	p = malloc( size);
421 
422 	if((read(fin, p, size)) != size )
423 		error(FATAL, "read error at %s\n", temp);
424 
425 	dumpfont(p);
426 	free( p );
427 	close (fin);
428 }
429