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