/*** ** ** Module: FReader ** ** Description: ** This is a module of the T1 to TT font converter. The module ** contains functions that decodes and decrypts the data of a ** T1 font file. ** ** Author: Michael Jansson ** ** Created: 5/26/93 ** ***/ /**** INCLUDES */ /* General types and definitions. */ #include #include /* Special types and definitions. */ #include "titott.h" #include "types.h" #include "safemem.h" #include "t1msg.h" /* Module dependent types and prototypes. */ #include "freader.h" #include "pfb.h" /***** LOCAL TYPES */ struct FontFile { /* Low-level I/O functions. */ errcode (FASTCALL *fclose)(struct t1file *); short (FASTCALL *fgetc)(struct t1file *); struct t1file *(*fopen)(const char *); boolean (FASTCALL *fstatus)(const struct t1file *); struct t1file *io; /* Font file state. */ enum {prolog, eexec} state; short nextbyte; USHORT r; }; /***** CONSTANTS */ static const USHORT c1 = 52845; static const USHORT c2 = 22719; /***** MACROS */ #define IOGetByte(f) ((*f->fgetc)(f->io)) #define IOError(f) ((*f->fstatus)(f->io)) #define IOOpen(f,n) ((*f->fopen)(n)) #define IOClose(f) ((*f->fclose)(f->io)) #define SetNextByte(ff, b) ff->nextbyte = (b) #define NextByte(ff) (ff->nextbyte) #define Eexec(ff) (boolean)(ff->state == eexec) #define StartEexec(ff) ff->state = eexec /***** STATIC FUNCTIONS */ /*-none-*/ /***** FUNCTIONS */ /*** ** Function: GetByte ** ** Description: ** Pull one byte out of the T1 font file. ***/ short FASTCALL GetByte(struct FontFile *ff) { short b, nb; b = IOGetByte(ff); /* Decrypt it? */ if (Eexec(ff)) b = (short)Decrypt(&ff->r, (UBYTE)b); /* Record look-a-head */ nb = NextByte(ff); SetNextByte(ff, b); return nb; } /*** ** Function: GetNewLine ** ** Description: ** Pull one whole line from the T1 font file, starting at ** the current position. ***/ char *GetNewLine(struct FontFile *ff, char *buf, const USHORT len) { short i = 0; /* Get string. */ while ((buf[i] = (char)GetByte(ff))!='\n' && buf[i]!='\r' && ++i<((short)len-1)); /* Skip extra characters. */ if (buf[i]!='\n' && buf[i]!='\r') while (!IOError(ff) && NextByte(ff)!='\n' && NextByte(ff)!='\r') (void)GetByte(ff); /* Terminate string. */ buf[i] = '\0'; /* Check for the start of the eexec section. */ if (!strcmp(buf, "eexec")) StartEexec(ff); /* Check error condition. */ if (IOError(ff)) return NULL; return buf; } /*** ** Function: Get_Token ** ** Description: ** Pull one token from the T1 font file. A token ** is delimited by white space and various brackets. ***/ char *Get_Token(struct FontFile *ff, char *buf, const USHORT len) { short i = 0; short nb; /* Skip leading blanks. */ while (isspace(NextByte(ff))) (void)GetByte(ff); /* Get string. */ do { buf[i] = (char)GetByte(ff); nb = NextByte(ff); } while (++i<((short)len-1) && !isspace(nb) && nb!='{' && nb!='(' && nb!='[' && nb!='/'); /* Skip extra characters. */ while (!IOError(ff) && !isspace(nb) && nb!='{' && nb!='(' && nb!='[' && nb!='/') { (void)GetByte(ff); nb = NextByte(ff); } /* Terminate string. */ buf[i] = '\0'; /* Check for the start of the eexec section. */ if (!strcmp(buf, "eexec")) StartEexec(ff); /* Check error condition. */ if (IOError(ff)) return NULL; return buf; } /*** ** Function: GetSeq ** ** Description: ** Pull one sequence of bytes that are delimited by ** a given pair of characters, e.g. '[' and ']'. ***/ char *GetSeq(struct FontFile *ff, char *buf, const USHORT len) { char d1, d2; short i = 0; short inside = 0; /* Skip leading blanks. */ while (NextByte(ff)!='[' && NextByte(ff)!='{' && NextByte(ff)!='(' && !IOError(ff)) (void)GetByte(ff); /* match the bracket. */ d1 = (char)NextByte(ff); if (d1=='[') d2 = ']'; else if (d1=='{') d2 = '}'; else if (d1=='(') d2 = ')'; else return NULL; /* Get string. */ (void)GetByte(ff); inside=1; do { buf[i] = (char)GetByte(ff); if (buf[i]==d1) inside++; if (buf[i]==d2) inside--; } while (inside && ++i<((short)len-1)); /* Terminate string. */ buf[i] = '\0'; /* Check error condition. */ if (IOError(ff)) return NULL; return buf; } /*** ** Function: FRInit ** ** Description: ** Initite the resources needed to read/decode data from ** a T1 font file. ***/ errcode FRInit(const char *name, const enum ftype type, struct FontFile **ff) { errcode status = SUCCESS; short b; if (((*ff)=(struct FontFile *)Malloc(sizeof(struct FontFile)))==NULL) { SetError(status = NOMEM); } else { /* Initiat the handle. */ memset((*ff), '\0', sizeof(**ff)); /* Initiate low-level I/O. */ switch (type) { case pfb_file: (*ff)->fgetc = PFBGetByte; (*ff)->fclose = PFBFreeIOBlock; (*ff)->fstatus = PFBFileError; (*ff)->fopen = PFBAllocIOBlock; break; case mac_file: #if MACFILEFORMAT (*ff)->fgetc = MACGetByte; (*ff)->fclose = MACFreeIOBlock; (*ff)->fstatus = MACFileError; (*ff)->fopen = MACAllocIOBlock; break; #endif case ascii_file: #if ASCIIFILEFORMAT (*ff)->fgetc = ASCIIGetByte; (*ff)->fclose = ASCIIFreeIOBlock; (*ff)->fstatus = ASCIFileError; (*ff)->fopen = ASCIIAllocIOBlock; break; #endif default: LogError(MSG_ERROR, MSG_BADFMT, NULL); SetError(status = BADINPUTFILE); break; } (*ff)->io = NULL; if (((*ff)->io = IOOpen((*ff),name))==NULL) { SetError(status = BADINPUTFILE); } else { (*ff)->state = prolog; (*ff)->r = 55665; b=GetByte(*ff); SetNextByte((*ff), b); } } return status; } /*** ** Function: FRCleanUp ** ** Description: ** Free the resources used when reading/decoding data from ** a T1 font file. ***/ errcode FRCleanUp(struct FontFile *ff) { errcode status = SUCCESS; if (ff) { if (ff->io) status = IOClose(ff); Free(ff); } return status; } /*** ** Function: Decrypt ** ** Description: ** Decrypt a byte. ***/ UBYTE FASTCALL Decrypt(USHORT *r, const UBYTE cipher) { UBYTE plain; plain = (UBYTE)(cipher ^ (*r>>8)); *r = (USHORT)((cipher+*r) * c1 + c2); return plain; }