📄 ps_afm.c
字号:
/* * This program converts AFM files to TeX TFM files, and optionally * to TeX VPL files that retain all kerning and ligature information. * Both files make the characters not normally encoded by TeX available * by character codes greater than 127. *//* (Modified by Don Knuth from Tom Rokicki's pre-VPL version.) *//* VM/CMS port by J. Hafner (hafner@almaden.ibm.com), based on * the port by Alessio Guglielmi (guglielmi@ipisnsib.bitnet) * and Marco Prevedelli (prevedelli@ipisnsva.bitnet). * This port is still in test state. No guarantees. * 11/3/92: more corrections to VM/CMS port. Now it looks correct * and will be supported by J. Hafner. **/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <stdarg.h>#include <stdio.h>#include <math.h>#include <string.h>#include "ps_intern.h"#include "ps_fontenc.h"#include "ps_error.h"#ifdef VMCMS#define interesting lookstr /* for 8 character truncation conflicts */#include "dvipscms.h"extern char ebcdic2ascii[] ;extern char ascii2ebcdic[] ;#ifdef fopen#undef fopen#endif#endif#if (defined(MSDOS) && defined(__TURBOC__)) || (defined(OS2) && defined(_MSC_VER))#define SMALLMALLOC#endif /* Ligatures {{{ * * It's easier to put this in static storage and parse it as we go * than to build the structures ourselves. */static char *staticligkern[] = { "% LIGKERN space l =: lslash ; space L =: Lslash ;", "% LIGKERN question quoteleft =: questiondown ;", "% LIGKERN exclam quoteleft =: exclamdown ;", "% LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ;", "% LIGKERN quoteleft quoteleft =: quotedblleft ;", "% LIGKERN quoteright quoteright =: quotedblright ;", "% LIGKERN space {} * ; * {} space ; zero {} * ; * {} zero ;", "% LIGKERN one {} * ; * {} one ; two {} * ; * {} two ;", "% LIGKERN three {} * ; * {} three ; four {} * ; * {} four ;", "% LIGKERN five {} * ; * {} five ; six {} * ; * {} six ;", "% LIGKERN seven {} * ; * {} seven ; eight {} * ; * {} eight ;", "% LIGKERN nine {} * ; * {} nine ;",/* Kern accented characters the same way as their base. *//* There cannot be used currently and what are they for, anyway? "% LIGKERN Aacute <> A ; aacute <> a ;", "% LIGKERN Acircumflex <> A ; acircumflex <> a ;", "% LIGKERN Adieresis <> A ; adieresis <> a ;", "% LIGKERN Agrave <> A ; agrave <> a ;", "% LIGKERN Aring <> A ; aring <> a ;", "% LIGKERN Atilde <> A ; atilde <> a ;", "% LIGKERN Ccedilla <> C ; ccedilla <> c ;", "% LIGKERN Eacute <> E ; eacute <> e ;", "% LIGKERN Ecircumflex <> E ; ecircumflex <> e ;", "% LIGKERN Edieresis <> E ; edieresis <> e ;", "% LIGKERN Egrave <> E ; egrave <> e ;", "% LIGKERN Iacute <> I ; iacute <> i ;", "% LIGKERN Icircumflex <> I ; icircumflex <> i ;", "% LIGKERN Idieresis <> I ; idieresis <> i ;", "% LIGKERN Igrave <> I ; igrave <> i ;", "% LIGKERN Ntilde <> N ; ntilde <> n ;", "% LIGKERN Oacute <> O ; oacute <> o ;", "% LIGKERN Ocircumflex <> O ; ocircumflex <> o ;", "% LIGKERN Odieresis <> O ; odieresis <> o ;", "% LIGKERN Ograve <> O ; ograve <> o ;", "% LIGKERN Oslash <> O ; oslash <> o ;", "% LIGKERN Otilde <> O ; otilde <> o ;", "% LIGKERN Scaron <> S ; scaron <> s ;", "% LIGKERN Uacute <> U ; uacute <> u ;", "% LIGKERN Ucircumflex <> U ; ucircumflex <> u ;", "% LIGKERN Udieresis <> U ; udieresis <> u ;", "% LIGKERN Ugrave <> U ; ugrave <> u ;", "% LIGKERN Yacute <> Y ; yacute <> y ;", "% LIGKERN Ydieresis <> Y ; ydieresis <> y ;", "% LIGKERN Zcaron <> Z ; zcaron <> z ;",*//* * These next are only included for deficient afm files that * have the lig characters but not the lig commands. */ "% LIGKERN f i =: fi ; f l =: fl ; f f =: ff ; ff i =: ffi ;", "% LIGKERN ff l =: ffl ;", 0 } ;/* * The above layout corresponds to TeX Typewriter Type and is compatible * with TeX Text because the position of ligatures is immaterial. *//* }}} */static int boundarychar = -1 ; /* the boundary character */static int ignoreligkern = 0; /* do we look at ligkern info in the encoding? */static char *encligops[] = { "=:", "|=:", "|=:>", "=:|", "=:|>", "|=:|", "|=:|>", "|=:|>>", 0} ;#define BUFFERLEN 512static char buffer[BUFFERLEN]; /* input buffer (modified while parsing) */static char obuffer[BUFFERLEN] ; /* unmodified copy of input buffer */static char *param ; /* current position in input buffer */static void error(char *s) { (void)fprintf(stderr, "%s\n", s) ; if (obuffer[0]) { (void)fprintf(stderr, "%s\n", obuffer) ; while (param > buffer) { (void)fprintf(stderr, " ") ; param-- ; } (void)fprintf(stderr, "^\n") ; } if (*s == '!') exit(1) ;}static int transform(int x, int y) { float efactor = 1.0; float slant = 0.0; double acc ; acc = efactor * x + slant *y ; return (int)(acc>=0? floor(acc+0.5) : ceil(acc-0.5) ) ;}static int getline(FILE *afmin) { char *p ; int c ; param = buffer ; for (p=buffer; (c=getc(afmin)) != EOF && c != '\n';)/* changed 10 to '\n' */ *p++ = c ; *p = 0 ; (void)strncpy(obuffer, buffer, BUFFERLEN) ; obuffer[BUFFERLEN-1] = '\0'; if (p == buffer && c == EOF) return(0) ; else return(1) ;}static char *interesting[] = { "FontName", "ItalicAngle", "IsFixedPitch", "XHeight", "C", "KPX", "CC", "EncodingScheme", "UnderlinePosition", "UnderlineThickness", "Ascender", "Descender", "CapHeight", "N", NULL} ;#define FontName (0)#define ItalicAngle (1)#define IsFixedPitch (2)#define XHeight (3)#define C (4)#define KPX (5)#define CC (6)#define EncodingScheme (7)#define UnderlinePosition (8)#define UnderlineThickness (9)#define Ascender (10)#define Descender (11)#define CapHeight (12)#define N (13) /* Needed for .pro files */#define NONE (-1)static int interest(char *s) { char **p ; int n ; for (p=interesting, n=0; *p; p++, n++) if (strcmp(s, *p)==0) return(n) ; return(NONE) ;}/*static char *mymalloc(unsigned long len) { char *p ;#ifdef SMALLMALLOC if (len > 65500L) error("! can't allocate more than 64K!") ;#endif p = (char *) malloc((unsigned int)len) ; if (p == NULL) error("! out of memory") ; memset(p, 0, len); return(p) ;}*/static char * newstring(PSDoc *psdoc, char *s) { char *q = psdoc->malloc(psdoc, (unsigned long)(strlen(s) + 1), s) ; (void)strcpy(q, s) ; return q ;}static char *paramnewstring(PSDoc *psdoc) { char *p, *q ; p = param ; while (*p > ' ') p++ ; if (*p != 0) *p++ = 0 ; q = newstring(psdoc, param) ; while (*p && *p <= ' ') p++ ; param = p ; return(q) ;}static char *paramstring() { char *p, *q ; p = param ; while (*p > ' ') p++ ; q = param ; if (*p != 0) *p++ = 0 ; while (*p && *p <= ' ') p++ ; param = p ; return(q) ;}static int paramnum() { char *p ; int i ; p = paramstring() ; if (sscanf(p, "%d", &i) != 1) error("! integer expected") ; return(i) ;}static float paramfloat() { char *p ; float i ; p = paramstring() ; if (sscanf(p, "%f", &i) != 1) error("! number expected") ; return(i) ;}static ADOBEINFO *newchar(PSDoc *psdoc) { ADOBEINFO *ai ; ai = (ADOBEINFO *) psdoc->malloc(psdoc, (unsigned long) sizeof(ADOBEINFO), "newchar: allocate memory for new character") ; ai->adobenum = -1 ; ai->texnum = -1 ; ai->width = -1 ; ai->adobename = NULL ; ai->llx = -1 ; ai->lly = -1 ; ai->urx = -1 ; ai->ury = -1 ; ai->lkern = 0; ai->rkern = 0; ai->ligs = NULL ; ai->kerns = NULL ; ai->kern_equivs = NULL ; ai->pccs = NULL ; return(ai) ;}static KERN *newkern(PSDoc *psdoc) { KERN *nk ; nk = (KERN *) psdoc->malloc(psdoc, (unsigned long) sizeof(KERN), "newkern: allocate memory for new kerning") ; nk->next = NULL ; nk->succ = NULL ; nk->delta = 0 ; return(nk) ;}static PCC *newpcc(PSDoc *psdoc) { PCC *np ; np = (PCC *) psdoc->malloc(psdoc, (unsigned long) sizeof(PCC), "newppc: allocate memory for new pcc") ; np->next = NULL ; np->partname = NULL ; np->xoffset = 0 ; np->yoffset = 0 ; return(np) ;}static LIG *newlig(PSDoc *psdoc) { LIG *nl ; nl = (LIG *) psdoc->malloc(psdoc, (unsigned long) sizeof(LIG), "newlig: allocate memory for new ligature") ; nl->next = NULL ; nl->succ = NULL ; nl->sub = NULL ; nl->op = 0 ; /* the default =: op */ nl->boundleft = 0 ; return(nl) ;}static int expect(char *s) { if (strcmp(paramstring(), s) != 0) { return(ps_false); } return(ps_true);}/* handlechar() {{{ */static ADOBEINFO * handlechar(PSDoc *psdoc, ADOBEFONTMETRIC *metric) { /* an input line beginning with C */ ADOBEINFO *ai ; LIG *nl ; ai = newchar(psdoc) ; ai->adobenum = paramnum() ; if(!expect(";")) { psdoc->free(psdoc, ai); ps_error(psdoc, PS_RuntimeError, _("Expected ';' in afm file.")); return(NULL); } if(!expect("WX")) { psdoc->free(psdoc, ai); ps_error(psdoc, PS_RuntimeError, _("Expected 'WX' in afm file.")); return(NULL); } ai->width = paramnum(); //transform(paramnum(),0) ;// if (ai->adobenum >= 0 && ai->adobenum < 256) {// metric->adobeptrs[ai->adobenum] = ai ;// } if(!expect(";")) { psdoc->free(psdoc, ai); ps_error(psdoc, PS_RuntimeError, _("Expected ';' in afm file.")); return(NULL); } if(!expect("N")) { psdoc->free(psdoc, ai); ps_error(psdoc, PS_RuntimeError, _("Expected 'N' in afm file.")); return(NULL); } ai->adobename = paramnewstring(psdoc) ; if(!expect(";")) { psdoc->free(psdoc, ai->adobename); psdoc->free(psdoc, ai); ps_error(psdoc, PS_RuntimeError, _("Expected ';' in afm file.")); return(NULL); } if(expect("B")) { ai->llx = paramnum() ; ai->lly = paramnum() ;// ai->llx = transform(ai->llx, ai->lly) ; ai->urx = paramnum() ; ai->ury = paramnum() ;// ai->urx = transform(ai->urx, ai->ury) ; expect(";") ; }/* Now look for ligatures (which aren't present in fixedpitch fonts) */ while (*param == 'L' && !metric->fixedpitch) { if(!expect("L")) { ps_error(psdoc, PS_RuntimeError, _("Expected 'L' in afm file.")); return(NULL); } nl = newlig(psdoc) ; nl->succ = paramnewstring(psdoc) ; nl->sub = paramnewstring(psdoc) ; nl->next = ai->ligs ; ai->ligs = nl ; if(!expect(";")) { ps_error(psdoc, PS_RuntimeError, _("Expected ';' in afm file.")); return(NULL); } } return(ai);}/* }}} *//* handleprotusion() {{{ */static int handleprotusion(PSDoc *psdoc, ADOBEFONTMETRIC *metric) { /* an input line begining with N */ ADOBEINFO *ai ; char *adobename; adobename = paramstring() ; ai = gfindadobe(metric->gadobechars, adobename); if(ai) { if(!expect(";")) { ps_error(psdoc, PS_RuntimeError, _("Expected ';' in protusion file.")); return(ps_false); } if(!expect("M")) { ps_error(psdoc, PS_RuntimeError, _("Expected 'M' in protusion file.")); return(ps_false); } ai->lkern = paramnum(); ai->rkern = paramnum();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -