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 / hp2627.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-28  |  6.4 KB  |  253 lines

  1. /*
  2.  * HP2627 Terminal Window interface to Unix Metafont.
  3.  */
  4.  
  5. #define    EXTERN    extern
  6. #include "../mfd.h"
  7.  
  8. #ifdef    HP2627WIN
  9.  
  10. #include <stdio.h>
  11.  
  12. /*
  13.  * HP2627a Color Graphics Terminal: Escape code definitions
  14.  *
  15.  *     Drawing pen colors
  16.  */
  17. #define    HP2627_BLACK        '0'
  18. #define    HP2627_RED        '1'
  19. #define    HP2627_GREEN        '2'
  20. #define    HP2627_YELLOW        '3'
  21. #define    HP2627_BLUE        '4'
  22. #define    HP2627_MAGENTA        '5'
  23. #define    HP2627_CYAN        '6'
  24. #define    HP2627_WHITE        '7'
  25.  
  26. /*
  27.  *    Initialization: just do a hard graphics reset
  28.  *        (then we can depend on the defaults
  29.  *         being as we want them)
  30.  */
  31. #define    HP2627_INITSTRING    "\033*wR"
  32. #define    HP2627_INITSTRINGLEN    4
  33.  
  34. /*
  35.  *    We want the text to be visible over both background and forground
  36.  *        graphics data; the best color combination I found for this
  37.  *        was to set the background RED and then paint with BLUE,
  38.  *        although the eye doesn't focus on BLUE very well (black 
  39.  *        might be better?  Or green? [to get in the holiday mood])
  40.  */
  41. #define    HP2627_BACKGROUNDPEN    HP2627_RED
  42. #define    HP2627_FOREGROUNDPEN    HP2627_BLUE
  43.  
  44. static    char    mf_hp2627_pencolors[2] = {
  45.         HP2627_BACKGROUNDPEN,        /* white */
  46.         HP2627_FOREGROUNDPEN        /* black */
  47. };
  48.  
  49. /*
  50.  *     Screen dimensions:  Note the origin is at the lower-left corner,
  51.  *        not the upper left as MF expects - hence we need to translate.
  52.  */
  53. #define    HP2627_MAXX        511
  54. #define    HP2627_MAXY        389
  55.  
  56. /*
  57.  * The actual Graphics routines.  Note that these are highly tty
  58.  *    dependent so I can minimize the number of characters that
  59.  *    need to be sent to paint an image, since we only talk to
  60.  *    the HP at 9.6Kb.
  61.  */
  62.  
  63. /*
  64.  *     function init_screen: boolean;
  65.  *
  66.  *        Return true if window operations legal.
  67.  *        We always return true (I suppose we could try to
  68.  *        sense status or something masochistic like that)
  69.  */
  70.  
  71. mf_hp2627_initscreen()
  72. {
  73.     (void) fflush(stdout);    /* make sure pascal-level output flushed */
  74.     (void) write(fileno(stdout), HP2627_INITSTRING, HP2627_INITSTRINGLEN);
  75.     return(1);
  76. }
  77.  
  78. /*
  79.  *    procedure updatescreen; 
  80.  *
  81.  *        Just make sure screen is ready to view
  82.  *        (since we do Unix-level WRITE()s,
  83.  *        we don't really need to flush stdio,
  84.  *        but why not?)
  85.  */
  86.  
  87. mf_hp2627_updatescreen()
  88. {
  89.     (void) fflush(stdout);
  90. }
  91.  
  92. /*
  93.  *    procedure blankrectangle(left, right, top, bottom: integer);
  94.  *
  95.  *         reset rectangle bounded by ([left,right],[top,bottom])
  96.  *            to background color
  97.  */
  98.  
  99. mf_hp2627_blankrectangle(left, right, top, bottom)
  100.     screencol left, right;
  101.     screenrow top, bottom;
  102. {
  103.     char    sprbuf[128];
  104.  
  105.     (void) sprintf(sprbuf, "\033*m%cx%d,%d %d,%dE", HP2627_BACKGROUNDPEN,
  106.             left, HP2627_MAXY-bottom,
  107.             right, HP2627_MAXY-top);
  108.     (void) write(fileno(stdout), sprbuf, strlen(sprbuf));
  109. }
  110.  
  111. /*
  112.  *    procedure paintrow(
  113.  *            row:        screenrow;
  114.  *            init_color:    pixelcolor;
  115.  *        var    trans_vector:    transspec;
  116.  *            vector_size:    screencol        );
  117.  *
  118.  *        Paint "row" starting with color "init_color",  up to next
  119.  *        transition specified by "transition_vector", switch colors,
  120.  *        and continue for "vector_size" transitions.
  121.  */
  122.  
  123. /*
  124.  *     First some useful definitions:
  125.  */
  126. #define    ASCIILABS    0        /* plot cmd format: ASCII long abs    */
  127. #define    BINLABS        1        /* plot cmd format: BINARY long abs   */
  128. #define    BINSINC        2        /* plot cmd format: BINARY short incr */
  129.  
  130. #define    ABS(x) ((x>=0)?x:-x)        /* absolute value              */
  131.  
  132. /*
  133.  *    An optimized "move to (x,y), with current pen lowered unless UP is
  134.  *        true" function.  Takes advantage of short commands for short
  135.  *        movements to minimize character traffic to term.
  136.  *
  137.  *        Note: the "x -= 1;" fudge is because we only want to DRAW
  138.  *            to the next transition_vector entry - 1, but if we
  139.  *            have the pen raised, we want to move to exactly the
  140.  *            next point.
  141.  */
  142. #define    MOVETO(x,y,up) \
  143.     if (up) *op++ = 'a'; \
  144.     else x -= 1; \
  145.     if (ABS(x-oldx) < 16 && ABS(y-oldy) < 16) { \
  146.         if (currentformat != BINSINC) { \
  147.             *op++ = 'j'; \
  148.             currentformat = BINSINC; \
  149.         } \
  150.         *op++ = (((x-oldx) & 0x1f) + ' '); \
  151.         *op++ = (((y-oldy) & 0x1f) + ' '); \
  152.     } else { \
  153.         if (currentformat != BINLABS) { \
  154.             *op++ = 'i'; \
  155.             currentformat = BINLABS; \
  156.         } \
  157.         *op++ = (((x&0x3e0)>>5)+' '); \
  158.         *op++ =  ((x&0x01f)    +' '); \
  159.         *op++ = (((y&0x3e0)>>5)+' '); \
  160.         *op++ =  ((y&0x01f)    +' '); \
  161.     } \
  162.     oldx = x; \
  163.     oldy = y;
  164.  
  165. mf_hp2627_paintrow(row, init_color, transition_vector, vector_size)
  166.     screenrow    row;
  167.     pixelcolor    init_color;
  168.     transspec    transition_vector;
  169.     screencol    vector_size;
  170. {
  171.     register    color;
  172.     char        outbuf[512*6];    /* enough to hold an alternate color */
  173.                     /* in each column             */
  174.     register    char    *op;
  175.     register    x, y, oldx, oldy;
  176.     int        currentformat;
  177.  
  178.     color = (init_color == 0)? 0 : 1;
  179.  
  180.     /*
  181.      * We put all escape sequences in a buffer so the write
  182.      * has a chance of being atomic, and not interrupted by
  183.      * other independent output to our TTY.  Also to avoid
  184.      * (literally millions) of stdio calls.
  185.      */
  186.     op = outbuf;
  187.     /*
  188.      * Select current pen to be the color of the first segment:
  189.      *
  190.      * our strategy here is to paint a long line from the first
  191.      * transition_vector value (left edge of row) to the last
  192.      * transition_vector entry (right edge of row).  Then we switch
  193.      * colors to the contrasting color, and paint alternate
  194.      * segments with that color.  Would that the HP2627 would provide
  195.      * a mode to paint the "background" color while the PEN is lifted.
  196.      * However, this is faster than using rectangular area fills.
  197.      */
  198.  
  199.     *op++ = '\033'; *op++ = '*'; *op++ = 'm';
  200.     *op++ = mf_hp2627_pencolors[color];
  201.     *op++ = 'X';
  202.  
  203.     /*
  204.      * Reset our "remembered" state for (X,Y) positioning and plot
  205.      *    command format
  206.      */
  207.     oldx = oldy = -999;
  208.     currentformat = ASCIILABS;
  209.  
  210.     /*
  211.      * Now, paint across the entire width of this row, make it the
  212.      *    initial segment color.
  213.      */
  214.     x = *transition_vector;
  215.     y = HP2627_MAXY-row;
  216.     *op++ = '\033'; *op++ = '*'; *op++ = 'p';
  217.     MOVETO(x,y,1);
  218.     x = transition_vector[vector_size];
  219.     MOVETO(x,y,0);
  220.     *op++ = 'Z';
  221.  
  222.     /*
  223.      * If there remain other segments (of contrasting color) to paint,
  224.      *    switch pens colors and draw them
  225.      */
  226.     if (--vector_size > 0) {
  227.         *op++ = '\033'; *op++ = '*'; *op++ = 'm';
  228.         *op++ = mf_hp2627_pencolors[1-color]; *op++ = 'X';
  229.         color = 1-color;
  230.  
  231.         oldx = oldy = -999;
  232.         currentformat = ASCIILABS;
  233.         *op++ = '\033'; *op++ = '*'; *op++ = 'p';
  234.         x = *++transition_vector;
  235.         MOVETO(x,y,1);
  236.         while (vector_size-- > 0) {
  237.             x = *++transition_vector;
  238.             MOVETO(x,y,(color==init_color));
  239.             color = 1 - color;
  240.         };
  241.         *op++ = 'Z';
  242.     };
  243.  
  244.     /*
  245.      * Write the resulting plot commands, hopefully atomically
  246.      */
  247.     (void) write(fileno(stdout), outbuf, op-outbuf);
  248. }
  249.  
  250. #else
  251. int hp2627_dummy;
  252. #endif    /* HP2627WIN */
  253.