tt11.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
tt11.c (7138B)
---
     1 #include "tdef.h"
     2 #include "fns.h"
     3 #include "ext.h"
     4 
     5 #define        MAXCH NCHARS                /* maximum number of global char names */
     6 char        *chnames[MAXCH];        /* chnames[n-ALPHABET] -> name of char n */
     7 int        nchnames;                /* number of Cxy names currently seen */
     8 
     9 #define        MAXPS        100                /* max number of point sizes */
    10 int        pstab[MAXPS];                /* point sizes */
    11 int        nsizes;                        /* number in DESC */
    12 
    13 Font        fonts[MAXFONTS+1];        /* font info + ptr to width info */
    14 
    15 
    16 #define        skipline(f)        while (getc(f) != '\n')
    17 
    18 #define        eq(s1, s2)        (strcmp(s1, s2) == 0)
    19 
    20 int
    21 getdesc(char *name)
    22 {
    23         FILE *fin;
    24         char cmd[100], s[100];
    25         int i, v;
    26 
    27         if ((fin = fopen(unsharp(name), "r")) == NULL)
    28                 return -1;
    29         while (fscanf(fin, "%s", cmd) != EOF) {
    30                 if (strcmp(cmd, "res") == 0) {
    31                         fscanf(fin, "%d", &Inch);
    32                 } else if (strcmp(cmd, "hor") == 0) {
    33                         fscanf(fin, "%d", &Hor);
    34                 } else if (strcmp(cmd, "vert") == 0) {
    35                         fscanf(fin, "%d", &Vert);
    36                 } else if (strcmp(cmd, "unitwidth") == 0) {
    37                         fscanf(fin, "%d", &Unitwidth);
    38                 } else if (strcmp(cmd, "sizes") == 0) {
    39                         nsizes = 0;
    40                         while (fscanf(fin, "%d", &v) != EOF && v != 0 && nsizes < MAXPS)
    41                                 pstab[nsizes++] = v;
    42                 } else if (strcmp(cmd, "fonts") == 0) {
    43                         fscanf(fin, "%d", &nfonts);
    44                         for (i = 1; i <= nfonts; i++) {
    45                                 fscanf(fin, "%s", s);
    46                                 fontlab[i] = PAIR(s[0], s[1]);
    47                         }
    48                 } else if (strcmp(cmd, "charset") == 0) {        /* add any names */
    49                         while (fscanf(fin, "%s", s) != EOF)
    50                                 chadd(s, Troffchar, Install);
    51                         break;
    52                 }
    53                 /* else
    54                         just skip anything else */
    55                 skipline(fin);
    56         }
    57         fclose(fin);
    58         return 1;
    59 }
    60 
    61 static int checkfont(char *name)
    62 {                /* in case it's not really a font description file */
    63                 /* really paranoid, but consider \f. */
    64         FILE *fp;
    65         char buf[300], buf2[300];
    66         int i, status = -1;
    67 
    68         if ((fp = fopen(unsharp(name), "r")) == NULL)
    69                 return -1;
    70         for (i = 1; i <= 10; i++) {
    71                 if (fgets(buf, sizeof buf, fp) == NULL)
    72                         break;
    73                 sscanf(buf, "%s", buf2);
    74                 if (buf2[0] == '#') {
    75                         i--;
    76                         continue;
    77                 }
    78                 if (eq(buf2, "name") || eq(buf2, "fontname") ||
    79                     eq(buf2, "special") || eq(buf2, "charset")) {
    80                         status = 1;
    81                         break;
    82                 }
    83         }
    84         fclose(fp);
    85         return status;
    86 
    87 }
    88 
    89 int
    90 getfont(char *name, int pos)        /* create width tab for font */
    91 {
    92         FILE *fin;
    93         Font *ftemp = &fonts[pos];
    94         Chwid chtemp[MAXCH];
    95         static Chwid chinit;
    96         int i, nw, n, wid, kern, code, type;
    97         char buf[100], ch[100], s1[100], s2[100], s3[100], cmd[300];
    98 
    99         nw = code = 0;
   100         /* fprintf(stderr, "read font %s onto %d\n", name, pos); */
   101         if (checkfont(name) == -1)
   102                 return -1;
   103         if ((fin = fopen(unsharp(name), "r")) == NULL)
   104                 return -1;
   105         for (i = 0; i < ALPHABET; i++)
   106                 chtemp[i] = chinit;        /* zero out to begin with */
   107         ftemp->specfont = ftemp->ligfont = 0;
   108         ftemp->defaultwidth = ftemp->spacewidth = Inch * Unitwidth / 72 / 3; /* should be rounded */
   109         while (fscanf(fin, "%s", cmd) != EOF) {
   110                 if (strcmp(cmd, "name") == 0)
   111                         fscanf(fin, "%s", ftemp->longname);
   112                 else if (strcmp(cmd, "special") == 0)
   113                         ftemp->specfont = 1;
   114                 else if (strcmp(cmd, "ligatures") == 0) {
   115                         ftemp->ligfont = getlig(fin);
   116                 } else if (strcmp(cmd, "spacewidth") == 0) {
   117                         fscanf(fin, "%d", &ftemp->spacewidth);
   118                 } else if (strcmp(cmd, "defaultwidth") == 0) {
   119                         fscanf(fin, "%d", &ftemp->defaultwidth);
   120                 } else if (strcmp(cmd, "charset") == 0) {
   121                         wchar_t wc;
   122                         skipline(fin);
   123                         nw = ALPHABET;
   124                         while (fgets(buf, sizeof buf, fin) != NULL) {
   125                                 sscanf(buf, "%s %s %s %s", ch, s1, s2, s3);
   126                                 if (s1[0] != '"') {        /* genuine new character */
   127                                         sscanf(s1, "%d", &wid);
   128                                         sscanf(s2, "%d", &kern);
   129                                         code = strtol(s3, 0, 0);        /* dec/oct/hex */
   130                                 }
   131                                 /* otherwise it's a synonym for prev character, */
   132                                 /* so leave previous values intact */
   133 
   134 
   135                                 /* decide what kind of alphabet it might come from here */
   136 
   137 
   138                                 if (strlen(ch) == 1) {        /* it's ascii */
   139                                         n = ch[0];        /* origin includes non-graphics */
   140                                         chtemp[n].num = ch[0];
   141                                 } else if (ch[0] == '\\' && ch[1] == '0') {
   142                                         n = strtol(ch+1, 0, 0);        /* \0octal or \0xhex */
   143                                         chtemp[n].num = n;
   144 #ifdef UNICODE
   145                                 } else if (mbtowc(&wc, ch, strlen(ch)) > 1) {
   146                                         chtemp[nw].num = chadd(ch,  MBchar, Install);
   147                                         n = nw;
   148                                         nw++;
   149 #endif        /*UNICODE*/
   150                                 } else {
   151                                         if (strcmp(ch, "---") == 0) { /* no name */
   152                                                 sprintf(ch, "%d", code);
   153                                                 type = Number;
   154                                         } else
   155                                                 type = Troffchar;
   156                                         chtemp[nw].num = chadd(ch, type, Install);
   157                                         n = nw;
   158                                         nw++;
   159                                 }
   160                                 chtemp[n].wid = wid;
   161                                 chtemp[n].kern = kern;
   162                                 chtemp[n].code = code;
   163                                 /*fprintf(stderr, "font %2.2s char %4.4s num %3d wid %2d code %3d\n",
   164                                         ftemp->longname, ch, n, wid, code);
   165                                 */
   166                         }
   167                         break;
   168                 }
   169                 skipline(fin);
   170         }
   171         fclose(fin);
   172         chtemp[' '].wid = ftemp->spacewidth;        /* width of space on this font */
   173         ftemp->nchars = nw;
   174         if (ftemp->wp)
   175                 free(ftemp->wp);        /* god help us if this wasn't allocated */
   176         ftemp->wp = (Chwid *) malloc(nw * sizeof(Chwid));
   177         if (ftemp->wp == NULL)
   178                 return -1;
   179         for (i = 0; i < nw; i++)
   180                 ftemp->wp[i] = chtemp[i];
   181 /*
   182  *        printf("%d chars: ", nw);
   183  *        for (i = 0; i < nw; i++)
   184  *                if (ftemp->wp[i].num > 0 && ftemp->wp[i].num < ALPHABET) {
   185  *                        printf("%c %d ", ftemp->wp[i].num, ftemp->wp[i].wid);
   186  *                else if (i >= ALPHABET)
   187  *                        printf("%d (%s) %d ", ftemp->wp[i].num,
   188  *                                chnames[ftemp->wp[i].num-ALPHABET], ftemp->wp[i].wid);
   189  *        }
   190  *        printf("\n");
   191  */
   192         return 1;
   193 }
   194 
   195 int
   196 chadd(char *s, int type, int install)        /* add s to global character name table; */
   197 {                                        /* or just look it up */
   198 
   199         /* a temporary kludge:  store the "type" as the first character */
   200         /* of the string, so we can remember from whence it came */
   201 
   202         char *p;
   203         int i;
   204 
   205 /* fprintf(stderr, "into chadd %s %c %c\n", s, type, install); /* */
   206         for (i = 0; i < nchnames; i++)
   207                 if (type == chnames[i][0] && eq(s, chnames[i]+1)) /* +1 since type at front */
   208                         break;
   209 /* fprintf(stderr, "i %d, nchnames %d\n", i, nchnames); /* */
   210         if (i < nchnames)                /* found same type and bytes at position i */
   211                 return ALPHABET + i;
   212         else if (install == Lookup)        /* not found, and we were just looking */
   213                 return -1;
   214 
   215         chnames[nchnames] = p = (char *) malloc(strlen(s)+1+1);        /* type + \0 */
   216         if (p == NULL) {
   217                 ERROR "out of space adding character %s", s WARN;
   218                 return LEFTHAND;
   219         }
   220         if (nchnames >= NCHARS - ALPHABET) {
   221                 ERROR "out of table space adding character %s", s WARN;
   222                 return LEFTHAND;
   223         }
   224         strcpy(chnames[nchnames]+1, s);
   225         chnames[nchnames][0] = type;
   226 /* fprintf(stderr, "installed %c%s at %d\n", type, s, nchnames); /* */
   227         return nchnames++ + ALPHABET;
   228 }
   229 
   230 char *chname(int n)        /* return string for char with index n */
   231 {                        /* includes type char at front, to be peeled off elsewhere */
   232         if (n >= ALPHABET && n < nchnames + ALPHABET)
   233                 return chnames[n-ALPHABET];
   234         else
   235                 return "";
   236 }
   237 
   238 int
   239 getlig(FILE *fin)        /* pick up ligature list */
   240 {
   241         int lig;
   242         char temp[200];
   243 
   244         lig = 0;
   245         while (fscanf(fin, "%s", temp) != EOF && strcmp(temp, "0") != 0) {
   246                 if (strcmp(temp, "fi") == 0)
   247                         lig |= LFI;
   248                 else if (strcmp(temp, "fl") == 0)
   249                         lig |= LFL;
   250                 else if (strcmp(temp, "ff") == 0)
   251                         lig |= LFF;
   252                 else if (strcmp(temp, "ffi") == 0)
   253                         lig |= LFFI;
   254                 else if (strcmp(temp, "ffl") == 0)
   255                         lig |= LFFL;
   256                 else
   257                         fprintf(stderr, "illegal ligature %s ignored\n", temp);
   258         }
   259         return lig;
   260 }