• No results found

Den sammenstiller ikke informasjonen for hvert tegn slik som tftopl(1) gjr, men viser hvordan TFM-len er bygget opp

Programmet benytter i tillegg til lene her, lene

splitpath.h

og

splitpath.c

som er frt opp under pltovpl .

3.1 tfmdump.c

/*#############################################################################

// tfmdump.c

//// Inneholder prosedyrer som finner metrics for en gitt font og gitt // tegnnr. Leser i fontens tilhrende .TFM-fil.

////###########################################################################*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/param.h>

#include <sys/stat.h>

#include "splitpath.h"

#define VERSION "0.4 (test)"

#define DATE "1993-06-22"

#define AUTHOR "larsth@ifi.uio.no"

#define COPYRIGHT "C Not at all, this is public domain"

#define TEXFONTS "TEXFONTS"

#define DEFAULTDIR "/local/lib/tex/fonts"

#define PATHSEP ':'

#define DIRSEP '/'

#define WHATEVER 200

#define TRUE 1

#define FALSE 0

#define FORMATSOCTAL "[%03o]"

#define FORMATShex "[%02x]"

#define FORMATSHEX "[%02X]"

#define FORMATSDECIMAL "[%02d]"

#define FORMAT1OCTAL "\t[%03o]"

#define FORMAT1hex "\t[%02x]"

#define FORMAT1HEX "\t[%02X]"

#define FORMAT1DECIMAL "\t[%03d]"

#define FORMAT1CHAR "\t[%c]"

#define FORMAT2OCTAL "\t[%03o] [%03o]"

#define FORMAT2hex "\t[%02x] [%02x]"

#define FORMAT2HEX "\t[%02X] [%02X]"

81

#define FORMAT2DECIMAL "\t[%03d] [%03d]"

#define FORMAT2CHAR "\t[%c] [%c]"

#define FORMAT4OCTAL "\t[%03o] [%03o] [%03o] [%03o]"

#define FORMAT4hex "\t[%02x] [%02x] [%02x] [%02x]"

#define FORMAT4HEX "\t[%02X] [%02X] [%02X] [%02X]"

#define FORMAT4DECIMAL "\t[%03d] [%03d] [%03d] [%03d]"

#define FORMAT4CHAR "\t[%c] [%c] [%c] [%c]"

typedef unsigned char byte;

typedef unsigned int halfword;

typedef unsigned long word;

typedef float real;

halfword lf,lh,bc,ec,nw,nh,nd,ni,nl,nk,ne,np;

byte charinfo_w[256]; /* address of width */

byte charinfo_h[256]; /* address of height */

byte charinfo_d[256]; /* address of depth */

byte charinfo_i[256]; /* address of italic corr */

byte charinfo_t[256]; /* address of tag */

byte charinfo_r[256]; /* address of remainder */

real width[256];

real height[16];

real depth[16];

real italic[64];

real kern[256]; /* OBS: dette kan vre feil */

real param[22];

char *paramname[] = { /* including math symbols and math extension */

"slant","space","stretch","shrink","x-height","quad","extraspace","num1",

"num2","num3","denum1","denum2","sup1","sup2","sup3","sub1","sub2",

"supdrop","subdrop","delin1","delim2","axis-height",

"default-rule-thickness","big-op-spacing1","big-op-spacing2",

"big-op-spacing3","big-op-spacing4","big-op-spacing5"

};

FILE *f;

char filnavn[MAXPATHLEN];

char *progname;

halfword filesize;

halfword bytes; /* file counter */

char byteinfo2[10], byteinfo1[9], byteinfo4[30], stringinfo[7];

int byteinfo, all, error_continue;

FILE *errorfile;

/*======================================================================*/

/* User interface module

/*======================================================================*/

/*---*/

/* Help message */

/*---*/

help()

{ printf("Dumps with usable information and checks a given tfm file.\n");

printf("All strings from file will be enclosed as <this>. Unprintable ");

printf("strings will\nbe printed in octal if no other options are present.");

printf(" Real values for metrics\nwill be rounded to 6 decimals.\n");

printf("%s will search for files in directories held in the ",progname);

printf("environment variable\nTEXFONTS\n");

printf("\nGuide to options:\n");

printf(" -C\tContinue after errors\n");

printf(" -S\tPrint sizeof info for variables (compilation information)\n");

printf(" -V\tVersion information\n");

printf(" -X\tPrint byte info in hexadecimal with capital letters\n");

printf(" -a\tPrints normally irrelevant information; indicates -o\n");

printf(" -c\tPrint byte info as characters\n");

printf(" -d\tPrint byte info in decimal\n");

printf(" -f\tForce, same as -C\n");

printf(" -h\tThis help message\n");

printf(" -o\tPrint byte info in octal\n");

printf(" -x\tPrint byte info in hexadecimal with small letters\n");

}

