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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
Draw: module
{
PATH: con "$Draw";
# predefined colors; pass to Display.color
Opaque: con int 16rFFFFFFFF;
Transparent: con int 16r00000000; # only useful for Display.newimage
Black: con int 16r000000FF;
White: con int 16rFFFFFFFF;
Red: con int 16rFF0000FF;
Green: con int 16r00FF00FF;
Blue: con int 16r0000FFFF;
Cyan: con int 16r00FFFFFF;
Magenta: con int 16rFF00FFFF;
Yellow: con int 16rFFFF00FF;
Grey: con int 16rEEEEEEFF;
Paleyellow: con int 16rFFFFAAFF;
Darkyellow: con int 16rEEEE9EFF;
Darkgreen: con int 16r448844FF;
Palegreen: con int 16rAAFFAAFF;
Medgreen: con int 16r88CC88FF;
Darkblue: con int 16r000055FF;
Palebluegreen: con int 16rAAFFFFFF;
Paleblue: con int 16r0000BBFF;
Bluegreen: con int 16r008888FF;
Greygreen: con int 16r55AAAAFF;
Palegreygreen: con int 16r9EEEEEFF;
Yellowgreen: con int 16r99994CFF;
Medblue: con int 16r000099FF;
Greyblue: con int 16r005DBBFF;
Palegreyblue: con int 16r4993DDFF;
Purpleblue: con int 16r8888CCFF;
Notacolor: con int 16rFFFFFF00;
Nofill: con Notacolor;
# end styles for line
Endsquare: con 0;
Enddisc: con 1;
Endarrow: con 2;
# flush control
Flushoff: con 0;
Flushon: con 1;
Flushnow: con 2;
# image backing store
Refbackup: con 0;
Refnone: con 1;
# compositing operators
SinD: con 1<<3;
DinS: con 1<<2;
SoutD: con 1<<1;
DoutS: con 1<<0;
S: con SinD|SoutD;
SoverD: con SinD|SoutD|DoutS;
SatopD: con SinD|DoutS;
SxorD: con SoutD|DoutS;
D: con DinS|DoutS;
DoverS: con DinS|DoutS|SoutD;
DatopS: con DinS|SoutD;
DxorS: con DoutS|SoutD;
Clear: con 0;
# Image channels descriptor
Chans: adt
{
desc: int; # descriptor packed into an int
# interpret standard channel string
mk: fn(s: string): Chans;
# standard printable form
text: fn(c: self Chans): string;
# equality
eq: fn(c: self Chans, d: Chans): int;
# bits per pixel
depth: fn(c: self Chans): int;
};
CRed, CGreen, CBlue, CGrey, CAlpha, CMap, CIgnore: con iota;
GREY1: con Chans((CGrey<<4) | 1);
GREY2: con Chans((CGrey<<4) | 2);
GREY4: con Chans((CGrey<<4) | 4);
GREY8: con Chans((CGrey<<4) | 8);
CMAP8: con Chans((CMap<<4) | 8);
RGB15: con Chans(((CIgnore<<4)|1)<<24 | ((CRed<<4)|5)<<16 | ((CGreen<<4)|5)<<8 | ((CBlue<<4)|5));
RGB16: con Chans(((CRed<<4)|5)<<16 | ((CGreen<<4)|6)<<8 | ((CBlue<<4)|5));
RGB24: con Chans(((CRed<<4)|8)<<16 | ((CGreen<<4)|8)<<8 | ((CBlue<<4)|8));
RGBA32: con Chans((((CRed<<4)|8)<<24 | ((CGreen<<4)|8)<<16 | ((CBlue<<4)|8))<<8 | ((CAlpha<<4)|8));
ARGB32: con Chans(((CAlpha<<4)|8)<<24 | ((CRed<<4)|8)<<16 | ((CGreen<<4)|8)<<8 | ((CBlue<<4)|8)); # stupid VGAs
XRGB32: con Chans(((CIgnore<<4)|8)<<24 | ((CRed<<4)|8)<<16 | ((CGreen<<4)|8)<<8 | ((CBlue<<4)|8)); # stupid VGAs
# Coordinate of a pixel on display
Point: adt
{
x: int;
y: int;
# arithmetic
add: fn(p: self Point, q: Point): Point;
sub: fn(p: self Point, q: Point): Point;
mul: fn(p: self Point, i: int): Point;
div: fn(p: self Point, i: int): Point;
# equality
eq: fn(p: self Point, q: Point): int;
# inside rectangle
in: fn(p: self Point, r: Rect): int;
};
# Rectangle of pixels on the display; min <= max
Rect: adt
{
min: Point; # upper left corner
max: Point; # lower right corner
# make sure min <= max
canon: fn(r: self Rect): Rect;
# extent
dx: fn(r: self Rect): int;
dy: fn(r: self Rect): int;
size: fn(r: self Rect): Point;
# equality
eq: fn(r: self Rect, s: Rect): int;
# intersection and clipping
Xrect: fn(r: self Rect, s: Rect): int;
inrect: fn(r: self Rect, s: Rect): int;
clip: fn(r: self Rect, s: Rect): (Rect, int);
contains: fn(r: self Rect, p: Point): int;
combine: fn(r: self Rect, s: Rect): Rect;
# arithmetic
addpt: fn(r: self Rect, p: Point): Rect;
subpt: fn(r: self Rect, p: Point): Rect;
inset: fn(r: self Rect, n: int): Rect;
};
# a picture; if made by Screen.newwindow, a window. always attached to a Display
Image: adt
{
# these data are local copies, but repl and clipr
# are monitored by the runtime and may be modified as desired.
r: Rect; # rectangle in data area, local coords
clipr: Rect; # clipping region
depth: int; # number of bits per pixel
chans: Chans;
repl: int; # whether data area replicates to tile the plane
display: ref Display; # where Image resides
screen: ref Screen; # nil if not window
iname: string;
# graphics operators
drawop: fn(dst: self ref Image, r: Rect, src: ref Image, matte: ref Image, p: Point, op: int);
draw: fn(dst: self ref Image, r: Rect, src: ref Image, matte: ref Image, p: Point);
gendrawop: fn(dst: self ref Image, r: Rect, src: ref Image, p0: Point, matte: ref Image, p1: Point, op: int);
gendraw: fn(dst: self ref Image, r: Rect, src: ref Image, p0: Point, matte: ref Image, p1: Point);
lineop: fn(dst: self ref Image, p0,p1: Point, end0,end1,radius: int, src: ref Image, sp: Point, op: int);
line: fn(dst: self ref Image, p0,p1: Point, end0,end1,radius: int, src: ref Image, sp: Point);
polyop: fn(dst: self ref Image, p: array of Point, end0,end1,radius: int, src: ref Image, sp: Point, op: int);
poly: fn(dst: self ref Image, p: array of Point, end0,end1,radius: int, src: ref Image, sp: Point);
bezsplineop: fn(dst: self ref Image, p: array of Point, end0,end1,radius: int, src: ref Image, sp: Point, op: int);
bezspline: fn(dst: self ref Image, p: array of Point, end0,end1,radius: int, src: ref Image, sp: Point);
fillpolyop: fn(dst: self ref Image, p: array of Point, wind: int, src: ref Image, sp: Point, op: int);
fillpoly: fn(dst: self ref Image, p: array of Point, wind: int, src: ref Image, sp: Point);
fillbezsplineop: fn(dst: self ref Image, p: array of Point, wind: int, src: ref Image, sp: Point, op: int);
fillbezspline: fn(dst: self ref Image, p: array of Point, wind: int, src: ref Image, sp: Point);
ellipseop: fn(dst: self ref Image, c: Point, a, b, thick: int, src: ref Image, sp: Point, op: int);
ellipse: fn(dst: self ref Image, c: Point, a, b, thick: int, src: ref Image, sp: Point);
fillellipseop: fn(dst: self ref Image, c: Point, a, b: int, src: ref Image, sp: Point, op: int);
fillellipse: fn(dst: self ref Image, c: Point, a, b: int, src: ref Image, sp: Point);
arcop: fn(dst: self ref Image, c: Point, a, b, thick: int, src: ref Image, sp: Point, alpha, phi: int, op: int);
arc: fn(dst: self ref Image, c: Point, a, b, thick: int, src: ref Image, sp: Point, alpha, phi: int);
fillarcop: fn(dst: self ref Image, c: Point, a, b: int, src: ref Image, sp: Point, alpha, phi: int, op: int);
fillarc: fn(dst: self ref Image, c: Point, a, b: int, src: ref Image, sp: Point, alpha, phi: int);
bezierop: fn(dst: self ref Image, a,b,c,d: Point, end0,end1,radius: int, src: ref Image, sp: Point, op: int);
bezier: fn(dst: self ref Image, a,b,c,d: Point, end0,end1,radius: int, src: ref Image, sp: Point);
fillbezierop: fn(dst: self ref Image, a,b,c,d: Point, wind:int, src: ref Image, sp: Point, op: int);
fillbezier: fn(dst: self ref Image, a,b,c,d: Point, wind:int, src: ref Image, sp: Point);
textop: fn(dst: self ref Image, p: Point, src: ref Image, sp: Point, font: ref Font, str: string, op: int): Point;
text: fn(dst: self ref Image, p: Point, src: ref Image, sp: Point, font: ref Font, str: string): Point;
textbgop: fn(dst: self ref Image, p: Point, src: ref Image, sp: Point, font: ref Font, str: string, bg: ref Image, bgp: Point, op: int): Point;
textbg: fn(dst: self ref Image, p: Point, src: ref Image, sp: Point, font: ref Font, str: string, bg: ref Image, bgp: Point): Point;
border: fn(dst: self ref Image, r: Rect, i: int, src: ref Image, sp: Point);
arrow: fn(a,b,c: int): int;
# direct access to pixels
readpixels: fn(src: self ref Image, r: Rect, data: array of byte): int;
writepixels: fn(dst: self ref Image, r: Rect, data: array of byte): int;
# publishing
name: fn(src: self ref Image, name: string, in: int): int;
# windowing
top: fn(win: self ref Image);
bottom: fn(win: self ref Image);
flush: fn(win: self ref Image, func: int);
origin: fn(win: self ref Image, log, scr: Point): int;
};
# a frame buffer, holding a connection to /dev/draw
Display: adt
{
image: ref Image; # holds the contents of the display
white: ref Image;
black: ref Image;
opaque: ref Image;
transparent: ref Image;
# allocate and start refresh slave
allocate: fn(dev: string): ref Display;
startrefresh: fn(d: self ref Display);
# attach to existing Screen
publicscreen: fn(d: self ref Display, id: int): ref Screen;
getwindow: fn(d: self ref Display, winname: string, screen: ref Screen, image: ref Image, backup: int): (ref Screen, ref Image);
# image creation
newimage: fn(d: self ref Display, r: Rect, chans: Chans, repl, color: int): ref Image;
color: fn(d: self ref Display, color: int): ref Image;
colormix: fn(d: self ref Display, c1: int, c2: int): ref Image;
rgb: fn(d: self ref Display, r, g, b: int): ref Image;
# attach to named Image
namedimage: fn(d: self ref Display, name: string): ref Image;
# I/O to files
open: fn(d: self ref Display, name: string): ref Image;
readimage: fn(d: self ref Display, fd: ref Sys->FD): ref Image;
writeimage: fn(d: self ref Display, fd: ref Sys->FD, i: ref Image): int;
# color map
rgb2cmap: fn(d: self ref Display, r, g, b: int): int;
cmap2rgb: fn(d: self ref Display, c: int): (int, int, int);
cmap2rgba: fn(d: self ref Display, c: int): int;
};
# a mapping between characters and pictures; always attached to a Display
Font: adt
{
name: string; # *default* or a file name (this may change)
height: int; # interline spacing of font
ascent: int; # distance from baseline to top
display: ref Display; # where Font resides
# read from file or construct from local description
open: fn(d: ref Display, name: string): ref Font;
build: fn(d: ref Display, name, desc: string): ref Font;
# string extents
width: fn(f: self ref Font, str: string): int;
bbox: fn(f: self ref Font, str: string): Rect;
};
# a collection of windows; always attached to a Display
Screen: adt
{
id: int; # for export when public
image: ref Image; # root of window tree
fill: ref Image; # picture to use when repainting
display: ref Display; # where Screen resides
# create; see also Display.publicscreen
allocate: fn(image, fill: ref Image, public: int): ref Screen;
# allocate a new window
newwindow: fn(screen: self ref Screen, r: Rect, backing: int, color: int): ref Image;
# raise or lower a group of windows
top: fn(screen: self ref Screen, wins: array of ref Image);
bottom: fn(screen: self ref Screen, wins: array of ref Image);
};
# the state of a pointer device, e.g. a mouse or stylus
Pointer: adt
{
buttons: int; # bits 1 2 4 ... represent state of buttons left to right; 1 means pressed
xy: Point; # position
msec: int; # millisecond time stamp
};
# graphics context
Context: adt
{
display: ref Display; # frame buffer on which windows reside
screen: ref Screen; # place to make windows (mux only)
wm: chan of (string, chan of (string, ref Wmcontext)); # connect to window manager
};
# connection to window manager for one or more windows (as Images)
Wmcontext: adt
{
kbd: chan of int; # incoming characters from keyboard
ptr: chan of ref Pointer; # incoming stream of mouse positions
ctl: chan of string; # commands from wm to application
wctl: chan of string; # commands from application to wm
images: chan of ref Image; # exchange of images
connfd: ref Sys->FD; # connection control
ctxt: ref Context;
};
# functions that don't fit well in any adt
setalpha: fn(c: int, a: int): int;
bytesperline: fn(r: Rect, d: int): int;
icossin: fn(deg: int): (int, int);
icossin2: fn(p: Point): (int, int);
};
|