-- BoxerImpl.mesa
-- Last changed by Doug Wyatt, September 15, 1980 6:00 PM
DIRECTORY
Boxer,
Vector USING [Vec, Add, Sub],
Area USING [Rec, Handle, Rectangle],
Memory USING [zone];
BoxerImpl: PROGRAM
IMPORTS Memory,Vector,Area
EXPORTS Boxer SHARES Boxer = {
OPEN Boxer;
zone: UNCOUNTED ZONE = Memory.zone;
Data: PUBLIC TYPE = Area.Rec;
DataRef: TYPE = LONG POINTER TO Data;
iprocs: LONG POINTER TO READONLY Procs = zone.NEW[Procs = [
Put: IPut,
Include: IInclude,
Expand: CExpand,
Rectangle: CRectangle,
Copy: CCopy,
Free: CFree
]];
procs: LONG POINTER TO READONLY Procs = zone.NEW[Procs = [
Put: CPut,
Include: CInclude,
Expand: CExpand,
Rectangle: CRectangle,
Copy: CCopy,
Free: CFree
]];
sinkprocs: LONG POINTER TO READONLY Procs = zone.NEW[Procs = [
Put: SPut,
Include: SInclude,
Expand: SExpand,
Rectangle: SRectangle,
Copy: SCopy,
Free: SFree
]];
-- Procedures for creating a Boxer object
sink: PUBLIC Handle ← zone.NEW[Object ← [procs: sinkprocs, data: NIL]];
New: PUBLIC PROC RETURNS[Handle] = {
d: DataRef=zone.NEW[Data ← [ll: [0,0], ur: [0,0]]];
RETURN[zone.NEW[Object ← [procs: iprocs, data: d]]];
};
-- Operations on a Boxer
IPut: PROC[self: Handle, v: Vector.Vec] = {
d: DataRef=self.data;
d.ll←d.ur←v; self.procs←procs;
};
CPut: PROC[self: Handle, v: Vector.Vec] = {
d: DataRef=self.data;
IF v.x<d.ll.x THEN d.ll.x←v.x
ELSE IF v.x>d.ur.x THEN d.ur.x←v.x;
IF v.y<d.ll.y THEN d.ll.y←v.y
ELSE IF v.y>d.ur.y THEN d.ur.y←v.y;
};
SPut: PROC[self: Handle, v: Vector.Vec] = {
};
IInclude: PROC[self: Handle, area: Area.Handle] = {
d: DataRef=self.data;
d↑←Area.Rectangle[area];
self.procs←procs;
};
CInclude: PROC[self: Handle, area: Area.Handle] = {
d: DataRef=self.data;
r: Area.Rec=Area.Rectangle[area];
IF r.ll.x<d.ll.x THEN d.ll.x←r.ll.x;
IF r.ll.y<d.ll.y THEN d.ll.y←r.ll.y;
IF r.ur.x>d.ur.x THEN d.ur.x←r.ur.x;
IF r.ur.y>d.ur.y THEN d.ur.y←r.ur.y;
};
SInclude: PROC[self: Handle, area: Area.Handle] = {
};
CExpand: PROC[self: Handle, slop: REAL] = {
d: DataRef=self.data;
v: Vector.Vec=[slop,slop];
d.ll←Vector.Sub[d.ll,v];
d.ur←Vector.Add[d.ur,v];
};
SExpand: PROC[self: Handle, slop: REAL] = {
};
CRectangle: PROC[self: Handle] RETURNS[Area.Rec] = {
d: DataRef=self.data;
RETURN[d↑];
};
SRectangle: PROC[self: Handle] RETURNS[Area.Rec] = {
RETURN[[[0,0],[0,0]]];
};
CCopy: PROC[self: Handle] RETURNS[Handle] = {
d: DataRef=self.data;
dd: DataRef=zone.NEW[Data ← d↑];
RETURN[zone.NEW[Object ← [procs: self.procs, data: dd]]];
};
SCopy: PROC[self: Handle] RETURNS[Handle] = {
RETURN[sink];
};
CFree: PROC[self: Handle] = {
d: DataRef←self.data;
zone.FREE[@d]; zone.FREE[@self];
};
SFree: PROC[self: Handle] = {
};
}.