diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /fonts/psfonts/tools/checksums/cs.c |
Initial commit
Diffstat (limited to 'fonts/psfonts/tools/checksums/cs.c')
-rw-r--r-- | fonts/psfonts/tools/checksums/cs.c | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/fonts/psfonts/tools/checksums/cs.c b/fonts/psfonts/tools/checksums/cs.c new file mode 100644 index 0000000000..73139ed15b --- /dev/null +++ b/fonts/psfonts/tools/checksums/cs.c @@ -0,0 +1,268 @@ +/* + * NAME + * cs - checksum for TeX fonts + * SYNOPSIS: + * cs [options] font + * DESCRIPTION + * This program can read checksums from existing TeX font files + * (TFM/PK/VF). It can also compute the checksum for TeX fonts that + * are used to cope with PostScript fonts in the same manner as + * afm2tfm(1), as part of dvips version 5.487 or higher, and ps2pk(1) + * do. In the case of a PostScript font, the checksum will depend upon: + * - the AFM file (containing WX values) + * - the encoding vector (or built-in default encoding) + * - the amount of extension used (-E<value>). + * Slanting has no effect on the checksum because it does not + * change the character box. + * + * Options and arguments: + * -n Use new checksum algorithm. + * -o Print checksum as an octal value. + * -e<encoding> The encoding scheme (default the encoding from the + * AFM file is used). + * -E<extension> The extension factor (real value, default 1.0). + * -S<slant> The slant (real value, default 0.0). + * + * font The name of a TeX PK, TFM or VF font, or the name of + * a PostScript AFM file. + * + * SEE ALSO + * afm2tfm(1), dvips(1), ps2pk(1) + * VERSION + * 1.0 (Januari 1995), derived from an earlier version (part of mtpk). + * 1.1 (August 1995), introduced UINT32 type definition so that + * program works correct on 16-bits (Borland C + * on MSDOS) and 64-bits platforms on UNIX + * AUTHOR + * Piet Tutelaers + * rcpt@urc.tue.nl + */ + +#include <ctype.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "uint32.h" /* typedef UINT32 <unsigned 32-bits integer> */ +#include "texfiles.h" + +/* read checksum (non negative integer less than 2^32) */ +UINT32 checksum_texfont(char *name, UINT32 *checksum); + +char *encfile = NULL, *afmfile, *font; + +typedef char *encoding[256]; +void getenc(encoding, int [256]); + +int octal = 0, new = 0; + +main(argc, argv) +int argc; char *argv[]; +{ char *argp, c; + int done, i; + char *myname = "cs"; + + UINT32 cs; + encoding ev; + int WX[256]; + + float efactor = 1.0, slant = 0.0; + + /* proto's */ + char *locate(char *, char *, char *); + UINT32 checksum(encoding, int [256]); + UINT32 new_checksum(encoding, int [256]); + void fatal(char *fmt, ...); + + while (--argc > 0 && (*++argv)[0] == '-') { + done=0; + while ((!done) && (c = *++argv[0])) /* allow -bcK like options */ + switch (c) { + case 'e': + if (*++argv[0] == '\0') { + argc--; argv++; + } + encfile = argv[0]; + done = 1; + break; + case 'E': + if (*++argv[0] == '\0') { + argc--; argv++; + } + efactor = atof(argv[0]); + done = 1; + break; + case 'S': + if (*++argv[0] == '\0') { + argc--; argv++; + } + slant = atof(argv[0]); + done = 1; + break; + case 'n': + new = 1; break; + case 'o': + octal = 1; break; + default: + fatal("%s: %c illegal option\n", myname, c); + } + } + + if (argc < 1 || argc >2) { + printf("cs: version 1.1 (Aug. 1995)\n"); + printf("Usage: cs [-o] TeXfont\n"); + printf(" or: cs [-n] [-o] [-e<enc>] [-E<expansion>] [-S<slant>] AFMfile\n"); + exit(1); + } + + font = argv[0]; + + /* Is it a TeX font? */ + if (checksum_texfont(font, &cs)) { + if (octal) +#ifdef __BORLANDC__ + printf("%lo\n", cs); +#else + printf("%o\n", cs); +#endif + else +#ifdef __BORLANDC__ + printf("%lu\n", cs); +#else + printf("%u\n", cs); +#endif + exit(0); + } + + /* It must be an AFM file now */ + afmfile = font; + getenc(ev, WX); + if (efactor != 1.0) + for (i=0; i < 256; i++) { + if (ev[i] == NULL) continue; + WX[i] = WX[i] * efactor + 0.5; + } + + if (new) + cs = new_checksum(ev, WX); + else + cs = checksum(ev, WX); + if (octal) +#ifdef __BORLANDC__ + printf("%lo\n", cs); +#else + printf("%o\n", cs); +#endif + else +#ifdef __BORLANDC__ + printf("%lu\n", cs); +#else + printf("%u\n", cs); +#endif + exit(0); +} + +/* + * The checksum should garantee that our PK file belongs to the correct TFM + * file! Exactly the same as the afm2tfm (dvips5487) calculation. + */ +UINT32 checksum(encoding ev, int width[256]) +{ + int i, leftbit ; + UINT32 s1 = 0, s2 = 0; + char *p ; + + for (i=0; i<256; i++) { + if (ev[i] == NULL) continue; + s1 = (s1<<1) ^ width[i]; /* left shift */ + for (p=ev[i]; *p; p++) + s2 = s2 * 3 + *p ; + } + return (s1<<1) ^ s2 ; +} + +/* + * The proposed new checksum algorithm. + */ +UINT32 new_checksum(encoding ev, int width[256]) +{ + int i, leftbit ; + UINT32 s1 = 0, s2 = 0; + char *p ; + + for (i=0; i<256; i++) { + if (ev[i] == NULL) continue; + s1 = ((s1<<1) ^ (s1>>31)) ^ width[i]; /* cyclic left shift */ + for (p=ev[i]; *p; p++) + s2 = s2 * 3 + *p ; + } + return (s1<<1) ^ s2 ; +} + +/* Give up ... */ +void fatal(char *fmt, ...) +{ va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + exit(1); +} + +#define PKPRE 247 +#define PKID 89 +#define VFID 202 + +#ifdef MSDOS +#define RB "rb" +#else +#define RB "r" +#endif + +/* + * Checksum_texfont() reads the <checksum> of a TFM file (if filename ends + * with ".tfm"), PK file (if magic code equals PK) or or VF file (if magic + * code equals VF). Function returns 1 upon succes otherwise (no TFM, PK or + * VF file) 0. + */ + +UINT32 checksum_texfont(char *name, UINT32 *checksum) +{ + FILE *fontfp; int id, i; + + if ((fontfp= fopen(name, RB)) == NULL) + fatal("%s: can't open file\n", name); + + if (strcmp(name+strlen(name)-4, ".tfm") ==0) { + + if (fseek(fontfp, 24L, 0)) + { + fclose(fontfp); + fatal("%s: really a TFM font?\n", name); + } + *checksum = four(fontfp); /* checksum */ + fclose(fontfp); + return(1); + } + + /* PK or VF font? */ + if (sone(fontfp) != PKPRE) return 0; + id = sone(fontfp); + if (id == VFID) { + /* skip header */ + for(i=sone(fontfp); i>0; i--) (void)sone(fontfp) ; + *checksum = four(fontfp); /* checksum */ + } + else if (id == PKID) { + /* skip header */ + for(i=sone(fontfp); i>0; i--) (void)sone(fontfp) ; + (void) four(fontfp); /* design size */ + *checksum = four(fontfp); /* checksum */ + } + else return 0; + + fclose(fontfp); + return(1); +} + |