/*---*/

/* Usage */

/*---*/

usage()

{ printf("usage: %s [options, -h for help] font.tfm\n",progname);

}

/*---*/

/* error. Norwegian: feil */

/*---*/

feil(char *t)

{ fprintf(errorfile,"ERROR: %s\n",t);

if ( !error_continue) exit(1);

}

/*---*/

/* displays the part headline message */

/*---*/

headline(char *line) { printf("\n%s\n",line);

}

/*---*/

/* Standard message displayer for byte */

/* Prints messages with byte information */

/*---*/

show1(char *t, byte b) { printf("%30s: %3d",t,b);

if (byteinfo)

printf(byteinfo1,b);

printf("\n");

}

/*---*/

/* Standard message displayer for halfword */

/* Prints messages with byte information */

/*---*/

show2(char *t, halfword value, byte b1, byte b2) { printf("%30s: %d",t,value);

if (byteinfo)

printf(byteinfo2,b1,b2);

printf("\n");

}

/*---*/

/* Standard message displayer for decimal word */

/* Prints messages with byte information */

/*---*/

show4(char *t, word value, byte b1, byte b2, byte b3, byte b4) { printf("%30s: %3ld",t,value);

if (byteinfo)

printf(byteinfo4,b1,b2,b3,b4);

printf("\n");

}

/*---*/

/* Standard message displayer for octal word */

/* Prints messages with byte information */

/*---*/

show4o(char *t, word value, byte b1, byte b2, byte b3, byte b4) { printf("%30s: %lo",t,value);

if (byteinfo)

printf(byteinfo4,b1,b2,b3,b4);

printf("\n");

}

/*---*/

/* Standard message displayer for single */

/* real/fix_word. */

/* Prints messages with byte information */

/*---*/

show4f(char *t, real value, byte b1, byte b2, byte b3, byte b4) { if (value-(int)value != 0.0)

printf("%30s: %g",t,value);

elseprintf("%30s: %.1f",t,value);

if (byteinfo)

printf(byteinfo4,b1,b2,b3,b4);

printf("\n");

}

/*---*/

/* Standard message displayer for real/fix_word. */

/* Prints messages with byte information */

/*---*/

show4fw(char *t, byte i,real value, byte b1, byte b2, byte b3, byte b4) { printf("%25s[%3d]: %f",t,i,value);

if (byteinfo)

printf(byteinfo4,b1,b2,b3,b4);

printf("\n");

}

/*---*/

/* Standard message displayer for char_info/address */

/* Prints messages with byte information */

/*---*/

showi(byte cno,byte w, byte h, byte d, byte i, byte t, byte r) { printf(" Character[%3d]: ",cno);

printf("w=%3d, h=%2d, d=%2d, i=%2d, t=%1d, r=%3d\n",w,h,d,i,t,r);

}

/*---*/

/* Standard message displayer for extensible chars */

/* Prints messages with byte information */

/*---*/

showe(byte no,byte top, byte mid, byte bot, byte rep) { printf(" Extensible character[%3d]: ",no);

printf("top=%3d, mid=%3d, bot=%3d, rep=%3d\n",top,mid,bot,rep);

}

/*---*/

/* Standard message displayer for strings */

/* Prints messages with byte information */

/*---*/

shows(char *t, char *value, int length) { int visible = TRUE;

int i,j;

for(i=0;i<length;i++)

if (value[i]<32) visible=FALSE;

if (visible)

printf("%30s: <%s>\n",t,value);

elseprintf("%30s: (string is not printable, %d bytes)\n",t,length);

if (!visible || all) { printf("%30s: ","");

for(i=0;i<length;i++)

{ printf(stringinfo,value[i]);

if ( (i+1)%8 == 0 && i+1 < length) printf("\n%30s: ","");

printf("\n");} } }

/*---*/

