ftp.nice.ch/pub/next/text/tex/apps/DviInfo.1.2.s.tar.gz#/DviInfo.1.2.s/unix/dviinfo.c

This is dviinfo.c in view mode; [Download] [Up]

/*
 * Dviinfo $Revision: 1.3 $ (c) 1991-93 by Valentino Kyriakides.
 *
 * $Log: dviinfo.c,v $
 * Revision 1.3  1993/11/23  22:49:30  vkyr
 * Added -h,-v options and a Makefile with one compilation def
 * for inch or centimeter.
 *
 * Revision 1.2  1992/05/09  12:30:26  vkyr
 * Added page metric options and a man-page, changed the
 * output text to english.
 *
 * Revision 1.1  1991/06/08  18:31:22  vkyr
 * Initial revision
 *
 * Compile: "cc -o dviinfo dviinfo.c ; strip dviinfo" or 
 * use the supplied Makefile.
 */


/*
 * RCS stuff
 */
 
#ifdef lint
   static char RCSid[] = "$Id: dviinfo.c,v 1.3 1993/11/23 22:49:30 vkyr Exp $";
#endif

/*
 * Needed header-files
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/*
 * Info and version defs
 */
 
#define version "Dviinfo, version 1.3 \n" /* version is $Revision: 1.3 $ */
#define info 	"This is dviinfo, a little TeX dvi-file tool.\n\n"

/*
 * Needed defs
 */
 
#define error(a)	{fprintf(stderr, a); exit(1);}
#define post		248
#define post_post	249
#define dvi_id		2
#define nop			138
#define fnt_def1	243
#define fnt_def2	244
#define fnt_def3	245
#define fnt_def4	246

typedef unsigned long four_bytes;

/*
 * Global vars
 */
 
int cur_command;
double unity;
char *filename,*prgname,**getargv;
FILE *dvi_file;


/*
 * Functions
 */

void print_dimen(four_bytes x)
{
	double val;
	char *unity_name;
	
	val = unity*x / 10000.0;
	if (getargv[1][0] == '-')
	{
		switch (getargv[1][1])
		{
			default:
			case 'c':	if (val > 10)
						{
							unity_name = "cms";
							val /= 10;
						}
						else
							unity_name = "mm";
						break;
			case 'i':	val /= 10;
						val = val * 0.3937;
						unity_name = "inches";
						break;
			case 'p':	val /= 10;
						val = val * 28.346;
						unity_name = "points";
						break;
			case 'P':	val /= 10;
						val = val * 2.3623;
						unity_name = "picas";
						break;
		}
	} else {
#ifdef INCH		/* defaults page metric to inches */
		val /= 10;
		val = val * 0.3937;
		unity_name = "inches";
#else	/* Not INCH defaults page metric to centimeters */
		if (val > 10)
		{
			unity_name = "cms";
			val /= 10;
		}
		else
			unity_name = "mm";
#endif	/* INCH */
	}
	printf("%5.2f %s", val, unity_name);
}



four_bytes read_unsigned(int bytes)
{
	four_bytes x;
	
	x = getc(dvi_file);
	while (bytes-- >1)
	{
		x *= 256;
		x += getc(dvi_file);
	}
	return(x);
}


int reverse_getc(void)
{
	fseek(dvi_file, -2, SEEK_CUR);
	return(getc(dvi_file));
}


void process_dvi_file(void)
{
	four_bytes design_size, at_size;
	four_bytes num, den, magnification;
	four_bytes page_width, page_height;
	int		   a, l, pages;
	double	   font_size;
	fpos_t	   post_loc;	
	
	
	fseek(dvi_file,0,SEEK_END);					  /* EOF */
									  /* ignore fillbytes */
	while ((cur_command = reverse_getc()) == 223)
		;
	if (cur_command != dvi_id)
		error("Wrong id-Byte in postamble");
									  /* read backwards till post_post */
	reverse_getc(); reverse_getc(); reverse_getc();
	reverse_getc();	cur_command = reverse_getc();
	if (cur_command != post_post)
		error("Postamble not found");
	post_loc = (fpos_t)read_unsigned(4);
									  /* jump to postamble */
	if (fseek(dvi_file,post_loc,SEEK_SET) != 0)
		error("Seek error, `postamble' not found");
	if ((cur_command = (int) read_unsigned(1)) != post)
		error("Postamble not found");
	read_unsigned(4);
									  /* pointer to begin of last page */
	num = read_unsigned(4);  den = read_unsigned(4);
	magnification = read_unsigned(4);
	unity = (num*((double) magnification/1000))/den;
	page_height = read_unsigned(4);
	page_width = read_unsigned(4);
	read_unsigned(2);						  /* ignore stacksize */
	pages = (int) read_unsigned(2);
	printf("\nThe dvi-file \"%s\" contains (%d) pages.\n",filename, pages);
	printf("Each page is ");
	print_dimen(page_width); printf(" wide and ");
	print_dimen(page_height); printf(" high.\n\n");
	printf("The dvi-file \"%s\" needs the following fonts: \n\n", filename);
	while (cur_command != post_post)
	{
		cur_command = (int) read_unsigned(1);
		switch (cur_command)
		{
			case nop:
			case post_post : break;
			case fnt_def1 :
			case fnt_def2 :
			case fnt_def3 :
			case fnt_def4 :
				read_unsigned(cur_command-fnt_def1+1);
				read_unsigned(4);			  /* overread checksum */
				at_size = read_unsigned(4);
				design_size = read_unsigned(4);
				a = (int) read_unsigned(1);
				l = (int) read_unsigned(1);
				while (a-- > 0)
					putc(getc(dvi_file), stdout);
				fputs(" -> ", stdout);  /* previously putc(':', stdout); */
				while (l-- > 0)
					putc(getc(dvi_file), stdout);
				font_size = (at_size*((double)magnification/1000))/design_size;
				printf(" at magstep %5.3f\n", font_size);
				break;
			default : error("Illegal command");
		}
	}
	printf("\n(EOF - bye!)\n\n");
}

int usage(char *prgname)
{	
	fputs(info, stderr);
	fprintf(stderr,"Usage: %s [-c | -i | -p | -P] [-h] [-v] [dvi-file]\n", prgname);
	fprintf(stderr,"Where: \n");
	fprintf(stderr,"\t -c \t Show page layout in cms (default)\n");
	fprintf(stderr,"\t -i \t Show page layout in inches \n");
	fprintf(stderr,"\t -p \t Show page layout in points \n");
	fprintf(stderr,"\t -P \t Show page layout in picas \n");
	fprintf(stderr,"\t -h \t Print a summary of the options \n");
	fprintf(stderr,"\t -v \t Print the version number \n\n");
	exit(0);
}

int main(int argc, char **argv)
{
    getargv = argv;
	prgname = *argv;
	if (argc < 2)
	{
		usage(prgname);
	}
	argv++;  
	if (argc == 3)
		argv++;
	if (getargv[1][0] == '-')
	{
		switch (getargv[1][1])
		{
			case 'v':	fputs(version, stderr);
						return(1);
						break;
			case 'h':	usage(prgname);
						break;
		}
	}
	dvi_file = fopen(*argv, "rb");
	if (dvi_file == NULL)
	{
		fprintf(stderr,"Can't open DVI-file %s \n", *argv);
		return(1);
	}
	filename = *argv;
	process_dvi_file();
	return(0);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.