home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Appls / dpv / dpvfunny.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-06  |  4.8 KB  |  205 lines  |  [TEXT/????]

  1. /* dpv -- ditroff previewer.  Funny character translation. */
  2.  
  3. #include "dpv.h"
  4. #include "dpvmachine.h"
  5. #include "dpvoutput.h"
  6.  
  7. char    *funnyfile;    /* File to read table from */
  8.  
  9. char    *funnytries[]= {    /* Alternative files to try */
  10.         "funnytab",
  11.         "/usr/local/lib/funnytab",
  12.         "/userfs3/amoeba/lib/funnytab",
  13.         "/ufs/guido/lib/funnytab",
  14.         NULL
  15.     };
  16.  
  17. /* Funny character translation table.
  18.    The table implies that character 'name' (the ditroff input name,
  19.    e.g. "bu" for bullet, which is input as "\(bu") must be translated
  20.    the string 'trans' drawn in font 'font', or in the current font
  21.    if 'font' is NULL.  'Trans' is a string because some characters
  22.    need several real characters to print them (e.g., ligatures).
  23.    For higher-quality output, the table should be extended to
  24.    include a point size increment/decrement and possibly a (dh, dv)
  25.    translation; but what the heck, this is only a previewer! */
  26.  
  27. static struct _funny {
  28.     char name[4];
  29.     char trans[4];
  30.     char *fontname;
  31. };
  32.  
  33. /* Read funny character translation table.
  34.    File format:
  35.        name    fontname    translation
  36.    where:
  37.        name is the ditroff character name, e.g., bs for \(bs
  38.        fontname is the font name, or - if the translation uses the current font
  39.        translation is one or more hexadecimal numbers, or a string
  40.        enclosed in double quotes
  41.        In any case the string may be no more than 3 characters long
  42. */
  43.  
  44. readfunnytab(filename)
  45.     char *filename;
  46. {
  47.     char buf[BUFSIZ];
  48.     FILE *fp= fopen(filename, "r");
  49.     if (fp == NULL) {
  50.         if (dbg > 0)
  51.             fprintf(stderr, "Can't open funnytab %s\n", filename);
  52.         return FALSE;
  53.     }
  54.     if (dbg > 0)
  55.         fprintf(stderr, "Reading funnytab from %s\n", filename);
  56.     while (fgets(buf, sizeof buf, fp) != NULL) {
  57.         char *name;
  58.         char *fontname;
  59.         char *trans;
  60.         char ctrans[4];
  61.         char *p= buf;
  62.         while (*p != EOS && isspace(*p))
  63.             ++p;
  64.         if (*p == EOS)
  65.             continue;
  66.         name= p;
  67.         while (*p != EOS && !isspace(*p))
  68.             ++p;
  69.         if (*p == EOS)
  70.             continue;
  71.         *p++ = EOS;
  72.         while (*p != EOS && isspace(*p))
  73.             ++p;
  74.         if (*p == EOS)
  75.             continue;
  76.         fontname= p;
  77.         while (*p != EOS && !isspace(*p))
  78.             ++p;
  79.         if (*p == EOS)
  80.             continue;
  81.         *p++ = EOS;
  82.         while (*p != EOS && isspace(*p))
  83.             ++p;
  84.         if (*p == EOS)
  85.             continue;
  86.         if (*p == '"') {
  87.             trans= ++p;
  88.             while (*p != EOS && *p != EOL && *p != '"')
  89.                 ++p;
  90.             *p= EOS;
  91.         }
  92.         else if (*p == '0' && p[1] == 'x') {
  93.             int a= 0, b= 0, c= 0;
  94.             (void) sscanf(p, "0x%x 0x%x 0x%x", &a, &b, &c);
  95.             ctrans[0]= a;
  96.             ctrans[1]= b;
  97.             ctrans[2]= c;
  98.             ctrans[3]= EOS;
  99.             trans= ctrans;
  100.         }
  101.         else
  102.             error(WARNING, "almost-match in funnytab");
  103.         addtranslation(name, fontname, trans);
  104.     }
  105.     fclose(fp);
  106.     sorttranslations();
  107.     return TRUE;
  108. }
  109.  
  110. int nfunny;
  111. struct _funny *funnytab;
  112.  
  113. static
  114. addtranslation(name, fontname, trans)
  115.     char *name, *fontname, *trans;
  116. {
  117.     struct _funny f;
  118.     strncpy(f.name, name, 4);
  119.     f.name[3]= EOS;
  120.     strncpy(f.trans, trans, 4);
  121.     f.trans[3]= EOS;
  122.     if (fontname == NULL || fontname[0] == EOS ||
  123.         fontname[0] == '-' && fontname[1] == EOS)
  124.         f.fontname= NULL;
  125.     else {
  126.         static char *lastfontname;
  127.         if (lastfontname == NULL ||
  128.             strcmp(fontname, lastfontname) != 0)
  129.             lastfontname= strdup(fontname);
  130.         f.fontname= lastfontname;
  131.     }
  132.     L_APPEND(nfunny, funnytab, struct _funny, f);
  133.     if (funnytab == NULL)
  134.         error(FATAL, "out of mem for funnytab");
  135. }
  136.  
  137. static
  138. funnycmp(p, q)
  139.     struct _funny *p, *q;
  140. {
  141.     return strcmp(p->name, q->name);
  142. }
  143.  
  144. static
  145. sorttranslations()
  146. {
  147.     /* Don't sort -- the lookup algorithm depends on the order */
  148. #if 0
  149.     if (nfunny > 1)
  150.         qsort(funnytab, nfunny, sizeof(struct _funny), funnycmp);
  151. #endif
  152. }
  153.  
  154. /* Draw a funny character.  Called from put1s. */
  155.  
  156. drawfunny(name)
  157.     register char *name;
  158. {
  159.     register struct _funny *f;
  160.     TEXTATTR save;
  161.     static bool inited;
  162.     
  163.     if (!inited) {
  164.         if (funnyfile != NULL) {
  165.             /* Explicitly specified funnyfile -- must exist */
  166.             if (!readfunnytab(funnyfile))
  167.                 error(FATAL, "can't find funnytab file %s",
  168.                     funnyfile);
  169.         }
  170.         else {
  171.             /* Try to find default funnyfile */
  172.             int i= 0;
  173.             while ((funnyfile= funnytries[i++]) != NULL) {
  174.                 if (readfunnytab(funnyfile))
  175.                     break;
  176.             }
  177.             /* If not found, limp ahead... */
  178.             if (funnyfile == NULL)
  179.                 error(WARNING,
  180.                     "can't find default funnytab");
  181.         }
  182.         inited= TRUE;
  183.     }
  184.     
  185.     /* If this is too slow, could use binary search and/or
  186.        replace the strcmp by an explicit comparison of two
  187.        characters.  But spend your time on the program's
  188.        main loop (especially, 'put1') first! */
  189.     for (f= funnytab; f < &funnytab[nfunny]; ++f) {
  190.         /* Assume names are always 1 or 2 chars */
  191.         if (f->name[0] == name[0] && f->name[1] == name[1])
  192.             break;
  193.     }
  194.     if (f >= &funnytab[nfunny])
  195.         return; /* Unknown character -- don't draw it */
  196.     if (f->fontname != NULL) {
  197.         char buf[256];
  198.         wgettextattr(&save);
  199.         fonthack(f->fontname);
  200.     }
  201.     wdrawtext(HWINDOW, VWINDOW - wbaseline(), f->trans, -1);
  202.     if (f->fontname != NULL)
  203.         wsettextattr(&save);
  204. }
  205.