/* Standard message displayer for description or */

/* message strings */

/*---*/

showd(char *t, char *message) { printf("%30s: %s\n",t,message);

}

/*======================================================================*/

/* Utilities module

/*======================================================================*/

/*---*/

/* Reads the next byte, if EOF, error */

/*---*/

byte next() { byte c;

if (bytes >= filesize)

{ fprintf(errorfile,"Unexpected end after %ld bytes\n",bytes);

exit(2);

}

c=(byte)getc(f);

bytes++;

return (byte)c;

}

/*---*/

/* Hjelpeprosedyre som dekoder lengdeinfo fr selve */

/* headeren begynner. */

/*---*/

eval_two_bytes(halfword *var, byte b1, byte b2) { *var = (b1<<8) | b2;

}

/*---*/

/* Hjelpeprosedyre som omregnet to bytes til en */

/* float iht den spesielle kodingen. */

/*---*/

real fix_word(byte k1,byte k2,byte k3,byte k4) { unsigned long t;

double fisk; /* fish */

t=(k1<<24)|(k2<<16)|(k3<<8)|k4;

if (k1 & 0x80)

{ t = t ^ 0xffffffff;

t++;fisk = -(double)t/ (double)1048576;

}

elsefisk=(double)t/(double)1048576;

return (real)fisk;

}

/*---*/

/* Decodes face information according to Xerox */

/*---*/

char *xerox(byte face)

{ static char code[] = "Xerox face code: ";

const int weight = 18 ; const int slope = 19 ; const int expansion = 20 ;

/* I could of course used a switch here... */

if (face>=12)

{ code[expansion]='E'; face-=12; } if (face>=6)

{ code[expansion]='C'; face-=6; } elsecode[expansion]='R';

if (face % 2 == 0) code[slope]='R';

elsecode[slope]='I';

if (face>=4) code[weight]='L';

else if (face>=2) code[weight]='B';

elsecode[weight]='M';

return code;

}

/*======================================================================*/

/* Initiating and terminating module

/*======================================================================*/

/*---*/

/* Gets the file size. If to small, error */

/*---*/

halfword getfilesize() { struct stat buf;

if ( fstat(fileno(f),&buf) != 0 )

{ fprintf(errorfile,"%s: Cannot stat file. Sorry.\n",progname);

exit(1);

}

if (buf.st_size > 65536) /* this should be 2^sizeof(halfword) */

fprintf(errorfile,"%s: File size to big, %ld\n",progname,buf.st_size);

return (halfword)buf.st_size;

}

/*---*/

/* variable size information */

/*---*/

varsizeinfo()

{ printf("Sizeof BYTE=%2d (should be at least 8 bit)\n",sizeof(byte));

printf("Sizeof HALFWORD=%2d (should be at least 16 bit)\n",sizeof(halfword));

printf("Sizeof WORD=%2d (should be at least 32 bit)\n",sizeof(word));

printf("Sizeof REAL=%2d (should be at least 32 bit)\n",sizeof(real));

printf("\nIf values are to small, ");

printf("fix the definition in source and recompile\n");

}

/*---*/

/* Options and parameters */

/*---*/

options(int argc, char *argv[]) { char c;

while (--argc > 0 && (*++argv)[0] == '-') { while (c = *++argv[0])

switch (c) {case 'C':

case 'f':

error_continue=TRUE;

errorfile=stdout;

break;

case 'S':

varsizeinfo();

exit(0);

break;

case 'V':

printf("%s, version %s, date %s\n",progname,VERSION,DATE);

printf("Written by %s. %s\n",AUTHOR,COPYRIGHT);

exit(0);

break;

case 'X':

byteinfo=TRUE;

strcpy(stringinfo,FORMATSHEX);

strcpy(byteinfo1,FORMAT1HEX);

strcpy(byteinfo2,FORMAT2HEX);

strcpy(byteinfo4,FORMAT4HEX);

break;

case 'a':

all=TRUE;

byteinfo=TRUE;

break;

case 'c':

byteinfo=TRUE;

strcpy(byteinfo1,FORMAT1CHAR);

strcpy(byteinfo2,FORMAT2CHAR);

strcpy(byteinfo4,FORMAT4CHAR);

break;

case 'd':

byteinfo=TRUE;

strcpy(stringinfo,FORMATSDECIMAL);

strcpy(byteinfo1,FORMAT1DECIMAL);

strcpy(byteinfo2,FORMAT2DECIMAL);

strcpy(byteinfo4,FORMAT4DECIMAL);

break;

case 'h':

help();

usage();

exit(0);

break;

case 'o':

byteinfo=TRUE;

break;

case 'x':

byteinfo=TRUE;

strcpy(stringinfo,FORMATShex);

strcpy(byteinfo1,FORMAT1hex);

strcpy(byteinfo2,FORMAT2hex);

strcpy(byteinfo4,FORMAT4hex);

break;

default:

usage();

exit(9);

break;

} /* while flere opsjoner */} if (argc--)

strcpy(filnavn,*argv);

else{

fprintf(errorfile,"%s: tfm file missing\n",progname);

usage();

exit(1);

if (argc)}

fprintf(errorfile,

"%s: Cannot examine more than one tfm file, ignoring others.\n", progname);

}

