home *** CD-ROM | disk | FTP | other *** search
/ Boldly Go Collection / version40.iso / TS / 17A / CURSIVE2.ZIP / CURSIVE.SH / cursive.c < prev    next >
C/C++ Source or Header  |  1991-12-29  |  7KB  |  265 lines

  1. /*        CURSIVE SIGNATURE PROGRAM        Version 0.10
  2.  *              (c) 1985 - Jan Wolter
  3.  *
  4.  *  Purpose:    This program translates text into crude cursive script.
  5.  *        It works on any terminal with a fairly normal character
  6.  *        set (must have backslashes and underscores and suchlike).
  7.  *        The font includes all upper and lower case letters, most
  8.  *        punctuation, and a few symbols.  No numbers are included
  9.  *        (It's difficult to make a nice italicized set of numbers).
  10.  *        Cursive was originally written to generate fancy signatures
  11.  *        for electronic mail messages, but other uses may occur to
  12.  *        you.  The attractiveness of the font varies greatly with
  13.  *        the display device.
  14.  *
  15.  *  Usage:    If no command line arguments are given, cursive reads the
  16.  *        text to translate from standard input.  Otherwise the args
  17.  *        are translated (e.g. "cursive Jan Wolter" prints my name).
  18.  *        Output is always to standard output.  A couple command line
  19.  *        arguments are recognized:
  20.  *
  21.  *          -in    Sets the amount of space to insert between letters.
  22.  *            The default is "-i1".  "-i0" gives interesting
  23.  *            results.
  24.  *          -tn    Sets the length of the trailing line off the end
  25.  *            of each word.  The default is "-t1".
  26.  *
  27.  *        One character in the text is treated in a special way:
  28.  *
  29.  *          '_'   Can be inserted in text to slightly lengthen the
  30.  *            the spacing between two letters, or add a longer
  31.  *            tail to the end of a word.
  32.  *
  33.  *  Internals:    Unfortunately, the program is a kludge and the font is
  34.  *        somewhat difficult to edit.  It should be easy to port
  35.  *        though.  Systems with short integers or unsigned characters
  36.  *        should be no problem.  You should probably run "xstr" on the
  37.  *        font.c file, but if you haven't got "xstr", just compiling it
  38.  *        the usual way works fine.
  39.  *
  40.  *  Copyright:    Both the cursive program and the font it generates are
  41.  *        copyrighted by yours truly.  However, both may be used
  42.  *        and distributed freely.  You even have my permission to
  43.  *        sell it, or include in it a system that you sell.  I only
  44.  *        ask that my name be retained on this program, or any direct
  45.  *        decendents of this program with approximately the same
  46.  *        visibility as in this posting.
  47.  *
  48.  *  Mail:    I'm interested in any comments you have on this program.
  49.  *        I can be mailed at "janc@crim.eecs.umich.edu".  Better yet,
  50.  *        if you are into teleconferencing, call M-Net at (313) 994-6333
  51.  *        and type "newuser" at the "login:" prompt to give yourself an
  52.  *        account.  Send mail to janc, or join the "ugames" conference.
  53.  *
  54.  *        Have fun,
  55.  *                  ___                _     __  _
  56.  *                 (   >              ' )   /   // _/_
  57.  *                  __/___.  ____      / / / __|/  /  _  __
  58.  *                 / / (_/|_/ / <__   (_(_/ (_) \_<__</_/ (__
  59.  *                <_/
  60.  */
  61.  
  62. #include <stdio.h>
  63. #include "cursive.h"
  64.  
  65. char *buffer[6];    /* memory buffers to build up line in */
  66. int c[6];        /* current index in each of the buffer lines */
  67. int tail[6];        /* which buffer lines have tails in them */
  68. int lasttail;        /* which line was the last letter's tail */
  69. int space;        /* how much white space before the next letter */
  70. int interspace = 1;    /* how much to spread adjacent letters out */
  71. int taillen = 1;    /* how long the tails on ends of words should be */
  72. char firstletter;    /* is this the first letter on the line? */
  73. char message[256] = "";    /* message to print */
  74.  
  75. char *malloc();
  76.  
  77. main(argc,argv)
  78. int argc;
  79. char **argv;
  80. {
  81. int i;
  82. char *s,*m;
  83. char ch;
  84.  
  85.     m = message;
  86.     for (i = 1; i < argc; i++)
  87.     {
  88.         if (*argv[i] == '-')
  89.             switch(ch = argv[i][1])
  90.             {
  91.             case 'i':
  92.             case 't':
  93.                 s = argv[i]+2;
  94.                 if (*s == '\000')
  95.                     if (++i < argc)
  96.                         s = argv[i];
  97.                 if (*s < '0' || *s > '9')
  98.                 {
  99.                     printf("%s: Illegal value %s\n",
  100.                         argv[0],s);
  101.                     exit(1);
  102.                 }
  103.                 if (ch == 'i')
  104.                     interspace = atoi(s);
  105.                 else
  106.                     taillen = atoi(s);
  107.                 break;
  108.             default:
  109.                 printf("usage: %s [-tn] [-in] message\n",
  110.                     argv[0]);
  111.                 exit(1);
  112.             }
  113.         else
  114.         {
  115.             if (m != message)
  116.                 *(m++) = ' ';
  117.             for (s=argv[i]; *s != '\000'; s++)
  118.                 *(m++) = *s;
  119.         }
  120.     }
  121.     /* Do the deed */
  122.     if (m != message)
  123.     {
  124.         /* Message from the arg list */
  125.         *(m++) = 0;
  126.         prline(message);
  127.     }
  128.     else
  129.     {
  130.         /* Message from standard input */
  131.         while (gets(message) != NULL)
  132.             prline(message);
  133.     }
  134. }
  135.  
  136.  
  137. /* Add the given letter to the end of the current line */
  138.  
  139. place(let)
  140. struct letter *let;
  141. {
  142. int i,j,n;
  143. int col;
  144. int max = -10000;
  145. char pad;
  146. char *l;
  147.  
  148.     if (firstletter)
  149.     {
  150.         col = space;        /* Leading spaces */
  151.         firstletter = 0;
  152.     }
  153.     else
  154.     {
  155.         /* Find the furthest left position we can place this letter */
  156.         for(i=0; i<6; i++)
  157.         {
  158.             if (let->line[i][0] != '\000' &&
  159.                 (col = c[i] - let->spcs[i]) > max)
  160.                 max = col;
  161.         }
  162.  
  163.         /* Insert some spaces between letters */
  164.         col = max + space + interspace;
  165.     }
  166.  
  167.     for(i=0; i<6; i++)
  168.  
  169.         /* If Nothing on this Line, Skip It */
  170.         if (let->line[i][0] != '\000')
  171.         {
  172.             /* Number of Spaces to Put on this Line? */
  173.             n = col - c[i] + let->spcs[i];
  174.  
  175.             /* Flyers off Ends of Letters */
  176.             if (tail[i])
  177.                 for (j = 0;
  178.                      j < 5 && n > space + 2; j++,n--)
  179.                     buffer[i][c[i]++] = '_';
  180.  
  181.             /* Connecting Lines Between Letters */
  182.             pad = (lasttail == i && let->tailin == i) ? '_' : ' ';
  183.  
  184.             /* In the middle of the intersection of South and */
  185.             /* East University, someone is playing the piano. */
  186.             for ( ; n > 0; n--)
  187.                 buffer[i][c[i]++] = pad;
  188.  
  189.             /* Copy in the letter text */
  190.             for (l = let->line[i]; *l != '\000'; l++)
  191.                 buffer[i][c[i]++] = *l;
  192.  
  193.             tail[i] = (i == let->tailout);
  194.         }
  195.  
  196.     lasttail = let->tailout;
  197.     space = 0;
  198. }
  199.  
  200. /* Lengthen the last trailer by n */
  201. tailer(n)
  202. int n;
  203. {
  204. int j;
  205.     if (lasttail >= 0)
  206.         for (j = 0; j < n; j++)
  207.             buffer[lasttail][c[lasttail]++] = '_';
  208. }
  209.  
  210. /* Handle a line */
  211. prline(s)
  212. char *s;
  213. {
  214. int l,i;
  215. char *ch;
  216. short lcode;
  217.  
  218.     lasttail = -1;
  219.     firstletter = 1;
  220.     space = 0;
  221.     /* Get some memory to put the output into */
  222.     l = strlen(s) * (CHARWIDTH + interspace);
  223.     for (i=0;i<6;i++)
  224.     {
  225.         buffer[i] = malloc((unsigned)l);
  226.         tail[i] = c[i] = 0;
  227.     }
  228.  
  229.     /* do each letter */
  230.     for (ch=s; *ch != '\000'; ch++)
  231.     {
  232.  
  233.         *ch &= '\177';
  234.         /* Find the letter */
  235.         lcode = (lasttail != 2) ? code1[*ch] : code2[*ch];
  236.         if (lcode >= 0)
  237.             place(&list[lcode]);
  238.         else
  239.             /* Various Special characters */
  240.             switch(lcode)
  241.             {
  242.             case SP:
  243.                 /* Insert white space before next letter */
  244.                 tailer(taillen);
  245.                 space += 3;
  246.                 lasttail = -1;
  247.                 break;
  248.             case ST:
  249.                 /* Lengthen the last tail */
  250.                 if (lasttail >= 0)
  251.                     buffer[lasttail][c[lasttail]++] = '_';
  252.                 break;
  253.             }
  254.     }
  255.     tailer(taillen);
  256.  
  257.     /* print the line and release the memory */
  258.     for (i=0;i<6;i++)
  259.     {
  260.         buffer[i][c[i]++] = '\n';
  261.         write(1,buffer[i],c[i]);
  262.         free(buffer[i]);
  263.     }
  264. }
  265.