PathImpl.mesa
Doug Wyatt, June 28, 1984 11:21:20 am PDT
PathImpl: CEDAR MONITOR
EXPORTS Path
~ BEGIN OPEN Path;
RealsFromSegs:
PROC[nSegs:
NAT, type: SegType]
RETURNS[
NAT] ~ {
realsPerSeg: NAT ~ (SELECT type FROM curve => 6, conic => 5, arc => 4, ENDCASE => 2);
n: INT ~ nSegs*realsPerSeg;
RETURN[MIN[n, NAT.LAST]];
};
New:
PUBLIC
PROC[nSegs:
NAT, expectedType: SegType ← move]
RETURNS[
PATH] ~ {
segsMax: NAT ~ MAX[4, nSegs];
realsMax: NAT ~ RealsFromSegs[segsMax, expectedType];
segs: Segs ~ NEW[SegsRep[segsMax] ← [length: 0, array: ]];
reals: Reals ~ NEW[RealsRep[realsMax] ← [length: 0, array: ]];
RETURN[NEW[PathRep ← [segs: segs, reals: reals, lp: [0, 0]]]];
};
nScratch: NAT ~ 3;
ScratchIndex: TYPE ~ [0..nScratch);
scratch: ARRAY ScratchIndex OF PATH ← ALL[NIL];
Alloc:
ENTRY
PROC
RETURNS[
PATH] ~ {
FOR i: ScratchIndex
IN ScratchIndex
DO
path: PATH ~ scratch[i];
IF path#NIL THEN { scratch[i] ← NIL; RETURN[path] };
ENDLOOP;
RETURN[NIL];
};
Free:
ENTRY
PROC[path:
PATH] ~ {
FOR i: ScratchIndex
DECREASING
IN ScratchIndex
DO
IF scratch[i]=NIL THEN { scratch[i] ← path; RETURN };
ENDLOOP;
};
ObtainScratch:
PUBLIC
PROC[nSegs:
NAT, expectedType: SegType ← move]
RETURNS[PATH] ~ {
ERROR;
};
ReleaseScratch:
PUBLIC
PROC[path:
PATH] ~ {
ERROR;
};
LastPoint:
PUBLIC
PROC[path:
PATH]
RETURNS[x, y:
REAL] ~ {
RETURN[path.lp.x, path.lp.y];
};
LastPointP:
PUBLIC
PROC[path:
PATH]
RETURNS[Pair] ~ {
RETURN[path.lp];
};
GetSegs:
PROC[path:
PATH]
RETURNS[Segs] ~ {
segs: Segs ~ path.segs;
IF segs.length<segs.max THEN RETURN[segs]
ELSE ERROR;
};
GetReals:
PROC[path:
PATH, n:
NAT]
RETURNS[Reals] ~ {
reals: Reals ~ path.reals;
IF (reals.length+n)<=reals.max THEN RETURN[reals]
ELSE ERROR;
};
MoveTo:
PUBLIC
PROC[path:
PATH, x, y:
REAL] ~ {
segs: Segs ~ GetSegs[path];
reals: Reals ~ GetReals[path, 2];
s: NAT ~ segs.length;
i: NAT ~ reals.length;
segs[s] ← [type: move, index: i];
segs.length ← s+1;
reals[i] ← x;
reals[i+1] ← y;
reals.length ← i+2;
path.lp ← [x, y];
};
MoveToP:
PUBLIC
PROC[path:
PATH, p: Pair] ~ {
MoveTo[path, p.x, p.y];
};
LineTo:
PUBLIC
PROC[path:
PATH, x, y:
REAL] ~ {
segs: Segs ~ GetSegs[path];
reals: Reals ~ GetReals[path, 2];
s: NAT ~ segs.length;
i: NAT ~ reals.length;
segs[s] ← [type: line, index: i];
segs.length ← s+1;
reals[i] ← x;
reals[i+1] ← y;
reals.length ← i+2;
path.lp ← [x, y];
};
LineToP:
PUBLIC
PROC[path:
PATH, p: Pair] ~ {
LineTo[path, p.x, p.y];
};
LineToX:
PUBLIC
PROC[path:
PATH, x:
REAL] ~ {
LineTo[path, x, path.lp.y];
};
LineToY:
PUBLIC
PROC[path:
PATH, y:
REAL] ~ {
LineTo[path, path.lp.x, y];
};
CurveTo:
PUBLIC
PROC[path:
PATH, x1, y1, x2, y2, x3, y3:
REAL] ~ {
segs: Segs ~ GetSegs[path];
reals: Reals ~ GetReals[path, 6];
s: NAT ~ segs.length;
i: NAT ~ reals.length;
segs[s] ← [type: curve, index: i];
segs.length ← s+1;
reals[i] ← x1;
reals[i+1] ← y1;
reals[i+2] ← x2;
reals[i+3] ← y2;
reals[i+4] ← x3;
reals[i+5] ← y3;
reals.length ← i+6;
path.lp ← [x3, y3];
};
CurveToP:
PUBLIC
PROC[path:
PATH, p1, p2, p3: Pair] ~ {
CurveTo[path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y];
};
ConicTo:
PUBLIC
PROC[path:
PATH, x1, y1, x2, y2:
REAL, r:
REAL] ~ {
segs: Segs ~ GetSegs[path];
reals: Reals ~ GetReals[path, 5];
s: NAT ~ segs.length;
i: NAT ~ reals.length;
segs[s] ← [type: conic, index: i];
segs.length ← s+1;
reals[i] ← x1;
reals[i+1] ← y1;
reals[i+2] ← x2;
reals[i+3] ← y2;
reals[i+4] ← r;
reals.length ← i+5;
path.lp ← [x2, y2];
};
ConicToP:
PUBLIC
PROC[path:
PATH, p1, p2: Pair, r:
REAL] ~ {
ConicTo[path, p1.x, p1.y, p2.x, p2.y, r];
};
ArcTo:
PUBLIC
PROC[path:
PATH, x1, y1, x2, y2:
REAL] ~ {
segs: Segs ~ GetSegs[path];
reals: Reals ~ GetReals[path, 4];
s: NAT ~ segs.length;
i: NAT ~ reals.length;
segs[s] ← [type: arc, index: i];
segs.length ← s+1;
reals[i] ← x1;
reals[i+1] ← y1;
reals[i+2] ← x2;
reals[i+3] ← y2;
reals.length ← i+4;
path.lp ← [x2, y2];
};
ArcToP:
PUBLIC
PROC[path:
PATH, p1, p2: Pair] ~ {
ArcTo[path, p1.x, p1.y, p2.x, p2.y];
};
MapPath:
PUBLIC PathProc ~ {
path: PATH ~ NARROW[data];
segs: Segs ~ path.segs;
reals: Reals ~ path.reals;
FOR s:
NAT
IN[0..segs.length)
DO
seg: Seg ~ segs[s];
i: NAT ~ seg.index;
SELECT seg.type
FROM
move => moveToP[[reals[i], reals[i+1]]];
line => lineToP[[reals[i], reals[i+1]]];
curve => curveToP[[reals[i], reals[i+1]], [reals[i+2], reals[i+3]], [reals[i+4], reals[i+5]]];
conic => conicToP[[reals[i], reals[i+1]], [reals[i+2], reals[i+3]], reals[i+4]];
arc => arcToP[[reals[i], reals[i+1]], [reals[i+2], reals[i+3]]];
ENDCASE => ERROR;
ENDLOOP;
};
END.