GriffinHitTestImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Maureen Stone July 4, 1985 2:21:23 pm PDT
~
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: BOOLEAN ← FALSE;
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: BOOLEAN ← FALSE;
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;