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
253
254
|
/*
* 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)
*/
#include <mfdisplay.h>
int mf_hp2627_initscreen(void)
{
(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)
{
(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 (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 (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 */
|