/*---*/

/* Initiererer diverse

/*---*/

init(int argc, char *argv[]) { int tmp;

/* Variable initialization */

progname = (char *) calloc(strlen(argv[0])+1,sizeof(char));

strcpy(progname,argv[0]);

bytes=0;

strcpy(stringinfo,FORMATSOCTAL);

strcpy(byteinfo1,FORMAT1OCTAL); /* Octal is default */

strcpy(byteinfo2,FORMAT2OCTAL);

strcpy(byteinfo4,FORMAT4OCTAL);

all=FALSE;

byteinfo=FALSE;

error_continue=FALSE;

errorfile=stderr;

/* checking options and parameters */

options(argc,argv);

/* Sjekker alle lovlige directories og apner tfm-filen */

split(getenv(TEXFONTS),DEFAULTDIR,PATHSEP,DIRSEP);

if ((f=findopen(filnavn,"r")) == NULL)

{ fprintf(errorfile,"%s: Cannot open <%s>\n",progname,filnavn);

exit(1);

}

/* checking file size and displays file info */

tmp=byteinfo; byteinfo=FALSE;

filesize=getfilesize();

headline("*FILE INFORMATION*");

showd("File path",findopenname());

show2("File size in bytes",filesize,0,0);

show2("File size in words",filesize/4,0,0);

byteinfo=tmp;

if (filesize%4 != 0)

feil("File size is not a multiple of words");

if (filesize < 24+4+4) /* preheader + header[0] + header[1] */

feil("File size is to small, not even a proper header");

}

/*---*/

/* Terminating stuff */

/* Checks for junk after logical end */

/*---*/

term() { byte cont;

char buffer[8];

/* junk after end? */

if (bytes < filesize) {

headline("*JUNK AFTER LOGICAL END*");

while (bytes < filesize) { cont=8;

while (bytes < filesize && cont) buffer[8-cont--]=next();

shows("Some bytes with junk",buffer,8-cont);

} } fclose(f);

printf("\nDet var det!\n");

}

/*======================================================================*/

/* Main module

/*======================================================================*/

/*---*/

/* preheader, first 24 byte */

/*---*/

