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