-- File: IPCoVerifierImpl.mesa
-- Last Edited by: CSChow, February 2, 1985 2:00:53 am PST
Preas, August 2, 1986 12:19:44 pm PDT
changed definition of coDimX and coDimY in GetTestComps November 30, 1987 2:42:26 pm PST
DIRECTORY
OrderedSymbolTableRef USING [Table, CompareProc, CreateTable, LookupSmallest, LookupNextLarger, Insert, DestroyTable, EnumerateIncreasing],
Imager USING [Context, MaskStrokeTrajectory, SetGray],
ImagerPath USING [Trajectory, MoveTo, LineToX, LineToY],
Rope,
IPConstants,
Misc,
IPCoTab,
IPCoVerifier;
IPCoVerifierImpl: CEDAR PROGRAM
IMPORTS OrderedSymbolTableRef, Rope, Misc, IPCoTab, Imager, ImagerPath
EXPORTS IPCoVerifier = BEGIN OPEN CT: IPCoTab, IPCoVerifier;
Conflict: TYPE = REF ConflictRep;
ConflictRep: TYPE = RECORD[comp1, comp2: CompItem];
Create: PUBLIC PROC[yOrdered: BOOLTRUE] RETURNS[Ref]={
RETURN[NEW[Rep ← [yOrdered: yOrdered, comps: CompsCreate[yOrdered]]]]
}; --Create --
Destroy: PUBLIC PROC [r: Ref] ={CompsDestroy[r.comps]}; -- Destroy--
InsertComponent: PUBLIC PROC[r: Ref, co: IPCoTab.Component]={
CompsInsert[r.comps, co]
}; -- InsertComponent--
CompItems: PUBLIC PROC [r: Ref, p: EachCompItemAction] ={
p1: PROC[Item: REF] RETURNS[BOOL] ={RETURN[p[NARROW[Item, CompItem]]]};
OrderedSymbolTableRef.EnumerateIncreasing[r.comps.tab, p1];
}; --CompItems--
GetBRect: PUBLIC PROC[r: Ref] RETURNS [Misc.Rect] ={RETURN [r.bRect]}; --GetBRect--
Verify: PUBLIC PROC [r: Ref] RETURNS[overlaps: LIST OF Misc.Rect ← NIL]={
conflicts: LIST OF Conflict ← NIL;
mainComp: CompItem;
WHILE (mainComp ← GetMainComp[r.comps]) # NIL DO
{r.bRect ← Misc.RectMakeBRect[r.bRect, IPCoTab.GetBRect[mainComp.comp]];
FOR testComps: LIST OF CompItem ← GetTestComps[r.comps, mainComp, r.yOrdered], testComps.rest UNTIL testComps = NIL DO {
testComp: CompItem ← testComps.first;
intrsctn: Misc.Rect;
--Part (1) ComputeHint for mainComp And Check for overlap--
IF (intrsctn ← ClipComp[mainComp, IPCoTab.GetBRect[testComp.comp]]) = NIL THEN LOOP;
IF (intrsctn ← ClipComp[testComp, intrsctn, TRUE, TRUE])# NIL THEN {
IF CompComputeHint[mainComp, intrsctn]
THEN NULL
ELSE {overlaps ← CONS[ClipComp[mainComp, intrsctn], overlaps]; LOOP}};
--Part (2) ComputeHint for testComp. Assumed all overlaps handled above. Handle Conflict--
IF (intrsctn ← ClipComp[mainComp, IPCoTab.GetBRect[testComp.comp]]) = NIL THEN LOOP;
IF (intrsctn ← ClipComp[testComp, intrsctn, FALSE]) = NIL THEN LOOP;
IF CompComputeHint[mainComp, intrsctn, TRUE] AND CompComputeHint[mainComp, intrsctn, TRUE]
THEN {conflicts ← CONS[NEW[ConflictRep← [mainComp, testComp]],conflicts]; LOOP};
IF CompComputeHint[testComp, intrsctn] THEN LOOP;
ERROR};
ENDLOOP};
ENDLOOP;
WHILE conflicts # NIL DO {
c: Conflict ← conflicts.first;
r: Misc.Rect;
IF (r ← ClipComp[c.comp1, IPCoTab.GetBRect[c.comp2.comp], FALSE]) = NIL THEN GOTO nextIter;
IF (r ← ClipComp[c.comp2, r, FALSE]) = NIL THEN GOTO nextIter;
ResolveConflict[c.comp1, c.comp2, r];
EXITS
nextIter => {conflicts ← conflicts.rest}};
ENDLOOP;
}; -- Verify--
PaintSelf: PUBLIC PROC[r: Ref, context: Imager.Context, xOffset, yOffset: REAL, scaleFactor: REAL ← 1.0, stipple: CARDINAL ← IPConstants.Gray, drawOutline: BOOLTRUE, drawComp:BOOLFALSE, showCompName: BOOLTRUE]={
paintCompItem: EachCompItemAction ={
co: IPCoTab.Component ← cI.comp;
IF drawOutline THEN {
OPEN h: cI.hint;
path: ImagerPath.Trajectory;
sw, se, ne, nw: IPCoTab.CornerSpace;
originX, originY: REAL;
dimX, dimY: REAL;
[originX, originY] ← co.origin;
originX ← xOffset + (originX * scaleFactor);
originY ← yOffset + (originY *scaleFactor);
[dimX, dimY] ← CT.GetDim[co];
dimX ← dimX * scaleFactor;
dimY ← dimY * scaleFactor;
[sw, se, ne, nw] ← CT.GetCornerSps[co];
Imager.SetGray[context, IPConstants.Black];
IF h.sw THEN {
path ← ImagerPath.MoveTo[[originX, originY + sw.y * scaleFactor]];
path ← ImagerPath.LineToX[path, originX + sw.x * scaleFactor];
path ← ImagerPath.LineToY[path, originY]} ELSE {
path ← ImagerPath.MoveTo[[originX, originY]]};
IF h.se THEN {
path ← ImagerPath.LineToX[path, originX+ dimX - se.x * scaleFactor];
path ← ImagerPath.LineToY[path, originY + se.y * scaleFactor];
path ← ImagerPath.LineToX[path, originX + dimX];} ELSE{
path ← ImagerPath.LineToX[path, originX + dimX];};
IF h.ne THEN {
path ← ImagerPath.LineToY[path, originY +dimY - ne.y * scaleFactor];
path ← ImagerPath.LineToX[path, originX + dimX - ne.x * scaleFactor];
path ← ImagerPath.LineToY[path, originY + dimY];} ELSE {
path ← ImagerPath.LineToY[path, originY + dimY]};
IF h.nw THEN {
path ← ImagerPath.LineToX[path, originX + nw.x * scaleFactor];
path ← ImagerPath.LineToY[path, originY + dimY - nw.y * scaleFactor];
path ← ImagerPath.LineToX[path, originX];} ELSE {
path ← ImagerPath.LineToX[path, originX]};
IF h.sw THEN {
path ← ImagerPath.LineToY[path, originY + sw.y * scaleFactor];} ELSE {
path ← ImagerPath.LineToY[path, originY]};
Imager.MaskStrokeTrajectory[context, path];};
IF drawComp THEN IPCoTab.PaintComponent[co, context, xOffset, yOffset, scaleFactor, stipple, showCompName];
}; --paintCompItem--
CompItems[r, paintCompItem]
}; --PaintSelf --
--#########Private##############--
xCompareProc: OrderedSymbolTableRef.CompareProc={
c1, c2: IPCoTab.Component;
IF r1 = r2 THEN RETURN [equal];
c1 ← NARROW[r1, CompItem].comp;
c2 ← NARROW[r2, CompItem].comp;
IF IPCoTab.GetOrigin[c1].x > IPCoTab.GetOrigin[c2].x THEN RETURN[greater];
IF IPCoTab.GetOrigin[c1].x < IPCoTab.GetOrigin[c2].x THEN RETURN[less];
IF IPCoTab.GetOrigin[c1].y > IPCoTab.GetOrigin[c2].y THEN RETURN[greater];
IF IPCoTab.GetOrigin[c1].y < IPCoTab.GetOrigin[c2].y THEN RETURN[less];
RETURN[Rope.Compare[IPCoTab.GetName[c1], IPCoTab.GetName[c2]]]}; --xCompareProc--
yCompareProc: OrderedSymbolTableRef.CompareProc={
c1, c2: IPCoTab.Component;
IF r1 = r2 THEN RETURN [equal];
c1 ← NARROW[r1, CompItem].comp;
c2 ← NARROW[r2, CompItem].comp;
IF IPCoTab.GetOrigin[c1].y > IPCoTab.GetOrigin[c2].y THEN RETURN[greater];
IF IPCoTab.GetOrigin[c1].y < IPCoTab.GetOrigin[c2].y THEN RETURN[less];
IF IPCoTab.GetOrigin[c1].x > IPCoTab.GetOrigin[c2].x THEN RETURN[greater];
IF IPCoTab.GetOrigin[c1].x < IPCoTab.GetOrigin[c2].x THEN RETURN[less];
RETURN[Rope.Compare[IPCoTab.GetName[c1], IPCoTab.GetName[c2]]]}; --yCompareProc--
CompsCreate: PROC[yOrdered: BOOL] RETURNS[Comps] = {
RETURN[NEW[CompsRep ← [tab:OrderedSymbolTableRef.CreateTable[IF yOrdered THEN yCompareProc ELSE xCompareProc]]]]}; -- CreateComps--
CompsInsert: PROC[comps: Comps, co: IPCoTab.Component] ={
cI: CompItem ← NEW[CompItemRep ← [comp: co]];
OrderedSymbolTableRef.Insert[comps.tab, cI];
}; --CompsInsert--
CompsDestroy: PROC [comps: Comps] ={
OrderedSymbolTableRef.DestroyTable[comps.tab];
}; -- Destroy--
LastMainComp: REFNIL;
GetMainComp: PROC[comps: Comps] RETURNS[CompItem] ={
IF LastMainComp = NIL
THEN {LastMainComp ← OrderedSymbolTableRef.LookupSmallest[comps.tab]}
ELSE {LastMainComp ← OrderedSymbolTableRef.LookupNextLarger[comps.tab, LastMainComp]};
RETURN[NARROW[LastMainComp]]}; --GetMainComp--
GetTestComps: PROC[comps: Comps, mComp: CompItem, yOrdered: BOOL] RETURNS[tComps: LIST OF CompItem ← NIL] ={
coDimX, coDimY: INT;
compMaxCoord: INT;
[coDimX, coDimY] ← CT.GetDim[mComp.comp];
compMaxCoord ← IF yOrdered THEN mComp.comp.origin.y + coDimY ELSE mComp.comp.origin.x + coDimX;
WHILE (mComp ← NARROW[OrderedSymbolTableRef.LookupNextLarger[comps.tab, mComp], CompItem]) #NIL DO
IF yOrdered
THEN {IF mComp.comp.origin.y > compMaxCoord THEN RETURN}
ELSE {IF mComp.comp.origin.x > compMaxCoord THEN RETURN};
tComps ← CONS[mComp, tComps];
ENDLOOP;
}; --GetTestComps--
PartialClipping: ERROR[partialResult: Misc.Rect] = CODE;
ClipComp: PROC[cI: CompItem, clipRect: Misc.Rect, partialClippingOk: BOOLTRUE, trueShape: BOOLFALSE] RETURNS[rect: Misc.Rect] ={
OPEN h: cI.hint;
comp: IPCoTab.Component ← cI.comp;
fullyClipped: BOOLTRUE;
sw, se, ne, nw: Misc.Rect;
IF (rect ← Misc.RectIntersect[IPCoTab.GetBRect[comp], clipRect]) = NIL THEN RETURN;
[sw, se, ne, nw] ← IPCoTab.GetCornerRects[comp];
IF trueShape OR h.sw THEN {rect ← Misc.RectSubtract[rect, sw ! Misc.RectSubtractFailure =>{rect ← r1; fullyClipped← FALSE; CONTINUE}]};
IF trueShape OR h.se THEN {rect ← Misc.RectSubtract[rect, se ! Misc.RectSubtractFailure =>{rect ← r1; fullyClipped← FALSE; CONTINUE}]};
IF trueShape OR h.ne THEN {rect ← Misc.RectSubtract[rect, ne ! Misc.RectSubtractFailure =>{rect ← r1; fullyClipped← FALSE; CONTINUE}]};
IF trueShape OR h.nw THEN {rect ← Misc.RectSubtract[rect, nw ! Misc.RectSubtractFailure =>{rect ← r1; fullyClipped← FALSE; CONTINUE}]};
IF fullyClipped OR partialClippingOk THEN {RETURN[rect]} ELSE {RETURN WITH ERROR PartialClipping[rect]};
}; --ClipComp--
CompComputeHint: PROC [cI: CompItem, rect: Misc.Rect, fakeIt: BOOLFALSE] RETURNS [done: BOOLFALSE] = {
IF rect = NIL THEN ERROR;
{OPEN h: cI.hint;
comp: IPCoTab.Component ← cI.comp;
sw, se, ne, nw: Misc.Rect;
[sw, se, ne, nw] ← IPCoTab.GetCornerRects[comp];
IF Misc.RectIntersect[sw, rect] # NIL THEN {
IF fakeIt THEN NULL ELSE {h.sw ← TRUE};
IF Misc.RectContainp[sw, rect] THEN {RETURN[TRUE]}};
IF Misc.RectIntersect[se, rect] # NIL THEN {
IF fakeIt THEN NULL ELSE {h.se ← TRUE};
IF Misc.RectContainp[se, rect] THEN {RETURN[TRUE]}};
IF Misc.RectIntersect[ne, rect] # NIL THEN {
IF fakeIt THEN NULL ELSE {h.ne ← TRUE};
IF Misc.RectContainp[ne, rect] THEN {RETURN[TRUE]}};
IF Misc.RectIntersect[nw, rect] # NIL THEN {
IF fakeIt THEN NULL ELSE {h.nw ← TRUE};
IF Misc.RectContainp[nw, rect] THEN {RETURN[TRUE]}};
};
}; --CompComputeHint--
ResolveConflict: PROC[c1, c2: CompItem, r: Misc.Rect] ={
IF r = NIL
THEN ERROR
ELSE {OPEN h1: c1.hint, h2: c2.hint;
sw1, se1, ne1, nw1, sw2, se2, ne2, nw2: Misc.Rect;
[sw1, se1, ne1, nw1] ← IPCoTab.GetCornerRects[c1.comp];
[sw2, se2, ne2, nw2] ← IPCoTab.GetCornerRects[c2.comp];
IF sw1.RectContainp[r] THEN {IF NOT ne2.RectContainp[r] THEN ERROR;
IF ne2.RectArea > sw1.RectArea THEN {h1.sw ← TRUE} ELSE {h2.ne ← TRUE};
RETURN};
IF se1.RectContainp[r] THEN {IF NOT nw2.RectContainp[r] THEN ERROR;
IF nw2.RectArea > se1.RectArea THEN {h1.se ← TRUE} ELSE {h2.nw ← TRUE};
RETURN};
IF ne1.RectContainp[r] THEN {IF NOT sw2.RectContainp[r] THEN ERROR;
IF sw2.RectArea > ne1.RectArea THEN {h1.ne ← TRUE} ELSE {h2.sw ← TRUE};
RETURN};
IF nw1.RectContainp[r] THEN {IF NOT se2.RectContainp[r] THEN ERROR;
IF se2.RectArea > nw1.RectArea THEN {h1.nw ← TRUE} ELSE {h2.se ← TRUE};
RETURN};
ERROR;}
}; --ResolveConflict--
END.