summaryrefslogtreecommitdiff
path: root/module/draw.m
diff options
context:
space:
mode:
Diffstat (limited to 'module/draw.m')
-rw-r--r--module/draw.m298
1 files changed, 298 insertions, 0 deletions
diff --git a/module/draw.m b/module/draw.m
new file mode 100644
index 00000000..730e62ac
--- /dev/null
+++ b/module/draw.m
@@ -0,0 +1,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)<<16 | ((CGreen<<4)|8)<<8 | ((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);
+};