home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / web2c / mf / MFwindow / uniterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-28  |  5.6 KB  |  185 lines

  1. /*
  2.  *  title:    uni.c
  3.  *  abstract: Uniterm Terminal Window interface for Metafont.
  4.  *  author:   T.R.Hageman, Groningen, The Netherlands.
  5.  *  created:  May 1990
  6.  *  modified:
  7.  *  description:
  8.  *    Uniterm (Simon Poole's terminal emulator for the Atari ST)
  9.  *    emulates a `smart' Tektronix 4014 graphics terminal,
  10.  *    and allows selective erasing of the graphics screen.
  11.  *    (I do not know whether this is a standard feature of smart Teks
  12.  *     or an invention of Mr. Poole)
  13.  *
  14.  *    This file is offered as an alternative to the "standard"
  15.  *    tektronix driver (which I find rather slow...)
  16.  *
  17.  *    {{a possible way to improve the standard TEK driver would be to
  18.  *      remember the (merged) transition lists instead converting to
  19.  *      a bit map and back again.}}
  20.  *---*/
  21.  
  22. #define EXTERN extern
  23. #include "../mfd.h"
  24.  
  25. #ifdef UNITERMWIN             /* Whole file */
  26.  
  27. #define WIDTH 1024
  28. #define HEIGHT        780
  29. /*
  30.  *    Send a vector to the graphics terminal
  31.  *    (in a slightly optimized way).
  32.  */
  33. static void
  34. sendvector(x, y)
  35. register unsigned     x, y;
  36. {
  37.       static int      Hi_Y, Lo_Y, Hi_X;       /* remembered values */
  38.       register int    Lo_Y_sent = 0;
  39.       register int    t;
  40. #ifdef DEBUG
  41.       if (x >= WIDTH)                 /* clip... */
  42.               x = WIDTH - 1;
  43.       if (y >= HEIGHT)
  44.               y = HEIGHT - 1;
  45. #endif
  46.       /*
  47.        * Send Hi_Y only if it has changed.
  48.        */
  49.       if ((t = 0x20|(y >> 5)) != Hi_Y) {
  50.               Hi_Y = t, putchar(t);
  51.       }
  52.       /*
  53.        * Likewise, send Lo_Y only if it has changed.
  54.        * (and remember that it has been sent)
  55.        */
  56.       if ((t = 0x60|(y & 0x1f)) != Lo_Y) {
  57.               Lo_Y_sent = 1;
  58.               Lo_Y = t, putchar(t);
  59.       }
  60.       /*
  61.        * A slight complication here. If Hi_X has changed,
  62.        * we must send Lo_Y too, but only if we didn't already send it.
  63.        */
  64.       if ((t = 0x20|(x >> 5)) != Hi_X) {
  65.               if (!Lo_Y_sent)
  66.                       putchar(Lo_Y);
  67.               Hi_X = t, putchar(t);
  68.       }
  69.       /*
  70.        * Lo_X is always sent, so don't bother to remember it.
  71.        */
  72.       t = 0x40|(x & 0x1f), putchar(t);
  73. }
  74. /*
  75.  *    Tektronix has origin in lower-left corner, whereas MetaFont
  76.  *    has its origin in the upper-left corner.
  77.  *    The next macro hides this.
  78.  */
  79. #define VECTOR(col,row) sendvector((unsigned)(col),(unsigned)(HEIGHT-1-(row)))
  80. /*
  81.  *    GS              - `Dark' vectors are in fact invisible, i.e., a move.
  82.  *                      (Also switches from text- to graphics screen.)
  83.  */
  84. #define DARK()                putchar('\35')
  85. /*
  86.  *    CAN             - Switch from graphics- to text screen.
  87.  */
  88. #define TEXT_SCREEN() putchar('\30')
  89. /*
  90.  *    ESC STX(ETX)    - Enable(disable) block-fill mode.
  91.  */
  92. #define BLOCK(on)     (putchar('\33'),putchar(2+!(on)))
  93. /*
  94.  *    ESC / 0(1) d    - Set black(white) ink.
  95.  */
  96. #define INK(on)               (putchar('\33'), putchar('\57'), \
  97.                        putchar('\61'-(on)), putchar('\144'))
  98. /*
  99.  *    US              - Switch to `alpha mode'
  100.  */
  101. #define ALPHA_MODE()  putchar('\37')
  102. /*
  103.  *    ESC FF          - clear graphics&alpha screen.
  104.  */
  105. #define ALPHA_CLS();  (putchar('\33'), putchar('\14'))
  106. mf_uniterm_initscreen()
  107. {
  108.       ALPHA_CLS();
  109.       TEXT_SCREEN();
  110.       return 1;
  111. }
  112. mf_uniterm_updatescreen()
  113. {
  114.       DARK();
  115.       VECTOR(0,HEIGHT-1);
  116.       fflush(stdout);
  117.       TEXT_SCREEN();          /*  switch to text mode */
  118. }
  119. mf_uniterm_blankrectangle(left, right, top, bottom)
  120. screencol     left, right;
  121. screenrow     top, bottom;
  122. {
  123.       if (top==0 && left==0 && bottom>=HEIGHT-1 && right>=WIDTH-1) {
  124.               ALPHA_CLS();
  125.               return;
  126.       }
  127.       DARK();
  128.       VECTOR(left, top);
  129.       BLOCK(1);                       /* setup block erase mode */
  130.       INK(0);                         /* use white ink */
  131.       VECTOR(right-1, bottom-1);      /* this draws the block */
  132.       BLOCK(0);                       /* back to (black) linedraw mode */
  133.       INK(1);                         /* black ink */
  134. }
  135. mf_uniterm_paintrow(row, init_color, transition_vector, vector_size)
  136. screenrow             row;
  137. pixelcolor            init_color;
  138. register transspec    transition_vector;
  139. register screencol    vector_size;
  140. {
  141.       register int            blank = !init_color;
  142. #if 0
  143.       /* This is the basic */
  144.       DARK();
  145.       VECTOR(*transition_vector++, row);      /* move to first transition */
  146.       do {
  147.               INK(blank ^= 1);
  148.               VECTOR(*transition_vector++ - 1, row);
  149.       } while (--vector_size > 0);
  150. #endif
  151.       register screencol      col;
  152.       /* However, we optimize the amount of output a bit by blanking
  153.          out the row first (since each INK command takes 4 bytes) */
  154.       DARK();
  155.       if (blank) {
  156.               VECTOR(transition_vector[((vector_size-1)&~1)+1] - 1, row);
  157.               INK(0);
  158.               VECTOR(*transition_vector++, row);
  159.               INK(1);
  160.               if (vector_size==1)
  161.                       return;
  162.       }
  163.       else {
  164.               if (vector_size > 1) {
  165.                       VECTOR(transition_vector[vector_size & ~1] - 1, row);
  166.                       INK(0);
  167.                       VECTOR(transition_vector[1], row);
  168.                       INK(1);
  169.                       DARK();
  170.               }
  171.               VECTOR(*transition_vector++, row);
  172.       }
  173.       do {
  174.               col = *transition_vector++;
  175.               if ((blank ^= 1) == 0)
  176.                       DARK();   /* white -> black; move to first black pixel */
  177.               else
  178.                       col--;    /* black -> white; blacken to col-1 */
  179.               VECTOR(col, row);
  180.       } while (--vector_size > 0);
  181. }
  182. #else
  183. int   uniterm_dummy;
  184. #endif /* UNITERMWIN */
  185.