GriffinHitTestImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Maureen Stone July 4, 1985 2:21:23 pm PDT
GriffinHitTestImpl: CEDAR PROGRAM
IMPORTS Encoding
EXPORTS GriffinHitTest
~ BEGIN
hit test
GetObjectHandle: PUBLIC PROCEDURE [pt: PointDefs.ScrPt] RETURNS [ObjectHandle] =
BEGIN
new: ObjectHandle ← GetObjectHandleBetweenObjects[pt, NIL,NIL];
IF new#NIL THEN WITH type: new SELECT FROM
selectToken => RETURN[type.selectedObj];
ENDCASE;
RETURN[new];
END;
GetObjectHandleBetweenObjects: PUBLIC PROCEDURE [pt: PointDefs.ScrPt,
topObject,bottomObject: ObjectHandle] RETURNS [ObjectHandle] =
BEGIN OPEN EncodingDefs;
obj: REF Object;
tol: INTEGER;
IF topObject=NIL THEN topObject ← tailObject;
IF bottomObject=NIL THEN bottomObject ← headObject;
FOR obj ← topObject, obj.backLink UNTIL obj = bottomObject DO
IF ~Visible[obj] THEN LOOP;
IF NOT obj.validEncoding THEN WITH obj SELECT FROM
object: REF Object[shape] => {
EncodingDefs.DeleteChainEncoding[object.chainEncoding];
EncodingDefs.DeleteAreaEncoding[object.areaEncoding];
EncodeTrajectory[object,object.closed];
IF object.closed THEN EncodeArea[object];
};
ENDCASE => ERROR;
IF pt[X]<obj.tl[X] OR pt[X]>obj.br[X] OR pt[Y]<obj.tl[Y] OR pt[Y]>obj.br[Y] THEN LOOP;
obj may be touched
WITH object: obj SELECT FROM
shape => BEGIN
tol ← MAX[1,ObjValToScrVal[object.style.width/2]];
IF TestTraj[pt,object.chainEncoding,tol] THEN RETURN[obj]
ELSE IF obj.style.filled AND TestArea[pt,object.areaEncoding,tol] THEN RETURN[obj];
END;
caption,token,menu, selectToken => RETURN[obj];
ENDCASE;
ENDLOOP;
RETURN[NIL];
END;
TestTraj: PROCEDURE[pt: ScrPt, encoding: EncodingDefs.ChainHandle,tol: INTEGER] RETURNS[BOOLEAN]=
BEGIN
flag: BOOLEANFALSE;
SetFlag: PROCEDURE[found: PointDefs.ScrPt] RETURNS[stop: BOOLEAN] = BEGIN
IF ABS[found[X]-pt[X]] > tol OR ABS[found[Y]-pt[Y]] > tol THEN RETURN[FALSE]
ELSE {flag ← TRUE; RETURN[TRUE]};
END;
UNTIL encoding=NIL DO
IF NOT ((pt[X] <encoding.tl[X]-tol) OR (pt[X] >encoding.br[X]+tol)
OR (pt[Y] <encoding.tl[Y]-tol) OR (pt[Y] >encoding.br[Y]+tol))
is now a possibility
THEN EncodingDefs.TestChainChunk[encoding,SetFlag];
IF flag THEN RETURN[TRUE];
encoding ← encoding.link;
ENDLOOP;
RETURN[FALSE];
END;
TestArea: PROCEDURE[pt: ScrPt, encoding: EncodingDefs.AreaHandle,tol: INTEGER] RETURNS[BOOLEAN]=
BEGIN
flag: BOOLEANFALSE;
SetFlag: PROCEDURE[y,lx,dx: INTEGER] RETURNS[stop: BOOLEAN] = BEGIN
rx: INTEGER ← lx+dx+tol;
lx ← lx-tol;
IF pt[Y]=y AND pt[X] IN [lx..rx] THEN {flag ← TRUE; RETURN[TRUE] }
ELSE RETURN[FALSE];
END;
UNTIL encoding=NIL DO
IF NOT ((pt[X] <encoding.tl[X]-tol) OR (pt[X] >encoding.br[X]+tol)
OR (pt[Y] <encoding.tl[Y]-tol) OR (pt[Y] >encoding.br[Y]+tol))
is now a possibility
THEN EncodingDefs.TestAreaChunk[encoding,SetFlag];
IF flag THEN RETURN[TRUE];
encoding ← encoding.link;
ENDLOOP;
RETURN[FALSE];
END;
END.