preheader() { byte b1,b2;

halfword lf2;

headline("PREHEADER INFORMATION (first 24 bytes):");

b1=next(); b2=next();

eval_two_bytes(&lf,b1,b2);

show2("Length of file in words",lf,b1,b2);

if (filesize < lf*4)

feil("File size is smaller than the given size");

else if (filesize > lf*4)

feil("File size is larger than the given size");

b1=next(); b2=next();

eval_two_bytes(&lh,b1,b2);

show2("Length of header in words",lh,b1,b2);

if (lh < 2)

feil("Should be at least 2 words");

b1=next(); b2=next();

eval_two_bytes(&bc,b1,b2);

show2("Smallest character code",bc,b1,b2);

if (bc < 0 || bc > 255)

feil("Smallest character code not in legal range [0-255]");

b1=next(); b2=next();

eval_two_bytes(&ec,b1,b2);

show2("Largest character code",ec,b1,b2);

if (bc > ec)

feil("Smallest character code is greater than largest");

if (ec > 255)

feil("Largest character code not in legal range [0-255]");

b1=next(); b2=next();

eval_two_bytes(&nw,b1,b2);

show2("Words in width table",nw,b1,b2);

if (nw > 256)

feil("Number of widths not in legal range [1-256]");

b1=next(); b2=next();

eval_two_bytes(&nh,b1,b2);

show2("Words in height table",nh,b1,b2);

if (nh > 16)

feil("Number of heights not in legal range [1-16]");

b1=next(); b2=next();

eval_two_bytes(&nd,b1,b2);

show2("Words in depth table",nd,b1,b2);

if (nd > 16)

feil("Number of depths not in legal range [1-16]");

b1=next(); b2=next();

eval_two_bytes(&ni,b1,b2);

show2("Words in italic table",ni,b1,b2);

if (ni > 64)

feil("Number of italics not in legal range [1-64]");

b1=next(); b2=next();

eval_two_bytes(&nl,b1,b2);

show2("Words in lig/kern table",nl,b1,b2);

b1=next(); b2=next();

eval_two_bytes(&nk,b1,b2);

show2("Words in kern table",nk,b1,b2);

b1=next(); b2=next();

eval_two_bytes(&ne,b1,b2);

show2("Words in extensible table",ne,b1,b2);

b1=next(); b2=next();

eval_two_bytes(&np,b1,b2);

show2("Words in font parameters",np,b1,b2);

if (np != 0 && np != 7 && np != 13 && np!= 22)

feil("Number of parameters should be 0, 7, 13 or 22");

/* and now for the total length check */

lf2 = 6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np;

if (lf2 > lf)

feil("Length of words is greater than given");

else if (lf2 < lf)

feil("Length of words is less than given");

}

/*---*/

/* Header, checksum, designsize, some text */

/*---*/

header()

{ int i,not_zero;

byte b1,b2,b3,b4;

byte codingschemechars,familychars;

byte sevenbitsafeflag,face;

word chksum;

real designsize;

char codingscheme[41], family[21];

char buffer[WHATEVER];

headline("HEADER INFORMATION");

/* checksum */

b4=next(); b3=next(); b2=next(); b1=next();

chksum = (b4<<24)|(b3<<16)|(b2<<8)|(b1);

show4o("Checksum in octal",chksum,b4,b3,b2,b1);

/* designsize */

b4=next(); b3=next(); b2=next(); b1=next();

designsize = fix_word(b4,b3,b2,b1);

show4f("Designsize",designsize,b4,b3,b2,b1);

/* if optional header info, then find it */

if (lh > 2) {

/* codingscheme */

codingschemechars=next();

show1("No. of chars in codingscheme",codingschemechars);

if (codingschemechars < 0 || codingschemechars > 39) feil("No. of chars not in legal range [0-39]");

for(i=0; i<codingschemechars; i++) codingscheme[i]=(char)next();

codingscheme[i]='\0';

shows("Codingscheme",codingscheme,codingschemechars);

not_zero=FALSE;

for(i=0; i<39-codingschemechars; i++) if ( (buffer[i]=(char)next()) != '\0')

not_zero=TRUE;

buffer[i]='\0';

if ( not_zero || all )

shows("Unused bytes i codingscheme",buffer,39-codingschemechars);

if (lh-1 > 11) {

/* font family */

familychars=next();

show1("No. of chars in family",familychars);

if (familychars < 0 || familychars > 19)

feil("No. of chars not in legal range [0-19]");

for(i=0; i<familychars;i++) family[i]=(char)next();

family[i]='\0';

shows("Font family",family,familychars);

not_zero=FALSE;

for(i=0; i<19-familychars; i++)

if ( (buffer[i]=(char)next()) != '\0') not_zero=TRUE;

buffer[i]='\0';

if ( not_zero || all )

shows("Unused bytes i family",buffer,19-familychars);

if (lh-1 > 16)

{ /* sevenbitsafeflag */

sevenbitsafeflag=next();

show1("Sevenbitsafeflag",sevenbitsafeflag);

b1=next(); b2=next(); /* ignoring the these 2 bytes */

if (all)

{ /* show these if al info wanted */

show1("Second byte in header[17]",b1);

show1("Third byte in header[17]",b2);

face=next();} show1("Face",face);

if (254-designsize*2==face)

showd("Face description","Standard METAFONT");

else if (face < 18)

showd("Face description",xerox(face));

elseshowd("Face description","(unknown, not METAFONT or Xerox)");

if (lh-1 > 17)

{ /* this is really optional, header[18..whatever] */

for(i=18;i<=lh-1;i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

show4("Optional header []",i,b1,b2,b3,b4);

} /* whatever part */} } /* sevenbitsafeflag */

} /* family */

} /* optional header info */

}

