/* 
 * $Locker:  $ 
 */ 
static char	*rcsid = "$XConsortium: showsnf.c,v 1.14 88/10/14 13:15:13 jim Exp $";
#include <stdio.h>
#include "Xos.h"
#include <sys/types.h>
#include <sys/stat.h> 
#include <fcntl.h>
#include <errno.h> 
#include <malloc.h>

#include "misc.h" 
#include "Xmd.h"
#include "X.h"
#include "Xproto.h"
#include "fontstruct.h"
#include "../../server/ddx/snf/snfstruct.h"
#include "font.h"

#include "bdftosnf.h"	/* used by converters only */
char *program;

extern void bitorderinvert(), twobyteinvert(), fourbyteinvert();
static void showfont(char *file, int verbose);

int glyphPad = DEFAULTGLPAD;
int bitorder = DEFAULTBITORDER;
int byteorder = DEFAULTBYTEORDER;
int scanunit = DEFAULTSCANUNIT;

main(argc, argv)
	int	argc;
	char	**argv;
{
	int	verbose = 0,
		fontcnt = 0;

	program = *argv;
	for (argc--, argv++; argc; argc--, argv++) {
		if (argv[0][0] == '-')
			switch(argv[0][1]) {
			case 'g':	verbose++; /* fall through */
			case 'v':	verbose++; break;
			case 'm':	bitorder = MSBFirst; break;
			case 'l':	bitorder = LSBFirst; break;
			case 'M':	byteorder = MSBFirst; break;
			case 'L':	byteorder = LSBFirst; break;
			case 'p':	glyphPad = atoi (argv[0] + 2);
			case 'u':	scanunit = atoi (argv[0] + 2);
			default:	usage(); break;
			}
		else {
			showfont(argv[0], verbose);
			fontcnt++;
		}
	}
	if (!fontcnt)
		usage();
	exit(0);
}

usage()
{
    fprintf (stderr, "usage:  %s [-options ...] snffile ...\n\n", program);
    fprintf (stderr, "where options include:\n");
    fprintf (stderr,
	"    -v            print character bearings and sizes\n");
    fprintf (stderr,
	"    -g            print character glyph bitmaps\n");
    fprintf (stderr,
	"    -m            set bit order to Most Significant Bit First\n");
    fprintf (stderr,
	"    -l            set bit order to Least Significant Bit First\n");
    fprintf (stderr,
	"    -M            set byte order to Most Significant Byte First\n");
    fprintf (stderr,
	"    -L            set byte order to Least Significant Byte First\n");
    fprintf (stderr,
	"    -p#           set glyph padding to #\n");
    fprintf (stderr,
	"    -u#           set scanline unit to #\n");
    fprintf (stderr, "\n");
    exit (1);
}

static void
showfont(file, verbose)
	char	*file;
	int	verbose;
{
	char	*buf;
	struct stat	st;
	TempFont	tf;
	FontInfoRec f;
	int	fd, i;
	char	*strings;
	int bytesGlUsed;
	long total;

	if (stat(file, &st) < 0) {
		fprintf(stderr, "can't stat %s\n", file);
		return;
	}

	fd = open(file, O_RDONLY|O_BINARY);
	if (fd < 0) {
		fprintf(stderr, "can't open %s\n", file);
		return;
	}
	i = st.st_size;
	if (st.st_size >= 0x10000) {
		fprintf(stderr, "%s: file too big\n", file);
		i = 0xfffe;
	}
	buf = malloc(i);
	if (buf == 0) {
		printf("size=%d\n", i);
		perror("malloc");
		return;
	}
	i = read(fd, buf, i);
	if (i == -1) {
		perror(file);
		return;
	}
	close(fd);

	total = (unsigned)i;
	tf.pFI = (FontInfoPtr)buf;
	i = BYTESOFFONTINFO(tf.pFI);
	total -= i;
	if (total < 0) {
		printf("FontInfo=%d\n", i);
		goto badSNF;
	}
	if (tf.pFI->version1 != FONT_FILE_VERSION ||
	    tf.pFI->version2 != FONT_FILE_VERSION) {
	    printf("version = %d %d\n", tf.pFI->version1, tf.pFI->version2);
	    goto badSNF;
	}
	tf.pCI = (CharInfoPtr)(buf + i);
	i = BYTESOFCHARINFO(tf.pFI);
	total -= i;
	if (total < 0) {
		printf("CharInfo=%d\n", i);
		goto badSNF;
	}
	tf.pGlyphs = ((unsigned char *)tf.pCI) + i;
	bytesGlUsed = BYTESOFGLYPHINFO(tf.pFI);
	total -= bytesGlUsed;
	if (total < 0) {
		printf("GlyphInfo=%d\n", i);
		goto badSNF;
	}
	tf.pFP = (FontPropPtr)(tf.pGlyphs + bytesGlUsed);
	i = BYTESOFPROPINFO(tf.pFI);
	total -= i;
	if (total < 0) {
		printf("PropInfo=%d\n", i);
		goto badSNF;
	}
	strings = (char *)tf.pFP + i;
	if (tf.pFI->inkMetrics) {
	    i = BYTESOFSTRINGINFO(tf.pFI);
	    total -= i;
	    if (total < 0) {
		    printf("StringInfo=%d\n", i);
		    goto badSNF;
	    }
	    tf.pInkMin = (CharInfoPtr)(strings + i);
	    tf.pInkMax = tf.pInkMin + 1;
	    tf.pInkCI = tf.pInkMax + 1;
	}

	for (i=0; i<tf.pFI->nProps; i++) {
		tf.pFP[i].name = (u_long)strings + tf.pFP[i].name;
		if (tf.pFP[i].indirect)
			tf.pFP[i].value = (u_long)strings + tf.pFP[i].value;
	}
	if (bitorder == LSBFirst)
	    bitorderinvert(tf.pGlyphs, bytesGlUsed);
	if (bitorder != byteorder) {
	    if (scanunit == 2)
		twobyteinvert(tf.pGlyphs, bytesGlUsed);
	    else if (scanunit == 4)
		fourbyteinvert(tf.pGlyphs, bytesGlUsed);
	}
	printf("\n\n-------------  %s  ---------------\n\n", file);
	DumpFont(&tf, glyphPad, verbose);
	free(buf);
	return;

badSNF:
	fprintf(stderr, "bad format SNF file: %s\n", file);
	return;
}