/*---*/

/* charinfo, info about each character */

/*---*/

char_info() { int i;

byte b1,b2,b3,b4;

char buffer[30];

headline("CHARACTER ADDRESS INFORMATION ARRAY");

for(i=bc; i<=ec; i++) {

b1=next(); b2=next(); b3=next(); b4=next();

charinfo_w[i]=b1;

charinfo_h[i]=b2/16;

charinfo_d[i]=b2%16;

charinfo_i[i]=b3/4;

charinfo_t[i]=b3%4;

charinfo_r[i]=b4;

if (charinfo_w[i] != 0 )

{ showi(i,charinfo_w[i],charinfo_h[i],charinfo_d[i],charinfo_i[i], charinfo_t[i],charinfo_r[i]);

if (byteinfo)

{ sprintf(buffer,byteinfo4,b1,b2,b3,b4);

showd("",buffer);

if (charinfo_w[i] > nw-1)}

feil("Width information out of range, see preheader");

if (charinfo_h[i] > nh-1)

feil("Height information out of range, see preheader");

if (charinfo_d[i] > nd-1)

feil("Width information out of range, see preheader");

if (charinfo_i[i] > ni-1)

feil("Width information out of range, see preheader");

else if (all)}

show4("None-existing character",i,b1,b2,b3,b4);

} /* for bc to ec */

}

/*---*/

/* width, legal values */

/*---*/

width_info() { int i;

byte b1,b2,b3,b4;

if (!nw) return;

headline("WIDTH VALUE ARRAY");

b1=next(); b2=next(); b3=next(); b4=next();

width[0]=fix_word(b1,b2,b3,b4);

show4fw("Width",0,width[0],b1,b2,b3,b4);

if (width[0]!=0.0)

feil("Width[0] should be 0.0");

for(i=1; i<nw; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

width[i]=fix_word(b1,b2,b3,b4);

show4fw("Width",i,width[i],b1,b2,b3,b4);

if (width[i]==0.0)

showd("","Previous value was zero, that't unusual");

} }

/*---*/

/* height, legal values */

/*---*/

height_info() { int i;

byte b1,b2,b3,b4;

if (!nh) return;

headline("HEIGHT VALUE ARRAY");

b1=next(); b2=next(); b3=next(); b4=next();

height[0]=fix_word(b1,b2,b3,b4);

show4fw("Height",0,height[0],b1,b2,b3,b4);

if (height[0]!=0.0)

feil("Height[0] should be 0.0");

for(i=1; i<nh; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

height[i]=fix_word(b1,b2,b3,b4);

show4fw("Height",i,height[i],b1,b2,b3,b4);

if (height[i]==0.0)

showd("","Previous value was zero, that't unusual");

} }

/*---*/

/* depth, legal values */

/*---*/

depth_info() { int i;

byte b1,b2,b3,b4;

if (!nd) return;

headline("DEPTH VALUE ARRAY");

b1=next(); b2=next(); b3=next(); b4=next();

depth[0]=fix_word(b1,b2,b3,b4);

show4fw("Depth",0,depth[0],b1,b2,b3,b4);

if (depth[0]!=0.0)

feil("Depth[0] should be 0.0");

for(i=1; i<nd; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

depth[i]=fix_word(b1,b2,b3,b4);

show4fw("Depth",i,depth[i],b1,b2,b3,b4);

if (depth[i]==0.0)

showd("","Previous value was zero, that't unusual");

} }

/*---*/

/* italic correction, legal values */

/*---*/

italic_info() { int i;

byte b1,b2,b3,b4;

if (!ni) return;

headline("ITALIC CORRECTION VALUE ARRAY");

b1=next(); b2=next(); b3=next(); b4=next();

italic[0]=fix_word(b1,b2,b3,b4);

show4fw("Italic correction",0,italic[0],b1,b2,b3,b4);

if (italic[0]!=0.0)

feil("Italic[0] should be 0.0");

for(i=1; i<ni; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

italic[i]=fix_word(b1,b2,b3,b4);

show4fw("Italic correction",i,italic[i],b1,b2,b3,b4);

if (italic[i]==0.0)

showd("","Previous value was zero, that's unusual");

} }

/*---*/

/* lig_kern, ligatures an kernings */

/*---*/

lig_kern_info() { int i;

byte b1,b2,b3,b4;

if (!nl) return;

headline("LIGATURE AND KERNING INFORMATION ARRAY");

printf("Not implemented yet, skipping...\n");

for (i=0;i<nl;i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

} }

/*---*/

/* kern */

/*---*/

kern_info() { int i;

byte b1,b2,b3,b4;

if (!nk) return;

headline("KERNING VALUE ARRAY");

for(i=0; i<nk; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

kern[i]=fix_word(b1,b2,b3,b4);

show4fw("Kerning",i,kern[i],b1,b2,b3,b4);

if (kern[i]==0.0)

showd("","Previous value was zero, that't unusual");

} }

/*---*/

/* exten */

/*---*/

exten_info() { int i;

byte b1,b2,b3,b4;

if (!ne) return;

headline("EXTENSIBLE CHARACTER INFORMATION");

for(i=0; i<ne; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

showe(i,b1,b2,b3,b4);

} }

/*---*/

/* param*/

/*---*/

param_info() { int i;

byte b1,b2,b3,b4;

if (!np) return;

headline("PARAMETER VALUE ARRAY");

for(i=0; i<7; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

param[i]=fix_word(b1,b2,b3,b4);

show4fw(paramname[i],i,param[i],b1,b2,b3,b4);

}

if (np==22)

for(i=7; i<np; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

param[i]=fix_word(b1,b2,b3,b4);

show4fw(paramname[i],i,param[i],b1,b2,b3,b4);

else}

for(i=7; i<np; i++)

{ b1=next(); b2=next(); b3=next(); b4=next();

param[i]=fix_word(b1,b2,b3,b4);

show4fw(paramname[i+15],i,param[i],b1,b2,b3,b4);

} }

int main(int argc, char *argv[]) { init(argc,argv);

preheader();

header();

char_info();

width_info();

height_info();

depth_info();

italic_info();

lig_kern_info();

kern_info();

exten_info();

param_info();

term();

return 0;

}

3.2 tfmdump.man

TFMDUMP(1) TFMDUMP(1)

NAME

tfmdump - dumps and checks a TFM file SYNOPSIS

tfmdump [ options ] font.tfm DESCRIPTION

tfmdump opens and reads a given TeX Font Metrics (.tfm) file, outputing its contents in a descriptive man-ner. tfmdump will always display character codes and array indexes in decimal, but byte values for fix_word and other stuff will be subject to formatting. All strings found in the font.tfm will be displayed quoted in angle brackets like <this>. Strings with character codes less than 32 will be displayed in octal notation (if not changed by an option). Unused bytes in header fields will be displayed if codes are differ-ent from 0.

Output will be presented in parts, corresponding to the TFM file. Before starting, tfmdump displays the path of the TFM file and its size in bytes and words.

The font.tfm must be complete with the extension. tfmdump will not add extension. No more than one TFM file will be examined at a run. tfmdump will search all directories given in the environment variable TEXFONTS. If you don’t hav e set it, the default directory for .tfm fonts will be searched.

OPTIONS

-C Continue after an error. Normally this will work fine, but there is no guaranty. Error messages will be sent to stdout.

-S Prints sizeof information. tfmdump doesn’t use integer calculation, if a dump dumps (core), check this option and eventually recompile.

-V Version number and date information.

-X Display bytes used for strings, fix_words and stuff in hexadecimal notation using capital letters.

-a Displays all information, even bytes that are not used. Bytes will be displayed in octal notation if no other display options are present.

-c Display bytes used for strings, fix_words and stuff as characters. This may fu**up the terminal.

-d Display bytes used for strings, fix_words and stuff in decimal notation.

-h Help message and usage. Brief description.

-o Display bytes used for strings, fix_words and stuff in octal notation.

-x Display bytes used for strings, fix_words and stuff in hexadecimal notation using small letters.

ENVIRONMENT VARIABLES TEXFONTS

Should contain colon-separated directories with .tfm files. A first and/or last colon will insert the default directory.

FILES

/local/lib/tex/fonts

Default directory for .tfm files.

SEE ALSO

tftopl(1), pltotf(1), TeX(1) AUTHOR

Lars Gunnar Thoresen, larsth@ifi.uio.no

wurk 22 June 1993 1